// ============================================================================= // Styles specific to PlanningPage — colocated next to PlanningPage.tsx since // nothing else uses these classes. Ported from the reviewed HTML mockup // (see the plan file / PR description) onto the app's real design tokens — // no light/dark duplication needed here, unlike the standalone mockup: // every `var(--color-*)` below already resolves per-theme globally (see // styles/_theme.scss). // ============================================================================= // `.app-content` (AppLayout.scss) already stretches to the full viewport // height (flex item of `.app-layout`, itself `min-height: 100vh` — the // same stretch the sidebar relies on to pin its footer at the bottom). // `.planning-page` just needs to fill that box and lay out as a column so // `.planning-grid-wrapper` can grow to fill whatever's left under the // header, instead of the grid being only as tall as its content. .planning-page { height: 100%; display: flex; flex-direction: column; &__header { flex-shrink: 0; display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: var(--space-md); margin-bottom: var(--space-lg); } &__status { color: var(--color-text-muted); font-size: var(--font-size-md); } &__status--error { color: var(--color-error); } } // --- Week navigator (arrows + clickable label opening the calendar) ------- .week-nav { position: relative; display: flex; align-items: center; gap: var(--space-xs); &__arrow { width: 2rem; height: 2rem; display: grid; place-items: center; border: 1px solid var(--color-border); border-radius: var(--radius-base); background: var(--color-surface); color: var(--color-text); font-size: var(--font-size-md); cursor: pointer; &:hover { background: var(--color-surface-alt); } } &__label { display: flex; align-items: center; gap: var(--space-xs); padding: 0.45rem var(--space-md); border: 1px solid var(--color-border); border-radius: var(--radius-base); background: var(--color-surface); color: var(--color-text); font-weight: 600; font-size: var(--font-size-sm); cursor: pointer; &:hover { background: var(--color-surface-alt); } } } .today-badge { font-size: var(--font-size-xs); font-weight: 600; color: var(--color-primary); background: color-mix(in srgb, var(--color-primary) 14%, transparent); padding: 0.1rem 0.4rem; border-radius: var(--radius-pill); } // --- Calendar popover ------------------------------------------------------- .calendar-popover { position: absolute; top: calc(100% + var(--space-xs)); right: 0; z-index: 10; width: 18rem; padding: var(--space-md); background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-md); box-shadow: var(--shadow-md); &__header { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-sm); font-weight: 700; font-size: var(--font-size-sm); text-transform: capitalize; button { width: 1.6rem; height: 1.6rem; border: none; background: none; cursor: pointer; font-size: var(--font-size-base); color: var(--color-text-muted); border-radius: var(--radius-base); &:hover { background: var(--color-surface-alt); } } } } .calendar-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; &__weekday { text-align: center; font-size: var(--font-size-xs); color: var(--color-text-muted); font-weight: 600; padding-bottom: var(--space-xs); } &__day { aspect-ratio: 1; display: grid; place-items: center; font-size: var(--font-size-sm); border-radius: var(--radius-base); cursor: pointer; color: var(--color-text); border: none; background: none; font: inherit; &:hover { background: var(--color-surface-alt); } &--muted { color: var(--color-border); } &--in-selected-week { background: color-mix(in srgb, var(--color-primary) 14%, transparent); border-radius: 0; } &--today { box-shadow: inset 0 0 0 2px var(--color-primary); font-weight: 700; } } } // --- The grid itself -------------------------------------------------------- .planning-grid-wrapper { flex: 1; min-height: 0; overflow: auto; background: var(--color-surface); border-radius: var(--radius-md); box-shadow: var(--shadow-sm); } table.planning-grid { width: 100%; height: 100%; min-width: 62rem; border-collapse: collapse; table-layout: fixed; th, td { border: 1px solid var(--color-border); vertical-align: top; } thead th { padding: var(--space-sm) var(--space-md); background: var(--color-surface-alt); text-align: left; &:first-child { width: 9rem; } .day-name { display: block; font-size: var(--font-size-xs); text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-text-muted); font-weight: 600; } .day-date { display: block; font-size: var(--font-size-md); font-weight: 700; margin-top: 2px; color: var(--color-text); } &.today { background: color-mix(in srgb, var(--color-primary) 10%, var(--color-surface-alt)); .day-date { color: var(--color-primary); } } } tbody th { padding: var(--space-sm) var(--space-md); background: var(--color-surface-alt); text-align: center; vertical-align: middle; font-size: var(--font-size-sm); font-weight: 600; } td.today { background: color-mix(in srgb, var(--color-primary) 4%, var(--color-surface)); } // Repas groupés par moment de la journée (Matin / Midi / Après-midi / // Soir) — piloté uniquement via `border-bottom` (jamais `border-top`) : // avec `border-collapse: collapse`, deux bordures différentes qui se // rencontrent sur la même arête peuvent fusionner de façon ambiguë selon // le navigateur — en désactivant `border-top` sur tbody, chaque arête // horizontale n'est plus définie que d'un seul côté, sans ambiguïté // possible. Toutes les séparations entre repas sont pleines (même couleur // que les séparations de jour) ; seule la frontière entre deux groupes // ("band-end", la dernière ligne d'un groupe) se distingue par une // épaisseur plus marquée. tbody th, tbody td { border-top: none; border-bottom: 1px solid var(--color-border); } tbody tr.band-end th, tbody tr.band-end td { border-bottom: 2px solid var(--color-border); } } // --- Case : pastilles de recette + bouton "+" ------------------------------- .meal-cell { padding: var(--space-sm); } .meal-cell__content { display: flex; flex-direction: column; gap: var(--space-xs); height: 100%; } .meal-cell__recipes { display: flex; flex-direction: column; gap: var(--space-xs); } .recipe-chip { display: flex; align-items: center; gap: var(--space-xs); width: 100%; box-sizing: border-box; padding: 0.3rem var(--space-sm); border-radius: var(--radius-pill); background: var(--color-tag); color: var(--color-tag-ink); font-size: var(--font-size-xs); font-weight: 600; &__name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } &__remove { flex-shrink: 0; width: 1rem; height: 1rem; display: grid; place-items: center; border: none; background: none; cursor: pointer; color: inherit; opacity: 0; font-size: 0.65rem; border-radius: 50%; } &:hover &__remove { opacity: 0.7; } &__remove:hover { opacity: 1; background: rgba(0, 0, 0, 0.15); } } // Pleine largeur, sans bordure (juste un fond au survol — plus épuré qu'un // contour pointillé), et toujours collé en haut de la case (juste sous la // dernière recette s'il y en a), jamais centré au milieu d'une case vide. .add-recipe-btn { width: 100%; box-sizing: border-box; padding: 0.35rem; display: flex; align-items: center; justify-content: center; border: none; border-radius: var(--radius-base); background: none; color: var(--color-text-muted); font-size: var(--font-size-base); line-height: 1; cursor: pointer; &:hover { color: var(--color-primary); background: color-mix(in srgb, var(--color-primary) 8%, transparent); } }