diff --git a/app/resources/css/app.css b/app/resources/css/app.css index 24856b6..df210d6 100644 --- a/app/resources/css/app.css +++ b/app/resources/css/app.css @@ -403,4 +403,228 @@ .clu-pill.danger { color: var(--color-danger); background: var(--color-danger-soft); border-color: rgba(219,59,59,0.28); } .clu-pill.accent { color: var(--color-accent); background: var(--color-accent-soft); border-color: rgba(59,111,242,0.28); } .clu-pill.muted { color: var(--color-muted); background: rgba(0,0,0,0.04); border-color: var(--color-hairline); } + + /* ───── Signup-specific ───── */ + + /* Stepper */ + .clu-stepper { + display: flex; align-items: center; gap: 8px; + margin-top: 24px; + font-family: var(--font-mono); + font-size: 11px; + } + .clu-step { display: flex; align-items: center; gap: 8px; } + .clu-step-num { + width: 22px; height: 22px; + border-radius: 50%; + border: 1px solid var(--color-hairline); + background: rgba(255,255,255,0.6); + display: grid; place-items: center; + font-size: 11px; font-weight: 600; + color: var(--color-muted-2); + transition: all .15s; + } + .clu-step.active .clu-step-num { background: var(--color-accent); border-color: var(--color-accent); color: #fff; box-shadow: 0 4px 12px -4px rgba(59,111,242,0.6); } + .clu-step.done .clu-step-num { background: var(--color-success); border-color: var(--color-success); color: #fff; } + .clu-step-label { + color: var(--color-muted); + text-transform: uppercase; + letter-spacing: 0.06em; + font-weight: 600; + } + .clu-step.active .clu-step-label { color: var(--color-fg); } + .clu-step-line { flex: 1; height: 1px; background: var(--color-hairline); min-width: 14px; max-width: 28px; } + + /* Input variants */ + .clu-field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; } + .clu-hint { + font-size: 10.5px; font-weight: 500; + color: var(--color-muted-2); + font-family: var(--font-mono); + text-transform: none; + letter-spacing: 0; + } + .clu-input.with-suffix { padding-right: 0; } + .clu-input-suffix { + height: 100%; + display: flex; align-items: center; + padding: 0 13px; + border-left: 1px solid var(--color-hairline); + color: var(--color-muted-2); + font-family: var(--font-mono); + font-size: 11.5px; + background: rgba(255,255,255,0.35); + border-top-right-radius: var(--radius-xs); + border-bottom-right-radius: var(--radius-xs); + } + .clu-input-check { color: var(--color-success); display: none; flex: none; } + .clu-input.valid .clu-input-check { display: inline-flex; } + + /* Slug preview */ + .clu-slug-preview { + font-family: var(--font-mono); + font-size: 11px; + color: var(--color-muted); + margin-top: 4px; + } + .clu-slug-preview b { color: var(--color-accent); font-weight: 600; } + + /* Password meter + rules */ + .clu-pw-meter { + display: flex; gap: 4px; + margin-top: 6px; + } + .clu-pw-meter span { + flex: 1; height: 3px; + border-radius: 2px; + background: rgba(30,35,60,0.10); + transition: background .2s; + } + .clu-pw-meter.s1 span:nth-child(-n+1) { background: var(--color-danger); } + .clu-pw-meter.s2 span:nth-child(-n+2) { background: var(--color-warning); } + .clu-pw-meter.s3 span:nth-child(-n+3) { background: var(--color-accent); } + .clu-pw-meter.s4 span { background: var(--color-success); } + .clu-pw-rules { + display: flex; flex-wrap: wrap; gap: 6px 12px; + margin-top: 6px; + font-family: var(--font-mono); + font-size: 10.5px; + color: var(--color-muted); + } + .clu-pw-rule { display: inline-flex; align-items: center; gap: 5px; } + .clu-pw-rule .clu-pw-bullet { + width: 5px; height: 5px; + border-radius: 50%; + background: var(--color-muted-2); + transition: background .15s; + } + .clu-pw-rule.ok { color: var(--color-success); } + .clu-pw-rule.ok .clu-pw-bullet { background: var(--color-success); } + + /* Trial card */ + .clu-trial-card { + background: var(--color-glass); + border: 1px solid var(--color-glass-border); + border-radius: var(--radius-sm); + padding: 18px 20px; + position: relative; + overflow: hidden; + backdrop-filter: blur(14px) saturate(160%); + -webkit-backdrop-filter: blur(14px) saturate(160%); + box-shadow: inset 0 1px 0 rgba(255,255,255,0.8); + } + .clu-trial-card::before { + content: ""; + position: absolute; top: 0; left: 0; right: 0; + height: 2px; + background: linear-gradient(90deg, var(--color-accent), var(--color-accent-2)); + } + .clu-trial-row { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px; } + .clu-trial-tag { + font-family: var(--font-mono); + font-size: 10.5px; font-weight: 600; + color: var(--color-accent); + background: var(--color-accent-soft); + padding: 3px 9px; + border-radius: 5px; + border: 1px solid rgba(59,111,242,0.25); + text-transform: uppercase; + letter-spacing: 0.05em; + } + .clu-trial-count { + font-family: var(--font-mono); + font-size: 11px; + color: var(--color-muted); + display: inline-flex; align-items: center; gap: 6px; + } + .clu-trial-title { + font-size: 22px; + font-weight: 600; + letter-spacing: -0.015em; + line-height: 1.25; + margin-top: 12px; + } + .clu-trial-title em { + font-style: normal; + background: linear-gradient(90deg, var(--color-accent), var(--color-accent-2)); + -webkit-background-clip: text; + background-clip: text; + color: transparent; + font-weight: 700; + } + .clu-trial-sub { + color: var(--color-muted); + font-size: 13px; + margin-top: 6px; + } + + /* Benefit list */ + .clu-benefit-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 14px; } + .clu-benefit { display: flex; gap: 12px; align-items: flex-start; } + .clu-benefit-ico { + width: 32px; height: 32px; + border-radius: 9px; + background: var(--color-accent-soft); + border: 1px solid rgba(59,111,242,0.22); + color: var(--color-accent); + display: grid; place-items: center; + flex: none; + } + .clu-benefit-ico.success { background: var(--color-success-soft); border-color: rgba(21,160,106,0.22); color: var(--color-success); } + .clu-benefit-ico.purple { background: rgba(124,92,255,0.12); border-color: rgba(124,92,255,0.25); color: var(--color-accent-2); } + .clu-benefit-ico.warn { background: var(--color-warning-soft); border-color: rgba(194,130,15,0.22); color: var(--color-warning); } + .clu-benefit-title { font-size: 13.5px; font-weight: 600; color: var(--color-fg); } + .clu-benefit-desc { font-size: 12.5px; color: var(--color-muted); margin-top: 2px; line-height: 1.5; } + + /* Quote card */ + .clu-quote-card { + background: var(--color-glass); + border: 1px solid var(--color-glass-border); + border-radius: var(--radius-sm); + padding: 18px 20px; + margin-top: auto; + backdrop-filter: blur(14px) saturate(160%); + -webkit-backdrop-filter: blur(14px) saturate(160%); + box-shadow: inset 0 1px 0 rgba(255,255,255,0.8); + } + .clu-quote-text { font-size: 13.5px; color: var(--color-fg); line-height: 1.55; } + .clu-quote-text::before { content: "„"; color: var(--color-accent); font-size: 24px; line-height: 0; margin-right: 4px; vertical-align: -6px; font-weight: 600; } + .clu-quote-text::after { content: """; color: var(--color-accent); font-weight: 600; } + .clu-quote-author { display: flex; align-items: center; gap: 10px; margin-top: 12px; } + .clu-avatar { + width: 32px; height: 32px; + border-radius: 50%; + background: linear-gradient(135deg, var(--color-success), #2a9d6f); + display: grid; place-items: center; + color: #fff; font-weight: 700; font-size: 12px; + font-family: var(--font-mono); + flex: none; + } + .clu-author-name { font-size: 12.5px; color: var(--color-fg); font-weight: 600; } + .clu-author-role { font-size: 11px; color: var(--color-muted); font-family: var(--font-mono); } + + /* Logo strip */ + .clu-logos { + display: flex; align-items: center; gap: 20px; flex-wrap: wrap; + font-family: var(--font-mono); + font-size: 11px; + color: var(--color-muted); + text-transform: uppercase; + letter-spacing: 0.08em; + } + .clu-logo-pill { + padding: 5px 11px; + border: 1px solid var(--color-glass-border); + border-radius: 7px; + background: var(--color-glass); + box-shadow: inset 0 1px 0 rgba(255,255,255,0.7); + } + + /* Top-link helper */ + .clu-top-link { + display: flex; align-items: center; gap: 6px; + color: var(--color-muted); + font-size: 12.5px; + } + .clu-top-link a { color: var(--color-accent); font-weight: 600; } } diff --git a/app/resources/views/livewire/pages/auth/register.blade.php b/app/resources/views/livewire/pages/auth/register.blade.php index 430161b..c5646fe 100644 --- a/app/resources/views/livewire/pages/auth/register.blade.php +++ b/app/resources/views/livewire/pages/auth/register.blade.php @@ -4,6 +4,7 @@ use App\Models\User; use Illuminate\Auth\Events\Registered; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Hash; +use Illuminate\Support\Str; use Illuminate\Validation\Rules; use Livewire\Attributes\Layout; use Livewire\Volt\Component; @@ -17,12 +18,38 @@ new #[Layout('layouts.login')] class extends Component public string $password = ''; public bool $terms = false; + public function getSlugProperty(): string + { + return Str::slug($this->workspace) ?: 'dein-team'; + } + + public function getEmailValidProperty(): bool + { + return (bool) preg_match('/^[^\s@]+@[^\s@]+\.[^\s@]+$/', $this->email); + } + + public function getPwChecksProperty(): array + { + $v = $this->password; + return [ + 'len' => mb_strlen($v) >= 10, + 'upper' => (bool) preg_match('/[A-Z]/', $v), + 'num' => (bool) preg_match('/[0-9]/', $v), + 'sym' => (bool) preg_match('/[^A-Za-z0-9]/', $v), + ]; + } + + public function getPwScoreProperty(): int + { + return count(array_filter($this->pwChecks)); + } + public function register(): void { $this->validate([ 'firstname' => ['required', 'string', 'max:255'], 'lastname' => ['required', 'string', 'max:255'], - 'email' => ['required', 'string', 'lowercase', 'email', 'max:255', 'unique:'.User::class], + 'email' => ['required', 'string', 'lowercase', 'email', 'max:255', 'unique:' . User::class], 'workspace' => ['required', 'string', 'max:255'], 'password' => ['required', 'string', Rules\Password::min(10)], 'terms' => ['accepted'], @@ -41,287 +68,283 @@ new #[Layout('layouts.login')] class extends Component } }; ?> -
Keine Kreditkarte. Volle Funktionen. Jederzeit kündbar.
-