Merge pull request #16 from velocitatem/15-define-the-color-and-style-scheme-for-the-hotel-and-airline-platforms

15 define the color and style scheme for the hotel and airline platforms
This commit is contained in:
Daniel Alves Rösel
2025-11-06 14:18:17 +01:00
committed by GitHub
4 changed files with 783 additions and 31 deletions

View File

@@ -1,36 +1,14 @@
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
## Getting Started # Phantom Air/Hotels
First, run the development server: Design Discovery Documentation: https://github.com/velocitatem/PHANTOM/wiki/Design-Discovery
```bash > This webapp serves two modes `{HOTEL,AIRLINE}` which are given by an env variable
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. The webapp should serve under the / route the landing page which for both platforms is very similar. We define a set of components like Hero, Card, Button, Link ... This we can then pass to specific components each mode might demand that makes it behave differently, hotel cards showing hotel rooms from database and airline cards showing flights from database and each fetching prices from the pricing provider with a different HTTP parameter.
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. - globally we define a middleware.ts which is our switcher for modes.
- /app will have (airline) and (hotel) children which each have a layout.tsx and page.tsx where /app also has a parent layout defining layout.tsx and globals.css for any shared styling to avoid repretition.
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. - /components/ is gonna have ui/ which defines things like Button, Card, DatePicker with generic definitions and any tracking or observation code. We then define feats/airline/ and feats/hotel/ as children of components with specific components like AirlineHero and HotelCard.
- in /styles/ we define airline.css and hotel.css to tailor accents and styling for each.
## Learn More
To learn more about Next.js, take a look at the following resources:
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
## Deploy on Vercel
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.

View File

@@ -3,6 +3,15 @@
:root { :root {
--background: #ffffff; --background: #ffffff;
--foreground: #171717; --foreground: #171717;
--bg-primary: #ffffff;
--bg-secondary: #f5f5f5;
--text-primary: #333333;
--text-secondary: #666666;
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 32px;
--border-radius: 8px;
--shadow-card: 0 2px 8px rgba(0, 0, 0, 0.1);
} }
@theme inline { @theme inline {
@@ -19,8 +28,71 @@
} }
} }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body { body {
background: var(--background); background: var(--background);
color: var(--foreground); color: var(--foreground);
font-family: Arial, Helvetica, sans-serif; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
line-height: 1.6;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
h1, h2, h3, h4, h5, h6 {
font-weight: 700;
color: var(--text-primary);
line-height: 1.2;
}
h1 { font-size: 2.5rem; }
h2 { font-size: 2rem; }
h3 { font-size: 1.5rem; }
button {
cursor: pointer;
border: none;
outline: none;
font-family: inherit;
transition: all 0.2s ease;
}
input, select, textarea {
font-family: inherit;
font-size: 1rem;
outline: none;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 var(--spacing-md);
}
.card {
background: var(--bg-primary);
border-radius: var(--border-radius);
box-shadow: var(--shadow-card);
overflow: hidden;
}
.btn-primary {
padding: 12px 24px;
font-weight: 600;
font-size: 1rem;
border-radius: var(--border-radius);
transition: all 0.2s ease;
}
.btn-primary:hover {
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.section-spacing {
margin-bottom: var(--spacing-lg);
} }

302
web/src/styles/airline.css Normal file
View File

@@ -0,0 +1,302 @@
/* Airline Platform - Sky Blue Theme */
:root[data-mode="airline"] {
--accent-primary: #007aff;
--accent-secondary: #4caf50;
--accent-warning: #ff3b30;
--accent-primary-hover: #0051d5;
--accent-primary-light: #e6f2ff;
--text-accent: #007aff;
}
[data-mode="airline"] {
--primary-color: var(--accent-primary);
}
[data-mode="airline"] .btn-primary {
background-color: var(--accent-primary);
color: #ffffff;
}
[data-mode="airline"] .btn-primary:hover {
background-color: var(--accent-primary-hover);
}
[data-mode="airline"] .btn-secondary {
background-color: transparent;
color: var(--accent-primary);
border: 2px solid var(--accent-primary);
}
[data-mode="airline"] .btn-secondary:hover {
background-color: var(--accent-primary-light);
}
[data-mode="airline"] .badge-value {
background-color: var(--accent-secondary);
color: #ffffff;
padding: 4px 8px;
border-radius: 4px;
font-size: 0.875rem;
font-weight: 600;
}
[data-mode="airline"] .badge-warning {
background-color: var(--accent-warning);
color: #ffffff;
padding: 4px 8px;
border-radius: 4px;
font-size: 0.875rem;
font-weight: 600;
}
[data-mode="airline"] .search-form {
background: var(--bg-primary);
padding: var(--spacing-lg);
border-radius: var(--border-radius);
box-shadow: var(--shadow-card);
}
[data-mode="airline"] .flight-card {
display: grid;
grid-template-columns: 2fr 3fr 2fr;
gap: var(--spacing-md);
padding: var(--spacing-md);
background: var(--bg-primary);
border-radius: var(--border-radius);
box-shadow: var(--shadow-card);
margin-bottom: var(--spacing-md);
transition: box-shadow 0.2s ease;
}
[data-mode="airline"] .flight-card:hover {
box-shadow: 0 4px 16px rgba(0, 122, 255, 0.15);
}
[data-mode="airline"] .flight-timing {
display: flex;
flex-direction: column;
justify-content: center;
}
[data-mode="airline"] .flight-time {
font-size: 1.5rem;
font-weight: 700;
color: var(--text-primary);
}
[data-mode="airline"] .flight-airport {
font-size: 0.875rem;
color: var(--text-secondary);
font-weight: 500;
}
[data-mode="airline"] .flight-route {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
}
[data-mode="airline"] .flight-duration {
font-size: 0.875rem;
color: var(--text-secondary);
margin-bottom: 4px;
}
[data-mode="airline"] .flight-stops {
font-size: 0.875rem;
color: var(--text-secondary);
font-weight: 600;
}
[data-mode="airline"] .flight-pricing {
display: flex;
flex-direction: column;
justify-content: center;
gap: var(--spacing-sm);
}
[data-mode="airline"] .fare-option {
display: flex;
justify-content: space-between;
align-items: center;
padding: var(--spacing-sm);
border: 1px solid #e0e0e0;
border-radius: 6px;
transition: all 0.2s ease;
}
[data-mode="airline"] .fare-option:hover {
border-color: var(--accent-primary);
background-color: var(--accent-primary-light);
}
[data-mode="airline"] .fare-class {
font-size: 0.875rem;
font-weight: 600;
color: var(--text-primary);
}
[data-mode="airline"] .fare-price {
font-size: 1.125rem;
font-weight: 700;
color: var(--accent-primary);
}
[data-mode="airline"] .date-price-bar {
display: flex;
overflow-x: auto;
gap: var(--spacing-sm);
padding: var(--spacing-md) 0;
margin-bottom: var(--spacing-lg);
}
[data-mode="airline"] .date-option {
min-width: 100px;
padding: var(--spacing-sm);
text-align: center;
border: 2px solid #e0e0e0;
border-radius: 6px;
cursor: pointer;
transition: all 0.2s ease;
}
[data-mode="airline"] .date-option:hover {
border-color: var(--accent-primary);
}
[data-mode="airline"] .date-option.active {
border-color: var(--accent-primary);
background-color: var(--accent-primary-light);
}
[data-mode="airline"] .date-label {
font-size: 0.75rem;
color: var(--text-secondary);
margin-bottom: 4px;
}
[data-mode="airline"] .date-price {
font-size: 1rem;
font-weight: 700;
color: var(--accent-primary);
}
[data-mode="airline"] .progress-wizard {
display: flex;
justify-content: space-between;
align-items: center;
max-width: 800px;
margin: var(--spacing-lg) auto;
padding: 0 var(--spacing-md);
}
[data-mode="airline"] .wizard-step {
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
position: relative;
}
[data-mode="airline"] .wizard-step::after {
content: '';
position: absolute;
top: 20px;
left: 50%;
width: 100%;
height: 2px;
background: #e0e0e0;
z-index: -1;
}
[data-mode="airline"] .wizard-step:last-child::after {
display: none;
}
[data-mode="airline"] .wizard-number {
width: 40px;
height: 40px;
border-radius: 50%;
background: #e0e0e0;
color: var(--text-secondary);
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
margin-bottom: var(--spacing-sm);
}
[data-mode="airline"] .wizard-step.active .wizard-number {
background: var(--accent-primary);
color: #ffffff;
}
[data-mode="airline"] .wizard-step.completed .wizard-number {
background: var(--accent-secondary);
color: #ffffff;
}
[data-mode="airline"] .wizard-label {
font-size: 0.875rem;
color: var(--text-secondary);
text-align: center;
}
[data-mode="airline"] .wizard-step.active .wizard-label {
color: var(--accent-primary);
font-weight: 600;
}
[data-mode="airline"] a {
color: var(--accent-primary);
text-decoration: none;
}
[data-mode="airline"] a:hover {
text-decoration: underline;
}
[data-mode="airline"] .input-field {
border: 2px solid #e0e0e0;
border-radius: 6px;
padding: 12px;
transition: border-color 0.2s ease;
}
[data-mode="airline"] .input-field:focus {
border-color: var(--accent-primary);
box-shadow: 0 0 0 3px var(--accent-primary-light);
}
[data-mode="airline"] .filter-sidebar {
background: var(--bg-primary);
padding: var(--spacing-md);
border-radius: var(--border-radius);
box-shadow: var(--shadow-card);
}
[data-mode="airline"] .filter-section {
margin-bottom: var(--spacing-lg);
}
[data-mode="airline"] .filter-title {
font-size: 1rem;
font-weight: 700;
color: var(--text-primary);
margin-bottom: var(--spacing-sm);
}
[data-mode="airline"] .checkbox-label {
display: flex;
align-items: center;
gap: var(--spacing-sm);
padding: var(--spacing-sm) 0;
cursor: pointer;
}
[data-mode="airline"] .checkbox-label:hover {
color: var(--accent-primary);
}

400
web/src/styles/hotel.css Normal file
View File

@@ -0,0 +1,400 @@
/* Hotel Platform - Action Blue Theme */
:root[data-mode="hotel"] {
--accent-primary: #007aff;
--accent-secondary: #4caf50;
--accent-warning: #d9534f;
--accent-primary-hover: #0051d5;
--accent-primary-light: #e6f2ff;
--text-accent: #007aff;
--bg-tertiary: #f5f5f7;
}
[data-mode="hotel"] {
--primary-color: var(--accent-primary);
}
[data-mode="hotel"] .btn-primary {
background-color: var(--accent-primary);
color: #ffffff;
}
[data-mode="hotel"] .btn-primary:hover {
background-color: var(--accent-primary-hover);
}
[data-mode="hotel"] .btn-secondary {
background-color: transparent;
color: var(--accent-primary);
border: 2px solid var(--accent-primary);
}
[data-mode="hotel"] .btn-secondary:hover {
background-color: var(--accent-primary-light);
}
[data-mode="hotel"] .badge-value {
background-color: var(--accent-secondary);
color: #ffffff;
padding: 4px 10px;
border-radius: 4px;
font-size: 0.875rem;
font-weight: 600;
}
[data-mode="hotel"] .badge-warning {
background-color: var(--accent-warning);
color: #ffffff;
padding: 4px 10px;
border-radius: 4px;
font-size: 0.875rem;
font-weight: 600;
}
[data-mode="hotel"] .badge-rating {
background-color: var(--accent-primary);
color: #ffffff;
padding: 6px 10px;
border-radius: 4px;
font-size: 0.875rem;
font-weight: 700;
}
[data-mode="hotel"] .search-form {
background: var(--bg-primary);
padding: var(--spacing-lg);
border-radius: var(--border-radius);
box-shadow: var(--shadow-card);
max-width: 900px;
margin: 0 auto;
}
[data-mode="hotel"] .hotel-card {
display: grid;
grid-template-columns: 300px 1fr auto;
gap: var(--spacing-md);
background: var(--bg-primary);
border-radius: var(--border-radius);
box-shadow: var(--shadow-card);
margin-bottom: var(--spacing-md);
overflow: hidden;
transition: box-shadow 0.2s ease;
}
[data-mode="hotel"] .hotel-card:hover {
box-shadow: 0 4px 16px rgba(0, 122, 255, 0.15);
}
[data-mode="hotel"] .hotel-image {
position: relative;
width: 100%;
height: 100%;
min-height: 220px;
overflow: hidden;
}
[data-mode="hotel"] .hotel-image img {
width: 100%;
height: 100%;
object-fit: cover;
}
[data-mode="hotel"] .image-carousel {
position: relative;
}
[data-mode="hotel"] .carousel-nav {
position: absolute;
bottom: var(--spacing-sm);
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 6px;
}
[data-mode="hotel"] .carousel-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.5);
cursor: pointer;
}
[data-mode="hotel"] .carousel-dot.active {
background: #ffffff;
}
[data-mode="hotel"] .hotel-info {
padding: var(--spacing-md);
display: flex;
flex-direction: column;
gap: var(--spacing-sm);
}
[data-mode="hotel"] .hotel-name {
font-size: 1.25rem;
font-weight: 700;
color: var(--text-primary);
margin: 0;
}
[data-mode="hotel"] .hotel-location {
font-size: 0.875rem;
color: var(--text-secondary);
display: flex;
align-items: center;
gap: 4px;
}
[data-mode="hotel"] .hotel-rating {
display: flex;
align-items: center;
gap: var(--spacing-sm);
}
[data-mode="hotel"] .rating-text {
font-size: 0.875rem;
font-weight: 600;
color: var(--text-primary);
}
[data-mode="hotel"] .hotel-features {
display: flex;
flex-wrap: wrap;
gap: var(--spacing-sm);
margin-top: var(--spacing-sm);
}
[data-mode="hotel"] .feature-tag {
padding: 4px 8px;
background: var(--bg-tertiary);
color: var(--text-secondary);
font-size: 0.75rem;
border-radius: 4px;
}
[data-mode="hotel"] .hotel-pricing {
padding: var(--spacing-md);
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: flex-end;
min-width: 200px;
}
[data-mode="hotel"] .price-wrapper {
text-align: right;
}
[data-mode="hotel"] .price-label {
font-size: 0.75rem;
color: var(--text-secondary);
margin-bottom: 4px;
}
[data-mode="hotel"] .price-amount {
font-size: 1.75rem;
font-weight: 700;
color: var(--accent-primary);
}
[data-mode="hotel"] .price-unit {
font-size: 0.875rem;
color: var(--text-secondary);
}
[data-mode="hotel"] .price-original {
text-decoration: line-through;
color: var(--text-secondary);
font-size: 1rem;
margin-right: var(--spacing-sm);
}
[data-mode="hotel"] .urgency-message {
font-size: 0.75rem;
color: var(--accent-warning);
font-weight: 600;
margin-top: 4px;
}
[data-mode="hotel"] .free-cancellation {
font-size: 0.75rem;
color: var(--accent-secondary);
font-weight: 600;
margin-top: 4px;
}
[data-mode="hotel"] .filter-sidebar {
background: var(--bg-primary);
padding: var(--spacing-md);
border-radius: var(--border-radius);
box-shadow: var(--shadow-card);
}
[data-mode="hotel"] .filter-section {
margin-bottom: var(--spacing-lg);
padding-bottom: var(--spacing-md);
border-bottom: 1px solid #e0e0e0;
}
[data-mode="hotel"] .filter-section:last-child {
border-bottom: none;
}
[data-mode="hotel"] .filter-title {
font-size: 1rem;
font-weight: 700;
color: var(--text-primary);
margin-bottom: var(--spacing-md);
}
[data-mode="hotel"] .checkbox-label {
display: flex;
align-items: center;
justify-content: space-between;
padding: var(--spacing-sm) 0;
cursor: pointer;
}
[data-mode="hotel"] .checkbox-label:hover {
color: var(--accent-primary);
}
[data-mode="hotel"] .checkbox-count {
font-size: 0.875rem;
color: var(--text-secondary);
}
[data-mode="hotel"] .price-slider {
margin-top: var(--spacing-md);
}
[data-mode="hotel"] .slider-track {
width: 100%;
height: 6px;
background: #e0e0e0;
border-radius: 3px;
position: relative;
}
[data-mode="hotel"] .slider-range {
height: 100%;
background: var(--accent-primary);
border-radius: 3px;
}
[data-mode="hotel"] .slider-values {
display: flex;
justify-content: space-between;
margin-top: var(--spacing-sm);
font-size: 0.875rem;
color: var(--text-secondary);
}
[data-mode="hotel"] .map-toggle {
background: var(--bg-primary);
border: 2px solid var(--accent-primary);
color: var(--accent-primary);
padding: 12px 24px;
border-radius: var(--border-radius);
font-weight: 600;
cursor: pointer;
transition: all 0.2s ease;
}
[data-mode="hotel"] .map-toggle:hover {
background: var(--accent-primary);
color: #ffffff;
}
[data-mode="hotel"] .results-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: var(--spacing-lg);
padding: var(--spacing-md);
background: var(--bg-primary);
border-radius: var(--border-radius);
}
[data-mode="hotel"] .sort-dropdown {
padding: 8px 12px;
border: 2px solid #e0e0e0;
border-radius: 6px;
background: var(--bg-primary);
cursor: pointer;
font-size: 0.875rem;
}
[data-mode="hotel"] .sort-dropdown:focus {
border-color: var(--accent-primary);
}
[data-mode="hotel"] .view-toggle {
display: flex;
gap: var(--spacing-sm);
}
[data-mode="hotel"] .view-button {
padding: 8px 12px;
background: transparent;
border: 2px solid #e0e0e0;
border-radius: 6px;
cursor: pointer;
transition: all 0.2s ease;
}
[data-mode="hotel"] .view-button.active {
background: var(--accent-primary);
color: #ffffff;
border-color: var(--accent-primary);
}
[data-mode="hotel"] a {
color: var(--accent-primary);
text-decoration: none;
}
[data-mode="hotel"] a:hover {
text-decoration: underline;
}
[data-mode="hotel"] .input-field {
border: 2px solid #e0e0e0;
border-radius: 6px;
padding: 12px;
width: 100%;
transition: border-color 0.2s ease;
}
[data-mode="hotel"] .input-field:focus {
border-color: var(--accent-primary);
box-shadow: 0 0 0 3px var(--accent-primary-light);
}
[data-mode="hotel"] .tab-navigation {
display: flex;
gap: 0;
margin-bottom: var(--spacing-lg);
border-bottom: 2px solid #e0e0e0;
}
[data-mode="hotel"] .tab-item {
padding: 12px 24px;
background: transparent;
border: none;
border-bottom: 3px solid transparent;
color: var(--text-secondary);
font-weight: 600;
cursor: pointer;
transition: all 0.2s ease;
}
[data-mode="hotel"] .tab-item:hover {
color: var(--accent-primary);
}
[data-mode="hotel"] .tab-item.active {
color: var(--accent-primary);
border-bottom-color: var(--accent-primary);
}