- Run record
- loading
Loading this Run…
Loading the Revisions of this Run…
A published source file of Revision 0 of Fjora — Taste the North 1.0.0, shown as text in the browser.
import { useState, type CSSProperties } from "react";
import { flavorCopy, products } from "../content";
/** Per-flavor accent colour, passed down as a custom property. */
const accentStyle = (accent: string) =>
({ "--accent": accent }) as CSSProperties;
export function FlavorSelector() {
const [selectedId, setSelectedId] = useState(products[0].id);
const selected = products.find((p) => p.id === selectedId) ?? products[0];
const copy = flavorCopy[selected.id];
return (
<section
className="section flavors"
id="flavors"
tabIndex={-1}
aria-labelledby="flavors-title"
style={accentStyle(copy.accent)}
>
<div className="section__head">
<p className="eyebrow">The line</p>
<h2 id="flavors-title">Three flavors of the season</h2>
<p className="section__lede">
Pick one to read its botanicals and tasting note.
</p>
</div>
<div className="flavors__layout">
<div
className="flavor-options"
role="radiogroup"
aria-label="Seasonal flavors"
>
{products.map((product) => {
const isSelected = product.id === selected.id;
return (
<label
key={product.id}
className={`flavor-option${isSelected ? " is-selected" : ""}`}
style={accentStyle(flavorCopy[product.id].accent)}
>
<input
type="radio"
name="flavor"
value={product.id}
checked={isSelected}
onChange={() => setSelectedId(product.id)}
/>
<span className="flavor-option__thumb">
<img
src={product.image}
alt={`Fjora ${product.name} bottle`}
loading="lazy"
/>
</span>
<span className="flavor-option__text">
<span className="flavor-option__name">{product.name}</span>
<span className="flavor-option__botanicals">
{product.botanicals.join(" · ")}
</span>
</span>
<span className="flavor-option__check" aria-hidden="true">
<svg width="14" height="14" viewBox="0 0 14 14" focusable="false">
<path
d="M2.5 7.5 5.5 10.5 11.5 3.5"
fill="none"
stroke="currentColor"
strokeWidth="1.8"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
</span>
</label>
);
})}
</div>
<article className="flavor-detail" aria-live="polite">
<div className="flavor-detail__media">
<img
key={selected.id}
src={selected.image}
alt={`Fjora ${selected.name}: a glass bottle of botanical sparkling water.`}
/>
</div>
<div className="flavor-detail__body">
<p className="eyebrow">{copy.season}</p>
<h3 className="flavor-detail__name">{selected.name}</h3>
<div className="flavor-detail__group">
<h4>Botanicals</h4>
<ul className="botanicals">
{selected.botanicals.map((botanical) => (
<li key={botanical}>{botanical}</li>
))}
</ul>
</div>
<div className="flavor-detail__group">
<h4>Tasting note</h4>
<p className="flavor-detail__note">{copy.tastingNote}</p>
</div>
<ul className="facts">
<li>No sugar, no sweeteners</li>
<li>Caffeine-free</li>
<li>Glass bottle, aluminium cap</li>
</ul>
</div>
</article>
</div>
</section>
);
}Source is browser-viewable only. There is no download or archive endpoint, and no additional license is granted beyond inspection and research.