diff --git a/client/src/assets/food/foodPairing.png b/client/src/assets/food/foodPairing.png new file mode 100644 index 0000000..f0080ee Binary files /dev/null and b/client/src/assets/food/foodPairing.png differ diff --git a/client/src/components/ExploreByTaste.css b/client/src/components/ExploreByTaste.css index 07d0935..c9ba0b0 100644 --- a/client/src/components/ExploreByTaste.css +++ b/client/src/components/ExploreByTaste.css @@ -287,20 +287,19 @@ main.taste-layout { line-height: 1.15; } -.taste-glass-box { +.taste-wine-image-box { flex: none; display: grid; place-items: center; - width: 3.25rem; - height: 4.25rem; - border-radius: 0.5rem; - background: var(--color-sunk); - color: var(--color-muted); + width: 3.5rem; + height: 5rem; } -.taste-glass { - width: 28px; - height: 44px; +.taste-wine-image { + width: auto; + height: 100%; + max-width: 100%; + object-fit: contain; } .taste-winery { diff --git a/client/src/components/FindWineByFood.css b/client/src/components/FindWineByFood.css index 31409d5..239159f 100644 --- a/client/src/components/FindWineByFood.css +++ b/client/src/components/FindWineByFood.css @@ -6,16 +6,53 @@ /* ---------- Hero ---------- */ .food-hero { - background: - radial-gradient(circle at 82% 50%, rgb(123 30 43 / 0.12), transparent 45%), - linear-gradient(90deg, var(--color-bg) 35%, var(--color-panel)); + background: var(--color-bg); border-bottom: 1px solid var(--color-border); + overflow: hidden; } .food-hero-inner { - max-width: 78rem; - margin: 0 auto; - padding: 3rem 1rem; + width: 100%; + min-height: 17rem; + margin: 0; + padding-left: max(1rem, calc((100vw - 78rem) / 2 + 1rem)); + padding-right: 0; + + display: grid; + grid-template-columns: minmax(22rem, 0.7fr) minmax(0, 1.6fr); + align-items: stretch; +} + +.food-hero-copy { + align-self: center; + padding: 3rem 2.5rem 3rem 0; +} + +.food-hero-media { + position: relative; + min-height: 17rem; + overflow: hidden; +} + +/* Makes the transition between text and image softer */ +.food-hero-media::before { + content: ''; + position: absolute; + inset: 0 auto 0 0; + z-index: 1; + width: 5rem; + pointer-events: none; + + background: linear-gradient(90deg, var(--color-bg) 0%, transparent 100%); +} + +.food-hero-image { + display: block; + width: 100%; + height: 100%; + min-height: 17rem; + object-fit: cover; + object-position: center; } .food-eyebrow { @@ -194,7 +231,7 @@ main.food-page { .food-card { height: 100%; display: grid; - grid-template-columns: 4.5rem minmax(0, 1fr); + grid-template-columns: 6rem minmax(0, 1fr); gap: 1rem; padding: 1.1rem; border: 1px solid var(--color-border); @@ -202,11 +239,19 @@ main.food-page { background: var(--color-surface); } +.food-bottle-wrap { + display: flex; + justify-content: center; + align-items: center; + width: 6rem; + min-height: 11rem; +} + .food-bottle { - width: 100%; - height: auto; - max-height: 10rem; - align-self: center; + width: auto; + height: 11rem; + max-width: 5.5rem; + object-fit: contain; } .food-card-body { @@ -335,6 +380,29 @@ main.food-page { color: var(--color-muted); } +@media (max-width: 48rem) { + .food-hero-inner { + grid-template-columns: 1fr; + padding: 0; + } + + .food-hero-copy { + padding: 2.25rem 1rem; + } + + .food-hero-media { + min-height: 12rem; + } + + .food-hero-image { + min-height: 12rem; + } + + .food-hero-media::before { + display: none; + } +} + @media (prefers-reduced-motion: reduce) { .food-category { transition: none; diff --git a/client/src/components/FindWineByFood.tsx b/client/src/components/FindWineByFood.tsx index 53b0d11..2760aab 100644 --- a/client/src/components/FindWineByFood.tsx +++ b/client/src/components/FindWineByFood.tsx @@ -2,6 +2,8 @@ import { useSearchParams } from 'react-router'; import { useQuery } from '@apollo/client/react'; import FoodWineCard from './FoodWineCard'; import Pagination from './Pagination'; +import foodPairingImage from '../assets/food/foodPairing.png'; + import { FOOD_CATEGORIES_QUERY, WINES_BY_FOOD_QUERY, @@ -86,12 +88,20 @@ export default function FindWineByFood() { <>
-

Explore

-

Find wine by food

-

- Choose what you’re eating and discover wines that make it even - better. -

+
+

Explore

+ +

Find wine by food

+ +

+ Choose what you’re eating and discover wines that make it even + better. +

+
+ +
+ +
diff --git a/client/src/components/FoodWineCard.tsx b/client/src/components/FoodWineCard.tsx index 225e1a9..d599cf9 100644 --- a/client/src/components/FoodWineCard.tsx +++ b/client/src/components/FoodWineCard.tsx @@ -1,46 +1,7 @@ import { Link } from 'react-router'; import type { FoodWine } from '../types/wine'; -import { ACIDITY_LEVELS, BODY_LEVELS, wineTypeColor } from '../data/taste'; - -/** - * A wine bottle in the colour of the wine type. Decorative only. - * X-Wines has no pictures of the wines, so we draw one. - */ -function Bottle({ type }: { type: string }) { - return ( - - ); -} +import { ACIDITY_LEVELS, BODY_LEVELS } from '../data/taste'; +import WineTypeImage from './WineTypeImage'; /** One row with label and bar, e.g. "Body ████░". The exact value is read by screen readers and shown on hover. */ function Bar(props: { label: string; share: number; value: string }) { @@ -68,7 +29,9 @@ function Bar(props: { label: string; share: number; value: string }) { export default function FoodWineCard({ wine }: { wine: FoodWine }) { return (
- +
+ +

diff --git a/client/src/components/SelectedWine.tsx b/client/src/components/SelectedWine.tsx index 895966e..2d12cf7 100644 --- a/client/src/components/SelectedWine.tsx +++ b/client/src/components/SelectedWine.tsx @@ -2,31 +2,13 @@ import { Link } from 'react-router'; import { useQuery } from '@apollo/client/react'; import type { TasteWine } from '../types/wine'; import { WINE_GRAPES_QUERY, type WineGrapesData } from '../graphql/queries'; -import { ACIDITY_LEVELS, BODY_LEVELS, wineTypeColor } from '../data/taste'; +import { ACIDITY_LEVELS, BODY_LEVELS } from '../data/taste'; +import WineTypeImage from './WineTypeImage'; type Props = { wine: TasteWine | null; }; -/** A wine glass filled with the colour of the wine type. Decorative only. */ -function WineGlass({ type }: { type: string }) { - return ( - - ); -} - /** One row with label, bar and value, e.g. "Body ████░ Full-bodied". */ function TasteBar(props: { label: string; share: number; value: string }) { return ( @@ -74,8 +56,8 @@ export default function SelectedWine({ wine }: Props) { aria-live="polite" >
-
- +
+

{wine.name}

diff --git a/client/src/components/WineList.tsx b/client/src/components/WineList.tsx index 37374a8..7c36a6b 100644 --- a/client/src/components/WineList.tsx +++ b/client/src/components/WineList.tsx @@ -1,24 +1,11 @@ import type { WineListItem } from '../types/wine'; import './WineList.css'; -import redWine from '../assets/wines/redWine.png'; -import whiteWine from '../assets/wines/whiteWine.png'; -import roseWine from '../assets/wines/roseWine.png'; -import sparklingWine from '../assets/wines/sparklingWine.png'; -import dessertWine from '../assets/wines/dessertWine.png'; -import portWine from '../assets/wines/portWine.png'; +import WineTypeImage from './WineTypeImage'; type Props = { wines: WineListItem[]; }; -const wineImages: Record = { - Red: redWine, - White: whiteWine, - Rosé: roseWine, - Sparkling: sparklingWine, - Dessert: dessertWine, - 'Dessert/Port': portWine, -}; /** * Shows a list of wines as cards. * @@ -54,15 +41,9 @@ export default function WineList({ wines }: Props) { aria-labelledby={`wine-${wine.id}`} data-wine-type={wine.type.toLowerCase()} > - {wineImages[wine.type] && ( -
- -
- )} +
+ +
{wine.type} diff --git a/client/src/components/WineTypeImage.tsx b/client/src/components/WineTypeImage.tsx new file mode 100644 index 0000000..3503c64 --- /dev/null +++ b/client/src/components/WineTypeImage.tsx @@ -0,0 +1,30 @@ +import redWine from '../assets/wines/redWine.png'; +import whiteWine from '../assets/wines/whiteWine.png'; +import roseWine from '../assets/wines/roseWine.png'; +import sparklingWine from '../assets/wines/sparklingWine.png'; +import dessertWine from '../assets/wines/dessertWine.png'; +import portWine from '../assets/wines/portWine.png'; + +const wineImages: Record = { + Red: redWine, + White: whiteWine, + Rosé: roseWine, + Sparkling: sparklingWine, + Dessert: dessertWine, + 'Dessert/Port': portWine, +}; + +type Props = { + type: string; + className?: string; +}; + +export default function WineTypeImage({ type, className }: Props) { + const image = wineImages[type]; + + if (!image) { + return null; + } + + return ; +}