// ============================================================================= // Styles specific to CookingSessionPage — colocated next to // CookingSessionPage.tsx since nothing else uses these classes. // // Layout: a fixed page shell (header + subtitle + tab bar), then one of two // tab panels. The "Recettes" panel is a plain scrolling list; the "Plan" // panel (`.cooking-plan`) is itself a flex column — a pinned stepper and // meta line on top, a pinned prev/next bar at the bottom, and the current // phase scrolling in between so the nav is always reachable. // // Every value goes through a `var(--token)` from _theme.scss; light/dark is // handled entirely by those tokens being redefined, nothing here branches // on the theme. // ============================================================================= .cooking-session-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-sm); } &__subtitle { flex-shrink: 0; margin: 0 0 var(--space-md); color: var(--color-text-muted); font-size: var(--font-size-md); } &__status { color: var(--color-text-muted); font-size: var(--font-size-md); } &__status--error { color: var(--color-error); } // --- Tab bar --------------------------------------------------------------- // Same underline-tab language as the recipe catalog's `.recipe-tabs` // (features/recipes/recipes.scss): scrolls within itself rather than // widening the page (global.scss forbids a horizontal body scroll). &__tabs { flex-shrink: 0; display: flex; gap: var(--space-xs); overflow-x: auto; border-bottom: 1px solid var(--color-border); margin-bottom: var(--space-md); } &__tab { appearance: none; flex-shrink: 0; padding: var(--space-sm) var(--space-md); font-family: var(--font-display); font-size: var(--font-size-sm); font-weight: 700; letter-spacing: 0.02em; color: var(--color-text-muted); background: none; border: none; border-bottom: 2.5px solid transparent; cursor: pointer; transition: color 0.15s ease, border-color 0.15s ease; &:hover { color: var(--color-text); } &.active { color: var(--color-primary); border-color: var(--color-primary); } } } // --- "Recettes" tab --------------------------------------------------------- // The week's planned recipes as a flat list — name, its own portion count, // and a jump to the recipe's page. Deliberately thin: `plan.recipes` only // carries `{recipeId, name, portions}`. .cooking-recipes { flex: 1; min-height: 0; overflow-y: auto; list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-xs); &__item { display: flex; align-items: center; gap: var(--space-sm); padding: var(--space-sm) var(--space-md); background: var(--color-surface); border-radius: var(--radius-md); box-shadow: var(--shadow-sm); } &__name { font-weight: 600; color: var(--color-text); } &__portions { padding: 0.1rem var(--space-sm); border-radius: var(--radius-pill); background: var(--color-surface-alt); font-size: var(--font-size-sm); color: var(--color-text-muted); font-variant-numeric: tabular-nums; } // Pushed to the trailing edge — a quiet secondary action, not the point // of the row. &__link { margin-left: auto; flex-shrink: 0; font-size: var(--font-size-sm); font-weight: 600; color: var(--color-primary); } } // --- "Plan" tab ----------------------------------------------------------- .cooking-plan { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: var(--space-md); // Meta line under the stepper: "Étape 2 / 4 · Cuisson" on the left, the // "{done} / {total} tâches" counter on the right. &__meta { flex-shrink: 0; display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: var(--space-sm); } &__position { font-family: var(--font-display); font-weight: 700; font-size: var(--font-size-md); color: var(--color-text); } &__count { font-size: var(--font-size-sm); color: var(--color-text-muted); font-variant-numeric: tabular-nums; } // The current phase scrolls; everything around it stays put. .cooking-phase { flex: 1; min-height: 0; overflow-y: auto; } &__nav { flex-shrink: 0; display: flex; justify-content: space-between; gap: var(--space-sm); } &__nav-btn { appearance: none; padding: var(--space-sm) var(--space-lg); border: 1.5px solid var(--color-primary); border-radius: var(--radius-base); background: var(--color-surface); color: var(--color-primary); font-family: var(--font-display); font-weight: 700; font-size: var(--font-size-sm); cursor: pointer; transition: background-color 0.15s ease, opacity 0.15s ease; &:hover:not(:disabled) { background: color-mix(in srgb, var(--color-primary) 10%, var(--color-surface)); } &:disabled { opacity: 0.4; cursor: not-allowed; } } } // --- Stepper -------------------------------------------------------------- // One clickable node per phase, in a row that scrolls sideways within // itself when the phases don't all fit. A thin connector sits between // consecutive nodes. .cooking-stepper { flex-shrink: 0; list-style: none; margin: 0; padding: 0 0 var(--space-xs); display: flex; gap: var(--space-xs); overflow-x: auto; &__step { flex: 0 0 auto; display: flex; align-items: center; &:not(:last-child)::after { content: ""; width: var(--space-md); height: 2px; background: var(--color-border); margin: 0 var(--space-xs); } } &__node { appearance: none; display: flex; align-items: center; gap: var(--space-xs); padding: var(--space-xs) var(--space-sm); border: 1.5px solid var(--color-border); border-radius: var(--radius-pill); background: var(--color-surface); color: var(--color-text-muted); font-family: var(--font-display); font-size: var(--font-size-sm); font-weight: 700; white-space: nowrap; cursor: pointer; transition: color 0.15s ease, border-color 0.15s ease, background-color 0.15s ease; &:hover { color: var(--color-text); border-color: var(--color-primary); } // The phase currently on screen. &--current { color: var(--color-primary); border-color: var(--color-primary); background: color-mix(in srgb, var(--color-primary) 10%, var(--color-surface)); } // Every task in the phase is ticked. &--done { color: var(--color-success); border-color: var(--color-success); } } // The leading circle — a step number, or a check once the phase is done. &__marker { display: inline-flex; align-items: center; justify-content: center; width: 1.4rem; height: 1.4rem; border-radius: var(--radius-pill); background: var(--color-surface-alt); font-size: var(--font-size-xs); font-variant-numeric: tabular-nums; } &__node--current &__marker { background: var(--color-primary); color: var(--color-surface); } &__node--done &__marker { background: var(--color-success); color: var(--color-surface); } } // --- One phase ---------------------------------------------------------------- .cooking-phase { display: flex; flex-direction: column; gap: var(--space-sm); // A phase-level caveat — today only the "four requis à 2 températures" // conflict. A tinted callout in the accent colour so it reads as a // heads-up, not a plain paragraph. &__note { margin: 0; padding: var(--space-sm) var(--space-md); border-left: 3px solid var(--color-accent); border-radius: 0 var(--radius-md) var(--radius-md) 0; background: color-mix(in srgb, var(--color-accent) 10%, var(--color-surface)); color: var(--color-text); font-size: var(--font-size-sm); font-weight: 600; } // "Pendant ce temps" — passive cooks still running from earlier phases. &__background { border-left: 3px solid var(--color-border); padding: var(--space-xs) var(--space-md); color: var(--color-text-muted); font-size: var(--font-size-sm); &-title { display: block; font-weight: 600; margin-bottom: 0.15rem; } ul { margin: 0; padding-left: var(--space-md); } } &__tasks { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-sm); > li { display: flex; } // The task card *is* a shared "selectable card" checkbox label (see // global.scss's `label:has(> input[type="checkbox"])`), so its frame, // hover, focus ring and hidden native input all come from there. The // rules below only set what's task-specific — a top-aligned multi-line // body, the merged-prep accent, and a faded/struck "done" look — and // are kept at `.cooking-phase__tasks` depth on purpose so they outrank // that shared rule's own `&.is-selected` treatment. .cooking-task { flex: 1; align-items: flex-start; } .cooking-task--merged-prep, .cooking-task--merged-setup { border-left: 3px solid var(--color-accent); } // Ticked = done: cancel the shared rule's "selected" green tint/border // (which would clash with the stepper's own green "current" node) and // just fade the card and strike its headline. .cooking-task--done { opacity: 0.7; background: var(--color-surface); border-color: var(--color-border); .cooking-task__headline { text-decoration: line-through; } } } } // --- One task card -------------------------------------------------------- // (frame comes from the shared checkbox-label rule — see above) .cooking-task { &__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.2rem; } &__headline { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-xs); font-weight: 600; color: var(--color-text); } // A pooled prep task is the headline feature of this page — flag it. &__badge { padding: 0.05rem var(--space-xs); border-radius: var(--radius-pill); background: var(--color-accent); color: var(--color-surface); font-size: var(--font-size-xs); font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; } &__recipes, &__utensils { display: block; font-size: var(--font-size-sm); color: var(--color-text-muted); } }