/* Main Styles */ :root { --primary-color: #4a90e2; --secondary-color: #f5f5f5; --text-color: #333; --border-color: #ddd; --fh-duration-fast: 0.18s; --fh-duration-med: 0.28s; --fh-ease-out: cubic-bezier(0.22, 1, 0.36, 1); --fh-shadow-tab: 0 2px 8px rgba(15, 23, 42, 0.12); --fh-shadow-tab-md: 0 3px 12px rgba(15, 23, 42, 0.14); --fh-shadow-raised: 0 1px 2px rgba(15, 23, 42, 0.06), 0 4px 14px rgba(15, 23, 42, 0.06), inset 0 1px 0 rgba(255, 255, 255, 0.55); --fh-shadow-lift: 0 4px 8px rgba(15, 23, 42, 0.08), 0 12px 28px rgba(15, 23, 42, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.55); } @keyframes fh-content-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } } body.family-hub-body { font-family: "Figtree", system-ui, -apple-system, sans-serif; line-height: 1.6; margin: 0; padding: 0; color: var(--text-color); } main { min-height: 100vh; } .app-header { background: linear-gradient(135deg, var(--person-accent, #4a90e2) 0%, #2c5282 100%); } /* Header top: title (left) ยท balance + persona (right from md up); mobile: second row = persona menu */ .app-header-top { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 0.75rem; row-gap: 0.5rem; align-items: center; } .app-header-brand { grid-column: 1; grid-row: 1; min-width: 0; } .app-header-actions { grid-column: 2; grid-row: 1; justify-self: end; max-width: 100%; } .app-header-persona-mobile { grid-column: 1 / -1; grid-row: 2; } @media (min-width: 768px) { .app-header-persona-mobile { display: none; } .app-header-top { row-gap: 0.35rem; } } .persona-chip { min-height: 2.75rem; touch-action: manipulation; transition: background-color var(--fh-duration-fast) var(--fh-ease-out), border-color var(--fh-duration-fast) var(--fh-ease-out), color var(--fh-duration-fast) var(--fh-ease-out), box-shadow var(--fh-duration-med) var(--fh-ease-out), transform var(--fh-duration-med) var(--fh-ease-out); } .persona-chip i { display: inline-block; transition: transform var(--fh-duration-med) var(--fh-ease-out); } @media (hover: hover) and (pointer: fine) { .persona-chip:not(:disabled):hover, .persona-chip:not(:disabled):focus-visible { transform: translateY(-1px); box-shadow: var(--fh-shadow-tab); } .persona-chip:not(:disabled):hover i, .persona-chip:not(:disabled):focus-visible i { transform: scale(1.08); } .persona-chip.btn-light.active:hover, .persona-chip.btn-light.active:focus-visible { transform: translateY(-1px); box-shadow: var(--fh-shadow-tab-md); } } .persona-chip.active { font-weight: 600; box-shadow: 0 0 0 0.15rem rgba(255, 255, 255, 0.35); } .persona-chip-mobile { transition: background-color var(--fh-duration-fast) var(--fh-ease-out), transform var(--fh-duration-med) var(--fh-ease-out); } .persona-chip-mobile i { display: inline-block; transition: transform var(--fh-duration-med) var(--fh-ease-out); } @media (hover: hover) and (pointer: fine) { .persona-chip-mobile:hover i, .persona-chip-mobile:focus-visible i { transform: scale(1.06); } } .persona-chip-mobile.active { font-weight: 600; background-color: rgba(74, 144, 226, 0.14); } .app-header .app-header-actions .dropdown-toggle { transition: background-color var(--fh-duration-fast) var(--fh-ease-out), box-shadow var(--fh-duration-med) var(--fh-ease-out), transform var(--fh-duration-med) var(--fh-ease-out); } @media (hover: hover) and (pointer: fine) { .app-header .app-header-actions .dropdown-toggle:hover, .app-header .app-header-actions .dropdown-toggle:focus-visible { transform: translateY(-1px); box-shadow: var(--fh-shadow-tab); } } .app-header-balance { transition: box-shadow var(--fh-duration-med) var(--fh-ease-out), transform var(--fh-duration-med) var(--fh-ease-out); } @media (hover: hover) and (pointer: fine) { .app-header-balance:hover { transform: translateY(-1px); box-shadow: var(--fh-shadow-tab); } } .chore-thumb { max-height: 180px; object-fit: cover; } .meal-hero { max-height: 320px; width: 100%; object-fit: cover; } .chore-card .card-body { display: flex; flex-direction: column; } .grocery-store-nav .nav-link { text-align: left; touch-action: manipulation; border-radius: 0.45rem; transition: background-color var(--fh-duration-fast) var(--fh-ease-out), color var(--fh-duration-fast) var(--fh-ease-out), box-shadow var(--fh-duration-med) var(--fh-ease-out), transform var(--fh-duration-med) var(--fh-ease-out), border-color var(--fh-duration-fast) var(--fh-ease-out); } @media (hover: hover) and (pointer: fine) { .grocery-store-nav .nav-link:hover, .grocery-store-nav .nav-link:focus-visible { transform: translateX(2px); box-shadow: 0 2px 8px rgba(15, 23, 42, 0.08); } } .grocery-line-thumb { width: 56px; height: 56px; object-fit: cover; } .container { max-width: 1200px; margin: 0 auto; padding: 20px; } /* Main area: cards depth & accent border */ .family-hub-body main .card { border-radius: 0.55rem; border-color: var(--border-color); box-shadow: var(--fh-shadow-raised); transition: transform var(--fh-duration-med) var(--fh-ease-out), box-shadow var(--fh-duration-med) var(--fh-ease-out), border-color var(--fh-duration-fast) var(--fh-ease-out); } @supports (color: color-mix(in srgb, #fff 50%, #000)) { .family-hub-body main .card { border-color: color-mix(in srgb, var(--person-accent, #4a90e2) 14%, var(--border-color)); } } @media (hover: hover) and (pointer: fine) { .family-hub-body main .card:hover { transform: translateY(-2px); box-shadow: var(--fh-shadow-lift); } } @supports (color: color-mix(in srgb, #fff 50%, #000)) { .family-hub-body main .card:focus-within { border-color: color-mix(in srgb, var(--person-accent, #4a90e2) 28%, var(--border-color)); box-shadow: var(--fh-shadow-lift), 0 0 0 3px color-mix(in srgb, var(--person-accent, #4a90e2) 32%, transparent); outline: none; } } @supports not (color: color-mix(in srgb, #fff 50%, #000)) { .family-hub-body main .card:focus-within { box-shadow: var(--fh-shadow-lift); outline: 2px solid var(--person-accent, #4a90e2); outline-offset: 2px; } } /* Solid (non-subtle) colored card headers: drop inset highlight */ .family-hub-body main .card:has(> .card-header.bg-dark), .family-hub-body main .card:has(> .card-header[class*="bg-"]:not(.bg-light):not(.bg-white):not([class*="-subtle"])) { box-shadow: 0 1px 2px rgba(15, 23, 42, 0.08), 0 4px 14px rgba(15, 23, 42, 0.07); } @media (hover: hover) and (pointer: fine) { .family-hub-body main .card:has(> .card-header.bg-dark):hover, .family-hub-body main .card:has(> .card-header[class*="bg-"]:not(.bg-light):not(.bg-white):not([class*="-subtle"])):hover { box-shadow: 0 4px 8px rgba(15, 23, 42, 0.12), 0 12px 24px rgba(15, 23, 42, 0.1); } } /* Tab panel entrance */ @media (prefers-reduced-motion: no-preference) { #dashboardContentArea.tab-content { animation: fh-content-in 0.3s var(--fh-ease-out) both; } } /* Buttons (main only); flatten in button groups */ .family-hub-body main .btn { transition: transform var(--fh-duration-fast) var(--fh-ease-out), box-shadow var(--fh-duration-fast) var(--fh-ease-out), background-color var(--fh-duration-fast) var(--fh-ease-out), border-color var(--fh-duration-fast) var(--fh-ease-out), color var(--fh-duration-fast) var(--fh-ease-out); } @media (hover: hover) and (pointer: fine) { .family-hub-body main .btn:hover:not(:disabled):not(.disabled) { transform: translateY(-1px); box-shadow: 0 3px 10px rgba(15, 23, 42, 0.12); } } .family-hub-body main .btn:focus-visible:not(:disabled):not(.disabled) { transform: translateY(-1px); } .family-hub-body main .btn:active:not(:disabled):not(.disabled) { transform: scale(0.98); box-shadow: none; } .family-hub-body main .btn-group .btn, .family-hub-body main .btn-group-vertical .btn { box-shadow: none; } @media (hover: hover) and (pointer: fine) { .family-hub-body main .btn-group .btn:hover:not(:disabled), .family-hub-body main .btn-group .btn:focus-visible:not(:disabled), .family-hub-body main .btn-group-vertical .btn:hover:not(:disabled), .family-hub-body main .btn-group-vertical .btn:focus-visible:not(:disabled) { transform: none; z-index: 2; } } .family-hub-body main .btn-group .btn:active:not(:disabled), .family-hub-body main .btn-group-vertical .btn:active:not(:disabled) { transform: scale(0.98); } .family-hub-body main .badge { transition: transform var(--fh-duration-fast) var(--fh-ease-out), box-shadow var(--fh-duration-fast) var(--fh-ease-out); } @media (hover: hover) and (pointer: fine) { .family-hub-body main a.badge:hover, .family-hub-body main a.badge:focus-visible { transform: scale(1.03); } } /* Header tab nav */ .app-header.app-header-with-tabs .tabs { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.35rem; margin-bottom: 0; } @media (min-width: 768px) { .app-header.app-header-with-tabs .app-header-top { margin-bottom: 0.35rem; } .app-header.app-header-with-tabs .tabs { margin-top: 1.1rem; } } .app-header .tab { display: inline-flex; align-items: center; gap: 0.45rem; min-height: 2.5rem; padding: 0.45rem 0.9rem; border-radius: 999px; border: 1px solid transparent; text-decoration: none; font-weight: 500; transition: background-color var(--fh-duration-fast) var(--fh-ease-out), color var(--fh-duration-fast) var(--fh-ease-out), border-color var(--fh-duration-fast) var(--fh-ease-out), box-shadow var(--fh-duration-med) var(--fh-ease-out), transform var(--fh-duration-med) var(--fh-ease-out); } .app-header .tab i { display: inline-block; transition: transform var(--fh-duration-med) var(--fh-ease-out); } @media (hover: hover) and (pointer: fine) { body.header-tone-dark .app-header .tab:hover, body.header-tone-dark .app-header .tab:focus-visible { transform: translateY(-1px); box-shadow: var(--fh-shadow-tab); } body.header-tone-light .app-header .tab:hover, body.header-tone-light .app-header .tab:focus-visible { transform: translateY(-1px); box-shadow: var(--fh-shadow-tab); } .app-header .tab:hover i, .app-header .tab:focus-visible i { transform: scale(1.08); } } @media (min-width: 768px) and (hover: hover) and (pointer: fine) { .app-header .tab:hover, .app-header .tab:focus-visible { transform: translateY(-1px) scale(1.02); } } body.header-tone-dark .app-header .tab { color: rgba(255, 255, 255, 0.92); background: rgba(255, 255, 255, 0.12); border-color: rgba(255, 255, 255, 0.28); } body.header-tone-dark .app-header .tab:hover, body.header-tone-dark .app-header .tab:focus-visible { color: #fff; background: rgba(255, 255, 255, 0.2); border-color: rgba(255, 255, 255, 0.45); } body.header-tone-dark .app-header .tab.active { color: #1f2a37; background: rgba(255, 255, 255, 0.92); border-color: rgba(255, 255, 255, 0.96); } body.header-tone-light .app-header .tab { color: #1f2a37; background: rgba(255, 255, 255, 0.5); border-color: rgba(31, 42, 55, 0.25); } body.header-tone-light .app-header .tab:hover, body.header-tone-light .app-header .tab:focus-visible { color: #111827; background: rgba(255, 255, 255, 0.7); border-color: rgba(31, 42, 55, 0.4); } body.header-tone-light .app-header .tab.active { color: #fff; background: #1f2a37; border-color: #1f2a37; } /* Mobile Responsive */ @media (max-width: 768px) { .container { padding: 10px; } .app-header h1.h3 { font-size: 1.3rem; } .user-balance { max-width: 58vw; } .app-header .tabs { gap: 0.4rem; } .app-header .tab { padding: 0.4rem 0.8rem; min-height: 2.3rem; } } .calendar-agenda-list .calendar-agenda-day:first-child .list-group-item.border-top { border-top: none !important; } .calendar-agenda-today { background-color: rgba(74, 144, 226, 0.06); } /* Calendar tab: Google column first; side-by-side 70% / 30% from xl up when embed is configured */ @media (min-width: 1200px) { .calendar-tab-layout-split > .calendar-tab-google { flex: 0 0 70%; max-width: 70%; width: 70%; } .calendar-tab-layout-split > .calendar-tab-agenda { flex: 0 0 30%; max-width: 30%; width: 30%; } } .calendar-tv-view .calendar-embed iframe { min-height: 70vh; } @media (min-width: 1200px) { .calendar-tv-view .calendar-embed iframe { min-height: 78vh; } } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; } }