@idp.global/catalog 2.1.1 → 2.2.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.
@@ -1,4 +1,4 @@
1
- import { DeesElement, html, customElement, css, type TemplateResult } from '@design.estate/dees-element';
1
+ import { DeesElement, html, customElement, css, property, type TemplateResult } from '@design.estate/dees-element';
2
2
  import { idpElementStyles } from './tokens.js';
3
3
  import './idp-button.js';
4
4
  import './idp-screenshot-placeholder.js';
@@ -14,6 +14,12 @@ export class IdpLandingHero extends DeesElement {
14
14
  public static demo = () => html`<idp-landing-hero></idp-landing-hero>`;
15
15
  public static demoGroups = ['idp.global v5 composed surfaces'];
16
16
 
17
+ @property({ type: String })
18
+ public accessor claimHref = '';
19
+
20
+ @property({ type: String })
21
+ public accessor secondaryHref = '';
22
+
17
23
  public static styles = [
18
24
  ...idpElementStyles,
19
25
  css`
@@ -100,8 +106,8 @@ export class IdpLandingHero extends DeesElement {
100
106
  Anchored to Cardano, so it can never be erased or taken away.
101
107
  </p>
102
108
  <div class="hero-actions">
103
- <idp-button variant="accent" size="lg">Claim your identity</idp-button>
104
- <idp-button variant="link" size="lg">See how it works</idp-button>
109
+ <idp-button variant="accent" size="lg" href=${this.claimHref}>Claim your identity</idp-button>
110
+ <idp-button variant="link" size="lg" href=${this.secondaryHref}>See how it works</idp-button>
105
111
  </div>
106
112
  <div class="hero-fine">
107
113
  <span>MIT licensed</span><span>Self-hostable</span><span>No credit card</span><span>Cardano mainnet</span>
@@ -1,4 +1,4 @@
1
- import { DeesElement, html, customElement, css, type TemplateResult } from '@design.estate/dees-element';
1
+ import { DeesElement, html, customElement, css, property, type TemplateResult } from '@design.estate/dees-element';
2
2
  import { idpElementStyles } from './tokens.js';
3
3
  import './idp-badge.js';
4
4
  import './idp-button.js';
@@ -12,11 +12,47 @@ declare global {
12
12
  }
13
13
  }
14
14
 
15
+ export interface IIdpLandingLinks {
16
+ signIn: string;
17
+ claim: string;
18
+ docs: string;
19
+ github: string;
20
+ contact: string;
21
+ }
22
+
15
23
  @customElement('idp-landing-page')
16
24
  export class IdpLandingPage extends DeesElement {
17
25
  public static demo = () => html`<idp-landing-page></idp-landing-page>`;
18
26
  public static demoGroups = ['idp.global v5 full pages'];
19
27
 
28
+ /**
29
+ * Real navigation targets for the page chrome. Consumers override any subset;
30
+ * labels without a link target stay presentational.
31
+ */
32
+ @property({ type: Object })
33
+ public accessor links: Partial<IIdpLandingLinks> = {};
34
+
35
+ private getLinks(): IIdpLandingLinks {
36
+ return {
37
+ signIn: 'https://idp.global/login',
38
+ claim: 'https://idp.global/register',
39
+ docs: 'https://about.idp.global/docs',
40
+ github: 'https://code.foss.global/idp.global/idp.global',
41
+ contact: 'mailto:hello@task.vc',
42
+ ...this.links,
43
+ };
44
+ }
45
+
46
+ private scrollToSection(eventArg: Event, sectionIdArg: string) {
47
+ eventArg.preventDefault();
48
+ if (sectionIdArg === 'product') {
49
+ // the product screenshot lives inside the hero's shadow root
50
+ this.shadowRoot?.querySelector('idp-landing-hero')?.scrollIntoView({ behavior: 'smooth', block: 'end' });
51
+ return;
52
+ }
53
+ this.shadowRoot?.getElementById(sectionIdArg)?.scrollIntoView({ behavior: 'smooth' });
54
+ }
55
+
20
56
  public static styles = [
21
57
  ...idpElementStyles,
22
58
  css`
@@ -767,20 +803,28 @@ export class IdpLandingPage extends DeesElement {
767
803
  ];
768
804
 
769
805
  private renderNav() {
806
+ const links = this.getLinks();
807
+ const sections = [
808
+ ['product', 'Product'],
809
+ ['features', 'Features'],
810
+ ['chain', 'On-chain'],
811
+ ['pricing', 'Pricing'],
812
+ ['developers', 'Developers'],
813
+ ] as const;
770
814
  return html`
771
815
  <div class="nav-shell">
772
816
  <nav>
773
- <a class="logo" href="#">idp<span class="logo-dot"></span>global</a>
817
+ <a class="logo" href="#" @click=${(eventArg: Event) => this.scrollToSection(eventArg, 'product')}>idp<span class="logo-dot"></span>global</a>
774
818
  <div class="nav-links">
775
- <a href="#product">Product</a>
776
- <a href="#features">Features</a>
777
- <a href="#chain">On-chain</a>
778
- <a href="#pricing">Pricing</a>
779
- <a href="#developers">Developers</a>
819
+ ${sections.map(
820
+ ([sectionId, label]) => html`
821
+ <a href="#${sectionId}" @click=${(eventArg: Event) => this.scrollToSection(eventArg, sectionId)}>${label}</a>
822
+ `,
823
+ )}
780
824
  </div>
781
825
  <div class="actions">
782
- <a class="nav-signin">Sign in</a>
783
- <idp-button variant="accent" size="sm">Claim identity</idp-button>
826
+ <a class="nav-signin" href=${links.signIn}>Sign in</a>
827
+ <idp-button variant="accent" size="sm" href=${links.claim}>Claim identity</idp-button>
784
828
  </div>
785
829
  </nav>
786
830
  </div>
@@ -977,6 +1021,7 @@ export class IdpLandingPage extends DeesElement {
977
1021
  }
978
1022
 
979
1023
  private renderPricing() {
1024
+ const links = this.getLinks();
980
1025
  const tiers = [
981
1026
  {
982
1027
  name: 'Personal',
@@ -992,6 +1037,7 @@ export class IdpLandingPage extends DeesElement {
992
1037
  'Recovery via your other devices',
993
1038
  ],
994
1039
  cta: 'Claim your identity',
1040
+ ctaHref: links.claim,
995
1041
  variant: 'tint',
996
1042
  featured: false,
997
1043
  },
@@ -1009,6 +1055,7 @@ export class IdpLandingPage extends DeesElement {
1009
1055
  'SSO & SCIM included, no upsell',
1010
1056
  ],
1011
1057
  cta: 'Start an organisation',
1058
+ ctaHref: links.claim,
1012
1059
  variant: 'accent',
1013
1060
  featured: true,
1014
1061
  },
@@ -1026,6 +1073,7 @@ export class IdpLandingPage extends DeesElement {
1026
1073
  'Priority engineering & SLA',
1027
1074
  ],
1028
1075
  cta: 'Talk to us',
1076
+ ctaHref: links.contact,
1029
1077
  variant: 'tint',
1030
1078
  featured: false,
1031
1079
  },
@@ -1051,7 +1099,7 @@ export class IdpLandingPage extends DeesElement {
1051
1099
  <div class="price">${tierArg.price}<span class="sub">${tierArg.sub}</span></div>
1052
1100
  <div class="price-note">${tierArg.note}</div>
1053
1101
  <ul class="tier-list">${tierArg.items.map((itemArg) => html`<li>${itemArg}</li>`)}</ul>
1054
- <idp-button variant=${tierArg.variant as any}>${tierArg.cta}</idp-button>
1102
+ <idp-button variant=${tierArg.variant as any} href=${tierArg.ctaHref}>${tierArg.cta}</idp-button>
1055
1103
  </div>
1056
1104
  `,
1057
1105
  )}
@@ -1077,8 +1125,8 @@ export class IdpLandingPage extends DeesElement {
1077
1125
  <p>One CLI. Standard OAuth 2 &amp; OIDC. Native SDKs for Node, Python, Swift, Kotlin, Go, Rust.</p>
1078
1126
  <div class="dev-tags">${tags.map((tagArg) => html`<span class="dev-tag">${tagArg}</span>`)}</div>
1079
1127
  <div class="dev-actions">
1080
- <idp-button variant="accent" icon="lucide:github">View on GitHub</idp-button>
1081
- <idp-button variant="link">Read the docs</idp-button>
1128
+ <idp-button variant="accent" icon="lucide:github" href=${this.getLinks().github}>View on GitHub</idp-button>
1129
+ <idp-button variant="link" href=${this.getLinks().docs}>Read the docs</idp-button>
1082
1130
  </div>
1083
1131
  </div>
1084
1132
  <div class="terminal">
@@ -1115,7 +1163,7 @@ export class IdpLandingPage extends DeesElement {
1115
1163
 
1116
1164
  private renderManifesto() {
1117
1165
  return html`
1118
- <section class="manifesto">
1166
+ <section class="manifesto" id="manifesto">
1119
1167
  <div class="wrap">
1120
1168
  <div class="eyebrow sm" style="margin-bottom: 24px;">Why we built this</div>
1121
1169
  <q>Identity should not be a product the user is sold. It should be a permanent <em>fact</em>, owned by the person it describes.</q>
@@ -1135,8 +1183,8 @@ export class IdpLandingPage extends DeesElement {
1135
1183
  we disappear.
1136
1184
  </p>
1137
1185
  <div class="cta-actions">
1138
- <idp-button variant="accent" size="lg">Claim your identity</idp-button>
1139
- <idp-button variant="link" size="lg">Read the manifesto</idp-button>
1186
+ <idp-button variant="accent" size="lg" href=${this.getLinks().claim}>Claim your identity</idp-button>
1187
+ <idp-button variant="link" size="lg" @click=${(eventArg: Event) => this.scrollToSection(eventArg, 'manifesto')}>Read the manifesto</idp-button>
1140
1188
  </div>
1141
1189
  </div>
1142
1190
  </section>
@@ -1144,17 +1192,30 @@ export class IdpLandingPage extends DeesElement {
1144
1192
  }
1145
1193
 
1146
1194
  private renderFooter() {
1195
+ const links = this.getLinks();
1196
+ const labelHrefs: Record<string, string> = {
1197
+ Documentation: links.docs,
1198
+ 'API reference': links.docs,
1199
+ 'Self-hosting': links.docs,
1200
+ GitHub: links.github,
1201
+ };
1147
1202
  const cols = [
1148
1203
  ['Product', ['For individuals', 'For organisations', 'Enterprise', 'Cardano sync', 'Changelog']],
1149
1204
  ['Developers', ['Documentation', 'API reference', 'Self-hosting', 'SDKs', 'GitHub']],
1150
1205
  ['Company', ['Manifesto', 'Blog', 'Security', 'Privacy', 'Terms']],
1151
1206
  ] as const;
1207
+ const renderFooterLink = (labelArg: string) =>
1208
+ labelHrefs[labelArg]
1209
+ ? html`<a href=${labelHrefs[labelArg]}>${labelArg}</a>`
1210
+ : labelArg === 'Manifesto'
1211
+ ? html`<a href="#manifesto" @click=${(eventArg: Event) => this.scrollToSection(eventArg, 'manifesto')}>${labelArg}</a>`
1212
+ : html`<a>${labelArg}</a>`;
1152
1213
  return html`
1153
1214
  <footer>
1154
1215
  <div class="wrap-wide">
1155
1216
  <div class="footer-cols">
1156
1217
  <div class="footer-brand">
1157
- <a class="logo" href="#">idp<span class="logo-dot"></span>global</a>
1218
+ <a class="logo" href="#" @click=${(eventArg: Event) => this.scrollToSection(eventArg, 'product')}>idp<span class="logo-dot"></span>global</a>
1158
1219
  <p>
1159
1220
  An open identity provider for everyone — from individuals to enterprises. Anchored on Cardano. Built in
1160
1221
  the open. Yours forever.
@@ -1165,14 +1226,14 @@ export class IdpLandingPage extends DeesElement {
1165
1226
  (colArg) => html`
1166
1227
  <div class="footer-col">
1167
1228
  <h4>${colArg[0]}</h4>
1168
- <ul>${colArg[1].map((linkArg) => html`<li><a>${linkArg}</a></li>`)}</ul>
1229
+ <ul>${colArg[1].map((linkArg) => html`<li>${renderFooterLink(linkArg)}</li>`)}</ul>
1169
1230
  </div>
1170
1231
  `,
1171
1232
  )}
1172
1233
  </div>
1173
1234
  <div class="footer-bottom">
1174
1235
  <span>© 2026 idp.global · MIT · Anchored to Cardano</span>
1175
- <span class="links"><a>Status</a><a>Twitter</a><a>GitHub</a><a>Discord</a></span>
1236
+ <span class="links"><a>Status</a><a href=${links.github}>GitHub</a></span>
1176
1237
  </div>
1177
1238
  </div>
1178
1239
  </footer>
@@ -1183,7 +1244,10 @@ export class IdpLandingPage extends DeesElement {
1183
1244
  return html`
1184
1245
  <div class="page">
1185
1246
  ${this.renderNav()}
1186
- <idp-landing-hero></idp-landing-hero>
1247
+ <idp-landing-hero
1248
+ claimHref=${this.getLinks().claim}
1249
+ secondaryHref=${this.getLinks().docs}
1250
+ ></idp-landing-hero>
1187
1251
  ${this.renderProof()}
1188
1252
  ${this.renderFeatures()}
1189
1253
  ${this.renderChain()}