@propbinder/mobile-design 0.0.1 → 0.0.2
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.
- package/ng-package.json +7 -0
- package/package.json +12 -39
- package/src/animations/page-transitions.ts +86 -0
- package/src/assets/fonts/Brockmann-Bold.otf +0 -0
- package/src/assets/fonts/Brockmann-BoldItalic.otf +0 -0
- package/src/assets/fonts/Brockmann-Medium.otf +0 -0
- package/src/assets/fonts/Brockmann-MediumItalic.otf +0 -0
- package/src/assets/fonts/Brockmann-Regular.otf +0 -0
- package/src/assets/fonts/Brockmann-RegularItalic.otf +0 -0
- package/src/assets/fonts/Brockmann-SemiBold.otf +0 -0
- package/src/assets/fonts/Brockmann-SemiBoldItalic.otf +0 -0
- package/src/assets/fonts/Brockmann_desktop_license.pdf +0 -0
- package/src/assets/fonts/brockmann-medium-webfont.woff2 +0 -0
- package/src/assets/fonts/brockmann-regular-webfont.woff2 +0 -0
- package/src/assets/fonts/brockmann-semibold-webfont.woff2 +0 -0
- package/src/components/action-list-item/ds-mobile-action-list-item.ts +83 -0
- package/src/components/action-list-item/index.ts +2 -0
- package/src/components/app-layout/ds-mobile-app-layout.css +343 -0
- package/src/components/app-layout/ds-mobile-app-layout.ts +271 -0
- package/src/components/app-layout/index.ts +2 -0
- package/src/components/avatar-with-badge/ds-avatar-with-badge.ts +130 -0
- package/src/components/avatar-with-badge/index.ts +2 -0
- package/src/components/bottom-sheet/ds-mobile-actions-bottom-sheet.ts +273 -0
- package/src/components/bottom-sheet/ds-mobile-bottom-sheet.css +110 -0
- package/src/components/bottom-sheet/ds-mobile-bottom-sheet.service.ts +167 -0
- package/src/components/bottom-sheet/ds-mobile-post-create-bottom-sheet.ts +656 -0
- package/src/components/bottom-sheet/index.ts +3 -0
- package/src/components/comment/ds-mobile-comment.ts +516 -0
- package/src/components/comment/index.ts +2 -0
- package/src/components/contact-list-item/ds-mobile-contact-list-item.ts +182 -0
- package/src/components/contact-list-item/index.ts +2 -0
- package/src/components/content/ds-mobile-content.ts +158 -0
- package/src/components/content/index.ts +2 -0
- package/src/components/ds-mobile-tabs.css +372 -0
- package/src/components/ds-mobile-tabs.ts +217 -0
- package/src/components/file-attachment/ds-mobile-file-attachment.ts +164 -0
- package/src/components/file-attachment/index.ts +2 -0
- package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.service.ts +98 -0
- package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.ts +514 -0
- package/src/components/handbook-detail-modal/index.ts +3 -0
- package/src/components/handbook-folder/ds-mobile-handbook-folder-mini.ts +130 -0
- package/src/components/handbook-folder/ds-mobile-handbook-folder.ts +444 -0
- package/src/components/handbook-folder/index.ts +4 -0
- package/src/components/header-content/ds-mobile-header-content.ts +211 -0
- package/src/components/header-content/index.ts +2 -0
- package/src/components/index.ts +45 -0
- package/src/components/inline-photo/ds-mobile-inline-photo.ts +269 -0
- package/src/components/inline-photo/index.ts +1 -0
- package/src/components/interactive-list-item-inquiry/ds-mobile-interactive-list-item-inquiry.css +60 -0
- package/src/components/interactive-list-item-inquiry/ds-mobile-interactive-list-item-inquiry.ts +280 -0
- package/src/components/interactive-list-item-inquiry/index.ts +2 -0
- package/src/components/interactive-list-item-message/ds-mobile-interactive-list-item-message.ts +197 -0
- package/src/components/interactive-list-item-message/index.ts +2 -0
- package/src/components/interactive-list-item-post/ds-mobile-interactive-list-item-post.css +70 -0
- package/src/components/interactive-list-item-post/ds-mobile-interactive-list-item-post.ts +594 -0
- package/src/components/interactive-list-item-post/ds-mobile-post-pdf-attachment.ts +124 -0
- package/src/components/interactive-list-item-post/index.ts +13 -0
- package/src/components/lightbox/ds-mobile-lightbox-footer.ts +331 -0
- package/src/components/lightbox/ds-mobile-lightbox-header.ts +173 -0
- package/src/components/lightbox/ds-mobile-lightbox-image.ts +464 -0
- package/src/components/lightbox/ds-mobile-lightbox-pdf.css +375 -0
- package/src/components/lightbox/ds-mobile-lightbox-pdf.ts +374 -0
- package/src/components/lightbox/ds-mobile-lightbox.css +587 -0
- package/src/components/lightbox/ds-mobile-lightbox.service.ts +293 -0
- package/src/components/lightbox/ds-mobile-lightbox.ts +529 -0
- package/src/components/lightbox/index.ts +22 -0
- package/src/components/list-item/ds-mobile-list-item.ts +499 -0
- package/src/components/list-item/index.ts +2 -0
- package/src/components/list-item-static/ds-mobile-list-item-static.ts +133 -0
- package/src/components/list-item-static/index.ts +2 -0
- package/src/components/logo/ds-logo.ts +85 -0
- package/src/components/logo/index.ts +2 -0
- package/src/components/modal/ds-mobile-modal.css +163 -0
- package/src/components/modal/ds-mobile-modal.service.ts +329 -0
- package/src/components/modal/index.ts +8 -0
- package/src/components/page-details/ds-mobile-page-details.css +285 -0
- package/src/components/page-details/ds-mobile-page-details.ts +128 -0
- package/src/components/page-details/index.ts +2 -0
- package/src/components/page-main/ds-mobile-page-main.css +346 -0
- package/src/components/page-main/ds-mobile-page-main.ts +331 -0
- package/src/components/page-main/index.ts +2 -0
- package/src/components/post-card/ds-mobile-post-card.ts +685 -0
- package/src/components/post-card/ds-mobile-post-pdf-attachment.ts +124 -0
- package/src/components/post-card/index.ts +11 -0
- package/src/components/post-composer/ds-mobile-post-composer.ts +140 -0
- package/src/components/post-composer/index.ts +2 -0
- package/src/components/post-detail-modal/ds-mobile-post-detail-modal.service.ts +104 -0
- package/src/components/post-detail-modal/ds-mobile-post-detail-modal.ts +1273 -0
- package/src/components/post-detail-modal/index.ts +9 -0
- package/src/components/shared/directives/index.ts +2 -0
- package/src/components/shared/directives/long-press.directive.ts +208 -0
- package/src/components/shared/index.ts +3 -0
- package/src/components/shared/mobile-common.css +94 -0
- package/src/components/shared/mobile-page-base.css +315 -0
- package/src/components/shared/mobile-page-base.ts +70 -0
- package/src/components/swiper/ds-mobile-swiper.ts +123 -0
- package/src/components/swiper/index.ts +2 -0
- package/src/components/tab-bar/ds-mobile-tab-bar.ts +132 -0
- package/src/components/tab-bar/index.ts +2 -0
- package/src/components/tabs/ds-mobile-tabs.css +405 -0
- package/src/components/tabs/ds-mobile-tabs.ts +204 -0
- package/src/components/tabs/index.ts +2 -0
- package/src/pages/community.page.ts +768 -0
- package/src/pages/handbook.page.ts +298 -0
- package/src/pages/home.page.ts +192 -0
- package/src/pages/index.ts +9 -0
- package/src/pages/inquiries.example.ts +212 -0
- package/src/pages/inquiry-detail.example.css +434 -0
- package/src/pages/inquiry-detail.example.ts +416 -0
- package/src/pages/mobile-tabs-example.component.ts +146 -0
- package/src/pages/post-create.page.ts +311 -0
- package/src/pages/post-detail.page.ts +295 -0
- package/src/pages/whitelabel-demo.page.ts +548 -0
- package/src/public-api.ts +5 -0
- package/src/services/user.service.ts +35 -0
- package/src/services/whitelabel.service.ts +171 -0
- package/src/styles/ionic.css +673 -0
- package/tsconfig.lib.json +17 -0
- package/tsconfig.lib.prod.json +9 -0
- package/tsconfig.spec.json +13 -0
- package/fesm2022/propbinder-mobile-design.mjs +0 -8294
- package/fesm2022/propbinder-mobile-design.mjs.map +0 -1
- package/index.d.ts +0 -2860
package/ng-package.json
ADDED
package/package.json
CHANGED
|
@@ -1,39 +1,12 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@propbinder/mobile-design",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"peerDependencies": {
|
|
5
|
-
"@angular/common": "^20.3.0",
|
|
6
|
-
"@angular/core": "^20.3.0"
|
|
7
|
-
},
|
|
8
|
-
"dependencies": {
|
|
9
|
-
"tslib": "^2.3.0"
|
|
10
|
-
},
|
|
11
|
-
"sideEffects":
|
|
12
|
-
|
|
13
|
-
"./ui/**/*.css"
|
|
14
|
-
],
|
|
15
|
-
"module": "fesm2022/propbinder-mobile-design.mjs",
|
|
16
|
-
"typings": "index.d.ts",
|
|
17
|
-
"exports": {
|
|
18
|
-
"./package.json": {
|
|
19
|
-
"default": "./package.json"
|
|
20
|
-
},
|
|
21
|
-
".": {
|
|
22
|
-
"types": "./index.d.ts",
|
|
23
|
-
"default": "./fesm2022/propbinder-mobile-design.mjs"
|
|
24
|
-
},
|
|
25
|
-
"./styles/*": {
|
|
26
|
-
"default": "./styles/*"
|
|
27
|
-
},
|
|
28
|
-
"./styles/globals.css": {
|
|
29
|
-
"default": "./styles/globals.css"
|
|
30
|
-
},
|
|
31
|
-
"./ui/*": {
|
|
32
|
-
"default": "./ui/*"
|
|
33
|
-
},
|
|
34
|
-
"./assets/*": {
|
|
35
|
-
"default": "./assets/*"
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
"types": "./index.d.ts"
|
|
39
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@propbinder/mobile-design",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"peerDependencies": {
|
|
5
|
+
"@angular/common": "^20.3.0",
|
|
6
|
+
"@angular/core": "^20.3.0"
|
|
7
|
+
},
|
|
8
|
+
"dependencies": {
|
|
9
|
+
"tslib": "^2.3.0"
|
|
10
|
+
},
|
|
11
|
+
"sideEffects": false
|
|
12
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { Animation } from '@ionic/angular';
|
|
2
|
+
import { createAnimation } from '@ionic/core';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Custom page transition - iOS-style push/pop
|
|
6
|
+
*
|
|
7
|
+
* FORWARD (navigating TO detail):
|
|
8
|
+
* - Entering page (detail): slides in from RIGHT, z-index 10 (on top)
|
|
9
|
+
* - Leaving page (list): slides LEFT slightly, z-index 9 (underneath)
|
|
10
|
+
*
|
|
11
|
+
* REVERSE (swipe back FROM detail):
|
|
12
|
+
* - Entering page (list): slides in from LEFT, z-index 9 (underneath)
|
|
13
|
+
* - Leaving page (detail): slides out to RIGHT, z-index 10 (on top)
|
|
14
|
+
*/
|
|
15
|
+
export const customPageTransition = (_: HTMLElement, opts: any): Animation => {
|
|
16
|
+
const DURATION = 400;
|
|
17
|
+
const isBackDirection = opts.direction === 'back';
|
|
18
|
+
|
|
19
|
+
const rootTransition = createAnimation()
|
|
20
|
+
.duration(opts.duration || DURATION)
|
|
21
|
+
.easing('cubic-bezier(0.32,0.72,0,1)');
|
|
22
|
+
|
|
23
|
+
// Entering page animation
|
|
24
|
+
const enteringPage = createAnimation()
|
|
25
|
+
.addElement(opts.enteringEl)
|
|
26
|
+
.beforeRemoveClass('ion-page-invisible')
|
|
27
|
+
.beforeStyles({
|
|
28
|
+
'z-index': isBackDirection ? '9' : '10',
|
|
29
|
+
'opacity': '1'
|
|
30
|
+
})
|
|
31
|
+
.fromTo('transform',
|
|
32
|
+
isBackDirection ? 'translateX(-20%)' : 'translateX(100%)',
|
|
33
|
+
'translateX(0)'
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
// Leaving page animation
|
|
37
|
+
const leavingPage = createAnimation()
|
|
38
|
+
.addElement(opts.leavingEl)
|
|
39
|
+
.beforeStyles({
|
|
40
|
+
'z-index': isBackDirection ? '10' : '9'
|
|
41
|
+
})
|
|
42
|
+
.fromTo('transform',
|
|
43
|
+
'translateX(0)',
|
|
44
|
+
isBackDirection ? 'translateX(100%)' : 'translateX(-20%)'
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
rootTransition.addAnimation([enteringPage, leavingPage]);
|
|
48
|
+
|
|
49
|
+
return rootTransition;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Custom back transition - iOS style where page slides out to reveal page underneath
|
|
54
|
+
* The entering page (inquiries) slides in from the LEFT underneath
|
|
55
|
+
* The leaving page (detail) slides out to the RIGHT on top
|
|
56
|
+
*/
|
|
57
|
+
export const customBackTransition = (_: HTMLElement, opts: any): Animation => {
|
|
58
|
+
const DURATION = 400;
|
|
59
|
+
|
|
60
|
+
const rootTransition = createAnimation()
|
|
61
|
+
.duration(opts.duration || DURATION)
|
|
62
|
+
.easing('cubic-bezier(0.32,0.72,0,1)');
|
|
63
|
+
|
|
64
|
+
// Entering page: underneath, sliding in from LEFT (-20% to 0)
|
|
65
|
+
const enteringPage = createAnimation()
|
|
66
|
+
.addElement(opts.enteringEl)
|
|
67
|
+
.beforeRemoveClass('ion-page-invisible')
|
|
68
|
+
.beforeStyles({
|
|
69
|
+
'z-index': '9',
|
|
70
|
+
'opacity': '1'
|
|
71
|
+
})
|
|
72
|
+
.fromTo('transform', 'translateX(-20%)', 'translateX(0)');
|
|
73
|
+
|
|
74
|
+
// Leaving page: on top, sliding out to the RIGHT (0 to 100%)
|
|
75
|
+
const leavingPage = createAnimation()
|
|
76
|
+
.addElement(opts.leavingEl)
|
|
77
|
+
.beforeStyles({
|
|
78
|
+
'z-index': '10',
|
|
79
|
+
})
|
|
80
|
+
.fromTo('transform', 'translateX(0)', 'translateX(100%)');
|
|
81
|
+
|
|
82
|
+
rootTransition.addAnimation([enteringPage, leavingPage]);
|
|
83
|
+
|
|
84
|
+
return rootTransition;
|
|
85
|
+
};
|
|
86
|
+
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Component, input, output } from '@angular/core';
|
|
2
|
+
import { DsMobileListItemComponent } from '../list-item/ds-mobile-list-item';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* DsMobileActionListItemComponent
|
|
6
|
+
*
|
|
7
|
+
* Specialized list item for action sheets and menus.
|
|
8
|
+
* Wraps ds-mobile-list-item with action-specific styling:
|
|
9
|
+
* - Vertically centered content
|
|
10
|
+
* - Interactive by default
|
|
11
|
+
* - No dividers (controlled per-item)
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```html
|
|
15
|
+
* <ds-mobile-action-list-item
|
|
16
|
+
* title="Edit"
|
|
17
|
+
* [showDivider]="true"
|
|
18
|
+
* (itemClick)="handleEdit()">
|
|
19
|
+
* <ds-icon content-leading name="remixEditLine" size="20px" />
|
|
20
|
+
* </ds-mobile-action-list-item>
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
@Component({
|
|
24
|
+
selector: 'ds-mobile-action-list-item',
|
|
25
|
+
standalone: true,
|
|
26
|
+
imports: [DsMobileListItemComponent],
|
|
27
|
+
template: `
|
|
28
|
+
<ds-mobile-list-item
|
|
29
|
+
[title]="title()"
|
|
30
|
+
[interactive]="true"
|
|
31
|
+
[enableLongPress]="false"
|
|
32
|
+
[showDivider]="showDivider()"
|
|
33
|
+
[disabled]="disabled()"
|
|
34
|
+
(itemClick)="itemClick.emit()">
|
|
35
|
+
|
|
36
|
+
<div content-leading>
|
|
37
|
+
<ng-content select="[action-icon]" />
|
|
38
|
+
</div>
|
|
39
|
+
</ds-mobile-list-item>
|
|
40
|
+
`,
|
|
41
|
+
styles: [`
|
|
42
|
+
/* Center all content vertically for action items */
|
|
43
|
+
:host ::ng-deep ds-mobile-list-item .list-item-inner {
|
|
44
|
+
align-items: center;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/* Center icon within leading slot */
|
|
48
|
+
:host ::ng-deep ds-mobile-list-item .content-leading {
|
|
49
|
+
align-items: center;
|
|
50
|
+
justify-content: center;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/* Remove gap from content-main for single-line actions */
|
|
54
|
+
:host ::ng-deep ds-mobile-list-item .content-main {
|
|
55
|
+
gap: 0;
|
|
56
|
+
justify-content: center;
|
|
57
|
+
}
|
|
58
|
+
`]
|
|
59
|
+
})
|
|
60
|
+
export class DsMobileActionListItemComponent {
|
|
61
|
+
/**
|
|
62
|
+
* Action title text
|
|
63
|
+
*/
|
|
64
|
+
title = input.required<string>();
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Whether to show divider below item
|
|
68
|
+
* @default false
|
|
69
|
+
*/
|
|
70
|
+
showDivider = input<boolean>(false);
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Whether the action is disabled
|
|
74
|
+
* @default false
|
|
75
|
+
*/
|
|
76
|
+
disabled = input<boolean>(false);
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Emits when the action item is clicked
|
|
80
|
+
*/
|
|
81
|
+
itemClick = output<void>();
|
|
82
|
+
}
|
|
83
|
+
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
/* ============================================
|
|
2
|
+
HOST & BASE LAYOUT
|
|
3
|
+
============================================ */
|
|
4
|
+
|
|
5
|
+
:host {
|
|
6
|
+
display: block;
|
|
7
|
+
height: 100vh; /* Fallback for older browsers */
|
|
8
|
+
height: 100svh; /* Small viewport height - excludes browser UI */
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/* ============================================
|
|
12
|
+
IONIC OVERRIDES - TABS
|
|
13
|
+
============================================ */
|
|
14
|
+
|
|
15
|
+
ion-tabs {
|
|
16
|
+
height: 100%;
|
|
17
|
+
background: var(--color-brand-secondary);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* ============================================
|
|
21
|
+
IONIC OVERRIDES - HEADER
|
|
22
|
+
============================================ */
|
|
23
|
+
|
|
24
|
+
ion-header {
|
|
25
|
+
background: var(--color-brand-secondary);
|
|
26
|
+
box-shadow: none;
|
|
27
|
+
position: relative;
|
|
28
|
+
z-index: 10;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/* Gradient fade effect at bottom of header */
|
|
32
|
+
ion-header::after {
|
|
33
|
+
content: '';
|
|
34
|
+
position: absolute;
|
|
35
|
+
bottom: 0;
|
|
36
|
+
left: 0;
|
|
37
|
+
right: 0;
|
|
38
|
+
height: 30px;
|
|
39
|
+
background: linear-gradient(
|
|
40
|
+
to bottom,
|
|
41
|
+
var(--color-brand-secondary) 0%,
|
|
42
|
+
transparent 100%
|
|
43
|
+
);
|
|
44
|
+
pointer-events: none;
|
|
45
|
+
z-index: 1;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
ion-header ion-toolbar {
|
|
49
|
+
--background: var(--color-brand-secondary);
|
|
50
|
+
--border-width: 0;
|
|
51
|
+
--box-shadow: none;
|
|
52
|
+
--padding-top: var(--ion-safe-area-top, 0px);
|
|
53
|
+
--padding-bottom: 0;
|
|
54
|
+
--padding-start: 0;
|
|
55
|
+
--padding-end: 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
ion-header.header-translucent ion-toolbar {
|
|
59
|
+
--backdrop-filter: none;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/* ============================================
|
|
63
|
+
IONIC OVERRIDES - CONTENT
|
|
64
|
+
============================================ */
|
|
65
|
+
|
|
66
|
+
ion-content {
|
|
67
|
+
--background: transparent;
|
|
68
|
+
--padding-top: 0;
|
|
69
|
+
--padding-start: 0;
|
|
70
|
+
--padding-end: 0;
|
|
71
|
+
--padding-bottom: 0;
|
|
72
|
+
/* Explicitly avoid creating stacking context */
|
|
73
|
+
isolation: auto;
|
|
74
|
+
border-radius: 24px;
|
|
75
|
+
overflow: hidden;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
ion-content::part(scroll) {
|
|
79
|
+
/* Ensure smooth scrolling on iOS */
|
|
80
|
+
-webkit-overflow-scrolling: touch;
|
|
81
|
+
/* Block browser overscroll - ion-refresher provides its own elastic pull animation */
|
|
82
|
+
overscroll-behavior-y: none;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* ============================================
|
|
86
|
+
IONIC OVERRIDES - REFRESHER
|
|
87
|
+
============================================ */
|
|
88
|
+
|
|
89
|
+
/* Ionic Refresher Styling - provides native-feeling elastic pull */
|
|
90
|
+
ion-refresher {
|
|
91
|
+
z-index: 0; /* Below everything */
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
ion-refresher-content {
|
|
95
|
+
--color: white;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* ============================================
|
|
99
|
+
TAB BAR
|
|
100
|
+
============================================ */
|
|
101
|
+
|
|
102
|
+
ion-tab-bar {
|
|
103
|
+
--background: var(--color-background-neutral-primary);
|
|
104
|
+
padding: 8px 0;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/* Mobile: Bottom tab bar styling */
|
|
108
|
+
ion-tab-bar[slot="bottom"] {
|
|
109
|
+
border-top: 1px solid var(--border-color-default);
|
|
110
|
+
/* Add padding for home indicator (safe-area) on both iOS and Android */
|
|
111
|
+
padding-bottom: calc(var(--ion-safe-area-bottom, 0px) + 8px);
|
|
112
|
+
/* Also ensure proper padding at the top */
|
|
113
|
+
padding-top: 8px;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/* Desktop: Top tab bar styling - floating overlay */
|
|
117
|
+
ion-tab-bar[slot="top"] {
|
|
118
|
+
--background: transparent;
|
|
119
|
+
position: absolute;
|
|
120
|
+
top: 0;
|
|
121
|
+
left: 0;
|
|
122
|
+
right: 0;
|
|
123
|
+
z-index: 100;
|
|
124
|
+
border-bottom: none;
|
|
125
|
+
padding: 12px 0;
|
|
126
|
+
max-width: 1400px;
|
|
127
|
+
margin: 0 auto;
|
|
128
|
+
display: flex;
|
|
129
|
+
justify-content: flex-start;
|
|
130
|
+
gap: 8px;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/* On larger screens or PWA mode, remove the extra Safari toolbar padding */
|
|
134
|
+
@media (min-width: 769px) {
|
|
135
|
+
ion-tab-bar {
|
|
136
|
+
padding-bottom: var(--ion-safe-area-bottom, 0px);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@media (display-mode: standalone) {
|
|
141
|
+
ion-tab-bar {
|
|
142
|
+
padding-bottom: var(--ion-safe-area-bottom, 0px) !important;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
ion-tab-button {
|
|
147
|
+
--color: var(--text-color-default-tertiary);
|
|
148
|
+
--color-selected: var(--color-brand-base);
|
|
149
|
+
display: flex;
|
|
150
|
+
flex-direction: column;
|
|
151
|
+
align-items: center;
|
|
152
|
+
justify-content: center;
|
|
153
|
+
gap: 4px;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/* Desktop: Horizontal pill layout */
|
|
157
|
+
@media (min-width: 768px) {
|
|
158
|
+
ion-tab-button {
|
|
159
|
+
flex-direction: row;
|
|
160
|
+
height: 36px;
|
|
161
|
+
padding: 0px 12px;
|
|
162
|
+
border-radius: 40px;
|
|
163
|
+
transition: background-color 0.2s ease;
|
|
164
|
+
width: -moz-fit-content;
|
|
165
|
+
width: fit-content;
|
|
166
|
+
min-width: auto;
|
|
167
|
+
flex: 0 0 auto;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
ion-tab-button .button-native {
|
|
171
|
+
width: auto;
|
|
172
|
+
padding: 0;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
ion-tab-button a,
|
|
176
|
+
ion-tab-button span {
|
|
177
|
+
width: auto;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
ion-tab-button ds-icon {
|
|
181
|
+
margin-right: 4px;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
ion-tab-button.tab-selected {
|
|
185
|
+
background: var(--color-brand-base);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
ion-tab-button ion-label {
|
|
190
|
+
font-size: var(--font-size-2xs);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/* Desktop: Larger label, always white */
|
|
194
|
+
@media (min-width: 768px) {
|
|
195
|
+
ion-tab-button ion-label {
|
|
196
|
+
font-size: var(--font-size-base);
|
|
197
|
+
font-weight: 500;
|
|
198
|
+
line-height: 24px;
|
|
199
|
+
letter-spacing: -0.64px;
|
|
200
|
+
color: white;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
ion-tab-button ds-icon {
|
|
205
|
+
color: var(--text-color-default-tertiary);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
ion-tab-button.tab-selected ds-icon {
|
|
209
|
+
color: var(--color-brand-base);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/* Desktop: Icon sizing and colors */
|
|
213
|
+
@media (min-width: 768px) {
|
|
214
|
+
ion-tab-button ds-icon {
|
|
215
|
+
color: white;
|
|
216
|
+
width: 20px;
|
|
217
|
+
height: 20px;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
ion-tab-button.tab-selected ds-icon {
|
|
221
|
+
color: white;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/* ============================================
|
|
226
|
+
HEADER VARIANT: HOME
|
|
227
|
+
============================================ */
|
|
228
|
+
|
|
229
|
+
.header-home {
|
|
230
|
+
display: flex;
|
|
231
|
+
align-items: center;
|
|
232
|
+
justify-content: space-between;
|
|
233
|
+
padding: 12px 16px;
|
|
234
|
+
/* Add safe area padding for Android/iOS notched devices */
|
|
235
|
+
padding-top: calc(12px + var(--ion-safe-area-top, 0px));
|
|
236
|
+
background: var(--color-brand-secondary);
|
|
237
|
+
position: relative;
|
|
238
|
+
z-index: 2;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
.logomark {
|
|
242
|
+
height: 28px;
|
|
243
|
+
width: auto;
|
|
244
|
+
flex-shrink: 0;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.header-home__actions {
|
|
248
|
+
display: flex;
|
|
249
|
+
align-items: center;
|
|
250
|
+
gap: 8px;
|
|
251
|
+
cursor: pointer;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.header-home__actions ds-avatar {
|
|
255
|
+
cursor: pointer;
|
|
256
|
+
transition: opacity var(--transition-duration-fast) var(--ease-smooth);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.header-home__actions ds-avatar:hover {
|
|
260
|
+
opacity: 0.9;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.header-home__actions ds-avatar:active {
|
|
264
|
+
opacity: 0.8;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/* ============================================
|
|
268
|
+
HEADER VARIANT: SIMPLE
|
|
269
|
+
============================================ */
|
|
270
|
+
|
|
271
|
+
.header-simple {
|
|
272
|
+
padding: 12px 16px;
|
|
273
|
+
/* Add safe area padding for Android/iOS notched devices */
|
|
274
|
+
padding-top: calc(12px + var(--ion-safe-area-top, 0px));
|
|
275
|
+
background: transparent;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.header-simple .header-title {
|
|
279
|
+
font-size: var(--font-size-xl);
|
|
280
|
+
font-weight: 600;
|
|
281
|
+
color: white;
|
|
282
|
+
margin: 0;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/* ============================================
|
|
286
|
+
HEADER VARIANT: BACK
|
|
287
|
+
============================================ */
|
|
288
|
+
|
|
289
|
+
.header-back {
|
|
290
|
+
display: flex;
|
|
291
|
+
align-items: center;
|
|
292
|
+
gap: 12px;
|
|
293
|
+
padding: 12px 16px;
|
|
294
|
+
/* Add safe area padding for Android/iOS notched devices */
|
|
295
|
+
padding-top: calc(12px + var(--ion-safe-area-top, 0px));
|
|
296
|
+
background: transparent;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.back-button {
|
|
300
|
+
background: none;
|
|
301
|
+
border: none;
|
|
302
|
+
padding: 0;
|
|
303
|
+
display: flex;
|
|
304
|
+
align-items: center;
|
|
305
|
+
justify-content: center;
|
|
306
|
+
cursor: pointer;
|
|
307
|
+
color: white;
|
|
308
|
+
transition: opacity var(--transition-duration-fast) var(--ease-smooth);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.back-button:hover {
|
|
312
|
+
opacity: 0.8;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
.back-button:active {
|
|
316
|
+
opacity: 0.6;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
.back-button ds-icon {
|
|
320
|
+
color: white;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
.header-back .header-title {
|
|
324
|
+
font-size: var(--font-size-xl);
|
|
325
|
+
font-weight: 600;
|
|
326
|
+
color: white;
|
|
327
|
+
margin: 0;
|
|
328
|
+
flex: 1;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/* ============================================
|
|
332
|
+
EXPANDABLE HEADER (for home page pattern)
|
|
333
|
+
============================================ */
|
|
334
|
+
|
|
335
|
+
.header-expandable {
|
|
336
|
+
background: var(--color-brand-secondary);
|
|
337
|
+
padding: 24px 16px;
|
|
338
|
+
color: white;
|
|
339
|
+
position: sticky;
|
|
340
|
+
top: 0;
|
|
341
|
+
z-index: 10;
|
|
342
|
+
}
|
|
343
|
+
|