@mostrom/app-shell 0.1.2 → 0.1.3

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # App Shell
2
2
 
3
- Shared Cloudscape-based layout shell used by all platform services. Mirrors the AWS Console layout pattern.
3
+ Shared layout shell used by all platform services. Provides a consistent layout pattern with global header, service navigation, and content areas.
4
4
 
5
5
  ## Publishing to npm
6
6
 
@@ -33,11 +33,24 @@ npm run publish:npm -- --tag next
33
33
 
34
34
  The script reads `NODE_AUTH_TOKEN` from environment variables, and also checks `app-shell/.env` for that key. It stores the last successful version in `scripts/.publish-version` and auto-increments patch versions on subsequent runs.
35
35
 
36
+ No init script is shipped in the published package.
37
+
36
38
  ## Quick Start
37
39
 
38
40
  ### Setup (No Init Script)
39
41
 
40
- App setup is now file-based and does not require running an init command.
42
+ App setup is file-based and does not require running an init command.
43
+
44
+ Install using npm aliases so existing imports stay as `@platform/*`:
45
+
46
+ ```json
47
+ {
48
+ "dependencies": {
49
+ "@platform/app-shell": "npm:@mostrom/app-shell@latest",
50
+ "@platform/service-catalog": "npm:@mostrom/service-catalog@latest"
51
+ }
52
+ }
53
+ ```
41
54
 
42
55
  Required app files:
43
56
 
@@ -82,66 +95,55 @@ Required app files:
82
95
  +--------+-----------------------------------------+---------------+
