{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "login-01",
  "title": "Console SSO Login",
  "type": "registry:page",
  "files": [
    {
      "path": "packages/registry-angular/blocks/login-01/login-01.component.ts",
      "content": "// Split-screen developer console authentication suite: brand telemetry showcase\n// with a live terminal widget on the left, OAuth providers, password / passkey /\n// SAML SSO tabs with enterprise-domain detection on the right. Port of the\n// Vue/React block 1:1 — emits `submit` with the validated payload, `oauth` with\n// the chosen provider, `forgotPassword` and `signUp`; the consumer wires the\n// actual auth calls.\nimport {\n  ChangeDetectionStrategy,\n  Component,\n  DestroyRef,\n  EventEmitter,\n  Input,\n  Output,\n  computed,\n  inject,\n  signal,\n} from '@angular/core'\nimport {\n  ArrowRight,\n  CheckCircle2,\n  Fingerprint,\n  Github,\n  KeyRound,\n  Lock,\n  LucideAngularModule,\n  Mail,\n  ShieldCheck,\n  Terminal,\n  Zap,\n} from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiBadgeComponent } from '@/ui/badge/badge.component'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport { UiInputComponent } from '@/ui/input/input.component'\nimport { UiLabelComponent } from '@/ui/label/label.component'\nimport { UiSeparatorComponent } from '@/ui/separator/separator.component'\nimport {\n  UiTabsComponent,\n  UiTabsContentComponent,\n  UiTabsListComponent,\n  UiTabsTriggerComponent,\n} from '@/ui/tabs/tabs.component'\n\nexport type Login01AuthMethod = 'password' | 'passkey' | 'sso'\nexport type Login01OauthProvider = 'github' | 'google'\n\nexport interface Login01Payload {\n  method: string\n  email: string\n  password?: string\n  domain?: string\n}\n\nconst publicMailDomains = ['gmail.com', 'yahoo.com', 'hotmail.com', 'outlook.com', 'icloud.com']\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-login-01, [ui-login-01]',\n  standalone: true,\n  // The block renders its own full-page root <div>: keep the host out of layout.\n  host: { '[attr.class]': '\"contents\"' },\n  imports: [\n    LucideAngularModule,\n    UiBadgeComponent,\n    UiButtonComponent,\n    UiInputComponent,\n    UiLabelComponent,\n    UiSeparatorComponent,\n    UiTabsComponent,\n    UiTabsContentComponent,\n    UiTabsListComponent,\n    UiTabsTriggerComponent,\n  ],\n  template: `\n    <div data-slot=\"login-01\" [class]=\"rootClass\">\n      <!-- Left Hero Brand & Proof Pane (Desktop) -->\n      <div\n        class=\"border-border bg-muted/30 relative hidden flex-col justify-between overflow-hidden border-r p-12 lg:col-span-6 lg:flex xl:col-span-7\"\n      >\n        <!-- Background Ambient Glow -->\n\n        <div class=\"relative z-10 flex items-center gap-2.5\">\n          <div\n            class=\"bg-primary text-primary-foreground flex size-9 items-center justify-center rounded-lg font-bold shadow-xs\"\n          >\n            <lucide-icon [img]=\"Zap\" class=\"size-5 fill-current\" />\n          </div>\n          <span class=\"text-foreground text-lg font-bold tracking-tight\">UIPKGE Studio</span>\n        </div>\n\n        <!-- Live Code/Terminal Showcase Widget -->\n        <div class=\"relative z-10 my-auto max-w-xl space-y-6\">\n          <div class=\"space-y-3\">\n            <div\n              class=\"border-primary/20 bg-primary/10 text-primary inline-flex items-center gap-2 rounded-full border px-3 py-1 font-mono text-xs font-semibold\"\n            >\n              <lucide-icon [img]=\"Terminal\" class=\"size-3.5\" />\n              <span>Developer Cloud Console v4.8</span>\n            </div>\n            <h1 class=\"text-foreground text-3xl leading-tight font-bold tracking-tight xl:text-4xl\">\n              The dual-framework UI registry for mission-critical software.\n            </h1>\n            <p class=\"text-muted-foreground text-sm leading-relaxed\">\n              Own your source code without runtime dependency lock-in. Built with Tailwind CSS v4, OKLCH color spaces,\n              and headless accessibility primitives.\n            </p>\n          </div>\n\n          <!-- Terminal Widget -->\n          <div class=\"border-border bg-card overflow-hidden rounded-xl border shadow-lg\">\n            <div class=\"border-border bg-muted/40 flex items-center justify-between border-b px-4 py-2.5\">\n              <div class=\"flex items-center gap-2\">\n                <span class=\"bg-destructive/60 size-2.5 rounded-full\"></span>\n                <span class=\"bg-warning/60 size-2.5 rounded-full\"></span>\n                <span class=\"bg-success/60 size-2.5 rounded-full\"></span>\n                <span class=\"text-muted-foreground ml-2 font-mono text-xs\">auth-session-init.ts</span>\n              </div>\n              <span ui-badge variant=\"outline\" class=\"font-mono text-xs\">mTLS Encrypted</span>\n            </div>\n            <div class=\"bg-card/90 space-y-1 p-4 font-mono text-xs leading-relaxed\">\n              <p class=\"text-muted-foreground\">// Validating SAML 2.0 / WebAuthn identity assertion</p>\n              <p class=\"text-foreground\">\n                <span class=\"text-primary font-bold\">const</span> session =\n                <span class=\"text-primary font-bold\">await</span> auth.<span class=\"text-foreground font-semibold\"\n                  >verifyCredentials</span\n                >({{ '{' }}\n              </p>\n              <p class=\"text-foreground pl-4\">\n                tenant: <span class=\"text-success\">'cyberdyne-systems.internal'</span>,\n              </p>\n              <p class=\"text-foreground pl-4\">\n                protocols: [<span class=\"text-success\">'webauthn-fido2'</span>,\n                <span class=\"text-success\">'saml2-okta'</span>]\n              </p>\n              <p class=\"text-foreground\">{{ '});' }}</p>\n              <p class=\"text-success flex items-center gap-1.5 pt-1 font-medium\">\n                <lucide-icon [img]=\"CheckCircle2\" class=\"size-3.5\" />\n                <span>✓ Cryptographic identity handshaking verified (0.8ms)</span>\n              </p>\n            </div>\n          </div>\n\n          <!-- Metric Badges -->\n          <div class=\"border-border grid grid-cols-3 gap-4 border-t pt-4 text-xs\">\n            <div>\n              <p class=\"text-foreground font-mono text-lg font-bold\">99.95%</p>\n              <p class=\"text-muted-foreground\">Auth Uptime SLA</p>\n            </div>\n            <div>\n              <p class=\"text-foreground font-mono text-lg font-bold\">FIDO2</p>\n              <p class=\"text-muted-foreground\">Passkey Standard</p>\n            </div>\n            <div>\n              <p class=\"text-foreground font-mono text-lg font-bold\">SOC 2 Type II</p>\n              <p class=\"text-muted-foreground\">Certified Cloud</p>\n            </div>\n          </div>\n        </div>\n\n        <div class=\"text-muted-foreground relative z-10 flex items-center justify-between text-xs\">\n          <span>© 2026 UIPKGE Inc.</span>\n          <div class=\"flex gap-4\">\n            <a href=\"#\" class=\"hover:text-foreground transition-colors\">Privacy Policy</a>\n            <a href=\"#\" class=\"hover:text-foreground transition-colors\">Terms of Service</a>\n            <a href=\"#\" class=\"hover:text-foreground transition-colors\">Trust Center</a>\n          </div>\n        </div>\n      </div>\n\n      <!-- Right Login Workbench Pane -->\n      <div class=\"flex flex-col items-center justify-center p-6 sm:p-12 lg:col-span-6 xl:col-span-5\">\n        <div class=\"w-full max-w-md space-y-6\">\n          <!-- Brand on mobile -->\n          <div class=\"mb-4 flex items-center gap-2 lg:hidden\">\n            <div\n              class=\"bg-primary text-primary-foreground flex size-8 items-center justify-center rounded-lg font-bold shadow-xs\"\n            >\n              <lucide-icon [img]=\"Zap\" class=\"size-4 fill-current\" />\n            </div>\n            <span class=\"text-foreground font-bold tracking-tight\">UIPKGE Studio</span>\n          </div>\n\n          <div class=\"space-y-2\">\n            <h2 class=\"text-foreground text-2xl font-bold tracking-tight\">Sign in to console</h2>\n            <p class=\"text-muted-foreground text-xs\">Enter your credentials, passkey or company Single Sign-On.</p>\n          </div>\n\n          <!-- Social / Fast Auth Buttons -->\n          <div class=\"grid grid-cols-2 gap-3\">\n            <button\n              ui-button\n              variant=\"outline\"\n              type=\"button\"\n              class=\"border-border hover:bg-muted h-10 gap-2 text-xs font-semibold\"\n              (click)=\"oauth.emit('github')\"\n            >\n              <lucide-icon [img]=\"Github\" class=\"size-4\" />\n              <span>GitHub</span>\n            </button>\n            <button\n              ui-button\n              variant=\"outline\"\n              type=\"button\"\n              class=\"border-border hover:bg-muted h-10 gap-2 text-xs font-semibold\"\n              (click)=\"oauth.emit('google')\"\n            >\n              <svg viewBox=\"0 0 24 24\" class=\"size-4\" aria-hidden=\"true\">\n                <path\n                  fill=\"#4285F4\"\n                  d=\"M22.5 12.27c0-.79-.07-1.54-.2-2.27H12v4.51h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.32z\"\n                />\n                <path\n                  fill=\"#34A853\"\n                  d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.99.66-2.25 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\"\n                />\n                <path\n                  fill=\"#FBBC05\"\n                  d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.06H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.94l2.85-2.22.81-.63z\"\n                />\n                <path\n                  fill=\"#EA4335\"\n                  d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.06l3.66 2.84c.87-2.6 3.3-4.52 6.16-4.52z\"\n                />\n              </svg>\n              <span>Google</span>\n            </button>\n          </div>\n\n          <div class=\"relative\">\n            <ui-separator />\n            <span\n              class=\"bg-background text-muted-foreground absolute -top-2.5 left-1/2 -translate-x-1/2 px-3 font-mono text-xs tracking-wider uppercase\"\n            >\n              Or continue with\n            </span>\n          </div>\n\n          <!-- Auth Method Tabs -->\n          <ui-tabs [value]=\"authMethod()\" (valueChange)=\"setAuthMethod($event)\" class=\"w-full\">\n            <ui-tabs-list class=\"grid h-9 w-full grid-cols-3\">\n              <button ui-tabs-trigger value=\"password\" class=\"text-xs font-medium\">Password</button>\n              <button ui-tabs-trigger value=\"passkey\" class=\"text-xs font-medium\">Passkey</button>\n              <button ui-tabs-trigger value=\"sso\" class=\"text-xs font-medium\">SAML SSO</button>\n            </ui-tabs-list>\n\n            <!-- Password Tab -->\n            <ui-tabs-content value=\"password\" class=\"mt-4 space-y-4\">\n              <form class=\"space-y-4\" (submit)=\"onSubmit($event)\">\n                <div class=\"space-y-1.5\">\n                  <label ui-label for=\"login01-email\" class=\"text-xs font-medium\">Work Email</label>\n                  <div class=\"relative\">\n                    <lucide-icon\n                      [img]=\"Mail\"\n                      class=\"text-muted-foreground pointer-events-none absolute top-2.5 left-3 size-4\"\n                    />\n                    <ui-input\n                      id=\"login01-email\"\n                      [value]=\"email()\"\n                      (valueChange)=\"email.set($event)\"\n                      type=\"email\"\n                      placeholder=\"alex@company.com\"\n                      autoComplete=\"email\"\n                      required\n                      class=\"h-9 pl-9 text-xs\"\n                    />\n                  </div>\n                  <!-- Enterprise domain detected badge -->\n                  @if (isEnterpriseEmail()) {\n                    <div class=\"text-primary mt-1 flex items-center gap-1.5 text-xs font-medium\">\n                      <lucide-icon [img]=\"ShieldCheck\" class=\"size-3.5\" />\n                      <span>Enterprise domain detected. Single Sign-On available.</span>\n                    </div>\n                  }\n                </div>\n\n                <div class=\"space-y-1.5\">\n                  <div class=\"flex items-center justify-between\">\n                    <label ui-label for=\"login01-password\" class=\"text-xs font-medium\">Password</label>\n                    <button\n                      type=\"button\"\n                      class=\"text-muted-foreground hover:text-foreground text-xs transition-colors\"\n                      (click)=\"forgotPassword.emit()\"\n                    >\n                      Forgot password?\n                    </button>\n                  </div>\n                  <div class=\"relative\">\n                    <lucide-icon\n                      [img]=\"Lock\"\n                      class=\"text-muted-foreground pointer-events-none absolute top-2.5 left-3 size-4\"\n                    />\n                    <ui-input\n                      id=\"login01-password\"\n                      [value]=\"password()\"\n                      (valueChange)=\"password.set($event)\"\n                      type=\"password\"\n                      placeholder=\"••••••••••••\"\n                      autoComplete=\"current-password\"\n                      required\n                      class=\"h-9 pl-9 text-xs\"\n                    />\n                  </div>\n                </div>\n\n                <button\n                  ui-button\n                  type=\"submit\"\n                  class=\"h-10 w-full gap-2 text-xs font-semibold shadow-xs\"\n                  [disabled]=\"isLoading()\"\n                >\n                  @if (isLoading()) {\n                    <span\n                      class=\"border-primary-foreground size-3.5 animate-spin rounded-full border-2 border-t-transparent\"\n                    ></span>\n                  } @else {\n                    <span>Continue with Password</span>\n                  }\n                  <lucide-icon [img]=\"ArrowRight\" class=\"size-3.5\" />\n                </button>\n              </form>\n            </ui-tabs-content>\n\n            <!-- Passkey Tab -->\n            <ui-tabs-content value=\"passkey\" class=\"mt-4 space-y-4\">\n              <div class=\"border-border bg-card space-y-4 rounded-xl border p-6 text-center\">\n                <div class=\"bg-primary/10 text-primary mx-auto flex size-12 items-center justify-center rounded-full\">\n                  <lucide-icon [img]=\"Fingerprint\" class=\"size-6\" />\n                </div>\n                <div class=\"space-y-1\">\n                  <p class=\"text-foreground text-sm font-semibold\">Passwordless Biometric Login</p>\n                  <p class=\"text-muted-foreground text-xs\">\n                    Use Touch ID, Face ID, or a FIDO2 hardware security key for zero-friction sign in.\n                  </p>\n                </div>\n                <button\n                  ui-button\n                  type=\"button\"\n                  class=\"h-10 w-full gap-2 text-xs font-semibold shadow-xs\"\n                  [disabled]=\"isLoading()\"\n                  (click)=\"onPasskey($event)\"\n                >\n                  <lucide-icon [img]=\"Fingerprint\" class=\"size-4\" />\n                  <span>{{ isLoading() ? 'Authenticating...' : 'Sign in with Passkey' }}</span>\n                </button>\n              </div>\n            </ui-tabs-content>\n\n            <!-- SSO Tab -->\n            <ui-tabs-content value=\"sso\" class=\"mt-4 space-y-4\">\n              <form class=\"space-y-4\" (submit)=\"onSubmit($event)\">\n                <div class=\"space-y-1.5\">\n                  <label ui-label for=\"login01-sso-domain\" class=\"text-xs font-medium\">Enterprise Domain</label>\n                  <ui-input\n                    id=\"login01-sso-domain\"\n                    [value]=\"ssoDomain()\"\n                    (valueChange)=\"ssoDomain.set($event)\"\n                    type=\"text\"\n                    placeholder=\"company.okta.com or domain.com\"\n                    required\n                    class=\"h-9 font-mono text-xs\"\n                  />\n                  <p class=\"text-muted-foreground text-xs\">\n                    Redirects to your corporate Identity Provider (Okta, Azure AD, Ping Identity).\n                  </p>\n                </div>\n\n                <button\n                  ui-button\n                  type=\"submit\"\n                  class=\"h-10 w-full gap-2 text-xs font-semibold shadow-xs\"\n                  [disabled]=\"isLoading()\"\n                >\n                  <lucide-icon [img]=\"KeyRound\" class=\"size-3.5\" />\n                  <span>Continue with SAML SSO</span>\n                  <lucide-icon [img]=\"ArrowRight\" class=\"size-3.5\" />\n                </button>\n              </form>\n            </ui-tabs-content>\n          </ui-tabs>\n\n          <div class=\"text-muted-foreground text-center text-xs\">\n            Don't have a workspace account?\n            <button type=\"button\" class=\"text-primary ml-1 font-semibold hover:underline\" (click)=\"signUp.emit()\">\n              Create free trial\n            </button>\n          </div>\n        </div>\n      </div>\n    </div>\n  `,\n})\nexport class UiLogin01Component {\n  protected readonly ArrowRight = ArrowRight\n  protected readonly CheckCircle2 = CheckCircle2\n  protected readonly Fingerprint = Fingerprint\n  protected readonly Github = Github\n  protected readonly KeyRound = KeyRound\n  protected readonly Lock = Lock\n  protected readonly Mail = Mail\n  protected readonly ShieldCheck = ShieldCheck\n  protected readonly Terminal = Terminal\n  protected readonly Zap = Zap\n\n  @Input('class') className?: string\n\n  @Output() readonly submit = new EventEmitter<Login01Payload>()\n  @Output() readonly forgotPassword = new EventEmitter<void>()\n  @Output() readonly signUp = new EventEmitter<void>()\n  @Output() readonly oauth = new EventEmitter<Login01OauthProvider>()\n\n  readonly authMethod = signal<Login01AuthMethod>('password')\n  readonly email = signal('')\n  readonly password = signal('')\n  readonly ssoDomain = signal('')\n  readonly isLoading = signal(false)\n\n  private timer: ReturnType<typeof setTimeout> | undefined\n\n  constructor() {\n    inject(DestroyRef).onDestroy(() => clearTimeout(this.timer))\n  }\n\n  readonly isEnterpriseEmail = computed(() => {\n    const parts = this.email().split('@')\n    if (parts.length < 2) return false\n    const domain = (parts[1] ?? '').toLowerCase()\n    return Boolean(domain) && !publicMailDomains.includes(domain) && domain.includes('.')\n  })\n\n  get rootClass(): string {\n    return cn('bg-background grid min-h-screen w-full grid-cols-1 lg:grid-cols-12', this.className)\n  }\n\n  setAuthMethod(value: string): void {\n    this.authMethod.set(value as Login01AuthMethod)\n  }\n\n  onSubmit(event: Event): void {\n    event.preventDefault()\n    this.beginAuth()\n  }\n\n  onPasskey(event: Event): void {\n    event.preventDefault()\n    this.beginAuth()\n  }\n\n  private beginAuth(): void {\n    if (this.isLoading()) return\n    this.isLoading.set(true)\n    clearTimeout(this.timer)\n    this.timer = setTimeout(() => {\n      this.isLoading.set(false)\n      this.submit.emit({\n        method: this.authMethod(),\n        email: this.email(),\n        password: this.password(),\n        domain: this.ssoDomain(),\n      })\n    }, 800)\n  }\n}\n",
      "type": "registry:page",
      "target": "~/src/app/components/blocks/login-01/login-01.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/login-01/index.ts",
      "content": "export {\n  UiLogin01Component,\n  type Login01AuthMethod,\n  type Login01OauthProvider,\n  type Login01Payload,\n} from './login-01.component'\n",
      "type": "registry:page",
      "target": "~/src/app/components/blocks/login-01/index.ts"
    }
  ],
  "dependencies": [
    "lucide-angular"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/angular/badge.json",
    "https://uipkge.dev/r/angular/button.json",
    "https://uipkge.dev/r/angular/input.json",
    "https://uipkge.dev/r/angular/label.json",
    "https://uipkge.dev/r/angular/separator.json",
    "https://uipkge.dev/r/angular/tabs.json"
  ],
  "description": "Split-screen developer console authentication suite featuring brand telemetry showcases, OAuth providers, passkey biometric sign-in, and automatic enterprise SAML SSO domain detection.",
  "categories": [
    "auth"
  ]
}