At Studio Hyperdrive, we’re all about building robust digital solutions.
We’ve been passionately developing our JavaScript and Angular expertise since
@@ -94,7 +94,10 @@
Tour
employees has grown into an active open source ecosystem powered by the
ingenuity of our team and the broader developer community.
-
+
+
Built for developers
for Angular applications, our packages have something to offer. And if not, stay
tuned. We’re working every day on expanding them.
-
+
“By switching our mindset from one-off to more robust solutions, we are now
working together across projects, which has had a remarkable impact on the
quality of our code and developer happiness.”
Denis Valcke, lead developer and project founder.
+
diff --git a/apps/docs/src/app/pages/landing/landing-page.component.scss b/apps/docs/src/app/pages/landing/landing-page.component.scss
index 92cd0b34..597ee938 100644
--- a/apps/docs/src/app/pages/landing/landing-page.component.scss
+++ b/apps/docs/src/app/pages/landing/landing-page.component.scss
@@ -86,31 +86,7 @@ div.landing {
b {
font-size: 1.1rem;
}
- .quote {
- width: 100%;
- font-size: 1.1rem;
- font-style: italic;
- padding: 1rem;
- background-color: light-dark(white, #e5e5e5);
- border-bottom: 5px solid #bd00ff;
- color: black;
- box-shadow: rgba(0, 0, 0, 0.5) 0px 0px 10px;
- border-image: linear-gradient(
- 90deg,
- #00cb9a 0.32%,
- #3858ca 29.01%,
- #38cfff 51.04%,
- #f872c2 98.69%
- )
- 1;
- p {
- margin-bottom: 1rem;
- text-align: center;
- }
- cite {
- color: grey;
- }
- }
+
a.button {
margin: 1rem auto;
display: flex;
@@ -123,7 +99,10 @@ div.landing {
text-decoration: none;
border: 1px solid light-dark(black, white);
align-items: center;
- transition: all 0.2s;
+ transition: all 0.3s;
+ img {
+ transition: all 0.3s;
+ }
&:hover {
cursor: pointer;
color: white;
@@ -136,8 +115,48 @@ div.landing {
}
&.divide {
display: grid;
- gap: 1.5rem;
+ gap: 1.5rem 2.5rem;
+ .photo {
+ position: relative;
+ width: 100%;
+ min-height: 16rem;
+ height: 100%;
+ background: black url('../../../../public/team.webp') center / cover
+ no-repeat;
+ }
+ .quote {
+ width: 100%;
+ font-size: 1.1rem;
+ font-style: italic;
+ background-color: light-dark(white, #e5e5e5);
+ color: black;
+ position: relative;
+ padding: 1rem;
+ p {
+ margin-bottom: 1rem;
+ text-align: center;
+ }
+ cite {
+ color: grey;
+ }
+ }
+ div.line {
+ width: 100%;
+ height: 2px;
+ bottom: 0;
+ left: 0;
+ position: absolute;
+ background-image: linear-gradient(
+ -90.97deg,
+ #00cb9a 0.32%,
+ #3858ca 29.01%,
+ #38cfff 51.04%,
+ #f872c2 98.69%
+ );
+ clip-path: inset(0 0 0 0);
+ }
}
+
&.bullets {
display: grid;
gap: 2rem;
@@ -163,7 +182,7 @@ div.landing {
align-items: end;
div.tool {
padding-bottom: 1rem;
- border-bottom: 2px solid light-dark(black, white);
+ border-bottom: 1px solid light-dark(black, white);
display: grid;
grid-template-columns: auto 1fr;
grid-template-rows: auto 1fr;
@@ -187,10 +206,11 @@ div.landing {
height: 1.5rem;
display: block;
padding: 0.25rem 0.5rem;
- transition: all 0.2s;
+ transition: background-color 0.3s, border 0.3s;
img {
display: block;
width: 100%;
+ transition: filter 0.3s;
}
&:hover {
background-color: #bd00ff;
@@ -269,6 +289,22 @@ div.landing {
padding: 4rem 3rem;
div.divide {
grid-template-columns: repeat(2, 1fr);
+ position: relative;
+ p.extra-margin {
+ margin-bottom: 2rem;
+ }
+ .photo {
+ position: static;
+ grid-row: 1 / 3;
+ grid-column-start: 1;
+ }
+ .quote {
+ position: static;
+ padding-bottom: 2rem;
+ }
+ div.line {
+ bottom: 1rem;
+ }
}
div.tools {
grid-template-columns: repeat(3, 1fr);
diff --git a/apps/docs/src/app/pages/landing/landing-page.component.ts b/apps/docs/src/app/pages/landing/landing-page.component.ts
index 4b252fb6..2d29d6b4 100644
--- a/apps/docs/src/app/pages/landing/landing-page.component.ts
+++ b/apps/docs/src/app/pages/landing/landing-page.component.ts
@@ -1,5 +1,6 @@
-import { Component } from '@angular/core';
+import { Component, ElementRef, HostListener, ViewChild } from '@angular/core';
import { RouterLink } from '@angular/router';
+import { trigger, state, style, animate, transition } from '@angular/animations';
import { ERoutes } from '../../shared/types';
@Component({
@@ -7,7 +8,46 @@ import { ERoutes } from '../../shared/types';
selector: 'landing-page',
templateUrl: 'landing-page.component.html',
styleUrl: 'landing-page.component.scss',
+ animations: [
+ trigger('slideIn', [
+ state(
+ 'hide',
+ style({
+ clipPath: 'inset(0 100% 0 0)',
+ })
+ ),
+ state(
+ 'show',
+ style({
+ clipPath: 'inset(0 0 0 0)',
+ })
+ ),
+ transition('hide => show', [animate('1s 100ms ease-in-out')]),
+ ]),
+ ],
})
export class LandingPageComponent {
public routes: typeof ERoutes = ERoutes;
+
+ clipQuoteLine = true;
+ clipPhotoLine = true;
+
+ @ViewChild('quote', { static: false }) private quote: ElementRef
| undefined;
+ @ViewChild('photo', { static: false }) private photo: ElementRef | undefined;
+
+ @HostListener('window:scroll', ['$event'])
+ isScrolledIntoView() {
+ if (this.quote && this.clipQuoteLine) {
+ const rect = this.quote.nativeElement.getBoundingClientRect();
+ const topShown = rect.top >= 0;
+ const bottomShown = rect.bottom <= window.innerHeight;
+ this.clipQuoteLine = !(topShown && bottomShown);
+ }
+ if (this.photo && this.clipPhotoLine) {
+ const rect = this.photo.nativeElement.getBoundingClientRect();
+ const topShown = rect.top >= 0;
+ const bottomShown = rect.bottom <= window.innerHeight;
+ this.clipPhotoLine = !(topShown && bottomShown);
+ }
+ }
}
diff --git a/apps/docs/src/styles.scss b/apps/docs/src/styles.scss
index 51cda626..f3ec0a66 100644
--- a/apps/docs/src/styles.scss
+++ b/apps/docs/src/styles.scss
@@ -43,7 +43,6 @@ ng-doc-navbar {
#f872c2 98.69%
)
1;
- border-width: 2px 0 0 0 !important;
}
.ng-doc-navbar-left {