83
96
  ```
84
97
 
85
- ## Component Map (Cloudscape)
86
-
87
- ### Global Header (top-most, full width)
88
-
89
- Cloudscape `TopNavigation`.
90
-
91
- | Position | Element | Cloudscape Component | Behavior |
92
- | -------- | -------- | ------------------------------------------------------ | ---------------------- |
93
- | Left | Logo | `TopNavigation` `identity` | Navigate to home |
94
- | Center | Search | `TopNavigation` `search` with `Input` or `Autosuggest` | Global search |
95
- | Right | Apps | `TopNavigation` utility with `Icon` `grid-view` | Opens dropdown (empty) |
96
- | Right | Settings | `TopNavigation` utility with `Icon` `settings` | Opens dropdown (empty) |
97
- | Right | User | `TopNavigation` utility with `Icon` `user-profile` | User menu |
98
+ ## UI Components
98
99
 
99
- ### Service Header (below Global Header, full width)
100
+ App Shell provides a comprehensive set of UI components built with Radix UI and Tailwind CSS:
100
101
 
101
- Cloudscape `AppLayoutToolbar`.
102
+ ### Layout Components
102
103
 
103
- | Position | Element | Cloudscape Component | Behavior |
104
- | -------- | ------------ | ------------------------------------------------ | ------------------------ |
105
- | Left | Menu | `Button` (icon-only) with `Icon` `menu` | Toggles Left Panel |
106
- | Left | Service Name | Text | Current service name |
107
- | Center | Breadcrumbs | `BreadcrumbGroup` | Single breadcrumb source |
108
- | Right | Panel Toggle | `Button` (icon-only) with `Icon` `view-vertical` | Toggles Right Panel |
104
+ | Component | Description |
105
+ | --------- | ----------- |
106
+ | `AppShell` | Main layout wrapper with header, navigation, and content areas |
107
+ | `SpaceBetween` | Flexbox container with consistent gap sizing (xxxs to xxl) |
109
108
 
110
- ### Left Panel
109
+ ### Form & Input Components
111
110
 
112
- - Slot: `navigation` in `AppLayoutToolbar`
113
- - Component: `SideNavigation`
114
- - Header: `Header` with an icon-only `Button` (`Icon` `angle-left`) to collapse
115
- - Content: Empty placeholder list (service provides content)
111
+ | Component | Description |
112
+ | --------- | ----------- |
113
+ | `Button` | Primary, normal, outline, ghost, link, and destructive variants |
114
+ | `Input` | Text input with validation states |
115
+ | `Select` | Dropdown selection with search/filter support |
116
+ | `Toggle` | On/off switch component |
116
117
 
117
- ### Right Panel
118
+ ### Display Components
118
119
 
119
- - Slot: `tools` in `AppLayoutToolbar`
120
- - Content: Empty container (no `HelpPanel`)
120
+ | Component | Description |
121
+ | --------- | ----------- |
122
+ | `Badge` | Status indicators with color variants (blue, green, grey, red) |
123
+ | `Avatar` | User/entity avatars with fallback initials |
124
+ | `Card` | Content container with header/footer slots |
121
125
 
122
- ### Notifications
126
+ ### Data Components
123
127
 
124
- - Slot: `notifications` in `AppLayoutToolbar`
125
- - Component: `Flashbar`
126
-
127
- ### Main Content Area
128
-
129
- - Renders `children` passed to `AppShell`
130
-
131
- ## Required Cloudscape Packages
132
-
133
- - `@cloudscape-design/components`
134
- - `@cloudscape-design/global-styles` (import once per app for base styles/fonts)
128
+ | Component | Description |
129
+ | --------- | ----------- |
130
+ | `DataTable` | Full-featured table with sorting, filtering, and pagination |
131
+ | `SectionedListBoard` | Kanban-style board with drag-and-drop |
132
+ | `SectionedListTable` | Grouped list view with collapsible sections |
135
133
 
136
134
  ## Service Catalog Dependency
137
135
 
138
- The App Shell builds the **All services** menu and global search suggestions from
139
- `@mostrom/service-catalog`. Until we move to a monorepo workspace setup, each
140
- app should explicitly depend on this package to avoid module resolution issues.
136
+ The App Shell builds the **All services** menu and global search suggestions from service-catalog.
137
+
138
+ Use this alias in consuming apps:
141
139
 
142
- When consuming published packages, install `@platform/service-catalog` as an npm alias to `@mostrom/service-catalog`.
140
+ ```json
141
+ {
142
+ "@platform/service-catalog": "npm:@mostrom/service-catalog@latest"
143
+ }
144
+ ```
143
145
 
144
146
  ## Notes
145
147
 
146
- - Do not duplicate breadcrumbs outside the `BreadcrumbGroup`.
147
- - Use Cloudscape components as-is. No custom styling overrides required for the initial scaffold.
148
+ - Use the provided UI components for consistent styling across all services.
149
+ - Import `@platform/app-shell/styles.css` in your app's entry point.
package/package.json CHANGED
@@ -1,12 +1,8 @@
1
1
  {
2
2
  "name": "@mostrom/app-shell",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "private": false,
5
5
  "type": "module",
6
- "bin": {
7
- "app-shell": "./bin/init.js",
8
- "app-shell-init": "./bin/init.js"
9
- },
10
6
  "exports": {
11
7
  ".": "./src/index.ts",
12
8
  "./styles.css": "./src/styles.css",
@@ -27,15 +23,13 @@
27
23
  },
28
24
  "dependencies": {
29
25
  "@base-ui/react": "^1.1.0",
30
- "@cloudscape-design/components": "*",
31
- "@cloudscape-design/global-styles": "*",
32
26
  "@dnd-kit/core": "^6.3.1",
33
27
  "@dnd-kit/modifiers": "^9.0.0",
34
28
  "@dnd-kit/sortable": "^10.0.0",
35
29
  "@dnd-kit/utilities": "^3.2.2",
36
30
  "@floating-ui/dom": "^1.7.5",
37
31
  "@hookform/resolvers": "^5.2.2",
38
- "@platform/service-catalog": "npm:@mostrom/service-catalog@^0.1.2",
32
+ "@platform/service-catalog": "npm:@mostrom/service-catalog@^0.1.3",
39
33
  "@radix-ui/react-dropdown-menu": "^2.1.4",
40
34
  "@tanstack/react-table": "^8.21.3",
41
35
  "class-variance-authority": "^0.7.1",
package/src/AppShell.tsx CHANGED
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * AppShell Component
3
3
  *
4
- * The primary layout wrapper for all platform services. Implements AWS Cloudscape
5
- * design system patterns to ensure visual and behavioral consistency.
4
+ * The primary layout wrapper for all platform services. Provides consistent
5
+ * visual and behavioral patterns across the platform.
6
6
  *
7
7
  * LAYOUT STRUCTURE:
8
8
  * ┌─────────────────────────────────────────────────────────────────────────────┐
@@ -43,7 +43,6 @@
43
43
 
44
44
  import React from "react";
45
45
 
46
- import "@cloudscape-design/global-styles/index.css";
47
46
  import "./styles.css";
48
47
 
49
48
  import { AppFlashbar, type FlashbarMessage } from "./components/layout/AppFlashbar";
@@ -72,7 +71,7 @@ import { GlobalHeaderSearch } from "./components/global-header/GlobalHeaderSearc
72
71
  import { type SearchOption } from "./components/search/GlobalSearch";
73
72
  import { HeaderUtilities } from "./components/global-header/HeaderUtilities";
74
73
 
75
- /** Local drawer type (replaces Cloudscape AppLayoutToolbarProps.Drawer) */
74
+ /** Drawer configuration for slide-in panels */
76
75
  interface Drawer {
77
76
  id: string;
78
77
  ariaLabels?: {
@@ -640,10 +639,9 @@ export function AppShell({
640
639
  * Left-side collapsible panel containing service-specific navigation.
641
640
  * Shows the service name in the header and hierarchical navigation items.
642
641
  */
643
- // Cast to internal type - both Cloudscape and custom types share the same shape
644
642
  const normalizedNavigationItems = (navigationItems ?? []) as ReadonlyArray<NavigationItem>;
645
643
 
646
- // Adapter to normalize Cloudscape CustomEvent to our NavigationFollowEvent
644
+ // Adapter to normalize NavigationFollowEvent
647
645
  const handleNavigationFollow = onNavigationFollow
648
646
  ? (event: NavigationFollowEvent) => {
649
647
  onNavigationFollow(event as CompatibleNavigationFollowEvent);
@@ -27,6 +27,6 @@ export type {
27
27
  export { CreateButtonGroup } from "../ui/create-button-group"
28
28
  export type { CreateButtonGroupProps } from "../ui/create-button-group"
29
29
 
30
- // Actions dropdown (replaces Cloudscape ButtonDropdown)
30
+ // Actions dropdown
31
31
  export { ActionsDropdown } from "../ui/actions-dropdown"
32
32
  export type { ActionsDropdownProps, ActionsDropdownItem } from "../ui/actions-dropdown"
@@ -2,7 +2,7 @@ import { useState, useMemo, type MouseEvent } from "react";
2
2
 
3
3
  import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
4
4
 
5
- // Custom types to replace Cloudscape ButtonDropdownProps
5
+ // Menu dropdown types
6
6
  export interface MenuDropdownItem {
7
7
  id: string;
8
8
  text: string;
@@ -26,7 +26,6 @@ export interface AppBreadcrumbProps {
26
26
 
27
27
  /**
28
28
  * AppBreadcrumb - A wrapper around reui Breadcrumb components
29
- * that provides a similar API to Cloudscape's BreadcrumbGroup
30
29
  */
31
30
  export function AppBreadcrumb({ items, onFollow, className }: AppBreadcrumbProps) {
32
31
  if (!items || items.length === 0) {
@@ -54,7 +54,7 @@ const HEADER_HEIGHT = 56;
54
54
  const SERVICE_BAR_HEIGHT = 56;
55
55
 
56
56
  /**
57
- * AppLayout - A custom layout component replacing Cloudscape's AppLayoutToolbar.
57
+ * AppLayout - A custom layout component for platform services.
58
58
  *
59
59
  * Layout structure:
60
60
  * ┌──────────────────────────────────────────────────────────────────────┐
@@ -100,8 +100,8 @@ export interface AppNavigationProps {
100
100
  }
101
101
 
102
102
  /**
103
- * AppNavigation - A navigation component that provides Cloudscape-compatible API
104
- * using Tailwind styling. Designed to work within AppLayout's navigation slot.
103
+ * AppNavigation - A navigation component using Tailwind styling.
104
+ * Designed to work within AppLayout's navigation slot.
105
105
  */
106
106
  export function AppNavigation({
107
107
  serviceName,
@@ -35,8 +35,7 @@ export interface AppSidebarProps {
35
35
  }
36
36
 
37
37
  /**
38
- * AppSidebar - A sidebar wrapper that provides Cloudscape-compatible API
39
- * using shadcn Sidebar components internally.
38
+ * AppSidebar - A sidebar wrapper using shadcn Sidebar components internally.
40
39
  */
41
40
  export function AppSidebar({
42
41
  serviceName,
@@ -69,7 +69,7 @@ function ExampleTable({ sections }: { sections: Section<Deal>[] }) {
69
69
  - `type`:
70
70
  - `text`: plain string rendering.
71
71
  - `currency`: localized currency formatting.
72
- - `badge`: Cloudscape badge with optional `badgeColorMap`.
72
+ - `badge`: badge with optional `badgeColorMap`.
73
73
  - `avatar`: initials avatar from string field.
74
74
  - `editable`: defaults to editable for `text`; set `false` to lock.
75
75
 
@@ -43,7 +43,6 @@ export interface ActionsDropdownProps {
43
43
  /**
44
44
  * ActionsDropdown - A dropdown menu for action buttons.
45
45
  *
46
- * This component replaces Cloudscape's ButtonDropdown with our design system.
47
46
  * Use it for action menus like "Actions", "More options", etc.
48
47
  *
49
48
  * @example
@@ -19,7 +19,7 @@ const badgeVariants = cva(
19
19
  ghost: "[a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
20
20
  link: "text-primary underline-offset-4 [a&]:hover:underline",
21
21
  },
22
- // Color variants for Cloudscape compatibility
22
+ // Color variants for status indicators
23
23
  color: {
24
24
  blue: "bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200",
25
25
  green: "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200",
@@ -19,7 +19,7 @@ const buttonVariants = cva(
19
19
  ghost:
20
20
  "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
21
21
  link: "text-primary underline-offset-4 hover:underline",
22
- // Cloudscape-compatible variants
22
+ // Semantic variants
23
23
  primary: "bg-primary text-primary-foreground hover:bg-primary/90",
24
24
  normal:
25
25
  "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
package/src/index.ts CHANGED
@@ -39,7 +39,7 @@ export type {
39
39
  export { AppLayout } from "./components/layout/AppLayout";
40
40
  export type { AppLayoutProps } from "./components/layout/AppLayout";
41
41
 
42
- // Flashbar components (replaces Cloudscape Flashbar)
42
+ // Flashbar components
43
43
  export { AppFlashbar } from "./components/layout/AppFlashbar";
44
44
  export type { AppFlashbarProps, FlashbarMessage } from "./components/layout/AppFlashbar";
45
45
 
package/src/styles.css CHANGED
@@ -1,7 +1,7 @@
1
1
  /* =============================================================================
2
2
  * Global Design System Styles
3
3
  * =============================================================================
4
- * Core styles previously in @platform/design-system, now merged into app-shell
4
+ * Core styles for @platform/app-shell
5
5
  *
6
6
  * NOTE: Font is loaded via <link> tag in AppShell component, not @import
7
7
  * NOTE: tw-animate-css is imported in the app's tailwind.css, not here
@@ -18,10 +18,6 @@
18
18
  --font-family-base: "Hanken Grotesk", -apple-system, BlinkMacSystemFont,
19
19
  "Segoe UI", sans-serif;
20
20
 
21
- /* Override Cloudscape font variables */
22
- --awsui-font-family-base: "Hanken Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
23
- --awsui-font-family-monospace: "SF Mono", "Monaco", "Inconsolata", "Fira Mono", "Droid Sans Mono", monospace;
24
-
25
21
  /* Dropdown styling */
26
22
  --dropdown-border-radius: 8px;
27
23
 
@@ -78,68 +74,11 @@ body,
78
74
  font-family: var(--font-family-base);
79
75
  }
80
76
 
81
- /* Force Hanken Grotesk on all Cloudscape components */
82
- [class*="awsui"] {
83
- font-family: "Hanken Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif !important;
84
- }
85
-
86
77
  /* =============================================================================
87
78
  * App Shell Styles
88
79
  * =============================================================================
89
80
  */
90
81
 
91
- /*
92
- * Force dark background on Cloudscape dropdown PORTALS only
93
- * CRITICAL: Use body > div[class*="awsui_dropdown"] to ONLY target dropdown portals
94
- * NOT body > div[class*="awsui"] which would match other portals and is too broad
95
- * This prevents styling table cells which also use "interior" class patterns
96
- */
97
- body > div[class*="awsui_dropdown"] [class*="awsui_dropdown-content-wrapper"],
98
- body > div[class*="awsui_dropdown"] [class*="awsui_interior"],
99
- body > div[class*="awsui_dropdown"] [class*="awsui_options-list"],
100
- body > div[class*="awsui_dropdown"] [class*="awsui_items-list"],
101
- body > div[class*="awsui_dropdown"] ul[class*="awsui"],
102
- body > div[class*="awsui_dropdown"] ul {
103
- background-color: #171717 !important;
104
- color: #f5f5f5 !important;
105
- }
106
-
107
- body > div[class*="awsui_dropdown"] li[class*="awsui"],
108
- body > div[class*="awsui_dropdown"] li,
109
- body > div[class*="awsui_dropdown"] [class*="awsui_option"],
110
- body > div[class*="awsui_dropdown"] [class*="awsui_item-element"] {
111
- background-color: transparent !important;
112
- color: #f5f5f5 !important;
113
- }
114
-
115
- body > div[class*="awsui_dropdown"] [class*="awsui_highlighted"],
116
- body > div[class*="awsui_dropdown"] li:hover,
117
- body > div[class*="awsui_dropdown"] li:focus,
118
- body > div[class*="awsui_dropdown"] [class*="awsui_option"]:hover,
119
- body > div[class*="awsui_dropdown"] [class*="awsui_item-element"]:hover {
120
- background-color: transparent !important;
121
- color: #26c6ff !important;
122
- }
123
-
124
- /* Ensure hover color applies to the text content inside dropdown items */
125
- body > div[class*="awsui_dropdown"] [class*="awsui_item-element"]:hover [class*="awsui_option-content"],
126
- body > div[class*="awsui_dropdown"] [class*="awsui_item-element"]:hover [class*="awsui_link"],
127
- body > div[class*="awsui_dropdown"] [class*="awsui_option"]:hover [class*="awsui_option-content"],
128
- body > div[class*="awsui_dropdown"] [class*="awsui_highlighted"] [class*="awsui_option-content"],
129
- body > div[class*="awsui_dropdown"] [class*="awsui_highlighted"] [class*="awsui_link"],
130
- body > div[class*="awsui_dropdown"] [aria-selected="true"] [class*="awsui_option-content"] {
131
- color: #26c6ff !important;
132
- background-color: transparent !important;
133
- }
134
-
135
- /* Override Cloudscape light mode dropdown backgrounds - scoped to dropdown portals */
136
- body > div[class*="awsui_dropdown"][class*="awsui_open"] [class*="awsui_interior"],
137
- body > div[class*="awsui_dropdown"] [class*="awsui_dropdown-content"],
138
- body > div[class*="awsui_dropdown"] > div,
139
- body > div[class*="awsui_dropdown"] ul {
140
- background-color: #171717 !important;
141
- }
142
-
143
82
  /* Global header - high z-index to ensure dropdowns appear above everything */
144
83
  #global-header {
145
84
  background-color: #171717;
@@ -149,19 +88,8 @@ body > div[class*="awsui_dropdown"] ul {
149
88
  overflow: visible !important;
150
89
  }
151
90
 
152
- #global-header [class*="awsui_top-navigation"],
153
- #global-header header {
154
- background-color: #171717 !important;
155
- overflow: visible !important;
156
- }
157
-
158
- #global-header [class*="awsui_utility"],
159
- #global-header [class*="awsui_utilities"] {
160
- overflow: visible !important;
161
- }
162
-
163
91
  /* =============================================================================
164
- * Custom Global Header Styles (non-Cloudscape)
92
+ * Custom Global Header Styles
165
93
  * =============================================================================
166
94
  */
167
95
 
@@ -412,65 +340,6 @@ body > div[class*="awsui_dropdown"] ul {
412
340
  background-color: #263445;
413
341
  }
414
342
 
415
- /* Force light mode background for app content area */
416
- body,
417
- #root,
418
- [class*="awsui_app-layout"],
419
- [class*="awsui_app-layout"] [class*="awsui_content"],
420
- [class*="awsui_app-layout"] [class*="awsui_content"] > * {
421
- background-color: #ffffff !important;
422
- color: #0f172a !important;
423
- }
424
-
425
- /* Panel trigger buttons in app layout (not global header) - circle shape */
426
- [class*="awsui_app-layout"] button[class*="awsui_trigger"],
427
- [class*="awsui_app-layout"] button[class*="awsui_circle"] {
428
- border-radius: 50% !important;
429
- }
430
-
431
- /* When panel is closed (no .selected class) - white background, dark icon */
432
- [class*="awsui_app-layout"] button[class*="awsui_trigger"]:not([class*="selected"]),
433
- [class*="awsui_app-layout"] button[class*="awsui_circle"]:not([class*="selected"]) {
434
- background-color: #ffffff !important;
435
- border: 1px solid #d5dbdb !important;
436
- color: #171717 !important;
437
- }
438
-
439
- /* Remove hover effects from trigger buttons */
440
- [class*="awsui_app-layout"] button[class*="awsui_trigger"]:hover:not([class*="selected"]),
441
- [class*="awsui_app-layout"] button[class*="awsui_circle"]:hover:not([class*="selected"]) {
442
- background-color: #ffffff !important;
443
- border: 1px solid #d5dbdb !important;
444
- color: #171717 !important;
445
- }
446
-
447
- [class*="awsui_app-layout"] button[class*="awsui_trigger"]:not([class*="selected"]) svg,
448
- [class*="awsui_app-layout"] button[class*="awsui_circle"]:not([class*="selected"]) svg {
449
- color: #171717 !important;
450
- }
451
-
452
- /* When panel is open (.selected class) - dark background, white icon */
453
- [class*="awsui_app-layout"] button[class*="awsui_trigger"][class*="selected"],
454
- [class*="awsui_app-layout"] button[class*="awsui_circle"][class*="selected"] {
455
- background-color: #171717 !important;
456
- border: 1px solid #171717 !important;
457
- color: #ffffff !important;
458
- }
459
-
460
- /* Remove hover effects from selected trigger buttons */
461
- [class*="awsui_app-layout"] button[class*="awsui_trigger"][class*="selected"]:hover,
462
- [class*="awsui_app-layout"] button[class*="awsui_circle"][class*="selected"]:hover {
463
- background-color: #171717 !important;
464
- border: 1px solid #171717 !important;
465
- color: #ffffff !important;
466
- }
467
-
468
- [class*="awsui_app-layout"] button[class*="awsui_trigger"][class*="selected"] svg,
469
- [class*="awsui_app-layout"] button[class*="awsui_circle"][class*="selected"] svg {
470
- color: #ffffff !important;
471
- fill: #ffffff !important;
472
- }
473
-
474
343
  /* Custom navigation trigger button with Menu icon */
475
344
  .app-shell-nav-trigger {
476
345
  display: flex;
@@ -504,54 +373,17 @@ body,
504
373
  font-weight: 400 !important;
505
374
  }
506
375
 
507
- /* Dark mode: ensure side navigation links are visible on dark background */
508
- body.awsui-dark-mode .app-shell-side-navigation a,
509
- body.awsui-dark-mode .app-shell-side-navigation button,
510
- body.awsui-dark-mode .app-shell-side-navigation [role="link"] {
511
- color: #f5f5f5 !important;
512
- }
513
-
514
- /* Keep the side navigation header/title bold */
515
- .app-shell-side-navigation [class*="awsui_header"],
516
- .app-shell-side-navigation [class*="awsui_header"] a,
517
- .app-shell-side-navigation [class*="awsui_header"] [class*="awsui_header-link"],
518
- .app-shell-side-navigation [class*="awsui_header"] [class*="awsui_header-text"] {
519
- font-weight: 600 !important;
520
- color: #171717 !important;
521
- }
522
-
523
- body.awsui-dark-mode .app-shell-side-navigation [class*="awsui_header"],
524
- body.awsui-dark-mode .app-shell-side-navigation [class*="awsui_header"] a,
525
- body.awsui-dark-mode .app-shell-side-navigation [class*="awsui_header"] [class*="awsui_header-link"],
526
- body.awsui-dark-mode .app-shell-side-navigation [class*="awsui_header"] [class*="awsui_header-text"] {
527
- color: #ffffff !important;
528
- }
529
-
530
376
  .app-shell-side-navigation a:hover,
531
377
  .app-shell-side-navigation button:hover,
532
378
  .app-shell-side-navigation [role="link"]:hover {
533
379
  color: #0972d3 !important;
534
380
  }
535
381
 
536
- .app-shell-side-navigation [aria-current="page"],
537
- .app-shell-side-navigation [class*="awsui_active"] {
382
+ .app-shell-side-navigation [aria-current="page"] {
538
383
  color: #0972d3 !important;
539
384
  font-weight: 600 !important;
540
385
  }
541
386
 
542
- body.awsui-dark-mode .app-shell-side-navigation [aria-current="page"],
543
- body.awsui-dark-mode .app-shell-side-navigation [class*="awsui_active"] {
544
- color: #26c6ff !important;
545
- font-weight: 600 !important;
546
- }
547
-
548
- .app-shell-side-navigation [class*="awsui_link-text"],
549
- .app-shell-side-navigation [class*="awsui_item-text"],
550
- .app-shell-side-navigation [class*="awsui_item"] {
551
- color: inherit !important;
552
- font-weight: inherit !important;
553
- }
554
-
555
387
  /* Search container with even spacing */
556
388
  .app-shell-search {
557
389
  display: flex;
@@ -808,7 +640,7 @@ button.app-shell-apps-button:hover .app-shell-apps-icon,
808
640
  }
809
641
 
810
642
  /* =============================================================================
811
- * Custom Global Search Styles (non-Cloudscape)
643
+ * Custom Global Search Styles
812
644
  * =============================================================================
813
645
  */
814
646
 
@@ -1072,655 +904,6 @@ button.app-shell-apps-button:hover .app-shell-apps-icon,
1072
904
  color: #f5f5f5;
1073
905
  }
1074
906
 
1075
- /* Legacy Cloudscape search styles (for backward compatibility) */
1076
- .app-shell-search-input-wrapper [class*="awsui_input"] {
1077
- background-color: #171717 !important;
1078
- border-radius: 20px !important;
1079
- }
1080
-
1081
- /* Inner elements of autosuggest dropdown - no radius (wrapper handles clipping) */
1082
- .app-shell-search-input-wrapper [class*="awsui_dropdown"],
1083
- .app-shell-search-input-wrapper [class*="awsui_content"],
1084
- [class*="awsui_autosuggest"] [class*="awsui_dropdown"],
1085
- [class*="awsui_autosuggest"] [class*="awsui_content"] {
1086
- border-radius: 0 !important;
1087
- }
1088
-
1089
- /*
1090
- * Force left alignment - override CloudScape's centered search layout.
1091
- * Scoped to the global header to avoid impacting AppLayoutToolbar internals.
1092
- */
1093
- #global-header [class*="awsui_header"] {
1094
- gap: 0 !important;
1095
- }
1096
-
1097
- /* Logo/identity area */
1098
- #global-header [class*="awsui_identity"] {
1099
- padding-inline-start: 8px !important;
1100
- padding-inline-end: 8px !important;
1101
- }
1102
-
1103
- #global-header [class*="awsui_search"],
1104
- #global-header [data-utility-special="search"] {
1105
- flex: 0 1 auto !important;
1106
- justify-content: flex-start !important;
1107
- margin-inline-start: 0 !important;
1108
- padding-inline-start: 0 !important;
1109
- margin-inline-end: auto !important;
1110
- }
1111
-
1112
- #global-header [class*="awsui_inputs"] {
1113
- justify-content: flex-start !important;
1114
- margin-inline-start: 0 !important;
1115
- }
1116
-
1117
- #global-header [class*="awsui_center"] {
1118
- flex: 0 1 auto !important;
1119
- justify-content: flex-start !important;
1120
- }
1121
-
1122
- /* Keep logo size stable to avoid layout shifts */
1123
- #global-header [class*="awsui_identity"] img {
1124
- height: 24px;
1125
- width: auto;
1126
- display: block;
1127
- }
1128
-
1129
- /*
1130
- * Remove rounded corners from ALL dropdown menus globally
1131
- * Cloudscape renders dropdowns in portals at document body level.
1132
- * Using very specific dropdown selectors to avoid affecting cards/containers.
1133
- */
1134
-
1135
- /* Dropdown containers - apply rounded corners */
1136
- [class*="awsui_dropdown-content-wrapper"] {
1137
- border-radius: var(--dropdown-border-radius) !important;
1138
- overflow: hidden !important;
1139
- }
1140
- /* Interior elements - no rounded corners (container handles it) */
1141
- [class*="awsui_dropdown-content"][class*="awsui_interior"],
1142
- [class*="awsui_list-bottom"],
1143
- [class*="awsui_open-dropdown"] {
1144
- border-radius: 0 !important;
1145
- }
1146
-
1147
- /* Dropdown list containers */
1148
- [class*="awsui_options-list"],
1149
- [class*="awsui_items-list-container"],
1150
- ul[class*="awsui_options"] {
1151
- border-radius: 0 !important;
1152
- }
1153
-
1154
- /* Individual dropdown/menu items - remove all rounded corners */
1155
- [class*="awsui_item-element"],
1156
- li[class*="awsui_option"],
1157
- [class*="awsui_highlighted"] {
1158
- border-radius: 0 !important;
1159
- }
1160
-
1161
- /* First and last items in dropdown lists */
1162
- [class*="awsui_options-list"] li:first-child,
1163
- [class*="awsui_options-list"] li:last-child,
1164
- [class*="awsui_items-list-container"] li:first-child,
1165
- [class*="awsui_items-list-container"] li:last-child {
1166
- border-radius: 0 !important;
1167
- }
1168
-
1169
- /*
1170
- * DROPDOWN BORDER RADIUS OVERRIDE - Scoped to dropdown portals only
1171
- * CRITICAL: Use body > div[class*="awsui_dropdown"] to avoid affecting tables
1172
- */
1173
- body > div[class*="awsui_dropdown"] [class*="awsui_dropdown-content-wrapper"],
1174
- body > div[class*="awsui_dropdown"] [class*="awsui_interior"],
1175
- body > div[class*="awsui_dropdown"][class*="awsui_open"],
1176
- body > div[class*="awsui_dropdown"] ul[class*="awsui_options-list"],
1177
- body > div[class*="awsui_dropdown"] ul[class*="awsui_items-list"],
1178
- body > div[class*="awsui_dropdown"] [class*="awsui_items-list-container"],
1179
- body > div[class*="awsui_dropdown"] li[class*="awsui_option"],
1180
- body > div[class*="awsui_dropdown"] li[class*="awsui_item-element"],
1181
- body > div[class*="awsui_dropdown"] li[class*="awsui_highlighted"],
1182
- body > div[class*="awsui_dropdown"] li,
1183
- body > div[class*="awsui_dropdown"] li:first-child,
1184
- body > div[class*="awsui_dropdown"] li:last-child {
1185
- border-radius: 0 !important;
1186
- border-top-left-radius: 0 !important;
1187
- border-top-right-radius: 0 !important;
1188
- border-bottom-left-radius: 0 !important;
1189
- border-bottom-right-radius: 0 !important;
1190
- }
1191
-
1192
- /* Global header dropdown theme - wrapper containers get rounded corners */
1193
- body .app-shell-apps-dropdown [class*="awsui_dropdown-content-wrapper"],
1194
- body .app-shell-search-autosuggest [class*="awsui_dropdown-content-wrapper"],
1195
- body .app-shell-categories-dropdown [class*="awsui_dropdown-content-wrapper"] {
1196
- background-color: #171717 !important;
1197
- color: #f5f5f5 !important;
1198
- border-radius: var(--dropdown-border-radius) !important;
1199
- overflow: hidden !important;
1200
- }
1201
-
1202
- /* Global header dropdown theme - interior elements no radius */
1203
- body .app-shell-apps-dropdown [class*="awsui_dropdown"],
1204
- body .app-shell-search-autosuggest [class*="awsui_dropdown"],
1205
- body .app-shell-apps-dropdown [class*="awsui_dropdown-content"],
1206
- body .app-shell-search-autosuggest [class*="awsui_dropdown-content"],
1207
- body .app-shell-apps-dropdown [class*="awsui_items-list-container"],
1208
- body .app-shell-search-autosuggest [class*="awsui_items-list-container"],
1209
- body .app-shell-apps-dropdown [class*="awsui_options-list"],
1210
- body .app-shell-search-autosuggest [class*="awsui_options-list"],
1211
- body .app-shell-apps-dropdown ul[class*="awsui"],
1212
- body .app-shell-search-autosuggest ul[class*="awsui"],
1213
- body .app-shell-categories-dropdown [class*="awsui_dropdown"],
1214
- body .app-shell-categories-dropdown [class*="awsui_dropdown-content"],
1215
- body .app-shell-categories-dropdown [class*="awsui_items-list-container"],
1216
- body .app-shell-categories-dropdown [class*="awsui_options-list"],
1217
- body .app-shell-categories-dropdown ul[class*="awsui"] {
1218
- background-color: #171717 !important;
1219
- color: #f5f5f5 !important;
1220
- border-radius: 0 !important;
1221
- }
1222
-
1223
- /* Force Apps dropdown to be wide enough for 4 columns */
1224
- body .app-shell-apps-dropdown [class*="awsui_dropdown"],
1225
- body .app-shell-apps-dropdown [class*="awsui_dropdown-content-wrapper"],
1226
- body .app-shell-apps-dropdown [class*="awsui_dropdown-content"],
1227
- body .app-shell-apps-dropdown [class*="awsui_items-list-container"],
1228
- body [class*="awsui_dropdown"]:has([aria-label="Apps"]),
1229
- body [class*="awsui_dropdown-content-wrapper"]:has([aria-label="Apps"]),
1230
- body [class*="awsui_dropdown-content"]:has([aria-label="Apps"]),
1231
- body [class*="awsui_items-list-container"]:has([aria-label="Apps"]) {
1232
- width: 1000px !important;
1233
- min-width: 1000px !important;
1234
- max-width: 1180px !important;
1235
- }
1236
-
1237
- /* Search results dropdown: keep dark background, text-only hover */
1238
- body .app-shell-search-autosuggest [class*="awsui_dropdown-content-wrapper"],
1239
- body .app-shell-search-autosuggest [class*="awsui_dropdown-content"],
1240
- body .app-shell-search-autosuggest [class*="awsui_interior"],
1241
- body .app-shell-search-autosuggest [class*="awsui_options-list"],
1242
- body .app-shell-search-autosuggest [class*="awsui_virtual-list"],
1243
- body .app-shell-search-autosuggest ul {
1244
- background-color: #171717 !important;
1245
- color: #f5f5f5 !important;
1246
- }
1247
-
1248
- body .app-shell-search-autosuggest li,
1249
- body .app-shell-search-autosuggest [class*="awsui_option"],
1250
- body .app-shell-search-autosuggest [class*="awsui_selectable-item"],
1251
- body .app-shell-search-autosuggest [class*="awsui_item-element"],
1252
- body .app-shell-search-autosuggest [class*="awsui_option-content"] {
1253
- background-color: transparent !important;
1254
- box-shadow: none !important;
1255
- border: none !important;
1256
- outline: none !important;
1257
- color: #f5f5f5 !important;
1258
- }
1259
-
1260
- body .app-shell-search-autosuggest li:hover,
1261
- body .app-shell-search-autosuggest [class*="awsui_option"]:hover,
1262
- body .app-shell-search-autosuggest [class*="awsui_selectable-item"]:hover,
1263
- body .app-shell-search-autosuggest [class*="awsui_item-element"]:hover,
1264
- body .app-shell-search-autosuggest [class*="awsui_option-content"]:hover,
1265
- body .app-shell-search-autosuggest [class*="awsui_item-element"]:focus,
1266
- body .app-shell-search-autosuggest [class*="awsui_item-element"]:focus-visible,
1267
- body .app-shell-search-autosuggest [class*="awsui_highlighted"],
1268
- body .app-shell-search-autosuggest [aria-selected="true"] {
1269
- background-color: transparent !important;
1270
- box-shadow: none !important;
1271
- border: none !important;
1272
- outline: none !important;
1273
- color: #26c6ff !important;
1274
- }
1275
-
1276
- /* Autosuggest dropdown background - force dark theme */
1277
- [class*="awsui_autosuggest"] [class*="awsui_dropdown-content-wrapper"],
1278
- [class*="awsui_autosuggest"] [class*="awsui_dropdown-content"],
1279
- [class*="awsui_autosuggest"] [class*="awsui_interior"],
1280
- [class*="awsui_autosuggest"] [class*="awsui_options-list"],
1281
- body [class*="awsui_autosuggest"] ul {
1282
- background-color: #171717 !important;
1283
- color: #f5f5f5 !important;
1284
- }
1285
-
1286
- [class*="awsui_autosuggest"] li,
1287
- [class*="awsui_autosuggest"] [class*="awsui_option"] {
1288
- background-color: transparent !important;
1289
- color: #f5f5f5 !important;
1290
- }
1291
-
1292
- [class*="awsui_autosuggest"] [class*="awsui_highlighted"],
1293
- [class*="awsui_autosuggest"] li:hover {
1294
- background-color: transparent !important;
1295
- color: #26c6ff !important;
1296
- }
1297
-
1298
- /* Top navigation dropdowns (apps/search/settings/user) */
1299
- body .awsui-context-top-navigation [class*="awsui_dropdown-content-wrapper"] {
1300
- background-color: #171717 !important;
1301
- border: none !important;
1302
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4) !important;
1303
- border-radius: var(--dropdown-border-radius) !important;
1304
- overflow: hidden !important;
1305
- padding-block: 0 !important;
1306
- }
1307
-
1308
- body .awsui-context-top-navigation [class*="awsui_dropdown-content-wrapper"]::after {
1309
- border: none !important;
1310
- border-radius: 0 !important;
1311
- }
1312
-
1313
- body .awsui-context-top-navigation [class*="awsui_options-list"],
1314
- body .awsui-context-top-navigation [class*="awsui_items-list-container"] {
1315
- background-color: #171717 !important;
1316
- color: #f5f5f5 !important;
1317
- border: none !important;
1318
- border-radius: 0 !important;
1319
- }
1320
-
1321
- /* Inner content elements - no radius (container handles clipping) */
1322
- body .awsui-context-top-navigation [class*="awsui_dropdown-content"],
1323
- body .awsui-context-top-navigation [class*="awsui_dropdown"]::after,
1324
- body .awsui-context-top-navigation [class*="awsui_dropdown-content-wrapper"]::after {
1325
- border-radius: 0 !important;
1326
- border: none !important;
1327
- box-shadow: none !important;
1328
- }
1329
-
1330
- body .awsui-context-top-navigation [class*="awsui_dropdown"] [class*="awsui_focus"],
1331
- body .awsui-context-top-navigation [class*="awsui_dropdown"] [class*="awsui_focus-ring"] {
1332
- box-shadow: none !important;
1333
- outline: none !important;
1334
- }
1335
-
1336
- body .awsui-context-top-navigation [class*="awsui_item-element"],
1337
- body .awsui-context-top-navigation [class*="awsui_option"] {
1338
- background-color: transparent !important;
1339
- border: none !important;
1340
- box-shadow: none !important;
1341
- outline: none !important;
1342
- color: #f5f5f5 !important;
1343
- }
1344
-
1345
- body .awsui-context-top-navigation [class*="awsui_item-element"]:hover,
1346
- body .awsui-context-top-navigation [class*="awsui_item-element"]:focus,
1347
- body .awsui-context-top-navigation [class*="awsui_item-element"]:focus-visible,
1348
- body .awsui-context-top-navigation [class*="awsui_highlighted"] {
1349
- background-color: transparent !important;
1350
- border: none !important;
1351
- box-shadow: none !important;
1352
- outline: none !important;
1353
- color: #26c6ff !important;
1354
- }
1355
-
1356
- /* List elements inside dropdown - no radius (container handles clipping) */
1357
- body ul[aria-label="Apps"],
1358
- body ul[aria-label="Categories"],
1359
- body ul[aria-label="Search"] {
1360
- background-color: #171717 !important;
1361
- color: #f5f5f5 !important;
1362
- border-radius: 0 !important;
1363
- }
1364
-
1365
- body .app-shell-apps-dropdown li,
1366
- body .app-shell-categories-dropdown li,
1367
- body .app-shell-search-autosuggest li,
1368
- body .app-shell-apps-dropdown [class*="awsui_item-element"],
1369
- body .app-shell-categories-dropdown [class*="awsui_item-element"],
1370
- body .app-shell-search-autosuggest [class*="awsui_item-element"] {
1371
- background-color: transparent !important;
1372
- border: none !important;
1373
- box-shadow: none !important;
1374
- outline: none !important;
1375
- border-radius: 0 !important;
1376
- color: #f5f5f5 !important;
1377
- }
1378
-
1379
- body ul[aria-label="Apps"] li,
1380
- body ul[aria-label="Categories"] li,
1381
- body ul[aria-label="Search"] li,
1382
- body ul[aria-label="Apps"] [class*="awsui_item-element"],
1383
- body ul[aria-label="Categories"] [class*="awsui_item-element"],
1384
- body ul[aria-label="Search"] [class*="awsui_item-element"] {
1385
- background-color: transparent !important;
1386
- border: none !important;
1387
- box-shadow: none !important;
1388
- outline: none !important;
1389
- border-radius: 0 !important;
1390
- color: #f5f5f5 !important;
1391
- }
1392
-
1393
- body .app-shell-apps-dropdown [class*="awsui_item-element"]:hover,
1394
- body .app-shell-categories-dropdown [class*="awsui_item-element"]:hover,
1395
- body .app-shell-search-autosuggest [class*="awsui_item-element"]:hover,
1396
- body .app-shell-apps-dropdown [class*="awsui_item-element"]:focus,
1397
- body .app-shell-categories-dropdown [class*="awsui_item-element"]:focus,
1398
- body .app-shell-search-autosuggest [class*="awsui_item-element"]:focus,
1399
- body .app-shell-apps-dropdown [class*="awsui_item-element"]:focus-visible,
1400
- body .app-shell-categories-dropdown [class*="awsui_item-element"]:focus-visible,
1401
- body .app-shell-search-autosuggest [class*="awsui_item-element"]:focus-visible,
1402
- body .app-shell-apps-dropdown [class*="awsui_highlighted"],
1403
- body .app-shell-categories-dropdown [class*="awsui_highlighted"],
1404
- body .app-shell-search-autosuggest [class*="awsui_highlighted"] {
1405
- background-color: transparent !important;
1406
- border: none !important;
1407
- box-shadow: none !important;
1408
- outline: none !important;
1409
- color: #26c6ff !important;
1410
- }
1411
-
1412
- body ul[aria-label="Apps"] [class*="awsui_item-element"]:hover,
1413
- body ul[aria-label="Categories"] [class*="awsui_item-element"]:hover,
1414
- body ul[aria-label="Search"] [class*="awsui_item-element"]:hover,
1415
- body ul[aria-label="Apps"] [class*="awsui_item-element"]:focus,
1416
- body ul[aria-label="Categories"] [class*="awsui_item-element"]:focus,
1417
- body ul[aria-label="Search"] [class*="awsui_item-element"]:focus,
1418
- body ul[aria-label="Apps"] [class*="awsui_item-element"]:focus-visible,
1419
- body ul[aria-label="Categories"] [class*="awsui_item-element"]:focus-visible,
1420
- body ul[aria-label="Search"] [class*="awsui_item-element"]:focus-visible,
1421
- body ul[aria-label="Apps"] [class*="awsui_highlighted"],
1422
- body ul[aria-label="Categories"] [class*="awsui_highlighted"],
1423
- body ul[aria-label="Search"] [class*="awsui_highlighted"] {
1424
- background-color: transparent !important;
1425
- border: none !important;
1426
- box-shadow: none !important;
1427
- outline: none !important;
1428
- color: #26c6ff !important;
1429
- }
1430
-
1431
- body ul[aria-label="Apps"] a:focus-visible,
1432
- body ul[aria-label="Categories"] a:focus-visible,
1433
- body ul[aria-label="Search"] a:focus-visible,
1434
- body ul[aria-label="Apps"] button:focus-visible,
1435
- body ul[aria-label="Categories"] button:focus-visible,
1436
- body ul[aria-label="Search"] button:focus-visible {
1437
- outline: none !important;
1438
- box-shadow: none !important;
1439
- }
1440
-
1441
- /* Make the "All services" dropdown wider + multi-column */
1442
- body ul[aria-label="Apps"] {
1443
- display: block !important;
1444
- column-count: 4 !important;
1445
- column-width: 220px !important;
1446
- column-gap: 20px !important;
1447
- column-fill: balance;
1448
- min-width: 960px !important;
1449
- max-width: 1180px !important;
1450
- padding-block: 16px !important;
1451
- }
1452
-
1453
- body ul[aria-label="Apps"] > li {
1454
- break-inside: avoid;
1455
- }
1456
-
1457
- body ul[aria-label="Apps"] [class*="awsui_item-element"] {
1458
- width: 100%;
1459
- }
1460
-
1461
- /* Settings and User dropdown - remove gap from header */
1462
- body ul[aria-label="Settings"],
1463
- body ul[aria-label="User menu"] {
1464
- padding: 4px 0 !important;
1465
- min-width: 140px !important;
1466
- }
1467
-
1468
- /* Categories dropdown - match standard dropdown padding */
1469
- body ul[aria-label="Categories"] {
1470
- padding: 4px 0 !important;
1471
- min-width: 220px !important;
1472
- }
1473
-
1474
- body ul[aria-label="Categories"] [class*="awsui_item-element"] {
1475
- padding: 4px 12px !important;
1476
- }
1477
-
1478
- /* Remove the gap between header and Settings/User dropdowns */
1479
- #global-header [class*="awsui_menu-dropdown"] [class*="awsui_dropdown-content-wrapper"],
1480
- body .awsui-context-top-navigation [class*="awsui_menu-dropdown"] [class*="awsui_dropdown-content-wrapper"] {
1481
- margin-top: -8px !important;
1482
- top: 100% !important;
1483
- padding-top: 0 !important;
1484
- }
1485
-
1486
- #global-header [class*="awsui_menu-dropdown"] [class*="awsui_dropdown"],
1487
- body .awsui-context-top-navigation [class*="awsui_menu-dropdown"] [class*="awsui_dropdown"] {
1488
- margin-top: -8px !important;
1489
- padding-top: 0 !important;
1490
- }
1491
-
1492
- /* Portal dropdowns for Settings/User - force flush to header with rounded corners */
1493
- body [class*="awsui_dropdown-content-wrapper"]:has(ul[aria-label="Settings"]),
1494
- body [class*="awsui_dropdown-content-wrapper"]:has(ul[aria-label="User menu"]) {
1495
- margin-top: -8px !important;
1496
- transform: translateY(-8px) !important;
1497
- border-radius: var(--dropdown-border-radius) !important;
1498
- overflow: hidden !important;
1499
- }
1500
-
1501
- /* Target portal-rendered Settings/User dropdowns and remove gap */
1502
- body > div[class*="awsui"] [class*="awsui_dropdown-content-wrapper"] {
1503
- margin-top: 0 !important;
1504
- }
1505
-
1506
- body > div[class*="awsui"][class*="awsui_dropdown"] {
1507
- margin-top: 0 !important;
1508
- padding-top: 0 !important;
1509
- }
1510
-
1511
- body ul[aria-label="Settings"] [class*="awsui_item-element"],
1512
- body ul[aria-label="User menu"] [class*="awsui_item-element"] {
1513
- padding: 4px 12px !important;
1514
- }
1515
-
1516
- /* General top navigation dropdown list padding */
1517
- body .awsui-context-top-navigation [class*="awsui_items-list-container"] ul {
1518
- padding: 4px 0 !important;
1519
- }
1520
-
1521
- body .awsui-context-top-navigation [class*="awsui_items-list-container"] [class*="awsui_item-element"] {
1522
- padding: 4px 12px !important;
1523
- }
1524
-
1525
- /*
1526
- * Comprehensive dropdown border-radius styling
1527
- * Targets: Apps dropdown, Autosuggest, ButtonDropdown, all menu types
1528
- * Uses --dropdown-border-radius variable for consistent rounded corners
1529
- */
1530
-
1531
- /* Autosuggest dropdown containers - apply rounded corners */
1532
- [class*="awsui_autosuggest"] [class*="awsui_dropdown-content-wrapper"] {
1533
- border-radius: var(--dropdown-border-radius) !important;
1534
- overflow: hidden !important;
1535
- }
1536
- [class*="awsui_autosuggest"] [class*="awsui_interior"],
1537
- [class*="awsui_autosuggest"] [class*="awsui_dropdown-content"],
1538
- [class*="awsui_autosuggest"] ul,
1539
- [class*="awsui_autosuggest"] li {
1540
- border-radius: 0 !important;
1541
- }
1542
-
1543
- /* ButtonDropdown containers (Apps button, Settings, Profile) - apply rounded corners */
1544
- [class*="awsui_button-dropdown"] [class*="awsui_dropdown-content-wrapper"] {
1545
- border-radius: var(--dropdown-border-radius) !important;
1546
- overflow: hidden !important;
1547
- }
1548
- [class*="awsui_button-dropdown"] [class*="awsui_interior"],
1549
- [class*="awsui_button-dropdown"] [class*="awsui_dropdown-content"],
1550
- [class*="awsui_button-dropdown"] ul,
1551
- [class*="awsui_button-dropdown"] li {
1552
- border-radius: 0 !important;
1553
- }
1554
-
1555
- /* Top navigation menu containers - apply rounded corners */
1556
- [class*="awsui_menu-dropdown"] [class*="awsui_dropdown-content-wrapper"] {
1557
- border-radius: var(--dropdown-border-radius) !important;
1558
- overflow: hidden !important;
1559
- }
1560
- [class*="awsui_menu-dropdown"] [class*="awsui_interior"],
1561
- [class*="awsui_menu-dropdown"] ul,
1562
- [class*="awsui_menu-dropdown"] li {
1563
- border-radius: 0 !important;
1564
- }
1565
-
1566
- /* Select component dropdown containers - apply rounded corners */
1567
- [class*="awsui_select"] [class*="awsui_dropdown-content-wrapper"],
1568
- [class*="awsui_select-dropdown"] [class*="awsui_dropdown-content-wrapper"] {
1569
- border-radius: var(--dropdown-border-radius) !important;
1570
- overflow: hidden !important;
1571
- }
1572
- [class*="awsui_select"] [class*="awsui_interior"],
1573
- [class*="awsui_select"] [class*="awsui_dropdown-content"],
1574
- [class*="awsui_select"] ul,
1575
- [class*="awsui_select"] li,
1576
- [class*="awsui_select-dropdown"] [class*="awsui_interior"],
1577
- [class*="awsui_select-dropdown"] ul,
1578
- [class*="awsui_select-dropdown"] li {
1579
- border-radius: 0 !important;
1580
- }
1581
-
1582
- /* Multiselect component dropdown containers - apply rounded corners */
1583
- [class*="awsui_multiselect"] [class*="awsui_dropdown-content-wrapper"] {
1584
- border-radius: var(--dropdown-border-radius) !important;
1585
- overflow: hidden !important;
1586
- }
1587
- [class*="awsui_multiselect"] [class*="awsui_interior"],
1588
- [class*="awsui_multiselect"] [class*="awsui_dropdown-content"],
1589
- [class*="awsui_multiselect"] ul,
1590
- [class*="awsui_multiselect"] li {
1591
- border-radius: 0 !important;
1592
- }
1593
-
1594
- /*
1595
- * DROPDOWN PORTAL STYLES - All scoped to body > div[class*="awsui_dropdown"]
1596
- * CRITICAL: Avoids affecting table cells which also use "interior" class patterns
1597
- * Uses --dropdown-border-radius for consistent rounded corners on containers
1598
- */
1599
-
1600
- /* Portal-rendered dropdown containers - apply rounded corners */
1601
- body > div[class*="awsui_dropdown"] [class*="awsui_dropdown-content-wrapper"],
1602
- body > div[class*="awsui_select"] [class*="awsui_dropdown-content-wrapper"],
1603
- body > div[class*="awsui_multiselect"] [class*="awsui_dropdown-content-wrapper"] {
1604
- border-radius: var(--dropdown-border-radius) !important;
1605
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15) !important;
1606
- outline: none !important;
1607
- border: none !important;
1608
- overflow: hidden !important;
1609
- }
1610
-
1611
- /* Universal portal dropdown wrappers - ensure rounded corners for all Cloudscape dropdowns */
1612
- body > div[class*="awsui"][class*="dropdown"] [class*="awsui_dropdown-content-wrapper"],
1613
- body > div[class*="awsui"] > [class*="awsui_dropdown-content-wrapper"],
1614
- body > div[class*="awsui"] [class*="awsui_dropdown-content-wrapper"] {
1615
- border-radius: var(--dropdown-border-radius) !important;
1616
- overflow: hidden !important;
1617
- }
1618
-
1619
- /* Interior and list elements - no rounded corners (container handles it) */
1620
- body > div[class*="awsui_dropdown"] [class*="awsui_interior"],
1621
- body > div[class*="awsui_dropdown"] [class*="awsui_content-wrapper"],
1622
- body > div[class*="awsui_dropdown"] ul[class*="awsui"],
1623
- body > div[class*="awsui_dropdown"] li[class*="awsui"],
1624
- body > div[class*="awsui_select"] [class*="awsui_interior"],
1625
- body > div[class*="awsui_select"] ul[class*="awsui"],
1626
- body > div[class*="awsui_select"] li[class*="awsui"],
1627
- body > div[class*="awsui_multiselect"] [class*="awsui_interior"],
1628
- body > div[class*="awsui_multiselect"] ul[class*="awsui"],
1629
- body > div[class*="awsui_multiselect"] li[class*="awsui"] {
1630
- border-radius: 0 !important;
1631
- }
1632
-
1633
- /* List items inside dropdown portals only */
1634
- body > div[class*="awsui_dropdown"] [class*="awsui_list"] li,
1635
- body > div[class*="awsui_dropdown"] ul li {
1636
- border-radius: 0 !important;
1637
- }
1638
-
1639
- /* Interior wrapper inside dropdown portals */
1640
- body > div[class*="awsui_dropdown"] [class*="awsui_interior"],
1641
- body > div[class*="awsui_select"] [class*="awsui_interior"],
1642
- body > div[class*="awsui_multiselect"] [class*="awsui_interior"] {
1643
- border-radius: 0 !important;
1644
- box-shadow: none !important;
1645
- outline: none !important;
1646
- border: none !important;
1647
- }
1648
-
1649
- /* Inner elements inside dropdown portals */
1650
- body > div[class*="awsui_dropdown"] [class*="awsui_dropdown-content-wrapper"] > *,
1651
- body > div[class*="awsui_dropdown"] [class*="awsui_dropdown-content"],
1652
- body > div[class*="awsui_dropdown"] [class*="awsui_dropdown-content"] > * {
1653
- border-radius: 0 !important;
1654
- box-shadow: none !important;
1655
- outline: none !important;
1656
- border: none !important;
1657
- }
1658
-
1659
- /* Pseudo-elements inside dropdown portals */
1660
- body > div[class*="awsui_dropdown"]::before,
1661
- body > div[class*="awsui_dropdown"]::after,
1662
- body > div[class*="awsui_dropdown"] *::before,
1663
- body > div[class*="awsui_dropdown"] *::after {
1664
- border-radius: 0 !important;
1665
- box-shadow: none !important;
1666
- outline: none !important;
1667
- border: none !important;
1668
- display: none !important;
1669
- }
1670
-
1671
- /* Options list inside dropdown portals */
1672
- body > div[class*="awsui_dropdown"] [class*="awsui_optionsList"],
1673
- body > div[class*="awsui_dropdown"] [class*="awsui_options-list"],
1674
- body > div[class*="awsui_dropdown"] [class*="awsui_virtual-list"],
1675
- body > div[class*="awsui_select"] [class*="awsui_optionsList"],
1676
- body > div[class*="awsui_select"] [class*="awsui_options-list"],
1677
- body > div[class*="awsui_select"] [class*="awsui_virtual-list"],
1678
- body > div[class*="awsui_multiselect"] [class*="awsui_optionsList"],
1679
- body > div[class*="awsui_multiselect"] [class*="awsui_options-list"],
1680
- body > div[class*="awsui_multiselect"] [class*="awsui_virtual-list"] {
1681
- border-radius: 0 !important;
1682
- box-shadow: none !important;
1683
- border: none !important;
1684
- }
1685
-
1686
- /* Focus rings inside dropdown portals */
1687
- body > div[class*="awsui_dropdown"] *:focus,
1688
- body > div[class*="awsui_dropdown"] *:focus-visible,
1689
- body > div[class*="awsui_dropdown"] *:focus-within {
1690
- outline: none !important;
1691
- box-shadow: none !important;
1692
- }
1693
-
1694
- /* All element types inside dropdown portals */
1695
- body > div[class*="awsui_dropdown"] div,
1696
- body > div[class*="awsui_dropdown"] ul,
1697
- body > div[class*="awsui_dropdown"] li,
1698
- body > div[class*="awsui_dropdown"] span,
1699
- body > div[class*="awsui_dropdown"] a,
1700
- body > div[class*="awsui_dropdown"] button {
1701
- border-radius: 0 !important;
1702
- }
1703
-
1704
- /* Hover styling inside dropdown portals */
1705
- body > div[class*="awsui_dropdown"] [role="option"]:hover,
1706
- body > div[class*="awsui_dropdown"] [role="menuitem"]:hover,
1707
- body > div[class*="awsui_dropdown"] [role="menuitemcheckbox"]:hover,
1708
- body > div[class*="awsui_dropdown"] [role="menuitemradio"]:hover,
1709
- body > div[class*="awsui_dropdown"] [role="option"][aria-selected="true"],
1710
- body > div[class*="awsui_dropdown"] [role="menuitem"][aria-selected="true"] {
1711
- color: #26c6ff !important;
1712
- background-color: transparent !important;
1713
- }
1714
-
1715
- body > div[class*="awsui_dropdown"] [role="option"]:hover *,
1716
- body > div[class*="awsui_dropdown"] [role="menuitem"]:hover *,
1717
- body > div[class*="awsui_dropdown"] [role="menuitemcheckbox"]:hover *,
1718
- body > div[class*="awsui_dropdown"] [role="menuitemradio"]:hover *,
1719
- body > div[class*="awsui_dropdown"] [role="option"][aria-selected="true"] *,
1720
- body > div[class*="awsui_dropdown"] [role="menuitem"][aria-selected="true"] * {
1721
- color: #26c6ff !important;
1722
- }
1723
-
1724
907
  /* ---break---
1725
908
  */
1726
909
 
@@ -1772,6 +955,18 @@ body > div[class*="awsui_dropdown"] [role="menuitem"][aria-selected="true"] * {
1772
955
  --invert-foreground: var(--color-zinc-50);
1773
956
  }
1774
957
 
958
+ /* Dark mode: ensure side navigation links are visible on dark background */
959
+ .dark .app-shell-side-navigation a,
960
+ .dark .app-shell-side-navigation button,
961
+ .dark .app-shell-side-navigation [role="link"] {
962
+ color: #f5f5f5 !important;
963
+ }
964
+
965
+ .dark .app-shell-side-navigation [aria-current="page"] {
966
+ color: #26c6ff !important;
967
+ font-weight: 600 !important;
968
+ }
969
+
1775
970
  /* ---break---
1776
971
  */
1777
972
 
package/src/vite.js CHANGED
@@ -101,6 +101,40 @@ function ssrCssStubPlugin() {
101
101
  * });
102
102
  */
103
103
  export function getSharedViteConfig(appDir) {
104
+ const installedAppShellSrc = path.resolve(appDir, "node_modules/@platform/app-shell/src");
105
+ const resolvedAppShellSrc = fs.existsSync(installedAppShellSrc) ? installedAppShellSrc : APP_SHELL_SRC_DIR;
106
+
107
+ // NPM-first shared config: keep only essential aliases/SSR handling.
108
+ return {
109
+ plugins: [ssrCssStubPlugin()],
110
+ resolve: {
111
+ preserveSymlinks: true,
112
+ alias: [
113
+ {
114
+ find: /^@\/(.*)$/,
115
+ replacement: `${resolvedAppShellSrc}/$1`,
116
+ },
117
+ ],
118
+ dedupe: ["react", "react-dom"],
119
+ },
120
+ ssr: {
121
+ external: [
122
+ /^react(\/.*)?$/,
123
+ /^react-dom(\/.*)?$/,
124
+ /^katex\/dist\/.*\.css$/,
125
+ ],
126
+ noExternal: [
127
+ /^@platform\/app-shell/,
128
+ /^@platform\/service-catalog/,
129
+ /^@copilotkit\//,
130
+ /^@copilotkitnext\//,
131
+ /^streamdown/,
132
+ /^rehype-katex/,
133
+ /^katex$/,
134
+ ],
135
+ },
136
+ };
137
+
104
138
  const monorepoRoot = getMonorepoRoot(appDir);
105
139
  const appNodeModules = path.resolve(appDir, "node_modules");
106
140
  const appShellSrc = APP_SHELL_SRC_DIR;
@@ -206,7 +240,6 @@ export function getSharedViteConfig(appDir) {
206
240
  /^katex\/dist\/.*\.css$/,
207
241
  ],
208
242
  noExternal: [
209
- /^@cloudscape-design\//,
210
243
  /^@radix-ui\//,
211
244
  /^@base-ui\//,
212
245
  /^radix-ui/,