From 23af9b33daf5aaff156cfe8bf0abb55c023e6d67 Mon Sep 17 00:00:00 2001 From: Jessica Orozco Date: Tue, 16 Jun 2026 15:49:10 -0400 Subject: [PATCH] feat: implement calendar booking component with Google Calendar-style UI and layout infrastructure --- frontend/src/app/app.component.css | 22 +- .../features/dashboard/dashboard.component.ts | 9 +- .../directorio/directorio.component.css | 25 +- .../features/info-hub/info-hub.component.ts | 60 +- .../calendar-booking.component.css | 1526 +++++++++++------ .../calendar-booking.component.html | 475 +++-- .../calendar-booking.component.ts | 68 +- .../features/workflows/workflows.component.ts | 60 +- 8 files changed, 1455 insertions(+), 790 deletions(-) diff --git a/frontend/src/app/app.component.css b/frontend/src/app/app.component.css index eb11ce7..16391ab 100644 --- a/frontend/src/app/app.component.css +++ b/frontend/src/app/app.component.css @@ -3,17 +3,20 @@ ========================================================= */ .app-shell { - min-height: 100vh; + height: 100vh; display: flex; flex-direction: column; background: #F5F4F1; - padding: 0 32px 32px; + padding: 0 16px; box-sizing: border-box; + overflow: hidden; } .app-shell.login-mode { padding: 0; background: #F5F4F1; /* ivory white — same as page */ + height: auto; + overflow: visible; } /* ── Header ── */ @@ -23,7 +26,7 @@ justify-content: space-between; padding: 18px 0; border-bottom: 1px solid rgba(15, 13, 10, 0.08); - margin-bottom: 32px; + flex-shrink: 0; } .header-brand { @@ -78,12 +81,18 @@ } /* ── Content ── */ -.app-content { flex: 1; display: flex; flex-direction: column; } +.app-content { + flex: 1; + display: flex; + flex-direction: column; + overflow-y: auto; + min-height: 0; + padding: 12px 0; +} /* ── Footer ── */ .app-footer { - margin-top: 32px; - padding-top: 18px; + padding: 18px 0; border-top: 1px solid rgba(15, 13, 10, 0.07); display: flex; align-items: center; @@ -94,6 +103,7 @@ color: #A8A29E; letter-spacing: 0.05em; text-transform: uppercase; + flex-shrink: 0; } .footer-dot { diff --git a/frontend/src/app/features/dashboard/dashboard.component.ts b/frontend/src/app/features/dashboard/dashboard.component.ts index 63bb9ca..e033c25 100644 --- a/frontend/src/app/features/dashboard/dashboard.component.ts +++ b/frontend/src/app/features/dashboard/dashboard.component.ts @@ -25,7 +25,7 @@ interface UserProfile { standalone: true, imports: [CommonModule], template: ` -
+
@@ -644,6 +644,13 @@ interface UserProfile {
`, styles: [` + :host { + display: flex; + flex-direction: column; + flex: 1; + min-height: 0; + height: 100%; + } .animate-fadeIn { animation: fadeIn 0.4s ease-out forwards; } diff --git a/frontend/src/app/features/directorio/directorio.component.css b/frontend/src/app/features/directorio/directorio.component.css index 2224777..95e97a1 100644 --- a/frontend/src/app/features/directorio/directorio.component.css +++ b/frontend/src/app/features/directorio/directorio.component.css @@ -2,6 +2,14 @@ APP PEOPLE — Employee Directory Stylesheet ========================================================================== */ +:host { + display: flex; + flex-direction: column; + flex: 1; + min-height: 0; + height: 100%; +} + .dir-shell { display: flex; flex-direction: column; @@ -10,8 +18,10 @@ overflow: hidden; border: 1px solid rgba(15, 13, 10, 0.06); box-shadow: 0 4px 20px rgba(0, 0, 0, 0.02); - min-height: 85vh; + height: 100%; font-family: 'Outfit', 'Inter', system-ui, sans-serif; + flex: 1; + min-height: 0; } /* ── TIMI PEOPLE NAVBAR ── */ @@ -137,11 +147,14 @@ /* ── MAIN CONTENT ── */ .dir-main { - padding: 32px; + padding: 12px 16px; display: flex; flex-direction: column; - gap: 24px; + gap: 16px; flex-grow: 1; + height: 100%; + overflow: hidden; + min-height: 0; } /* Header block */ @@ -370,7 +383,11 @@ .dir-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); - gap: 24px; + gap: 16px; + flex: 1; + overflow-y: auto; + min-height: 0; + padding: 4px; /* avoid box-shadow clipping */ } /* Card details */ diff --git a/frontend/src/app/features/info-hub/info-hub.component.ts b/frontend/src/app/features/info-hub/info-hub.component.ts index fc6891d..2fbbd5c 100644 --- a/frontend/src/app/features/info-hub/info-hub.component.ts +++ b/frontend/src/app/features/info-hub/info-hub.component.ts @@ -262,62 +262,38 @@ import { Router } from '@angular/router';
`, styles: [` + :host { + display: flex; + flex-direction: column; + flex: 1; + min-height: 0; + height: 100%; + } + /* ── LAYOUT PRINCIPAL ── */ .ih-shell { display: flex; background: #f4f3ef; /* Light beige/grey background matching workflow */ - min-height: 90vh; + height: 100%; border-radius: 24px; overflow: hidden; border: 1px solid rgba(15, 13, 10, 0.08); box-shadow: 0 4px 20px rgba(0, 0, 0, 0.02); font-family: 'Outfit', 'Inter', system-ui, sans-serif; - } - - /* Sidebar */ - .ih-sidebar { - width: 90px; - background: #000000; - display: flex; - flex-direction: column; - align-items: center; - padding: 24px 0; - flex-shrink: 0; - } - - .ih-sidebar__brand { - font-size: 11px; - font-weight: 900; - letter-spacing: 0.12em; - color: rgba(255, 255, 255, 0.4); - margin-bottom: 24px; - } - - .ih-sidebar__logo-container { - width: 44px; - height: 44px; - border-radius: 12px; - background: #ffffff; - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - } - - .ih-sidebar__logo-btn { - font-size: 18px; - font-weight: 900; - color: #000000; + flex: 1; + min-height: 0; } /* Content Area */ .ih-content { flex-grow: 1; - padding: 24px; + padding: 12px 16px; display: flex; flex-direction: column; - gap: 20px; + gap: 12px; min-width: 0; + height: 100%; + overflow: hidden; } /* Topbar */ @@ -421,7 +397,11 @@ import { Router } from '@angular/router'; .ih-grid { display: grid; grid-template-columns: 1fr; - gap: 24px; + gap: 16px; + flex: 1; + overflow-y: auto; + min-height: 0; + padding: 4px; /* avoid box-shadow clipping */ } @media (min-width: 1024px) { diff --git a/frontend/src/app/features/reservas/calendar-booking/calendar-booking.component.css b/frontend/src/app/features/reservas/calendar-booking/calendar-booking.component.css index c03dd29..ad4c534 100644 --- a/frontend/src/app/features/reservas/calendar-booking/calendar-booking.component.css +++ b/frontend/src/app/features/reservas/calendar-booking/calendar-booking.component.css @@ -1,588 +1,1084 @@ /* ========================================================================== - APP SPACES — Resource Scheduler Layout + APP SPACES — Google Calendar layout style ========================================================================== */ -.wf-shell { +:host { display: flex; - background: #f4f3ef; /* Light beige/grey background */ - min-height: 90vh; - border-radius: 24px; + flex-direction: column; + flex: 1; + min-height: 0; + height: 100%; +} + +.gc-container { + display: flex; + flex-direction: column; + height: 100%; + width: 100%; + background: #ffffff; + color: #3c4043; + font-family: 'Roboto', 'Inter', system-ui, sans-serif; overflow: hidden; - border: 1px solid rgba(15, 13, 10, 0.08); - box-shadow: 0 4px 20px rgba(0, 0, 0, 0.02); - font-family: 'Outfit', 'Inter', system-ui, sans-serif; - width: 100%; + box-sizing: border-box; } -/* Sidebar */ -.wf-sidebar { - width: 90px; - background: #000000; +/* ═══════════════════════════════ HEADER (TOPBAR) ═══════════════════════════════ */ +.gc-header { + height: 64px; display: flex; - flex-direction: column; align-items: center; - padding: 24px 0; + justify-content: space-between; + padding: 0 12px; + border-bottom: 1px solid #dadce0; + background: #ffffff; flex-shrink: 0; + box-sizing: border-box; } -.wf-sidebar__brand { - font-size: 11px; - font-weight: 900; - letter-spacing: 0.12em; - color: rgba(255, 255, 255, 0.4); - margin-bottom: 24px; -} - -.wf-sidebar__logo-container { - width: 44px; - height: 44px; - border-radius: 12px; - background: #ffffff; - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; -} - -.wf-sidebar__logo-btn { - font-size: 18px; - font-weight: 900; - color: #000000; -} - -/* Content Area */ -.wf-content { - flex-grow: 1; - padding: 24px; - display: flex; - flex-direction: column; - gap: 20px; - min-width: 0; - position: relative; -} - -/* Topbar */ -.wf-topbar { - background: #111625; - border-radius: 16px; - padding: 14px 24px; - display: flex; - flex-direction: column; - gap: 12px; -} - -.wf-topbar__header-row { - display: flex; - justify-content: space-between; - align-items: center; - flex-wrap: wrap; - gap: 12px; - width: 100%; -} - -.wf-topbar__title { - font-size: 18px; - font-weight: 700; - color: #ffffff; - margin: 0; -} - -.wf-topbar__controls { - display: flex; - align-items: center; - gap: 12px; -} - -.wf-search { - position: relative; - width: 180px; -} - -.wf-search__field { - width: 100%; - background: rgba(255, 255, 255, 0.08); - border: 1px solid rgba(255, 255, 255, 0.1); - border-radius: 10px; - padding: 6px 12px 6px 32px; - font-size: 11px; - color: #ffffff; - outline: none; -} - -.wf-search__field::placeholder { - color: rgba(255, 255, 255, 0.4); -} - -.wf-search__btn { - position: absolute; - left: 10px; - top: 50%; - transform: translateY(-50%); - background: transparent; - border: none; - color: rgba(255, 255, 255, 0.4); - cursor: pointer; - display: flex; - align-items: center; -} - -.wf-filter-dropdown__trigger { - background: rgba(255, 255, 255, 0.08); - border: 1px solid rgba(255, 255, 255, 0.1); - border-radius: 10px; - font-size: 11px; - font-weight: 600; - color: #ffffff; - padding: 6px 12px; - cursor: pointer; - display: flex; - align-items: center; - gap: 6px; -} - -.wf-filter-dropdown__arrow { - font-size: 8px; - color: rgba(255, 255, 255, 0.4); -} - -.wf-btn-filter { - background: rgba(255, 255, 255, 0.08); - border: 1px solid rgba(255, 255, 255, 0.1); - border-radius: 10px; - color: #ffffff; - font-size: 11px; - font-weight: 600; - padding: 6px 14px; - cursor: pointer; - display: inline-flex; - align-items: center; - gap: 6px; -} - -/* Category Filters */ -.ih-category-filters { - display: flex; - gap: 10px; - flex-wrap: wrap; -} - -.ih-category-btn { - background: rgba(255, 255, 255, 0.08); - border: none; - color: rgba(255, 255, 255, 0.6); - font-size: 11px; - font-weight: 700; - padding: 6px 14px; - border-radius: 10px; - cursor: pointer; - transition: background 0.15s ease, color 0.15s ease; -} - -.ih-category-btn:hover { - background: rgba(255, 255, 255, 0.15); - color: #ffffff; -} - -.ih-category-btn--active { - background: #ffffff !important; - color: #000000 !important; -} - -/* Main Grid */ -.ih-grid { - display: grid; - grid-template-columns: 1fr; - gap: 24px; - flex-grow: 1; -} - -@media (min-width: 1024px) { - .ih-grid { - grid-template-columns: 7fr 3fr; - } -} - -/* Calendar Card */ -.wf-card { - background: #ffffff; - border-radius: 20px; - padding: 24px; - border: 1px solid #e2e8f0; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.01); - display: flex; - flex-direction: column; - gap: 16px; -} - -.wf-card__header { - display: flex; - justify-content: space-between; - align-items: center; -} - -.wf-card__title { - font-size: 16px; - font-weight: 800; - color: #000000; - margin: 0; - letter-spacing: -0.01em; -} - -/* View toggle */ -.wf-view-toggle { - display: flex; - background: #e2e8f0; - border-radius: 8px; - padding: 2px; -} - -.wf-view-toggle__btn { - background: transparent; - border: none; - color: #475569; - font-size: 11px; - font-weight: 700; - padding: 6px 12px; - border-radius: 6px; - cursor: pointer; - transition: background-color 0.15s, color 0.15s; -} - -.wf-view-toggle__btn--active { - background: #084d47; /* Teal-dark green */ - color: #ffffff; -} - -/* Scheduler Table Layout */ -.res-calendar-container { - display: flex; - flex-direction: column; - overflow-x: auto; - width: 100%; -} - -.res-grid-header { - display: grid; - grid-template-columns: 60px repeat(4, 1fr); - border-bottom: 2px solid #f1f5f9; - padding-bottom: 12px; - gap: 16px; - min-width: 600px; -} - -.res-time-column-label { - width: 60px; -} - -.res-resource-column { - min-width: 120px; -} - -.res-resource-header { +.gc-header__left { display: flex; align-items: center; gap: 8px; } -.res-resource-icon { - width: 32px; - height: 32px; - border-radius: 8px; - background: #e0f2fe; /* Light blue */ +.gc-header__menu-btn { + background: transparent; + border: none; + border-radius: 50%; + width: 40px; + height: 40px; display: flex; align-items: center; justify-content: center; - font-size: 16px; + color: #5f6368; + cursor: pointer; + outline: none; +} + +.gc-header__menu-btn:hover { + background: #f1f3f4; +} + +.gc-header__menu-btn svg { + width: 20px; + height: 20px; +} + +.gc-header__logo { + display: flex; + align-items: center; + gap: 8px; + margin-right: 24px; + user-select: none; +} + +.gc-header__logo-icon { + width: 40px; + height: 40px; + background-image: url('https://ssl.gstatic.com/calendar/images/dynamiclogo_2020q4/calendar_16_2x.png'); + background-size: contain; + background-repeat: no-repeat; + display: flex; + align-items: center; + justify-content: center; + position: relative; +} + +.gc-header__logo-icon span { + font-size: 13.5px; + font-weight: 700; + color: #1a73e8; + margin-top: 6px; + font-family: 'Google Sans', 'Roboto', sans-serif; +} + +.gc-header__logo-text { + font-size: 22px; + color: #5f6368; + font-weight: 400; + font-family: 'Product Sans', 'Google Sans', 'Inter', sans-serif; + letter-spacing: -0.03em; +} + +.gc-header__btn { + background: #ffffff; + border: 1px solid #dadce0; + color: #3c4043; + font-size: 14px; + font-weight: 500; + cursor: pointer; + outline: none; + box-sizing: border-box; + transition: background-color 0.15s; +} + +.gc-header__btn:hover { + background: #f1f3f4; +} + +.gc-header__btn--rounded { + padding: 8px 16px; + border-radius: 4px; + margin-right: 12px; +} + +.gc-header__nav { + display: flex; + align-items: center; + margin-right: 20px; +} + +.gc-header__nav-btn { + background: transparent; + border: none; + border-radius: 50%; + width: 32px; + height: 32px; + font-size: 20px; + color: #5f6368; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + outline: none; +} + +.gc-header__nav-btn:hover { + background: #f1f3f4; +} + +.gc-header__title { + font-size: 20px; + font-weight: 400; + color: #3c4043; + margin: 0; +} + +.gc-header__right { + display: flex; + align-items: center; + gap: 8px; +} + +.gc-header__search-container { + position: relative; + width: 240px; + margin-right: 16px; +} + +.gc-header__search-icon { + position: absolute; + left: 12px; + top: 50%; + transform: translateY(-50%); + color: #5f6368; + pointer-events: none; +} + +.gc-header__search-input { + width: 100%; + background: #f1f3f4; + border: 1px solid transparent; + border-radius: 8px; + padding: 8px 12px 8px 36px; + font-size: 14px; + color: #3c4043; + outline: none; + transition: background-color 0.15s, border-color 0.15s, box-shadow 0.15s; +} + +.gc-header__search-input:focus { + background: #ffffff; + border-color: #dadce0; + box-shadow: 0 1px 3px rgba(60,64,67,0.15); +} + +.gc-header__icon-btn { + background: transparent; + border: none; + border-radius: 50%; + width: 40px; + height: 40px; + display: flex; + align-items: center; + justify-content: center; + color: #5f6368; + cursor: pointer; + outline: none; +} + +.gc-header__icon-btn:hover { + background: #f1f3f4; +} + +.gc-header__view-select { + margin-right: 8px; +} + +.gc-header__view-trigger { + background: #ffffff; + border: 1px solid #dadce0; + border-radius: 4px; + padding: 8px 12px; + display: flex; + align-items: center; + gap: 8px; + font-size: 14px; + font-weight: 500; + color: #3c4043; + cursor: pointer; +} + +.gc-header__view-trigger:hover { + background: #f1f3f4; +} + +.gc-header__view-arrow { + font-size: 8px; + color: #5f6368; +} + +.gc-header__user-avatar { + width: 32px; + height: 32px; + border-radius: 50%; + background: #1a73e8; + color: #ffffff; + font-weight: bold; + font-size: 13px; + display: flex; + align-items: center; + justify-content: center; + margin-left: 8px; + cursor: pointer; +} + +/* ═══════════════════════════════ LAYOUT BODY ═══════════════════════════════ */ +.gc-body { + display: flex; + flex: 1; + min-height: 0; + width: 100%; +} + +/* ── SIDEBAR IZQUIERDO (256px) ── */ +.gc-left-sidebar { + width: 256px; flex-shrink: 0; -} - -.res-resource-icon--yellow { - background: #fef3c7; /* Light yellow */ -} - -.res-resource-icon--office { - background: #f1f5f9; /* Grey */ -} - -.res-resource-info { + border-right: 1px solid #dadce0; + background: #ffffff; + padding: 8px 12px 16px; display: flex; flex-direction: column; - min-width: 0; + gap: 16px; + box-sizing: border-box; + overflow-y: auto; } -.res-resource-name { +.gc-left-sidebar::-webkit-scrollbar { + width: 4px; +} + +.gc-left-sidebar::-webkit-scrollbar-thumb { + background: transparent; + border-radius: 4px; +} + +.gc-left-sidebar:hover::-webkit-scrollbar-thumb { + background: #dadce0; +} + +/* Pill style "+ Crear" button */ +.gc-sidebar-create { + padding: 4px 0 12px; +} + +.gc-btn-create { + height: 48px; + padding: 0 24px 0 8px; + background: #ffffff; + border: none; + border-radius: 24px; + box-shadow: 0 1px 3px rgba(60,64,67,0.3), 0 4px 8px 3px rgba(60,64,67,0.15); + display: flex; + align-items: center; + gap: 12px; + cursor: pointer; + transition: box-shadow 0.15s, background-color 0.15s; + outline: none; +} + +.gc-btn-create:hover { + background: #f8f9fa; + box-shadow: 0 2px 3px rgba(60,64,67,0.3), 0 6px 10px 4px rgba(60,64,67,0.15); +} + +.gc-btn-create__icon { + width: 36px; + height: 36px; +} + +.gc-btn-create__text { + font-size: 14px; + font-weight: 500; + color: #3c4043; + font-family: 'Google Sans', Roboto, sans-serif; + letter-spacing: 0.25px; +} + +.gc-btn-create__arrow { + font-size: 8px; + color: #5f6368; + margin-left: 4px; +} + +/* Mini monthly calendar */ +.gc-mini-calendar { + display: flex; + flex-direction: column; + padding: 0 4px; +} + +.gc-mini-calendar__header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 8px; + padding: 0 8px; +} + +.gc-mini-calendar__title { + font-size: 13.5px; + font-weight: 500; + color: #3c4043; +} + +.gc-mini-calendar__nav { + display: flex; + gap: 4px; +} + +.gc-mini-calendar__nav-btn { + background: transparent; + border: none; + border-radius: 50%; + width: 24px; + height: 24px; + font-size: 14px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + color: #5f6368; +} + +.gc-mini-calendar__nav-btn:hover { + background: #f1f3f4; +} + +.gc-mini-calendar__days-header { + display: grid; + grid-template-columns: repeat(7, 1fr); + text-align: center; font-size: 11px; - font-weight: 800; - color: #0f172a; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; + font-weight: 500; + color: #70757a; + margin-bottom: 4px; } -.res-resource-desc { - font-size: 9px; - color: #94a3b8; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; +.gc-mini-calendar__days-grid { + display: grid; + grid-template-columns: repeat(7, 1fr); + row-gap: 2px; + text-align: center; } -/* Body of Scheduler */ -.res-grid-body { +.gc-mini-calendar__day { + height: 24px; + font-size: 11px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + border-radius: 50%; + color: #3c4043; +} + +.gc-mini-calendar__day:hover { + background: #f1f3f4; +} + +.gc-mini-calendar__day--inactive { + color: #a0a5ab; +} + +.gc-mini-calendar__day--active { + background: #1a73e8 !important; + color: #ffffff !important; + font-weight: bold; +} + +/* Sidebar Search Box */ +.gc-sidebar-search { + padding: 0 4px; +} + +.gc-search-box { + display: flex; + align-items: center; + gap: 10px; + border: 1px solid #dadce0; + border-radius: 4px; + padding: 6px 12px; + background: #ffffff; +} + +.gc-search-box__icon { + font-size: 18px; + color: #5f6368; +} + +.gc-search-box__input { + border: none; + outline: none; + font-size: 13px; + width: 100%; + color: #3c4043; +} + +.gc-search-box__input::placeholder { + color: #70757a; +} + +/* Collapsible Accordions (Mis Calendarios) */ +.gc-accordion { + display: flex; + flex-direction: column; + border-top: 1px solid #dadce0; + padding-top: 12px; +} + +.gc-accordion__header { + display: flex; + justify-content: space-between; + align-items: center; + cursor: pointer; + padding: 4px 8px; + user-select: none; +} + +.gc-accordion__header:hover { + background: #f1f3f4; + border-radius: 4px; +} + +.gc-accordion__title { + font-size: 13.5px; + font-weight: 500; + color: #3c4043; +} + +.gc-accordion__chevron { + font-size: 18px; + color: #5f6368; +} + +.gc-accordion__content { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; - min-width: 600px; + padding: 0 4px; } -.res-grid-row { - display: grid; - grid-template-columns: 60px repeat(4, 1fr); - gap: 16px; - align-items: center; -} - -.res-time-cell { - font-size: 11px; - font-weight: 700; - color: #94a3b8; - height: 32px; +.gc-checkbox-item { display: flex; align-items: center; -} - -.res-slot-cell { - position: relative; - height: 32px; -} - -.res-booking-block { - width: 100%; - height: 100%; - background: #e2e8f0; /* Default available grey cell */ - border-radius: 8px; - transition: background-color 0.15s; -} - -.res-booking-block--filled { - background: #084d47; /* Green busy block */ -} - -.res-booking-block--luna { - background: #084d47; - color: #ffffff; - font-size: 10px; - font-weight: 700; - display: flex; - align-items: center; - padding-left: 12px; - border-radius: 8px; -} - -.res-mini-avatar { - width: 20px; - height: 20px; - border-radius: 50%; - border: 1.5px solid #ffffff; - margin-left: -5px; - object-fit: cover; -} - -.res-mini-avatar:first-child { - margin-left: 0; -} - -/* Flotante Popup Card (Luna) */ -.res-popup-card { - position: absolute; - top: -30px; - left: 20px; - width: 240px; - background: #ffffff; - border: 1px solid #e2e8f0; - border-radius: 16px; - padding: 16px; - box-shadow: 0 10px 25px rgba(0, 0, 0, 0.12); - z-index: 50; - display: flex; - flex-direction: column; - gap: 8px; -} - -.res-popup-title { - font-size: 12px; - font-weight: 900; - color: #000000; - margin: 0; - letter-spacing: -0.01em; -} - -.res-popup-detail { - font-size: 11px; - color: #475569; - margin: 0; -} - -.res-popup-capacity { - font-size: 9px; - font-weight: 700; - color: #64748b; - text-transform: uppercase; - background: #f1f5f9; - padding: 2px 6px; - border-radius: 4px; - align-self: flex-start; -} - -.res-popup-actions { - display: flex; - gap: 6px; - margin-top: 4px; -} - -.res-popup-btn-confirm { - flex: 1; - background: #084d47; - border: none; - color: #ffffff; - font-size: 10px; - font-weight: 700; - padding: 6px 0; - border-radius: 8px; - cursor: pointer; - transition: background 0.15s; -} - -.res-popup-btn-confirm:hover { - background: #053b36; -} - -.res-popup-btn-details { - flex: 1; - background: #f1f5f9; - border: 1px solid #e2e8f0; - color: #334155; - font-size: 10px; - font-weight: 700; - padding: 6px 0; - border-radius: 8px; - cursor: pointer; - transition: background 0.15s; -} - -.res-popup-btn-details:hover { - background: #e2e8f0; -} - -.res-popup-status { - font-size: 9.5px; - color: #059669; - display: flex; - align-items: center; - gap: 4px; - margin-top: 2px; - font-weight: 600; -} - -.res-popup-status-dot { - width: 6px; - height: 6px; - border-radius: 50%; - background: #10b981; -} - -/* ── COLUMN DERECHA: NOTIFICACIONES ── */ -.ih-activity-section { - display: flex; - flex-direction: column; -} - -.ih-card-activity { - background: #ffffff; - border-radius: 20px; - border: 1px solid #e2e8f0; - padding: 24px; - display: flex; - flex-direction: column; - gap: 20px; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.01); -} - -.ih-card-activity__title { - font-size: 15px; - font-weight: 800; - color: #000000; - margin: 0; - letter-spacing: -0.01em; -} - -.ih-activity-list { - display: flex; - flex-direction: column; - gap: 16px; -} - -.ih-activity-item { - display: flex; gap: 12px; + padding: 4px 8px; + cursor: pointer; + border-radius: 4px; + font-size: 12.5px; + color: #3c4043; +} + +.gc-checkbox-item:hover { + background: #f1f3f4; +} + +.gc-checkbox-item__input { + width: 16px; + height: 16px; + border-radius: 4px; + cursor: pointer; + accent-color: #1a73e8; /* Default */ +} + +.gc-checkbox-item__input--blue { accent-color: #1a73e8; } +.gc-checkbox-item__input--green { accent-color: #0f9d58; } +.gc-checkbox-item__input--yellow { accent-color: #f4b400; } +.gc-checkbox-item__input--purple { accent-color: #ab47bc; } + +/* Accordion for Reservas list */ +.gc-accordion--reservas { + flex: 1; + min-height: 0; + display: flex; + flex-direction: column; +} + +.gc-accordion__content--scroll { + flex: 1; + overflow-y: auto; + min-height: 0; +} + +.gc-activity-item { + display: flex; + gap: 10px; align-items: flex-start; - border-bottom: 1px solid #f1f5f9; - padding-bottom: 12px; + padding: 8px; + border-bottom: 1px solid #f1f3f4; } -.ih-activity-item:last-child { +.gc-activity-item:last-child { border-bottom: none; - padding-bottom: 0; } -.ih-activity-avatar { - width: 32px; - height: 32px; +.gc-activity-item__avatar { + width: 28px; + height: 28px; border-radius: 50%; object-fit: cover; flex-shrink: 0; } -.ih-activity-avatar-icon { +.gc-activity-item__body { + display: flex; + flex-direction: column; + gap: 1px; +} + +.gc-activity-item__title { + font-size: 12px; + color: #202124; +} + +.gc-activity-item__desc { + font-size: 11px; + color: #5f6368; + line-height: 1.3; +} + +.gc-activity-item__time { + font-size: 9.5px; + color: #9aa0a6; +} + +/* ── CENTRAL CALENDAR VIEW (GRID LAYOUT WEEK VIEW) ── */ +.gc-main-calendar { + flex: 1; + display: flex; + flex-direction: column; + background: #ffffff; + min-width: 0; + position: relative; +} + +/* Columns Day/Resource Headers */ +.gc-grid-header { + height: 96px; + border-bottom: 1px solid #dadce0; + display: flex; + flex-shrink: 0; +} + +.gc-grid-header__corner { + width: 60px; + border-right: 1px solid #dadce0; + display: flex; + align-items: flex-end; + justify-content: center; + padding-bottom: 8px; + flex-shrink: 0; +} + +.gc-corner-gmt { + font-size: 10px; + color: #70757a; +} + +.gc-grid-header__columns { + flex: 1; + display: grid; + grid-auto-flow: column; + grid-auto-columns: minmax(100px, 1fr); + height: 100%; +} + +.gc-col-header { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + border-right: 1px solid #dadce0; + text-align: center; + padding: 4px 8px; + background: #ffffff; + min-width: 0; +} + +.gc-col-header:last-child { + border-right: none; +} + +.gc-col-header__day { + font-size: 11px; + font-weight: 500; + color: #70757a; + text-transform: uppercase; + letter-spacing: 0.8px; +} + +.gc-col-header__day-circle { width: 32px; height: 32px; border-radius: 50%; - background: #f1f5f9; - font-size: 15px; display: flex; align-items: center; justify-content: center; + margin: 4px 0; + font-size: 16px; + background: #f1f3f4; +} + +.gc-col-header__day-circle--active { + background: #1a73e8; + color: #ffffff; +} + +.gc-col-header__name { + font-size: 12.5px; + font-weight: bold; + color: #3c4043; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + width: 100%; +} + +/* Scrollable Time Grid Area */ +.gc-grid-scroll-area { + flex: 1; + overflow-y: auto; + overflow-x: hidden; + min-height: 0; + background: #ffffff; + position: relative; +} + +.gc-grid-scroll-area::-webkit-scrollbar { + width: 8px; +} + +.gc-grid-scroll-area::-webkit-scrollbar-thumb { + background: #dadce0; + border-radius: 4px; +} + +.gc-grid-body { + display: flex; + position: relative; + min-height: 600px; +} + +/* Left scale column of hours */ +.gc-hours-column { + width: 60px; + border-right: 1px solid #dadce0; flex-shrink: 0; } -.ih-activity-body { +.gc-hour-cell { + height: 72px; /* Fixed height for scheduler slots */ + position: relative; + display: flex; + justify-content: flex-end; + padding-right: 8px; +} + +.gc-hour-label { + font-size: 11px; + color: #70757a; + position: relative; + top: -6px; +} + +/* Columns for calendar events and cells */ +.gc-columns-grid { + flex: 1; + display: grid; + grid-auto-flow: column; + grid-auto-columns: minmax(100px, 1fr); + position: relative; +} + +/* Red Time Indicator Line */ +.gc-current-time-line { + position: absolute; + left: 0; + right: 0; + height: 2px; + background: #ea4335; + z-index: 10; + pointer-events: none; +} + +.gc-current-time-line__circle { + width: 8px; + height: 8px; + border-radius: 50%; + background: #ea4335; + position: absolute; + left: -4px; + top: -3px; +} + +/* Resource Column container */ +.gc-resource-column { + border-right: 1px solid #dadce0; + position: relative; + height: 100%; + display: flex; + flex-direction: column; +} + +.gc-resource-column:last-child { + border-right: none; +} + +/* Grid Cell block (hour slot) */ +.gc-grid-slot-cell { + height: 72px; /* Matching gc-hour-cell height */ + border-bottom: 1px solid #e8eaed; + position: relative; + box-sizing: border-box; +} + +.gc-slot-click-zone { + width: 100%; + height: 100%; + cursor: pointer; +} + +.gc-slot-click-zone:hover { + background: rgba(26, 115, 232, 0.04); +} + +/* Google Calendar Style Events (Pastel blocks) */ +.gc-event { + position: absolute; + inset: 4px; + border-radius: 4px; + padding: 6px 8px; display: flex; flex-direction: column; gap: 2px; + font-size: 11px; + overflow: hidden; + box-shadow: 0 1px 2px rgba(60,64,67,0.15); + box-sizing: border-box; + cursor: not-allowed; + user-select: none; } -.ih-activity-text { +.gc-event__title { + font-weight: 500; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.gc-event__time { + opacity: 0.8; + font-size: 9.5px; +} + +/* Pastel Colors per column to make it visually attractive and like Google Calendar */ +.gc-event--color-0 { + background: #d2e3fc; /* Soft Blue */ + color: #185abc; + border-left: 4px solid #1a73e8; +} + +.gc-event--color-1 { + background: #e6f4ea; /* Soft Green */ + color: #137333; + border-left: 4px solid #0f9d58; +} + +.gc-event--color-2 { + background: #fef7e0; /* Soft Yellow */ + color: #b06000; + border-left: 4px solid #f4b400; +} + +.gc-event--color-3 { + background: #f3e5f5; /* Soft Purple */ + color: #7b1fa2; + border-left: 4px solid #ab47bc; +} + +.gc-event-flex-avatars { + position: absolute; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + background: rgba(26, 115, 232, 0.02); +} + +.gc-event-flex-avatars:hover { + background: rgba(26, 115, 232, 0.06); +} + +.gc-mini-avatar { + width: 24px; + height: 24px; + border-radius: 50%; + border: 1.5px solid #ffffff; + margin-left: -6px; + object-fit: cover; + box-shadow: 0 1px 3px rgba(0,0,0,0.15); +} + +.gc-mini-avatar:first-child { + margin-left: 0; +} + +/* Empty state styling */ +.gc-empty-state { + position: absolute; + inset: 0; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 16px; + background: #ffffff; + z-index: 5; + color: #5f6368; +} + +.gc-empty-state__icon { + font-size: 48px; + color: #dadce0; +} + +/* ── SIDEBAR DERECHO (48px) ── */ +.gc-right-sidebar { + width: 48px; + border-left: 1px solid #dadce0; + background: #ffffff; + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; + padding: 16px 0 8px; + box-sizing: border-box; + flex-shrink: 0; +} + +.gc-right-sidebar__icons { + display: flex; + flex-direction: column; + align-items: center; + gap: 20px; + width: 100%; +} + +.gc-right-sidebar__btn { + background: transparent; + border: none; + border-radius: 50%; + width: 36px; + height: 36px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + outline: none; + transition: background-color 0.15s; +} + +.gc-right-sidebar__btn:hover { + background: #f1f3f4; +} + +.gc-right-sidebar__btn img { + width: 20px; + height: 20px; +} + +.gc-right-sidebar__divider { + width: 20px; + height: 1px; + background: #dadce0; + margin: 4px 0; +} + +.gc-right-sidebar__btn--plus { + color: #5f6368; +} + +.gc-right-sidebar__btn--plus span { + font-size: 20px; +} + +.gc-right-sidebar__btn--chevron { + color: #5f6368; +} + +.gc-right-sidebar__btn--chevron span { + font-size: 18px; +} + +/* ── INTERACTIVE EVENT CREATION POPUP ── */ +.gc-popup-card { + position: absolute; + top: -45px; + left: 20px; + width: 280px; + background: #ffffff; + border-radius: 8px; + box-shadow: 0 24px 38px 3px rgba(0,0,0,0.14), 0 9px 46px 8px rgba(0,0,0,0.12), 0 11px 15px -7px rgba(0,0,0,0.2); + z-index: 100; + display: flex; + flex-direction: column; + box-sizing: border-box; + border: 1px solid #dadce0; +} + +.gc-popup-card__header { + height: 36px; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 8px 0 12px; + background: #f1f3f4; + border-bottom: 1px solid #dadce0; + border-top-left-radius: 8px; + border-top-right-radius: 8px; +} + +.gc-popup-card__drag { + font-size: 18px; + color: #70757a; + cursor: move; +} + +.gc-popup-card__close-btn { + background: transparent; + border: none; + font-size: 12px; + color: #5f6368; + cursor: pointer; + width: 24px; + height: 24px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; +} + +.gc-popup-card__close-btn:hover { + background: #dadce0; +} + +.gc-popup-card__body { + padding: 16px; + display: flex; + flex-direction: column; + gap: 12px; +} + +.gc-popup-card__title { + font-size: 16px; + font-weight: 500; + color: #202124; + margin: 0 0 4px; + font-family: 'Google Sans', Roboto, sans-serif; +} + +.gc-popup-card__row { + display: flex; + gap: 12px; + align-items: center; + font-size: 12.5px; + color: #3c4043; +} + +.gc-popup-card__icon { + font-size: 18px; + color: #5f6368; +} + +.gc-popup-card__details { + display: flex; + flex-direction: column; +} + +.gc-popup-card__time { font-size: 11.5px; - color: #475569; - margin: 0; - line-height: 1.4; + color: #70757a; } -.ih-activity-text strong { - color: #0f172a; -} - -.ih-activity-time { +.gc-popup-card__tag { + background: #e8eaed; + padding: 2px 6px; + border-radius: 4px; font-size: 10px; - color: #94a3b8; + font-weight: bold; + color: #3c4043; } -.animate-fadeIn { - animation: fadeIn 0.2s ease-out forwards; +.gc-popup-card__actions { + display: flex; + justify-content: flex-end; + gap: 8px; + padding: 8px 12px 12px; + border-top: 1px solid #f1f3f4; } -@keyframes fadeIn { - from { opacity: 0; transform: translateY(4px); } - to { opacity: 1; transform: translateY(0); } +.gc-popup-btn-secondary { + background: transparent; + border: none; + border-radius: 4px; + color: #1a73e8; + font-size: 13px; + font-weight: 500; + padding: 6px 12px; + cursor: pointer; +} + +.gc-popup-btn-secondary:hover { + background: rgba(26, 115, 232, 0.04); +} + +.gc-popup-btn-primary { + background: #1a73e8; + border: none; + border-radius: 4px; + color: #ffffff; + font-size: 13px; + font-weight: 500; + padding: 6px 16px; + cursor: pointer; + box-shadow: 0 1px 2px rgba(60,64,67,0.3), 0 1px 3px 1px rgba(60,64,67,0.15); +} + +.gc-popup-btn-primary:hover { + background: #185abc; + box-shadow: 0 1px 3px rgba(60,64,67,0.3), 0 2px 6px 2px rgba(60,64,67,0.15); } \ No newline at end of file diff --git a/frontend/src/app/features/reservas/calendar-booking/calendar-booking.component.html b/frontend/src/app/features/reservas/calendar-booking/calendar-booking.component.html index 6ac32a1..0bd67ec 100644 --- a/frontend/src/app/features/reservas/calendar-booking/calendar-booking.component.html +++ b/frontend/src/app/features/reservas/calendar-booking/calendar-booking.component.html @@ -1,201 +1,320 @@ -
+
- - -
+ +
+
+ + + + + + +
+ + +
+ +

Junio de 2026

+
- -
-
-

RESERVAS DE ESPACIOS

+
+ +
+ + + + + +
+ + + + +
+ +
+ + +
JM
+
+
+ + +
+ + +
- - -
- -
-
+ +
+
+ Mis Espacios + keyboard_arrow_up +
+ +
+ -
-

Calendario de Espacios

- - -
- - - -
-
+ + + + + +
+
- -
-
-
- - - @for (res of filteredResources(); track res.id) { -
-
- {{ res.icon }} -
- {{ res.name }} - {{ res.desc }} -
-
-
- } -
- - -
- @for (time of timeSlots; track time) { -
- -
{{ time }}
- - - @for (res of filteredResources(); track res.id) { -
- - @if (isSlotOccupied(res.name, time)) { - -
- Ocupado -
- } @else { - - @if (res.name === 'OFICINA FLEX A1' && time === '12:00') { -
- emp - emp -
- } @else if (res.name === 'OFICINA FLEX A1' && time === '13:30') { -
- emp -
- } @else { - -
- } - } - - - @if (selectedSlot()?.resource?.id === res.id && selectedSlot()?.time === time) { -
-
-

{{ res.name }}

- -
-

Available {{ time }} - {{ getEndTime(time) }}

- Capacidad {{ res.capacity }} - -
- - -
- - - - Disponibilidad, disponible - -
- } - -
- } -
- } -
-
- - @if (filteredResources().length === 0) { -
- No se encontraron recursos disponibles en esta sección. + +
+
+ Actividad de Reservas + keyboard_arrow_up +
+
+ @for (act of recentActivities(); track act.title) { +
+ user +
+ {{ act.title }} + {{ act.detail }} + {{ act.time }} +
} -
- - -
-
-

Mis Reservas y Notificaciones

+ + + + +
+ + +
+ +
+ GMT-04 +
+ + +
+ @for (res of filteredResources(); track res.id; let idx = $index) { +
+ {{ res.type }} +
+ {{ res.icon }} +
+ {{ res.name }} +
+ } +
+
+ + +
+
-
- @for (act of recentActivities(); track act.title) { -
- @if (act.type === 'reserva') { - res -
-

{{ act.title }}
{{ act.detail }}

- {{ act.time }} -
- } @else { - notif -
-

David Chen compartió Resultados del Trimestre

- {{ act.time }} -
- } + +
+ @for (time of timeSlots; track time) { +
+ {{ time }}
}
+ + +
+ + +
+
+
+ + + @for (res of filteredResources(); track res.id; let colIdx = $index) { +
+ + @for (time of timeSlots; track time) { +
+ + @if (isSlotOccupied(res.name, time)) { + +
+
Reservado / Ocupado
+
{{ time }} - {{ getEndTime(time) }}
+
+ } @else { + + + @if (res.name === 'OFICINA FLEX A1' && time === '12:00') { +
+ emp + emp +
+ } @else if (res.name === 'OFICINA FLEX A1' && time === '13:30') { +
+ emp +
+ } @else { + +
+ } + + } + + + @if (selectedSlot()?.resource?.id === res.id && selectedSlot()?.time === time) { +
+
+ drag_handle + +
+ +
+

{{ res.name }}

+
+ schedule +
+ Martes, 16 de Junio + {{ time }} – {{ getEndTime(time) }} +
+
+ +
+ room + Capacidad máxima: {{ res.capacity }} personas +
+ +
+ info_outline + {{ res.type }} +
+
+ +
+ + +
+
+ } + +
+ } + +
+ } + +
+ + @if (filteredResources().length === 0) { +
+ calendar_today +

No hay recursos seleccionados. Marque las categorías en el panel izquierdo.

+
+ } -
+
+ + + -
+
\ No newline at end of file diff --git a/frontend/src/app/features/reservas/calendar-booking/calendar-booking.component.ts b/frontend/src/app/features/reservas/calendar-booking/calendar-booking.component.ts index d0f386a..e059228 100644 --- a/frontend/src/app/features/reservas/calendar-booking/calendar-booking.component.ts +++ b/frontend/src/app/features/reservas/calendar-booking/calendar-booking.component.ts @@ -37,7 +37,7 @@ export class CalendarBookingComponent implements OnInit { ]); // Signals para gestionar estado interactivo - activeCategory = signal('Sala Reuniones'); + selectedCategories = signal(['Sala Reuniones', 'Oficina Flexible', 'Zona Relax', 'Evento']); searchQuery = signal(''); // Slot seleccionado para el popup dinámico @@ -59,12 +59,58 @@ export class CalendarBookingComponent implements OnInit { { title: 'David Chen', detail: 'compartió Resultados del Trimestre', time: 'Hace 15m', type: 'notif', avatar: 'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?auto=format&fit=crop&w=120&q=80' } ]; + // Mini calendar data for June 2026 + miniCalendarDays = [ + { day: 31, currentMonth: false }, + { day: 1, currentMonth: true }, + { day: 2, currentMonth: true }, + { day: 3, currentMonth: true }, + { day: 4, currentMonth: true }, + { day: 5, currentMonth: true }, + { day: 6, currentMonth: true }, + { day: 7, currentMonth: true }, + { day: 8, currentMonth: true }, + { day: 9, currentMonth: true }, + { day: 10, currentMonth: true }, + { day: 11, currentMonth: true }, + { day: 12, currentMonth: true }, + { day: 13, currentMonth: true }, + { day: 14, currentMonth: true }, + { day: 15, currentMonth: true }, + { day: 16, currentMonth: true, active: true }, + { day: 17, currentMonth: true }, + { day: 18, currentMonth: true }, + { day: 19, currentMonth: true }, + { day: 20, currentMonth: true }, + { day: 21, currentMonth: true }, + { day: 22, currentMonth: true }, + { day: 23, currentMonth: true }, + { day: 24, currentMonth: true }, + { day: 25, currentMonth: true }, + { day: 26, currentMonth: true }, + { day: 27, currentMonth: true }, + { day: 28, currentMonth: true }, + { day: 29, currentMonth: true }, + { day: 30, currentMonth: true }, + { day: 1, currentMonth: false }, + { day: 2, currentMonth: false }, + { day: 3, currentMonth: false }, + { day: 4, currentMonth: false }, + { day: 5, currentMonth: false }, + { day: 6, currentMonth: false }, + { day: 7, currentMonth: false }, + { day: 8, currentMonth: false }, + { day: 9, currentMonth: false }, + { day: 10, currentMonth: false }, + { day: 11, currentMonth: false } + ]; + // Computed signals filteredResources = computed(() => { - const cat = this.activeCategory(); + const selectedCats = this.selectedCategories(); const query = this.searchQuery().toLowerCase().trim(); return this.resources().filter(r => - r.type === cat && + selectedCats.includes(r.type) && (!query || r.name.toLowerCase().includes(query) || r.desc.toLowerCase().includes(query)) ); }); @@ -95,9 +141,19 @@ export class CalendarBookingComponent implements OnInit { } } - setCategory(cat: string): void { - this.activeCategory.set(cat); - this.selectedSlot.set(null); // Reset popup al cambiar pestaña + toggleCategory(cat: string): void { + this.selectedCategories.update(prev => { + if (prev.includes(cat)) { + return prev.filter(c => c !== cat); + } else { + return [...prev, cat]; + } + }); + this.selectedSlot.set(null); // Reset popup al cambiar filtros + } + + isCategorySelected(cat: string): boolean { + return this.selectedCategories().includes(cat); } onSearch(event: Event): void { diff --git a/frontend/src/app/features/workflows/workflows.component.ts b/frontend/src/app/features/workflows/workflows.component.ts index 74c0125..aeedc53 100644 --- a/frontend/src/app/features/workflows/workflows.component.ts +++ b/frontend/src/app/features/workflows/workflows.component.ts @@ -237,63 +237,39 @@ import { Router } from '@angular/router'; `, styles: [` + :host { + display: flex; + flex-direction: column; + flex: 1; + min-height: 0; + height: 100%; + } + /* ── LAYOUT PRINCIPAL ── */ .wf-shell { display: flex; background: #f4f3ef; /* Light beige/grey background */ - min-height: 90vh; + height: 100%; border-radius: 24px; overflow: hidden; border: 1px solid rgba(15, 13, 10, 0.08); box-shadow: 0 4px 20px rgba(0, 0, 0, 0.02); font-family: 'Outfit', 'Inter', system-ui, sans-serif; - } - - /* Sidebar */ - .wf-sidebar { - width: 90px; - background: #000000; - display: flex; - flex-direction: column; - align-items: center; - padding: 24px 0; - flex-shrink: 0; - } - - .wf-sidebar__brand { - font-size: 11px; - font-weight: 900; - letter-spacing: 0.12em; - color: rgba(255, 255, 255, 0.4); - margin-bottom: 24px; - } - - .wf-sidebar__logo-container { - width: 44px; - height: 44px; - border-radius: 12px; - background: #ffffff; - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - } - - .wf-sidebar__logo-btn { - font-size: 18px; - font-weight: 900; - color: #000000; + flex: 1; + min-height: 0; } /* Content Area */ .wf-content { flex-grow: 1; - padding: 24px; + padding: 12px 16px; display: flex; flex-direction: column; - gap: 20px; + gap: 12px; min-width: 0; position: relative; + height: 100%; + overflow: hidden; } /* Topbar */ @@ -396,7 +372,11 @@ import { Router } from '@angular/router'; .wf-grid { display: grid; grid-template-columns: 1fr; - gap: 24px; + gap: 16px; + flex: 1; + overflow-y: auto; + min-height: 0; + padding: 4px; /* avoid box-shadow clipping */ } @media (min-width: 1024px) {