@neptune.fintech/web-ui 1.0.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 (42) hide show
  1. package/LICENSE +104 -0
  2. package/README.md +62 -0
  3. package/dist/components/base.d.ts +18 -0
  4. package/dist/components/base.d.ts.map +1 -0
  5. package/dist/components/base.js +57 -0
  6. package/dist/components/base.js.map +1 -0
  7. package/dist/components/button.d.ts +12 -0
  8. package/dist/components/button.d.ts.map +1 -0
  9. package/dist/components/button.js +70 -0
  10. package/dist/components/button.js.map +1 -0
  11. package/dist/components/card.d.ts +13 -0
  12. package/dist/components/card.d.ts.map +1 -0
  13. package/dist/components/card.js +46 -0
  14. package/dist/components/card.js.map +1 -0
  15. package/dist/components/financial.d.ts +23 -0
  16. package/dist/components/financial.d.ts.map +1 -0
  17. package/dist/components/financial.js +164 -0
  18. package/dist/components/financial.js.map +1 -0
  19. package/dist/components/inputs.d.ts +27 -0
  20. package/dist/components/inputs.d.ts.map +1 -0
  21. package/dist/components/inputs.js +167 -0
  22. package/dist/components/inputs.js.map +1 -0
  23. package/dist/components/nav.d.ts +24 -0
  24. package/dist/components/nav.d.ts.map +1 -0
  25. package/dist/components/nav.js +131 -0
  26. package/dist/components/nav.js.map +1 -0
  27. package/dist/index.d.ts +12 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +19 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/register.d.ts +3 -0
  32. package/dist/register.d.ts.map +1 -0
  33. package/dist/register.js +24 -0
  34. package/dist/register.js.map +1 -0
  35. package/dist/theme/applyTheme.d.ts +27 -0
  36. package/dist/theme/applyTheme.d.ts.map +1 -0
  37. package/dist/theme/applyTheme.js +118 -0
  38. package/dist/theme/applyTheme.js.map +1 -0
  39. package/package.json +58 -0
  40. package/styles/neptune-odyssey.css +6 -0
  41. package/styles/system.css +74 -0
  42. package/styles/themes.css +246 -0
