2024-03-06 09:32:50 -08:00
|
|
|
<main
|
2025-08-20 15:06:24 -04:00
|
|
|
class="tw-relative tw-flex tw-w-full tw-mx-auto tw-flex-col tw-bg-background-alt tw-p-5 tw-text-main"
|
2024-08-31 13:19:48 -07:00
|
|
|
[ngClass]="{
|
2024-09-13 09:16:25 -07:00
|
|
|
'tw-min-h-screen': clientType === 'web',
|
2024-10-08 14:51:08 -04:00
|
|
|
'tw-min-h-full': clientType === 'browser' || clientType === 'desktop',
|
2024-08-31 13:19:48 -07:00
|
|
|
}"
|
2024-03-06 09:32:50 -08:00
|
|
|
>
|
2025-12-17 15:02:37 -05:00
|
|
|
<div
|
|
|
|
|
[class]="
|
|
|
|
|
'tw-flex tw-justify-between tw-items-center tw-w-full' + (!hideLogo() ? ' tw-mb-12' : '')
|
|
|
|
|
"
|
|
|
|
|
>
|
2025-12-11 13:56:13 -05:00
|
|
|
@if (!hideLogo()) {
|
|
|
|
|
<a
|
|
|
|
|
[routerLink]="['/']"
|
|
|
|
|
class="tw-w-32 sm:tw-w-[200px] tw-self-center sm:tw-self-start tw-block [&>*]:tw-align-top"
|
|
|
|
|
>
|
|
|
|
|
<bit-icon [icon]="logo" [ariaLabel]="'appLogoLabel' | i18n"></bit-icon>
|
|
|
|
|
</a>
|
|
|
|
|
}
|
|
|
|
|
<div class="tw-ms-auto">
|
|
|
|
|
<ng-content select="[slot=header-actions]"></ng-content>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2024-07-30 13:48:51 -05:00
|
|
|
|
2025-06-30 13:47:31 -04:00
|
|
|
<div class="tw-text-center tw-mb-4 sm:tw-mb-6 tw-mx-auto" [ngClass]="maxWidthClass">
|
2025-10-20 14:07:48 -04:00
|
|
|
@let iconInput = icon();
|
|
|
|
|
|
2025-09-16 14:41:17 -04:00
|
|
|
<!-- In some scenarios this icon's size is not limited by container width correctly -->
|
|
|
|
|
<!-- Targeting the SVG here to try and ensure it never grows too large in even the media queries are not working as expected -->
|
|
|
|
|
<div
|
2025-10-20 14:07:48 -04:00
|
|
|
*ngIf="iconInput !== null"
|
2025-09-16 14:41:17 -04:00
|
|
|
class="tw-size-20 sm:tw-size-24 [&_svg]:tw-w-full [&_svg]:tw-max-w-24 tw-mx-auto tw-content-center"
|
|
|
|
|
>
|
2025-10-20 14:07:48 -04:00
|
|
|
<bit-icon [icon]="iconInput"></bit-icon>
|
2024-03-06 09:32:50 -08:00
|
|
|
</div>
|
2024-07-30 13:48:51 -05:00
|
|
|
|
2025-12-11 13:56:13 -05:00
|
|
|
@if (title()) {
|
2024-09-09 15:12:31 -07:00
|
|
|
<!-- Small screens -->
|
2025-08-20 15:06:24 -04:00
|
|
|
<h1 bitTypography="h2" class="tw-mt-2 sm:tw-hidden">
|
2025-07-16 08:39:37 -04:00
|
|
|
{{ title() }}
|
2024-09-09 15:12:31 -07:00
|
|
|
</h1>
|
|
|
|
|
<!-- Medium to Larger screens -->
|
2025-08-20 15:06:24 -04:00
|
|
|
<h1 bitTypography="h1" class="tw-mt-2 tw-hidden sm:tw-block">
|
2025-07-16 08:39:37 -04:00
|
|
|
{{ title() }}
|
2024-09-09 15:12:31 -07:00
|
|
|
</h1>
|
2025-12-11 13:56:13 -05:00
|
|
|
}
|
2024-09-13 09:16:25 -07:00
|
|
|
|
2025-12-11 13:56:13 -05:00
|
|
|
@if (subtitle()) {
|
|
|
|
|
<div class="tw-text-sm sm:tw-text-base">{{ subtitle() }}</div>
|
|
|
|
|
}
|
2024-03-06 09:32:50 -08:00
|
|
|
</div>
|
2024-07-30 13:48:51 -05:00
|
|
|
|
2024-06-04 14:45:10 -07:00
|
|
|
<div
|
2025-08-20 15:06:24 -04:00
|
|
|
class="tw-z-10 tw-grow tw-w-full tw-mx-auto tw-flex tw-flex-col tw-items-center sm:tw-min-w-[28rem]"
|
2025-06-30 13:47:31 -04:00
|
|
|
[ngClass]="maxWidthClass"
|
2024-06-04 14:45:10 -07:00
|
|
|
>
|
2025-07-16 08:39:37 -04:00
|
|
|
@if (hideCardWrapper()) {
|
2025-06-26 17:09:25 -04:00
|
|
|
<div class="tw-mb-6 sm:tw-mb-10">
|
|
|
|
|
<ng-container *ngTemplateOutlet="defaultContent"></ng-container>
|
|
|
|
|
</div>
|
|
|
|
|
} @else {
|
2025-10-27 11:14:42 -04:00
|
|
|
<bit-base-card
|
|
|
|
|
class="!tw-rounded-2xl tw-mb-6 sm:tw-mb-10 tw-mx-auto tw-w-full tw-bg-transparent tw-border-none tw-shadow-none sm:tw-bg-background sm:tw-border sm:tw-border-solid sm:tw-border-secondary-100 sm:tw-shadow sm:tw-p-8"
|
2025-06-26 17:09:25 -04:00
|
|
|
>
|
|
|
|
|
<ng-container *ngTemplateOutlet="defaultContent"></ng-container>
|
2025-10-27 11:14:42 -04:00
|
|
|
</bit-base-card>
|
2025-06-26 17:09:25 -04:00
|
|
|
}
|
2024-03-06 09:32:50 -08:00
|
|
|
<ng-content select="[slot=secondary]"></ng-content>
|
|
|
|
|
</div>
|
2024-07-30 13:48:51 -05:00
|
|
|
|
2025-12-11 13:56:13 -05:00
|
|
|
@if (!hideFooter()) {
|
|
|
|
|
<footer class="tw-text-center tw-mt-4 sm:tw-mt-6">
|
|
|
|
|
@if (showReadonlyHostname()) {
|
|
|
|
|
<div bitTypography="body2">{{ "accessing" | i18n }} {{ hostname }}</div>
|
|
|
|
|
} @else {
|
|
|
|
|
<ng-content select="[slot=environment-selector]"></ng-content>
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@if (!hideYearAndVersion) {
|
|
|
|
|
<div bitTypography="body2">© {{ year }} Bitwarden Inc.</div>
|
|
|
|
|
<div bitTypography="body2">{{ version }}</div>
|
|
|
|
|
}
|
|
|
|
|
</footer>
|
|
|
|
|
}
|
2025-08-20 15:06:24 -04:00
|
|
|
|
2025-10-15 10:32:02 -04:00
|
|
|
@if (!hideBackgroundIllustration()) {
|
|
|
|
|
<div
|
|
|
|
|
class="tw-hidden md:tw-block [&_svg]:tw-absolute tw-z-[1] tw-opacity-[.11] [&_svg]:tw-bottom-0 [&_svg]:tw-start-0 [&_svg]:tw-w-[35%] [&_svg]:tw-max-w-[450px]"
|
|
|
|
|
>
|
|
|
|
|
<bit-icon [icon]="leftIllustration"></bit-icon>
|
|
|
|
|
</div>
|
|
|
|
|
<div
|
|
|
|
|
class="tw-hidden md:tw-block [&_svg]:tw-absolute tw-z-[1] tw-opacity-[.11] [&_svg]:tw-bottom-0 [&_svg]:tw-end-0 [&_svg]:tw-w-[35%] [&_svg]:tw-max-w-[450px]"
|
|
|
|
|
>
|
|
|
|
|
<bit-icon [icon]="rightIllustration"></bit-icon>
|
|
|
|
|
</div>
|
|
|
|
|
}
|
2024-03-06 09:32:50 -08:00
|
|
|
</main>
|
2025-06-26 17:09:25 -04:00
|
|
|
|
|
|
|
|
<ng-template #defaultContent>
|
|
|
|
|
<ng-content></ng-content>
|
|
|
|
|
</ng-template>
|