package/LICENSE ADDED
@@ -0,0 +1,104 @@
1
+ Neptune Odyssey Community License
2
+ Version 1.0
3
+
4
+ Copyright (c) 2026 Neptune.Fintech. All rights reserved.
5
+
6
+ This is a source-available license. It is NOT an OSI-approved open-source license.
7
+ "Neptune Odyssey" and "Neptune.Fintech" are names and marks of the Licensor; this
8
+ license does not grant rights to use them except as required for attribution.
9
+
10
+ ------------------------------------------------------------------------------
11
+ 1. DEFINITIONS
12
+ ------------------------------------------------------------------------------
13
+ "Software" means the Neptune Odyssey design system and all materials in this
14
+ repository: design tokens, configuration files, documentation, reference
15
+ implementations, and generated libraries (Flutter, web, and any other target).
16
+
17
+ "Licensor" means Neptune.Fintech.
18
+
19
+ "You" means the individual or legal entity exercising rights under this license,
20
+ together with all entities that control, are controlled by, or are under common
21
+ control with that entity.
22
+
23
+ "Qualifying User" means You, if You are either:
24
+ (a) using the Software for a Non-Commercial Purpose; or
25
+ (b) an individual or entity whose total gross revenue (across all controlled
26
+ entities) in the most recently completed 12-month period was less than
27
+ twenty-five thousand United States dollars (USD $25,000), or the equivalent
28
+ in any other currency.
29
+
30
+ "Non-Commercial Purpose" means use that is not primarily intended for or directed
31
+ toward commercial advantage or monetary compensation — including personal
32
+ projects, evaluation, research, teaching, and use by registered non-profit or
33
+ charitable organizations.
34
+
35
+ ------------------------------------------------------------------------------
36
+ 2. GRANT OF RIGHTS (for Qualifying Users)
37
+ ------------------------------------------------------------------------------
38
+ Subject to the terms below, the Licensor grants each Qualifying User a worldwide,
39
+ royalty-free, non-exclusive, non-transferable license to use, copy, modify,
40
+ create derivative works of, and distribute the Software, including in Your own
41
+ applications and products, for as long as You remain a Qualifying User.
42
+
43
+ ------------------------------------------------------------------------------
44
+ 3. COMMERCIAL USE ABOVE THE THRESHOLD
45
+ ------------------------------------------------------------------------------
46
+ If You do not meet the definition of a Qualifying User — for example, if Your
47
+ gross revenue equals or exceeds USD $25,000 in the most recently completed
48
+ 12-month period and Your use is not a Non-Commercial Purpose — You must obtain a
49
+ separate commercial license from the Licensor before using the Software in
50
+ production. Contact: licensing@neptune.fintech.
51
+
52
+ A Qualifying User who later crosses the revenue threshold has a 60-day grace
53
+ period from the end of the 12-month period in which the threshold was crossed to
54
+ obtain a commercial license or cease production use.
55
+
56
+ ------------------------------------------------------------------------------
57
+ 4. CONDITIONS
58
+ ------------------------------------------------------------------------------
59
+ (a) Attribution. You must retain, in source and in any distributed copies of the
60
+ Software or substantial portions of it, this license, the copyright notice,
61
+ and a notice stating the Software is "Neptune Odyssey by Neptune.Fintech."
62
+ (b) No misrepresentation. You may not remove or alter notices, or represent the
63
+ Software (or a derivative) as Your own original design system.
64
+ (c) No trademark use. This license grants no rights in the Licensor's names,
65
+ logos, or brand names beyond the attribution required above.
66
+ (d) The brands, names, and visual identities of example tenants in this
67
+ repository (e.g. "Andalus Bank", "Nuran", "First Gulf Libyan") are reference
68
+ illustrations only and convey no rights.
69
+
70
+ ------------------------------------------------------------------------------
71
+ 5. TERMINATION
72
+ ------------------------------------------------------------------------------
73
+ This license terminates automatically if You breach it and do not cure the breach
74
+ within 30 days of becoming aware of it, or if You use the Software in production
75
+ while not a Qualifying User and without a commercial license. Upon termination
76
+ You must cease use and distribution, except that copies You distributed to
77
+ downstream Qualifying Users in compliance with this license remain licensed.
78
+
79
+ ------------------------------------------------------------------------------
80
+ 6. DISCLAIMER OF WARRANTY
81
+ ------------------------------------------------------------------------------
82
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
83
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
84
+ FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
85
+
86
+ ------------------------------------------------------------------------------
87
+ 7. LIMITATION OF LIABILITY
88
+ ------------------------------------------------------------------------------
89
+ IN NO EVENT SHALL THE LICENSOR BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER
90
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM,
91
+ OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
92
+ SOFTWARE.
93
+
94
+ ------------------------------------------------------------------------------
95
+ 8. SUMMARY (non-binding, for convenience)
96
+ ------------------------------------------------------------------------------
97
+ • Free to use, modify and ship — including commercially — IF your use is
98
+ non-commercial OR your organization makes under USD $25,000/year.
99
+ • Make USD $25,000/year or more from commercial use? Get a commercial license:
100
+ licensing@neptune.fintech.
101
+ • Keep the attribution. Don't pass it off as your own. Don't use our marks.
102
+
103
+ This summary does not modify the terms above. For anything load-bearing, consult
104
+ your own legal counsel — the Licensor provides this text without legal advice.
package/README.md ADDED
@@ -0,0 +1,62 @@
1
+ # @neptune.fintech/web-ui
2
+
3
+ Framework-agnostic **web kit** for [Neptune Odyssey](https://neptune.ly) — the white-label
4
+ banking design system by **Neptune.Fintech**. Standards-based custom elements, themed
5
+ entirely through **CSS variables** (zero runtime CSS-in-JS), with the one-call `applyTheme`
6
+ surface. Works with plain HTML, and is the layer the Svelte and Vue packages wrap.
7
+
8
+ > Source-available under the **Neptune Odyssey Community License v1.0** — free for
9
+ > non-commercial use and orgs under USD $25k/yr. See `LICENSE`.
10
+
11
+ ## Install
12
+
13
+ ```sh
14
+ pnpm add @neptune.fintech/web-ui @neptune.fintech/tokens
15
+ ```
16
+
17
+ ESM-only, tree-shakeable, SSR-safe. Importing modules never touches the DOM; element
18
+ registration and theming run only when you call them.
19
+
20
+ ## Use
21
+
22
+ ```ts
23
+ import "@neptune.fintech/web-ui/styles.css"; // ships themes.css + system.css
24
+ import { applyTheme, registerAll } from "@neptune.fintech/web-ui";
25
+
26
+ registerAll(); // define the custom elements
27
+ applyTheme(document.documentElement, "andalus", { mode: "system", dir: "auto" });
28
+ ```
29
+
30
+ ```html
31
+ <npt-app-bar title="Accounts"></npt-app-bar>
32
+ <npt-balance-card hero label="Available balance" amount="12,480.50" currency="LYD"
33
+ account="•••• 4821"></npt-balance-card>
34
+ <npt-transaction-row title="Coffee" subtitle="Today · Card" amount="-4.50" currency="LYD">
35
+ </npt-transaction-row>
36
+ <npt-button variant="filled">New transfer</npt-button>
37
+ ```
38
+
39
+ ## Three ways to theme — one surface
40
+
41
+ ```ts
42
+ applyTheme(root, "neptune"); // 1 · reference brand id
43
+ applyTheme(root, "NO1-AYB4AKKeeABWDBIaIiw4B_YBAAABAQEBAQAAyA"); // 2 · brandprint string
44
+ applyTheme(root, { primary: {L,C,H}, tertiary: {…}, corners: {…}, … }); // 3 · config
45
+ ```
46
+
47
+ For the four reference brands, re-skinning is **pure CSS** — `applyTheme` only sets
48
+ `data-theme`/`data-mode`/`dir`; the shipped `styles.css` holds every variable, so swapping
49
+ a brand is zero JavaScript. Custom configs and brandprints resolve through
50
+ `@neptune.fintech/tokens` and write the resolved variables onto the element.
51
+
52
+ ## Components
53
+
54
+ `npt-button` · `npt-card` (incl. `glass`) · `npt-balance-card` · `npt-transaction-row` ·
55
+ `npt-text-field` · `npt-chip` · `npt-badge` · `npt-app-bar` · `npt-nav-bar` / `npt-nav-item`.
56
+
57
+ Every component reads **only** `var(--md-sys-color-*)` / `var(--npt-*)` — no literal color,
58
+ radius, or font anywhere (principle P2). Layout is logical (`*-inline-*`) so it mirrors in
59
+ RTL for free. Focus rings are visible; reduced-motion is honoured; targets are ≥ 48px.
60
+
61
+ ---
62
+ © 2026 Neptune.Fintech. The bundled example brands are reference illustrations only.
@@ -0,0 +1,18 @@
1
+ export declare abstract class NptElement extends HTMLElement {
2
+ /** Component CSS — custom-property driven only. Implemented per component. */
3
+ protected abstract styles(): string;
4
+ /** Shadow markup. Implemented per component. */
5
+ protected abstract render(): string;
6
+ protected root: ShadowRoot;
7
+ constructor();
8
+ connectedCallback(): void;
9
+ protected update(): void;
10
+ }
11
+ /** Identity tag for editor CSS highlighting; returns the string unchanged. */
12
+ export declare const css: (strings: TemplateStringsArray, ...values: unknown[]) => string;
13
+ export declare const html: (strings: TemplateStringsArray, ...values: unknown[]) => string;
14
+ /** Register a custom element only in a browser, idempotently. SSR-safe. */
15
+ export declare function define(tag: string, ctor: CustomElementConstructor): void;
16
+ /** Shared focus-visible ring + reduced-motion guard, reused by components. */
17
+ export declare const A11Y: string;
18
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/components/base.ts"],"names":[],"mappings":"AAWA,8BAAsB,UAAW,SAAQ,WAAW;IAClD,8EAA8E;IAC9E,SAAS,CAAC,QAAQ,CAAC,MAAM,IAAI,MAAM;IACnC,gDAAgD;IAChD,SAAS,CAAC,QAAQ,CAAC,MAAM,IAAI,MAAM;IAEnC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC;;IAO3B,iBAAiB,IAAI,IAAI;IAIzB,SAAS,CAAC,MAAM,IAAI,IAAI;CAWzB;AAED,8EAA8E;AAC9E,eAAO,MAAM,GAAG,GAAI,SAAS,oBAAoB,EAAE,GAAG,QAAQ,OAAO,EAAE,KAAG,MACiB,CAAC;AAE5F,eAAO,MAAM,IAAI,YAHY,oBAAoB,aAAa,OAAO,EAAE,KAAG,MAGnD,CAAC;AAExB,2EAA2E;AAC3E,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,wBAAwB,GAAG,IAAI,CAGxE;AAED,8EAA8E;AAC9E,eAAO,MAAM,IAAI,QAehB,CAAC"}
@@ -0,0 +1,57 @@
1
+ // Neptune Odyssey — custom-element base · © 2026 Neptune.Fintech (neptune.ly)
2
+ //
3
+ // Standards-based custom elements. Styles live in a Shadow DOM stylesheet that
4
+ // reads ONLY CSS custom properties (--md-sys-color-*, --npt-*) — and custom
5
+ // properties inherit THROUGH the shadow boundary, so a component is encapsulated
6
+ // yet fully themed by whatever data-theme/data-mode is on an ancestor. No literal
7
+ // colors/radii/fonts; no runtime CSS-in-JS beyond a single cached stylesheet per
8
+ // component class. SSR-safe: nothing touches the DOM at import time.
9
+ const sheetCache = new WeakMap();
10
+ export class NptElement extends HTMLElement {
11
+ constructor() {
12
+ super();
13
+ this.root = this.attachShadow({ mode: "open" });
14
+ }
15
+ connectedCallback() {
16
+ this.update();
17
+ }
18
+ update() {
19
+ const ctor = this.constructor;
20
+ let sheet = sheetCache.get(ctor);
21
+ if (!sheet) {
22
+ sheet = new CSSStyleSheet();
23
+ sheet.replaceSync(this.styles());
24
+ sheetCache.set(ctor, sheet);
25
+ }
26
+ this.root.adoptedStyleSheets = [sheet];
27
+ this.root.innerHTML = this.render();
28
+ }
29
+ }
30
+ /** Identity tag for editor CSS highlighting; returns the string unchanged. */
31
+ export const css = (strings, ...values) => strings.reduce((acc, s, i) => acc + s + (i < values.length ? String(values[i]) : ""), "");
32
+ export const html = css;
33
+ /** Register a custom element only in a browser, idempotently. SSR-safe. */
34
+ export function define(tag, ctor) {
35
+ if (typeof customElements === "undefined")
36
+ return;
37
+ if (!customElements.get(tag))
38
+ customElements.define(tag, ctor);
39
+ }
40
+ /** Shared focus-visible ring + reduced-motion guard, reused by components. */
41
+ export const A11Y = css `
42
+ :host {
43
+ --_focus: var(--npt-focus-ring, 2px solid var(--md-sys-color-primary));
44
+ }
45
+ :host(:focus-visible),
46
+ *:focus-visible {
47
+ outline: var(--_focus);
48
+ outline-offset: 2px;
49
+ }
50
+ @media (prefers-reduced-motion: reduce) {
51
+ * {
52
+ transition: none !important;
53
+ animation: none !important;
54
+ }
55
+ }
56
+ `;
57
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/components/base.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,EAAE;AACF,+EAA+E;AAC/E,4EAA4E;AAC5E,iFAAiF;AACjF,kFAAkF;AAClF,iFAAiF;AACjF,qEAAqE;AAErE,MAAM,UAAU,GAAG,IAAI,OAAO,EAAoC,CAAC;AAEnE,MAAM,OAAgB,UAAW,SAAQ,WAAW;IAQlD;QACE,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,iBAAiB;QACf,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;IAES,MAAM;QACd,MAAM,IAAI,GAAG,IAAI,CAAC,WAAgC,CAAC;QACnD,IAAI,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,KAAK,GAAG,IAAI,aAAa,EAAE,CAAC;YAC5B,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACjC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC9B,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,kBAAkB,GAAG,CAAC,KAAK,CAAC,CAAC;QACvC,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;IACtC,CAAC;CACF;AAED,8EAA8E;AAC9E,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,OAA6B,EAAE,GAAG,MAAiB,EAAU,EAAE,CACjF,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;AAE5F,MAAM,CAAC,MAAM,IAAI,GAAG,GAAG,CAAC;AAExB,2EAA2E;AAC3E,MAAM,UAAU,MAAM,CAAC,GAAW,EAAE,IAA8B;IAChE,IAAI,OAAO,cAAc,KAAK,WAAW;QAAE,OAAO;IAClD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,cAAc,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AACjE,CAAC;AAED,8EAA8E;AAC9E,MAAM,CAAC,MAAM,IAAI,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;CAetB,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { NptElement } from "./base.js";
2
+ /**
3
+ * <npt-button variant="filled|tonal|outlined|text" [disabled]>Label</npt-button>
4
+ * M3 Expressive button. Pill shape, brand-tinted, 48dp min target.
5
+ */
6
+ export declare class NptButton extends NptElement {
7
+ static observedAttributes: string[];
8
+ attributeChangedCallback(): void;
9
+ protected styles(): string;
10
+ protected render(): string;
11
+ }
12
+ //# sourceMappingURL=button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../src/components/button.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAmB,MAAM,WAAW,CAAC;AAExD;;;GAGG;AACH,qBAAa,SAAU,SAAQ,UAAU;IACvC,MAAM,CAAC,kBAAkB,WAA2B;IAEpD,wBAAwB,IAAI,IAAI;IAIhC,SAAS,CAAC,MAAM,IAAI,MAAM;IAqD1B,SAAS,CAAC,MAAM,IAAI,MAAM;CAI3B"}
@@ -0,0 +1,70 @@
1
+ // Neptune Odyssey — <npt-button> · © 2026 Neptune.Fintech (neptune.ly)
2
+ import { NptElement, css, html, A11Y } from "./base.js";
3
+ /**
4
+ * <npt-button variant="filled|tonal|outlined|text" [disabled]>Label</npt-button>
5
+ * M3 Expressive button. Pill shape, brand-tinted, 48dp min target.
6
+ */
7
+ export class NptButton extends NptElement {
8
+ attributeChangedCallback() {
9
+ if (this.isConnected)
10
+ this.update();
11
+ }
12
+ styles() {
13
+ return css `
14
+ ${A11Y}
15
+ :host {
16
+ display: inline-block;
17
+ }
18
+ button {
19
+ font-family: var(--npt-font-text);
20
+ font-size: var(--npt-text-label, 14px);
21
+ font-weight: 600;
22
+ letter-spacing: 0.01em;
23
+ min-height: 48px;
24
+ padding-inline: var(--npt-space-6, 24px);
25
+ border: none;
26
+ border-radius: var(--npt-corner-full, 999px);
27
+ cursor: pointer;
28
+ display: inline-flex;
29
+ align-items: center;
30
+ justify-content: center;
31
+ gap: var(--npt-space-2, 8px);
32
+ transition: background-color var(--npt-dur-fast, 200ms) var(--npt-ease-standard, ease),
33
+ box-shadow var(--npt-dur-fast, 200ms) var(--npt-ease-standard, ease);
34
+ }
35
+ button:disabled {
36
+ cursor: not-allowed;
37
+ opacity: 0.38;
38
+ }
39
+ :host([variant="filled"]) button,
40
+ :host(:not([variant])) button {
41
+ background: var(--md-sys-color-primary);
42
+ color: var(--md-sys-color-on-primary);
43
+ }
44
+ :host([variant="filled"]) button:hover:not(:disabled),
45
+ :host(:not([variant])) button:hover:not(:disabled) {
46
+ box-shadow: var(--npt-elevation-1, 0 1px 3px rgba(0, 0, 0, 0.2));
47
+ }
48
+ :host([variant="tonal"]) button {
49
+ background: var(--md-sys-color-secondary-container);
50
+ color: var(--md-sys-color-on-secondary-container);
51
+ }
52
+ :host([variant="outlined"]) button {
53
+ background: transparent;
54
+ color: var(--md-sys-color-primary);
55
+ border: 1px solid var(--md-sys-color-outline);
56
+ }
57
+ :host([variant="text"]) button {
58
+ background: transparent;
59
+ color: var(--md-sys-color-primary);
60
+ padding-inline: var(--npt-space-3, 12px);
61
+ }
62
+ `;
63
+ }
64
+ render() {
65
+ const disabled = this.hasAttribute("disabled") ? "disabled" : "";
66
+ return html `<button part="button" ${disabled}><slot></slot></button>`;
67
+ }
68
+ }
69
+ NptButton.observedAttributes = ["variant", "disabled"];
70
+ //# sourceMappingURL=button.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"button.js","sourceRoot":"","sources":["../../src/components/button.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAExD;;;GAGG;AACH,MAAM,OAAO,SAAU,SAAQ,UAAU;IAGvC,wBAAwB;QACtB,IAAI,IAAI,CAAC,WAAW;YAAE,IAAI,CAAC,MAAM,EAAE,CAAC;IACtC,CAAC;IAES,MAAM;QACd,OAAO,GAAG,CAAA;QACN,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAgDP,CAAC;IACJ,CAAC;IAES,MAAM;QACd,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;QACjE,OAAO,IAAI,CAAA,yBAAyB,QAAQ,yBAAyB,CAAC;IACxE,CAAC;;AA9DM,4BAAkB,GAAG,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { NptElement } from "./base.js";
2
+ /**
3
+ * <npt-card variant="standard|elevated|tonal|glass"> … </npt-card>
4
+ * Brand-shaped surface. `glass` is the optional translucent material — use only
5
+ * on approved surfaces (nav, hero, auth, modals), never on tables/forms (docs/06 §3).
6
+ */
7
+ export declare class NptCard extends NptElement {
8
+ static observedAttributes: string[];
9
+ attributeChangedCallback(): void;
10
+ protected styles(): string;
11
+ protected render(): string;
12
+ }
13
+ //# sourceMappingURL=card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card.d.ts","sourceRoot":"","sources":["../../src/components/card.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAa,MAAM,WAAW,CAAC;AAElD;;;;GAIG;AACH,qBAAa,OAAQ,SAAQ,UAAU;IACrC,MAAM,CAAC,kBAAkB,WAAe;IAExC,wBAAwB,IAAI,IAAI;IAIhC,SAAS,CAAC,MAAM,IAAI,MAAM;IA6B1B,SAAS,CAAC,MAAM,IAAI,MAAM;CAG3B"}
@@ -0,0 +1,46 @@
1
+ // Neptune Odyssey — <npt-card> · © 2026 Neptune.Fintech (neptune.ly)
2
+ import { NptElement, css, html } from "./base.js";
3
+ /**
4
+ * <npt-card variant="standard|elevated|tonal|glass"> … </npt-card>
5
+ * Brand-shaped surface. `glass` is the optional translucent material — use only
6
+ * on approved surfaces (nav, hero, auth, modals), never on tables/forms (docs/06 §3).
7
+ */
8
+ export class NptCard extends NptElement {
9
+ attributeChangedCallback() {
10
+ if (this.isConnected)
11
+ this.update();
12
+ }
13
+ styles() {
14
+ return css `
15
+ :host {
16
+ display: block;
17
+ }
18
+ .card {
19
+ border-radius: var(--npt-corner-lg, 24px);
20
+ padding: var(--npt-space-6, 24px);
21
+ background: var(--md-sys-color-surface-container-low);
22
+ color: var(--md-sys-color-on-surface);
23
+ box-sizing: border-box;
24
+ }
25
+ :host([variant="elevated"]) .card {
26
+ background: var(--md-sys-color-surface-container);
27
+ box-shadow: var(--npt-elevation-2, 0 2px 6px rgba(0, 0, 0, 0.18));
28
+ }
29
+ :host([variant="tonal"]) .card {
30
+ background: var(--md-sys-color-secondary-container);
31
+ color: var(--md-sys-color-on-secondary-container);
32
+ }
33
+ :host([variant="glass"]) .card {
34
+ background: var(--npt-glass-tint, color-mix(in oklab, var(--md-sys-color-surface) 70%, transparent));
35
+ backdrop-filter: blur(var(--npt-glass-blur, 18px));
36
+ -webkit-backdrop-filter: blur(var(--npt-glass-blur, 18px));
37
+ border: 1px solid var(--md-sys-color-outline-variant);
38
+ }
39
+ `;
40
+ }
41
+ render() {
42
+ return html `<div class="card" part="card"><slot></slot></div>`;
43
+ }
44
+ }
45
+ NptCard.observedAttributes = ["variant"];
46
+ //# sourceMappingURL=card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card.js","sourceRoot":"","sources":["../../src/components/card.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAElD;;;;GAIG;AACH,MAAM,OAAO,OAAQ,SAAQ,UAAU;IAGrC,wBAAwB;QACtB,IAAI,IAAI,CAAC,WAAW;YAAE,IAAI,CAAC,MAAM,EAAE,CAAC;IACtC,CAAC;IAES,MAAM;QACd,OAAO,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;KAyBT,CAAC;IACJ,CAAC;IAES,MAAM;QACd,OAAO,IAAI,CAAA,mDAAmD,CAAC;IACjE,CAAC;;AArCM,0BAAkB,GAAG,CAAC,SAAS,CAAC,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { NptElement } from "./base.js";
2
+ /**
3
+ * <npt-balance-card label="Available balance" amount="12,480.50" currency="LYD"
4
+ * account="•••• 4821" [hero]></npt-balance-card>
5
+ * The dashboard balance hero. `hero` enables the brand gradient surface.
6
+ */
7
+ export declare class NptBalanceCard extends NptElement {
8
+ static observedAttributes: string[];
9
+ attributeChangedCallback(): void;
10
+ protected styles(): string;
11
+ protected render(): string;
12
+ }
13
+ /**
14
+ * <npt-transaction-row title="Coffee" subtitle="Today · Card" amount="-4.50"
15
+ * currency="LYD" [credit]></npt-transaction-row>
16
+ */
17
+ export declare class NptTransactionRow extends NptElement {
18
+ static observedAttributes: string[];
19
+ attributeChangedCallback(): void;
20
+ protected styles(): string;
21
+ protected render(): string;
22
+ }
23
+ //# sourceMappingURL=financial.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"financial.d.ts","sourceRoot":"","sources":["../../src/components/financial.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAa,MAAM,WAAW,CAAC;AAKlD;;;;GAIG;AACH,qBAAa,cAAe,SAAQ,UAAU;IAC5C,MAAM,CAAC,kBAAkB,WAAsD;IAE/E,wBAAwB,IAAI,IAAI;IAIhC,SAAS,CAAC,MAAM,IAAI,MAAM;IAiD1B,SAAS,CAAC,MAAM,IAAI,MAAM;CAa3B;AAED;;;GAGG;AACH,qBAAa,iBAAkB,SAAQ,UAAU;IAC/C,MAAM,CAAC,kBAAkB,WAAyD;IAElF,wBAAwB,IAAI,IAAI;IAIhC,SAAS,CAAC,MAAM,IAAI,MAAM;IA2D1B,SAAS,CAAC,MAAM,IAAI,MAAM;CAiB3B"}
@@ -0,0 +1,164 @@
1
+ // Neptune Odyssey — financial components · © 2026 Neptune.Fintech (neptune.ly)
2
+ // <npt-balance-card>, <npt-transaction-row>. Money uses tabular figures.
3
+ import { NptElement, css, html } from "./base.js";
4
+ const escape = (v) => (v ?? "").replace(/[&<>"]/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" })[c]);
5
+ /**
6
+ * <npt-balance-card label="Available balance" amount="12,480.50" currency="LYD"
7
+ * account="•••• 4821" [hero]></npt-balance-card>
8
+ * The dashboard balance hero. `hero` enables the brand gradient surface.
9
+ */
10
+ export class NptBalanceCard extends NptElement {
11
+ attributeChangedCallback() {
12
+ if (this.isConnected)
13
+ this.update();
14
+ }
15
+ styles() {
16
+ return css `
17
+ :host {
18
+ display: block;
19
+ }
20
+ .hero {
21
+ border-radius: var(--npt-corner-xl, 32px);
22
+ padding: var(--npt-space-6, 24px);
23
+ background: var(--md-sys-color-surface-container);
24
+ color: var(--md-sys-color-on-surface);
25
+ box-sizing: border-box;
26
+ }
27
+ :host([hero]) .hero {
28
+ background: linear-gradient(135deg, var(--md-sys-color-primary), var(--md-sys-color-tertiary));
29
+ color: var(--md-sys-color-on-primary);
30
+ }
31
+ .label {
32
+ font-family: var(--npt-font-text);
33
+ font-size: var(--npt-text-label, 14px);
34
+ opacity: 0.86;
35
+ margin: 0 0 var(--npt-space-2, 8px);
36
+ }
37
+ .amount {
38
+ font-family: var(--npt-font-num);
39
+ font-feature-settings: "tnum" 1;
40
+ font-variant-numeric: tabular-nums;
41
+ font-size: var(--npt-text-display-md, 45px);
42
+ line-height: var(--npt-leading-display-md, 52px);
43
+ font-weight: var(--npt-display-weight, 700);
44
+ letter-spacing: var(--npt-display-tracking, -0.02em);
45
+ margin: 0;
46
+ display: flex;
47
+ align-items: baseline;
48
+ gap: var(--npt-space-2, 8px);
49
+ }
50
+ .currency {
51
+ font-size: var(--npt-text-title, 18px);
52
+ opacity: 0.85;
53
+ }
54
+ .account {
55
+ font-family: var(--npt-font-num);
56
+ font-variant-numeric: tabular-nums;
57
+ font-size: var(--npt-text-body, 14px);
58
+ opacity: 0.78;
59
+ margin: var(--npt-space-3, 12px) 0 0;
60
+ }
61
+ `;
62
+ }
63
+ render() {
64
+ const label = escape(this.getAttribute("label"));
65
+ const amount = escape(this.getAttribute("amount"));
66
+ const currency = escape(this.getAttribute("currency"));
67
+ const account = escape(this.getAttribute("account"));
68
+ return html `
69
+ <div class="hero" part="hero" role="group" aria-label="${label} ${amount} ${currency}">
70
+ <p class="label">${label}</p>
71
+ <p class="amount"><span class="currency">${currency}</span>${amount}</p>
72
+ ${account ? html `<p class="account">${account}</p>` : ""}
73
+ </div>
74
+ `;
75
+ }
76
+ }
77
+ NptBalanceCard.observedAttributes = ["label", "amount", "currency", "account", "hero"];
78
+ /**
79
+ * <npt-transaction-row title="Coffee" subtitle="Today · Card" amount="-4.50"
80
+ * currency="LYD" [credit]></npt-transaction-row>
81
+ */
82
+ export class NptTransactionRow extends NptElement {
83
+ attributeChangedCallback() {
84
+ if (this.isConnected)
85
+ this.update();
86
+ }
87
+ styles() {
88
+ return css `
89
+ :host {
90
+ display: block;
91
+ }
92
+ .row {
93
+ display: flex;
94
+ align-items: center;
95
+ gap: var(--npt-space-4, 16px);
96
+ min-height: 56px;
97
+ padding-block: var(--npt-space-3, 12px);
98
+ padding-inline: var(--npt-space-2, 8px);
99
+ border-bottom: 1px solid var(--md-sys-color-outline-variant);
100
+ }
101
+ .icon {
102
+ inline-size: 40px;
103
+ block-size: 40px;
104
+ border-radius: var(--npt-corner-md, 16px);
105
+ background: var(--md-sys-color-secondary-container);
106
+ color: var(--md-sys-color-on-secondary-container);
107
+ display: grid;
108
+ place-items: center;
109
+ flex: 0 0 auto;
110
+ font-family: var(--npt-font-display);
111
+ font-weight: 700;
112
+ }
113
+ .body {
114
+ flex: 1 1 auto;
115
+ min-inline-size: 0;
116
+ }
117
+ .title {
118
+ font-family: var(--npt-font-text);
119
+ font-size: var(--npt-text-body-lg, 16px);
120
+ color: var(--md-sys-color-on-surface);
121
+ margin: 0;
122
+ white-space: nowrap;
123
+ overflow: hidden;
124
+ text-overflow: ellipsis;
125
+ }
126
+ .subtitle {
127
+ font-family: var(--npt-font-text);
128
+ font-size: var(--npt-text-body, 14px);
129
+ color: var(--md-sys-color-on-surface-variant);
130
+ margin: 2px 0 0;
131
+ }
132
+ .amount {
133
+ font-family: var(--npt-font-num);
134
+ font-variant-numeric: tabular-nums;
135
+ font-size: var(--npt-text-body-lg, 16px);
136
+ font-weight: 600;
137
+ color: var(--md-sys-color-on-surface);
138
+ white-space: nowrap;
139
+ }
140
+ :host([credit]) .amount {
141
+ color: var(--md-sys-color-success);
142
+ }
143
+ `;
144
+ }
145
+ render() {
146
+ const title = escape(this.getAttribute("title"));
147
+ const subtitle = escape(this.getAttribute("subtitle"));
148
+ const amount = escape(this.getAttribute("amount"));
149
+ const currency = escape(this.getAttribute("currency"));
150
+ const initial = title.trim().charAt(0).toUpperCase() || "•";
151
+ return html `
152
+ <div class="row" part="row">
153
+ <div class="icon" aria-hidden="true">${initial}</div>
154
+ <div class="body">
155
+ <p class="title">${title}</p>
156
+ ${subtitle ? html `<p class="subtitle">${subtitle}</p>` : ""}
157
+ </div>
158
+ <div class="amount">${amount} ${currency}</div>
159
+ </div>
160
+ `;
161
+ }
162
+ }
163
+ NptTransactionRow.observedAttributes = ["title", "subtitle", "amount", "currency", "credit"];
164
+ //# sourceMappingURL=financial.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"financial.js","sourceRoot":"","sources":["../../src/components/financial.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,yEAAyE;AACzE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAElD,MAAM,MAAM,GAAG,CAAC,CAAgB,EAAU,EAAE,CAC1C,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC;AAEvG;;;;GAIG;AACH,MAAM,OAAO,cAAe,SAAQ,UAAU;IAG5C,wBAAwB;QACtB,IAAI,IAAI,CAAC,WAAW;YAAE,IAAI,CAAC,MAAM,EAAE,CAAC;IACtC,CAAC;IAES,MAAM;QACd,OAAO,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA6CT,CAAC;IACJ,CAAC;IAES,MAAM;QACd,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;QACnD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC;QACvD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC;QACrD,OAAO,IAAI,CAAA;+DACgD,KAAK,IAAI,MAAM,IAAI,QAAQ;2BAC/D,KAAK;mDACmB,QAAQ,UAAU,MAAM;UACjE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAA,sBAAsB,OAAO,MAAM,CAAC,CAAC,CAAC,EAAE;;KAE3D,CAAC;IACJ,CAAC;;AAnEM,iCAAkB,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;AAsEjF;;;GAGG;AACH,MAAM,OAAO,iBAAkB,SAAQ,UAAU;IAG/C,wBAAwB;QACtB,IAAI,IAAI,CAAC,WAAW;YAAE,IAAI,CAAC,MAAM,EAAE,CAAC;IACtC,CAAC;IAES,MAAM;QACd,OAAO,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAuDT,CAAC;IACJ,CAAC;IAES,MAAM;QACd,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;QACjD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;QACnD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC;QACvD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,GAAG,CAAC;QAC5D,OAAO,IAAI,CAAA;;+CAEgC,OAAO;;6BAEzB,KAAK;YACtB,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAA,uBAAuB,QAAQ,MAAM,CAAC,CAAC,CAAC,EAAE;;8BAEvC,MAAM,IAAI,QAAQ;;KAE3C,CAAC;IACJ,CAAC;;AAjFM,oCAAkB,GAAG,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { NptElement } from "./base.js";
2
+ /**
3
+ * <npt-text-field label="IBAN" value="" placeholder="LY.." [error="msg"]></npt-text-field>
4
+ * Outlined M3 field. Logical padding → mirrors in RTL.
5
+ */
6
+ export declare class NptTextField extends NptElement {
7
+ static observedAttributes: string[];
8
+ attributeChangedCallback(): void;
9
+ get value(): string;
10
+ protected styles(): string;
11
+ protected render(): string;
12
+ }
13
+ /** <npt-chip [selected]>Label</npt-chip> */
14
+ export declare class NptChip extends NptElement {
15
+ static observedAttributes: string[];
16
+ attributeChangedCallback(): void;
17
+ protected styles(): string;
18
+ protected render(): string;
19
+ }
20
+ /** <npt-badge tone="primary|success|error|neutral">3</npt-badge> */
21
+ export declare class NptBadge extends NptElement {
22
+ static observedAttributes: string[];
23
+ attributeChangedCallback(): void;
24
+ protected styles(): string;
25
+ protected render(): string;
26
+ }
27
+ //# sourceMappingURL=inputs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inputs.d.ts","sourceRoot":"","sources":["../../src/components/inputs.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAmB,MAAM,WAAW,CAAC;AAKxD;;;GAGG;AACH,qBAAa,YAAa,SAAQ,UAAU;IAC1C,MAAM,CAAC,kBAAkB,WAAsD;IAE/E,wBAAwB,IAAI,IAAI;IAIhC,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,SAAS,CAAC,MAAM,IAAI,MAAM;IAgD1B,SAAS,CAAC,MAAM,IAAI,MAAM;CAkB3B;AAED,4CAA4C;AAC5C,qBAAa,OAAQ,SAAQ,UAAU;IACrC,MAAM,CAAC,kBAAkB,WAAgB;IAEzC,wBAAwB,IAAI,IAAI;IAIhC,SAAS,CAAC,MAAM,IAAI,MAAM;IA2B1B,SAAS,CAAC,MAAM,IAAI,MAAM;CAI3B;AAED,oEAAoE;AACpE,qBAAa,QAAS,SAAQ,UAAU;IACtC,MAAM,CAAC,kBAAkB,WAAY;IAErC,wBAAwB,IAAI,IAAI;IAIhC,SAAS,CAAC,MAAM,IAAI,MAAM;IAmC1B,SAAS,CAAC,MAAM,IAAI,MAAM;CAG3B"}