/* ============================================================
   Saaed Vegetable Trading — pages added after the approved build

   Breadcrumbs, product detail, pagination and empty states. The approved
   style.css is not edited; this file only adds what it does not cover, and
   uses design tokens exclusively — no literal colour or size belongs here.
   ============================================================ */

/* A page's H1 sits in the same .section-head as the homepage H2s and must look
   identical to them. The approved shop page had no H1 at all. */
.section-head h1{font-size:var(--text-h2);color:var(--green-brand);font-weight:600}

/* Category tiles are links on the category pages and buttons on the homepage.
   Normalise the anchor so the two render the same. */
a.category-tile{text-decoration:none;color:inherit}

/* The card image and title link to the product page. The anchor has to fill the
   image wrapper, or the image's 100% height resolves against an inline box. */
.product-card .img-wrap > a{display:block;width:100%;height:100%}
.product-card .p-title a{color:inherit;text-decoration:none}
.product-card .p-title a:hover{color:var(--green-accent)}

/* ---- breadcrumbs ---- */
.breadcrumbs{margin-bottom:var(--space-4)}
.breadcrumbs ol{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2)}
.breadcrumbs li{font-size:var(--text-small);color:var(--text-secondary)}
.breadcrumbs li+li::before{content:"›";margin-right:var(--space-2);color:var(--text-secondary)}
.breadcrumbs a{color:var(--text-secondary)}
.breadcrumbs a:hover{color:var(--green-accent)}
.breadcrumbs li[aria-current="page"]{color:var(--text-primary);font-weight:600}

/* ---- page intro copy ---- */
.page-intro{max-width:76ch;margin-bottom:var(--space-5);color:var(--text-secondary);font-size:var(--text-body)}
.page-intro p{margin-bottom:var(--space-3)}

/* ---- product detail ---- */
.product-detail{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,6fr);gap:var(--space-7);align-items:start;margin-bottom:var(--space-7)}
.pd-gallery{position:sticky;top:90px}
.pd-image{position:relative;background:var(--card-white);border-radius:var(--radius-card);box-shadow:var(--shadow-card);overflow:hidden;aspect-ratio:1/1}
.pd-image img{width:100%;height:100%;object-fit:cover}
.pd-thumbs{display:flex;gap:var(--space-2);margin-top:var(--space-3)}
.pd-thumb{width:72px;height:72px;padding:0;border:1px solid var(--input-border);border-radius:var(--radius-field);background:var(--card-white);overflow:hidden}
.pd-thumb.active{border-color:var(--green-accent)}
.pd-thumb img{width:100%;height:100%;object-fit:cover}

.pd-title{font-size:var(--text-hero-lg);color:var(--green-brand);font-weight:600;margin-bottom:var(--space-2)}
.pd-origin-line{font-size:var(--text-small);color:var(--text-secondary);margin-bottom:var(--space-3)}
.pd-info .product-note{margin-bottom:var(--space-3)}
.pd-info .unit-selector,.pd-info .p-unit{margin-bottom:var(--space-3)}
.pd-price{margin-bottom:var(--space-2)}
.pd-price .price-now{font-size:var(--text-jumbo)}
.pd-info .stock-line{margin-bottom:var(--space-4)}
.pd-actions{max-width:420px}
.pd-actions .add-btn{flex:1}
.pd-section{margin-top:var(--space-5);padding-top:var(--space-4);border-top:1px solid var(--input-border)}
.pd-section h2{font-size:var(--text-body-lg);color:var(--green-brand);font-weight:600;margin-bottom:var(--space-2)}
.pd-copy{color:var(--text-secondary);font-size:var(--text-body);max-width:70ch}
.pd-copy p{margin-bottom:var(--space-3)}

@media (max-width:900px){
  .product-detail{grid-template-columns:1fr;gap:var(--space-4)}
  .pd-gallery{position:static}
  .pd-title{font-size:var(--text-h1)}
  .pd-price .price-now{font-size:var(--text-hero-lg)}
}

/* ---- category FAQ block ---- */
.faq-block{padding-top:var(--space-6)}
.faq-item{background:var(--card-white);border-radius:var(--radius-card);box-shadow:var(--shadow-card);padding:var(--space-3) var(--space-4);margin-bottom:var(--space-2)}
.faq-item summary{font-weight:600;cursor:pointer;font-size:var(--text-body)}
.faq-answer{color:var(--text-secondary);font-size:var(--text-small);padding-top:var(--space-2)}

/* ---- pagination ---- */
.pagination{display:flex;flex-wrap:wrap;gap:var(--space-2);justify-content:center;margin-top:var(--space-6)}
.page-link{display:inline-flex;align-items:center;justify-content:center;min-width:40px;height:40px;padding:0 var(--space-3);border-radius:var(--radius-pill);border:1px solid var(--input-border);background:var(--card-white);font-size:var(--text-small);font-weight:600;color:var(--text-primary)}
.page-link:hover{border-color:var(--green-accent);color:var(--green-accent)}
.page-link.current{background:var(--green-accent);border-color:var(--green-accent);color:var(--text-on-dark)}

/* ---- empty states ---- */
.empty-state{text-align:center;padding:var(--space-7) var(--space-3);color:var(--text-secondary)}
.empty-state-page{padding:var(--space-9) var(--space-3)}
.empty-state h1{font-size:var(--text-h1);color:var(--green-brand);font-weight:600;margin-bottom:var(--space-3)}
.empty-state p{margin-bottom:var(--space-3)}
.empty-state-links{display:flex;flex-wrap:wrap;gap:var(--space-2);justify-content:center;margin-top:var(--space-4)}

/* The header search is a real form so it works before JavaScript loads. It must
   not change how the approved search bar looks. */
.search-wrap form{display:contents}

/* ============================================================
   Cart, checkout, confirmation and tracking
   ============================================================ */

.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* ---- form messages and fields ---- */
.form-message{border-radius:var(--radius-card);padding:var(--space-3);margin-bottom:var(--space-4);font-size:var(--text-small);font-weight:600}
.form-message-error{background:#FDECEA;color:var(--sale-red)}
.form-message-ok{background:var(--green-light);color:var(--green-brand)}

.field{margin-bottom:var(--space-3)}
.field label,.field-label{display:block;font-size:var(--text-small);font-weight:600;margin-bottom:var(--space-1)}
/* type=password was missing from this list, so every password box on the site —
   both logins, register, forgot and reset — rendered as a raw browser default
   sitting directly beneath a styled email box. Listing the types we use is
   still safer than a bare `.field input`, which would also catch checkboxes and
   radios and stretch them to full width. */
.field input[type=text],.field input[type=tel],.field input[type=email],
.field input[type=password],.field input[type=number],.field input[type=search],
.field input[type=url],.field input[type=date],.field input[type=time],
.field select,.field textarea{
  width:100%;padding:1.1rem 1.4rem;border:1px solid var(--input-border);border-radius:var(--radius-field);
  font-family:var(--font-sans);font-size:var(--text-body);background:var(--card-white);color:var(--text-primary);
  transition:border-color .18s ease,box-shadow .18s ease}
.field input:focus,.field select:focus,.field textarea:focus{
  outline:none;border-color:var(--green-accent);box-shadow:0 0 0 3px var(--green-light)}
.field textarea{resize:vertical}
.field input:focus-visible,.field select:focus-visible,.field textarea:focus-visible{border-color:var(--green-accent)}
.field [aria-invalid=true]{border-color:var(--sale-red)}
.field-hint{display:block;font-size:var(--text-micro);color:var(--text-secondary);margin-top:var(--space-1)}
.field-error{display:block;font-size:var(--text-micro);color:var(--sale-red);font-weight:600;margin-top:var(--space-1)}
.field-optional{font-weight:400;color:var(--text-secondary)}
.field-row{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-3)}

.choice-row{display:flex;flex-wrap:wrap;gap:var(--space-2)}
.choice{display:inline-flex;align-items:center;gap:var(--space-2);border:1px solid var(--input-border);border-radius:var(--radius-pill);padding:1rem 1.8rem;font-size:var(--text-small);font-weight:600;background:var(--card-white);cursor:pointer}
.choice:has(input:checked){border-color:var(--green-accent);background:var(--green-light);color:var(--green-brand)}
.choice-block{display:flex;border-radius:var(--radius-card);align-items:flex-start;font-weight:400;padding:var(--space-3)}

/* ---- cart page ---- */
.cart-layout{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:var(--space-5);align-items:start}
.cart-lines{background:var(--card-white);border-radius:var(--radius-card);box-shadow:var(--shadow-card);padding:var(--space-3) var(--space-4)}
.cart-row{display:grid;grid-template-columns:80px minmax(0,1fr) auto;gap:var(--space-3);align-items:center;padding:var(--space-3) 0;border-bottom:1px solid var(--input-border)}
.cart-row:last-child{border-bottom:none}
.cart-row-img{width:80px;height:80px;border-radius:8px;overflow:hidden;background:var(--neutral-cool)}
.cart-row-img img{width:100%;height:100%;object-fit:cover}
.cart-row-info .cl-title a{color:inherit}
.cart-row-info .stepper{margin-top:var(--space-2)}
.cart-row-total{text-align:right}
.stock-warning{font-size:var(--text-micro);color:var(--warning-amber);font-weight:600;margin-top:var(--space-1)}

.cart-summary,.checkout-summary{background:var(--card-white);border-radius:var(--radius-card);box-shadow:var(--shadow-card);padding:var(--space-4);position:sticky;top:90px}
.cart-summary h2,.checkout-summary h2{font-size:var(--text-body-lg);color:var(--green-brand);font-weight:600;margin-bottom:var(--space-3)}
.summary-row{display:flex;justify-content:space-between;align-items:baseline;gap:var(--space-3);font-size:var(--text-small);padding:var(--space-2) 0}
.summary-discount strong{color:var(--success-green)}
.summary-muted{color:var(--text-secondary)}
.summary-total{border-top:1px solid var(--input-border);margin-top:var(--space-2);padding-top:var(--space-3);font-size:var(--text-body)}
.summary-total strong{font-size:var(--text-price-lg);color:var(--green-brand)}
.summary-note{font-size:var(--text-micro);color:var(--text-secondary);margin:var(--space-2) 0 var(--space-1)}
.summary-note-good{color:var(--success-green);font-weight:600}
.coupon-form{display:flex;gap:var(--space-2);align-items:center;margin:var(--space-3) 0;padding:var(--space-3) 0;border-top:1px solid var(--input-border)}
.coupon-form input[type=text]{flex:1;min-width:0;padding:1rem 1.2rem;border:1px solid var(--input-border);border-radius:var(--radius-field);font-family:var(--font-sans);font-size:var(--text-small)}
.coupon-applied{flex:1;font-size:var(--text-small);font-weight:600;color:var(--success-green)}
.cart-checkout-btn{width:100%;margin-top:var(--space-3)}
.cart-continue{display:block;text-align:center;margin-top:var(--space-3)}

/* ---- checkout ---- */
.checkout-layout{display:grid;grid-template-columns:minmax(0,1fr) 360px;gap:var(--space-5);align-items:start}
.checkout-block{background:var(--card-white);border-radius:var(--radius-card);box-shadow:var(--shadow-card);padding:var(--space-4);margin-bottom:var(--space-4)}
.checkout-block h2{font-size:var(--text-body-lg);color:var(--green-brand);font-weight:600;margin-bottom:var(--space-3)}
.summary-lines{list-style:none;margin:0 0 var(--space-3);padding:0 0 var(--space-3);border-bottom:1px solid var(--input-border)}
.summary-lines li{display:grid;grid-template-columns:32px minmax(0,1fr) auto;gap:var(--space-2);font-size:var(--text-small);padding:var(--space-2) 0}
.summary-qty{font-weight:700;color:var(--green-brand)}
.summary-amount{text-align:right;white-space:nowrap}
.checkout-submit{width:100%;margin-top:var(--space-3)}
.checkout-submit:disabled{opacity:.6;cursor:not-allowed}
.checkout-terms{text-align:center;margin:var(--space-2) 0 var(--space-3)}
.checkout-summary .ghost-link{display:block;text-align:center}

/* ---- order confirmation ---- */
.order-received{text-align:center;padding:var(--space-6) var(--space-3) var(--space-5)}
.order-received-mark{color:var(--success-green);display:flex;justify-content:center;margin-bottom:var(--space-3)}
.order-received h1{font-size:var(--text-h1);color:var(--green-brand);font-weight:600;margin-bottom:var(--space-2)}
.order-number{font-size:var(--text-body-lg);margin-bottom:var(--space-2)}
.order-panels{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(280px,100%),1fr));gap:var(--space-4);align-items:start}
.order-panel{background:var(--card-white);border-radius:var(--radius-card);box-shadow:var(--shadow-card);padding:var(--space-4)}
.order-panel h2{font-size:var(--text-body-lg);color:var(--green-brand);font-weight:600;margin-bottom:var(--space-3)}
.next-steps{margin:0 0 var(--space-3);padding-left:var(--space-4);font-size:var(--text-small);line-height:1.7}
.order-continue{text-align:center;margin-top:var(--space-5)}

/* ---- tracking ---- */
.track-layout{display:grid;grid-template-columns:340px minmax(0,1fr);gap:var(--space-5);align-items:start}
.track-form,.track-result{background:var(--card-white);border-radius:var(--radius-card);box-shadow:var(--shadow-card);padding:var(--space-4)}
.track-result h2{font-size:var(--text-body-lg);color:var(--green-brand);font-weight:600}
.track-form .form-message{margin:var(--space-3) 0 0}
.status-timeline{list-style:none;margin:var(--space-4) 0;padding:0;display:flex;flex-direction:column;gap:var(--space-3)}
.timeline-step{display:flex;align-items:center;gap:var(--space-3);font-size:var(--text-small);position:relative;padding-left:var(--space-1)}
.timeline-dot{width:14px;height:14px;border-radius:50%;border:2px solid var(--input-border);background:var(--card-white);flex:0 0 auto}
.timeline-done .timeline-dot{background:var(--success-green);border-color:var(--success-green)}
.timeline-current .timeline-dot{border-color:var(--green-accent);box-shadow:0 0 0 4px var(--green-light)}
.timeline-current .timeline-label{font-weight:700;color:var(--green-brand)}
.timeline-todo .timeline-label{color:var(--text-secondary)}
.track-meta{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(140px,100%),1fr));gap:var(--space-3);padding:var(--space-3) 0;border-top:1px solid var(--input-border);border-bottom:1px solid var(--input-border);margin-bottom:var(--space-3);font-size:var(--text-small)}

@media (max-width:900px){
  .cart-layout,.checkout-layout,.track-layout{grid-template-columns:1fr}
  .cart-summary,.checkout-summary{position:static}
  .field-row{grid-template-columns:1fr}
  .cart-row{grid-template-columns:64px minmax(0,1fr);grid-template-areas:"img info" "total total"}
  .cart-row-img{grid-area:img;width:64px;height:64px}
  .cart-row-info{grid-area:info}
  .cart-row-total{grid-area:total;text-align:left;display:flex;align-items:center;justify-content:space-between;gap:var(--space-3)}
}

/* ============================================================
   Accounts — auth pages, dashboard and the printable invoice
   ============================================================ */

/* ---- auth ---- */
/* ---------------------------------------------------------------- auth pages
   Sign in, register, forgot and reset all share this card, so everything here
   lands on all four. The card used to be a 440px white box with the site's
   default page background behind it, which read as a form on a page rather
   than as a way in.
   The backdrop is built from palette tokens only — two greens and the warm
   canvas — so it reads as the brand rather than as a stock gradient. */
.auth-page{min-height:70vh;display:flex;align-items:center;justify-content:center;
  padding:var(--space-7) var(--gutter-desktop);
  background:
    radial-gradient(ellipse 60% 50% at 15% 0%, var(--green-light) 0%, transparent 60%),
    radial-gradient(ellipse 50% 45% at 90% 100%, var(--amber-lightest) 0%, transparent 55%),
    var(--canvas-warm)}
.auth-card{max-width:460px;width:100%;margin:0 auto;background:var(--card-white);
  border-radius:16px;border:1px solid rgba(0,0,0,.04);
  box-shadow:0 1px 2px rgba(0,0,0,.04),0 12px 32px -8px rgba(16,53,43,.16);
  padding:var(--space-7) var(--space-6)}
/* Rises in once. Small distance, unhurried ease — the card should settle, not
   arrive. */
@media (prefers-reduced-motion:no-preference){
  .auth-card{animation:auth-card-in .5s cubic-bezier(.2,.7,.3,1) both}
}
@keyframes auth-card-in{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}

/* Brand lockup, so the page identifies itself above the heading instead of
   opening on a bare "Sign in". */
.auth-brand{display:flex;align-items:center;justify-content:center;gap:var(--space-2);
  margin-bottom:var(--space-5);color:var(--green-brand);font-weight:700;font-size:var(--text-body-lg)}
.auth-brand svg{flex:0 0 auto}

.auth-card h1{font-size:var(--text-h1);color:var(--text-primary);font-weight:700;
  margin-bottom:var(--space-1);letter-spacing:var(--track-tight);text-align:center}
.auth-lede{text-align:center;color:var(--text-secondary);font-size:var(--text-small);
  margin-bottom:var(--space-5)}
.auth-card form{margin-top:var(--space-4)}
.auth-card .field{margin-bottom:var(--space-4)}

/* The toggle sits inside the input's own box, so the field keeps one outline
   and one focus ring rather than looking like two controls.
   The positioning context is a wrapper around the input, not the whole .field:
   a field can carry a hint below the input, and anchoring to the field's bottom
   would drop the button underneath it. */
.password-wrap{position:relative;display:block}
.password-wrap input{padding-right:6.4rem}
.password-toggle{position:absolute;right:.6rem;top:50%;transform:translateY(-50%);height:3.6rem;padding:0 1.2rem;
  border:none;background:transparent;color:var(--green-accent);font-weight:600;
  font-size:var(--text-micro);border-radius:var(--radius-field);font-family:var(--font-sans)}
.password-toggle:hover{background:var(--green-light);color:var(--green-brand)}

.auth-submit{width:100%;margin-top:var(--space-2);padding:1.3rem;font-size:var(--text-body);font-weight:600}
.auth-alt{text-align:center;font-size:var(--text-small);margin-top:var(--space-3);color:var(--text-secondary)}
.auth-guest{text-align:center;margin-top:var(--space-5);padding-top:var(--space-4);border-top:1px solid var(--input-border)}

@media (max-width:767px){
  .auth-page{padding:var(--space-5) var(--gutter-mobile);min-height:auto}
  .auth-card{padding:var(--space-5) var(--space-4);border-radius:12px}
}

/* ---- dashboard shell ---- */
.account-layout{display:grid;grid-template-columns:248px minmax(0,1fr);gap:var(--space-6);align-items:start}
/* The sidebar becomes a panel rather than a bare list, and follows the reader
   down a long order history instead of scrolling away at the top. */
.account-nav{background:var(--card-white);border-radius:var(--radius-card);
  box-shadow:var(--shadow-card);padding:var(--space-3);position:sticky;top:calc(var(--space-6) + 56px)}
.account-nav ul{list-style:none;margin:0;padding:0}
/* Who is signed in, at the top of their own account. The pages used to say it
   once in the greeting and nowhere else. */
.account-who{padding:var(--space-3) var(--space-3) var(--space-4);border-bottom:1px solid var(--input-border);margin-bottom:var(--space-2)}
.account-who strong{display:block;font-size:var(--text-body);font-weight:700;line-height:1.3}
.account-who span{display:block;font-size:var(--text-micro);color:var(--text-secondary);
  margin-top:.2rem;overflow-wrap:anywhere}
.account-nav li a{display:block;padding:1.1rem 1.6rem;border-radius:var(--radius-pill);font-size:var(--text-small);font-weight:600;color:var(--text-primary)}
.account-nav li a:hover{background:var(--green-light);color:var(--green-brand)}
.account-nav li a.active{background:var(--green-accent);color:var(--text-on-dark)}
.account-logout{margin-top:var(--space-3);padding-top:var(--space-3);border-top:1px solid var(--input-border)}
.account-logout button{background:none;border:none;padding:0 1.6rem}

.account-card{background:var(--card-white);border-radius:var(--radius-card);box-shadow:var(--shadow-card);padding:var(--space-5);margin-bottom:var(--space-4)}
.account-card-highlight{background:var(--green-light)}
.account-card h2{font-size:var(--text-body-lg);color:var(--green-brand);font-weight:600}
.account-subhead{font-size:var(--text-body-lg);color:var(--green-brand);font-weight:600;margin-bottom:var(--space-3)}
.account-card .account-subhead:not(:first-child){margin-top:var(--space-5);padding-top:var(--space-4);border-top:1px solid var(--input-border)}
.next-delivery{margin:var(--space-2) 0 var(--space-3);font-size:var(--text-body)}

.account-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(150px,100%),1fr));gap:var(--space-3);margin-bottom:var(--space-4)}
/* These are links, so they behave like links: the number leads, the label sits
   under it, and the whole tile lifts on hover. Centred text gave no reading
   order and no clue any of it was clickable. */
.account-stat{background:var(--card-white);border-radius:var(--radius-card);box-shadow:var(--shadow-card);
  padding:var(--space-4);color:inherit;text-align:left;display:block;position:relative;
  border:1px solid transparent;transition:transform .18s ease,box-shadow .18s ease,border-color .18s ease}
.account-stat:hover{transform:translateY(-2px);border-color:var(--green-light);
  box-shadow:var(--shadow-card),0 8px 20px -8px rgba(16,53,43,.18)}
.account-stat strong{display:block;font-size:var(--text-hero-lg);color:var(--green-brand);font-weight:700;line-height:1.05}
.account-stat span{display:block;font-size:var(--text-micro);color:var(--text-secondary);margin-top:.4rem}
.account-stat::after{content:"→";position:absolute;top:var(--space-4);right:var(--space-4);
  color:var(--green-accent);opacity:0;transform:translateX(-4px);transition:opacity .18s ease,transform .18s ease}
.account-stat:hover::after{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){
  .account-stat,.account-stat::after{transition:none}
  .account-stat:hover{transform:none}
}

/* ---- order list ---- */
.order-list{list-style:none;margin:0;padding:0}
/* Negative inline margin so the hover tint reaches the card's edges instead of
   stopping short and looking like a mistake. */
.order-row{display:grid;grid-template-columns:minmax(0,1fr) auto auto;gap:var(--space-3);align-items:center;
  padding:var(--space-3);margin:0 calc(var(--space-3) * -1);border-bottom:1px solid var(--input-border);
  border-radius:var(--radius-field);transition:background-color .15s ease}
.order-row:hover{background:var(--neutral-cool)}
.order-row:last-child{border-bottom:none}
.order-number-link{font-weight:700;color:var(--green-brand)}
.order-row-total{font-weight:700;white-space:nowrap}
.order-detail-actions{margin-top:var(--space-4);padding-top:var(--space-4);border-top:1px solid var(--input-border)}

.status-chip{display:inline-block;border-radius:var(--radius-pill);padding:.3rem 1rem;font-size:var(--text-micro);font-weight:700;margin-left:var(--space-2);background:var(--ceramic);color:var(--text-secondary)}
/* Every chip was the same grey, so the state was something you read rather than
   something you saw — the one thing a customer scanning a list of orders is
   actually looking for. Palette tokens only, and the wording stays: colour is
   the second signal, never the only one. */
.status-chip.status-pending{background:var(--amber-lightest);color:#8A6318}
.status-chip.status-confirmed{background:var(--green-light);color:var(--green-brand)}
.status-chip.status-out_for_delivery{background:var(--green-accent);color:var(--text-on-dark)}
.status-chip.status-delivered{background:var(--green-brand);color:var(--text-on-dark)}
.status-chip.status-cancelled{background:#FDECEA;color:var(--sale-red)}
.status-pending{background:var(--amber-lightest);color:var(--amber-harvest)}
.status-confirmed,.status-packing{background:var(--green-light);color:var(--green-brand)}
.status-out_for_delivery{background:var(--green-accent);color:var(--text-on-dark)}
.status-delivered{background:var(--green-brand);color:var(--text-on-dark)}
.status-cancelled,.status-refunded{background:#FDECEA;color:var(--sale-red)}

/* ---- baskets ---- */
.basket-save-form{display:flex;gap:var(--space-2);align-items:center;flex-wrap:wrap}
.basket-save-form input[type=text]{flex:1;min-width:200px;padding:1.1rem 1.4rem;border:1px solid var(--input-border);border-radius:var(--radius-field);font-family:var(--font-sans);font-size:var(--text-body)}
.basket-items{list-style:none;margin:var(--space-2) 0 var(--space-3);padding:0;font-size:var(--text-small);line-height:1.9}
.basket-actions{display:flex;gap:var(--space-3);align-items:center;flex-wrap:wrap}
.basket-actions button.ghost-link{background:none;border:none}

/* ---- addresses ---- */
.address-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(260px,100%),1fr));gap:var(--space-3);margin-bottom:var(--space-4)}
.address-card{background:var(--card-white);border-radius:var(--radius-card);box-shadow:var(--shadow-card);padding:var(--space-4);font-size:var(--text-small)}
.address-default{border:1.5px solid var(--green-accent)}
.address-label{font-weight:700;margin-bottom:var(--space-2)}
.address-label .status-chip{margin-left:var(--space-2)}
.address-actions{display:flex;gap:var(--space-3);align-items:center;flex-wrap:wrap;margin-top:var(--space-3);padding-top:var(--space-3);border-top:1px solid var(--input-border)}
.address-actions button.ghost-link{background:none;border:none}

@media (max-width:900px){
  /* The sidebar becomes a scrollable tab strip — one-handed, no menu to open. */
  .account-layout{grid-template-columns:1fr;gap:var(--space-4)}
  /* Undo the desktop panel: at this size it is a tab strip, not a card, so the
     shadow, radius and identity block all come off. */
  .account-nav{position:sticky;top:0;z-index:5;background:var(--canvas-warm);padding:var(--space-2) 0;margin:0 calc(-1 * var(--gutter-mobile));padding-left:var(--gutter-mobile);padding-right:var(--gutter-mobile);box-shadow:none;border-radius:0}
  .account-who{display:none}
  .account-nav ul{display:flex;gap:var(--space-2);overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}
  .account-nav ul::-webkit-scrollbar{display:none}
  .account-nav li a{white-space:nowrap;border:1px solid var(--input-border);background:var(--card-white)}
  .account-nav li a.active{border-color:var(--green-accent)}
  .account-logout{border-top:none;margin-top:var(--space-2);padding-top:0}
  .order-row{grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"main total" "action action"}
  .order-row-main{grid-area:main}
  .order-row-total{grid-area:total}
  .order-row-action{grid-area:action;margin-top:var(--space-2)}
}

/* ---- printable invoice ---- */
.invoice-sheet{max-width:800px;margin:0 auto;padding:var(--space-6) var(--gutter-desktop);background:var(--card-white)}
.invoice-actions{display:flex;justify-content:space-between;align-items:center;gap:var(--space-3);margin-bottom:var(--space-5)}
.invoice-head{display:flex;justify-content:space-between;gap:var(--space-4);flex-wrap:wrap;padding-bottom:var(--space-4);border-bottom:2px solid var(--green-brand)}
.invoice-brand{font-size:var(--text-body-lg);font-weight:700;color:var(--green-brand)}
.invoice-meta{font-size:var(--text-small);color:var(--text-secondary)}
.invoice-head-right{text-align:right}
.invoice-head-right h1{font-size:var(--text-h1);color:var(--green-brand);font-weight:600}
.invoice-parties{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-4);margin:var(--space-4) 0}
.invoice-parties h2{font-size:var(--text-micro);text-transform:uppercase;letter-spacing:.04em;color:var(--text-secondary);margin-bottom:var(--space-1)}
.invoice-parties p{font-size:var(--text-small);line-height:1.6}
.invoice-table{width:100%;border-collapse:collapse;font-size:var(--text-small);margin-top:var(--space-3)}
.invoice-table th,.invoice-table td{padding:var(--space-2) var(--space-1);text-align:left;border-bottom:1px solid var(--input-border)}
.invoice-table thead th{font-size:var(--text-micro);text-transform:uppercase;letter-spacing:.04em;color:var(--text-secondary)}
.invoice-table .num{text-align:right;white-space:nowrap}
.invoice-table tfoot th{text-align:right;font-weight:400;color:var(--text-secondary)}
.invoice-table tfoot .invoice-total th,.invoice-table tfoot .invoice-total td{font-weight:700;font-size:var(--text-body);color:var(--green-brand);border-top:2px solid var(--green-brand)}
.invoice-note{margin-top:var(--space-4);font-size:var(--text-small);color:var(--text-secondary)}

@media (max-width:600px){
  .invoice-parties{grid-template-columns:1fr}
  .invoice-sheet{padding:var(--space-4) var(--gutter-mobile)}
}

@media print{
  .announcement-bar,.utility-bar,.site-header,.primary-nav,.site-footer,.bottom-tabs,
  .fab-cart,.cart-drawer,.overlay-scrim,.toast-wrap,.no-print{display:none !important}
  body{background:#FFFFFF}
  .invoice-sheet{max-width:none;padding:0;box-shadow:none}
  .invoice-table{font-size:11pt}
  a{color:inherit;text-decoration:none}
}

/* ============================================================
   Long-form copy: pages, policies, area pages and Kitchen Notes
   ============================================================ */

/* One place that styles stored HTML, so a policy page and a blog post read the
   same and neither needs inline styling in the body. */
/* A reading column, centred.

   .prose has always been 72ch — the right measure, and a line longer than that
   is genuinely harder to read, so widening it to fill the container would be
   the wrong fix. The problem was that the column sat hard against the left of a
   1360px container with 640px of nothing beside it, which is what "everything
   is aligned to the left" describes.

   The heading has to come with it. Centring the text and leaving the h1 where
   it was would trade one misalignment for a worse one, so both live inside
   .page-reading and share the measure. Grids, FAQ blocks and product rows stay
   full width — they are not reading, and they were never the complaint. */
.page-reading{max-width:72ch;margin-inline:auto}
.page-reading .prose{max-width:none}
.prose{max-width:72ch;margin-inline:auto;color:var(--text-primary);font-size:var(--text-body);line-height:1.7}
.prose h2{font-size:var(--text-body-lg);color:var(--green-brand);font-weight:600;margin:var(--space-5) 0 var(--space-2)}
.prose h3{font-size:var(--text-body);color:var(--green-brand);font-weight:600;margin:var(--space-4) 0 var(--space-1)}
.prose p{margin-bottom:var(--space-3)}
.prose ul,.prose ol{margin:0 0 var(--space-3) var(--space-4);padding:0}
.prose li{margin-bottom:var(--space-1)}
.prose strong{font-weight:600}
.prose a{text-decoration:underline}
.prose blockquote{margin:var(--space-4) 0;padding:var(--space-3) var(--space-4);border-left:3px solid var(--green-light);
  background:var(--card-white);border-radius:0 var(--radius-card) var(--radius-card) 0;color:var(--text-secondary)}
.prose table{width:100%;border-collapse:collapse;margin-bottom:var(--space-3);font-size:var(--text-small)}
.prose th,.prose td{padding:var(--space-2);text-align:left;border-bottom:1px solid var(--input-border)}
.prose th{font-weight:600}

.area-facts .usp-row{margin-top:0}

/* ---- Kitchen Notes ---- */
.blog-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(280px,100%),1fr));gap:var(--space-4)}
.blog-card h3 a{color:inherit}
.blog-card h3 a:hover{color:var(--green-accent)}
.blog-excerpt{font-size:var(--text-small);color:var(--text-secondary);margin:var(--space-1) 0 var(--space-2)}

.post{max-width:72ch;margin:0 auto}
.post-head h1{font-size:var(--text-hero-lg);color:var(--green-brand);font-weight:600;margin-bottom:var(--space-2)}
.post-meta{font-size:var(--text-small);color:var(--text-secondary);margin-bottom:var(--space-3)}
.post-standfirst{font-size:var(--text-body-lg);color:var(--text-secondary);line-height:1.6;margin-bottom:var(--space-4)}
.post-cover{width:100%;border-radius:var(--radius-card);margin-bottom:var(--space-5)}

@media (max-width:700px){
  .post-head h1{font-size:var(--text-h1)}
}

/* ============================================================
   Small screens — the things that push a page sideways
   ============================================================
   A layout does not have to look wrong to be wrong: one element wider than the
   viewport makes the whole document scroll horizontally, and the reader blames
   the page rather than the element. These are the causes that were actually
   present, not a general tidy-up. */

/* A long unbroken string is the classic one: an email address, a URL or a TRN
   in a policy page cannot wrap at 288px and drags the document out with it.
   Scoped to prose and content, so it cannot affect code-like text elsewhere. */
.prose,.page-reading,.faq-answer,.account-card,.empty-state{overflow-wrap:anywhere}

@media (max-width:767px){
  /* Content tables come from the database, so they cannot be wrapped in a
     scroll container from a template. This is the same trade the admin already
     makes: a wide table scrolls sideways inside itself rather than squeezing
     its columns to nothing. It costs the table's implicit semantics in some
     screen readers, which is why it is a mobile-only rule and not the default. */
  .prose table{display:block;overflow-x:auto;-webkit-overflow-scrolling:touch;max-width:100%}

  /* Touch targets. A 40px control is reachable with a thumb; the pagination
     links and small pills were sized for a cursor. */
  .page-link{min-width:44px;height:44px}
  .pill-btn.small{min-height:40px}
  /* Measured in a browser rather than assumed: the hamburger renders 26x28,
     each header action 34x24 and the announcement's dismiss 13x16 — all three
     are controls a thumb has to hit. The glyphs stay the size they are; the
     padding grows the target around them. */
  .hamburger-btn{min-width:44px;min-height:44px;display:flex;align-items:center;justify-content:center;padding:0}
  .header-actions .action{min-width:44px;min-height:44px;justify-content:center}
  /* Icons only. With their labels the three actions come to 143px, and beside a
     44px hamburger and a 98px logo that is 333px of a 358px row — so the row
     wrapped and the header grew to three lines and 180px before any content.
     The badge stays: an unread count is the one thing that has to be legible. */
  .header-actions .action > span:not(.badge-count){display:none}
  /* 44 hamburger + 98 logo + 172 actions is 314, and two 24px gaps put it at
     362 in a 358px row — four pixels over, so the row wrapped and the header
     stood three lines and 180px tall. A 16px gap brings it to 346 and the
     header back to two lines. */
  .site-header .container{gap:var(--space-3)}
  .close-announcement{min-width:44px;min-height:44px;display:flex;align-items:center;justify-content:center}
  /* A product note in a 140px card at 320px had nowhere to break. */
  .product-note{overflow-wrap:anywhere}

  /* The rest of the controls a thumb has to hit, all measured at 320px:
     the quantity stepper renders 27x26, the wishlist heart 30x30, the hero
     dots 9x9 and a footer link 39x17. The recommended minimum is 44.
     Where the control has a visible shape — the stepper circle, the dot — the
     shape is left alone and the target is grown around it with transparent
     padding and background-clip, so nothing looks heavier than it did. */
  .stepper button{width:38px;height:38px;font-size:1.6rem}
  .wishlist-btn{width:40px;height:40px}
  .hero-dots{gap:0}
  .hero-dots button{width:9px;height:9px;padding:0;border:12px solid transparent;
    background-clip:content-box;box-sizing:content-box}
  .footer-cols .col-links a{min-height:40px;display:flex;align-items:center;padding:0;margin-bottom:0}
}

/* Nothing may exceed the viewport. A guard, not a fix — if this ever starts
   doing visible work, something above it needs correcting instead. */
html,body{overflow-x:hidden}

/* ============================================================
   Brand logo and the mobile tab bar
   ============================================================ */

/* The header carried an inline leaf and the word "Saaed" set in the page font.
   The real lockup goes in as an image, sized by height so the aspect never
   drifts. A link, because a logo in a header is how people get home. */
.logo{display:flex;align-items:center;flex-shrink:0}
.logo img{height:44px;width:auto;display:block}
.footer-logo{display:inline-block;margin-bottom:var(--space-3)}
.footer-logo img{height:56px;width:auto;display:block}

@media (max-width:767px){
  .logo img{height:34px}
  .footer-logo img{height:48px}
}

/* Tab bar. The glyphs are gone; these are the icons that replaced them. */
.bottom-tabs .tab-icon{display:block;margin:0 auto .3rem}
.bottom-tabs a span{display:block;font-size:1.05rem;line-height:1}

/* The login card carried a hand-drawn leaf and the word "Saaed" set in Lora.
   It now carries the real lockup, so the type rules that styled that word are
   no longer doing anything and the image needs a size. */
.auth-brand img{height:52px;width:auto;display:block;margin-inline:auto}

/* Admin bar: the circular mark beside the wordmark. */
.admin-brand{display:flex;align-items:center;gap:.8rem}
.admin-brand img{height:26px;width:26px;flex:0 0 auto}

/* ============================================================
   Footer contact block
   ============================================================ */

/* Each number is a row: the number itself as a tel: link, WhatsApp beside it.
   Both are real targets, so both need real hit areas. */
.footer-contact-row{display:flex;align-items:center;gap:var(--space-3);flex-wrap:wrap;margin:.8rem 0}
a.footer-phone{color:var(--green-light);font-size:2rem;font-weight:700;text-decoration:none;display:inline-block;margin:0}
a.footer-phone:hover{color:#fff}
.footer-whatsapp{display:inline-flex;align-items:center;gap:.5rem;color:var(--text-on-dark-muted);
  font-size:var(--text-small);font-weight:600;text-decoration:none;border:1px solid rgba(255,255,255,.28);
  border-radius:var(--radius-pill);padding:.5rem 1.2rem;min-height:36px}
.footer-whatsapp:hover{color:#fff;border-color:rgba(255,255,255,.6)}
.footer-legal,.footer-credit{color:var(--text-on-dark-muted);font-size:var(--text-small)}
.footer-credit a{color:var(--green-light);font-weight:600;text-decoration:none}
.footer-credit a:hover{color:#fff;text-decoration:underline}

@media (max-width:479px){
  a.footer-phone{font-size:var(--text-body-lg)}
}

/* Live support. Bottom-left, opposite the cart FAB, clear of the tab bar. */
.fab-support{position:fixed;bottom:2.8rem;left:2.8rem;z-index:80;display:inline-flex;align-items:center;gap:.8rem;
  background:#25D366;color:#fff;border-radius:var(--radius-pill);padding:1.2rem 1.8rem;text-decoration:none;
  font-weight:700;font-size:var(--text-small);box-shadow:var(--shadow-fab-base),var(--shadow-fab-ambient)}
.fab-support:active{box-shadow:var(--shadow-fab-base);transform:var(--press-scale)}
/* Set by initSupportFab() once the footer is on screen. Fades rather than
   snaps, and stops taking taps while it is on its way out. */
.fab-support.is-hidden{opacity:0;visibility:hidden;pointer-events:none;transform:translateY(8px)}
.fab-support{transition:opacity .2s ease,transform .2s ease,visibility .2s}
.fab-support svg{flex:0 0 auto}

@media (max-width:767px){
  /* Above the tab bar, and label off — the mark is the most recognised icon on
     a phone in this market and the pill was eating a third of the row. */
  .fab-support{bottom:8.4rem;left:1.6rem;padding:1.1rem;border-radius:50%}
  .fab-support span{display:none}
  /* The footer gets extra bottom padding at this width precisely so this button
     sits over empty green at the end of the page rather than over the payment
     line, which it used to cover. */
}
@media print{.fab-support{display:none}}

/* ============================================================
   Contact details
   ============================================================ */

.contact-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(260px,100%),1fr));gap:var(--space-3)}
.contact-card{background:var(--card-white);border:1px solid var(--input-border);border-radius:var(--radius-card);
  padding:var(--space-4);display:flex;flex-direction:column;gap:.6rem;box-shadow:var(--shadow-card)}
.contact-label{font-size:var(--text-caption-upper);text-transform:uppercase;letter-spacing:.06em;
  color:var(--text-secondary);font-weight:700}
.contact-value{font-size:var(--text-price-lg);font-weight:700;color:var(--green-brand);text-decoration:none;word-break:break-word}
.contact-value-sm{font-size:var(--text-body-lg);line-height:1.4}
a.contact-value:hover{color:var(--green-accent)}
.contact-action{font-size:var(--text-small);font-weight:600;color:var(--green-accent);text-decoration:none;min-height:32px;display:inline-flex;align-items:center}
.contact-action:hover{text-decoration:underline}
.contact-note{font-size:var(--text-small);color:var(--text-secondary)}

/* ============================================================
   Forms — one treatment, every form on the site
   ============================================================

   The fields were white boxes on white cards with a hairline border, which is
   what an unstyled browser input looks like. Nothing below changes the approved
   tokens — field radius is still 4px, the palette is untouched — the difference
   is that a field now reads as a place to type before you click in it:

     - a tinted fill, so the input is distinguishable from the card behind it
     - a heavier border that responds to hover as well as focus
     - a two-part focus state: the border goes brand green and a soft halo
       spreads behind it, so which field is active is obvious at a glance
     - one height for every control, including selects and the date pickers
     - real error and disabled states rather than a red border alone

   Everything is scoped under .field, .enquiry-form and .checkout-form so it
   cannot leak into the search bar or the newsletter row, which are their own
   approved components. */

.field input[type=text],.field input[type=tel],.field input[type=email],
.field input[type=password],.field input[type=number],.field input[type=search],
.field input[type=url],.field input[type=date],.field input[type=time],
.field select,.field textarea{
  min-height:48px;
  background:var(--neutral-cool);
  border:1px solid var(--input-border);
  box-shadow:inset 0 1px 2px rgba(0,0,0,.03);
  transition:border-color .18s ease,box-shadow .18s ease,background-color .18s ease}

.field input:hover:not(:disabled),.field select:hover:not(:disabled),.field textarea:hover:not(:disabled){
  border-color:var(--green-uplift);background:var(--card-white)}

.field input:focus,.field select:focus,.field textarea:focus{
  outline:none;background:var(--card-white);
  border-color:var(--green-accent);
  box-shadow:0 0 0 3px var(--green-light),inset 0 1px 2px rgba(0,0,0,.02)}

.field input::placeholder,.field textarea::placeholder{color:var(--text-secondary);opacity:.75}

.field input:disabled,.field select:disabled,.field textarea:disabled{
  background:var(--ceramic);color:var(--text-secondary);cursor:not-allowed;box-shadow:none}

/* Labels step back so the field itself carries the weight. Black bold labels
   above empty white boxes made the writing the loudest thing in the form. */
.field label,.field-label{font-size:var(--text-small);font-weight:600;color:var(--text-secondary);
  letter-spacing:.01em;margin-bottom:.6rem}

/* The browser's own arrow is a different shape in every engine. This is one
   chevron everywhere, drawn in the brand ink. */
.field select{
  appearance:none;-webkit-appearance:none;padding-right:4rem;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1.5 6 6.5l5-5' stroke='%2314603F' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 1.6rem center}
.field select:hover:not(:disabled),.field select:focus{background-color:var(--card-white)}

.field textarea{min-height:120px;line-height:1.55;padding-top:1.2rem}

/* Error. A red border on its own is invisible to anyone who cannot separate red
   from grey, so the message below it carries the meaning and the border only
   reinforces it. */
.field [aria-invalid=true],.field.has-error input,.field.has-error select,.field.has-error textarea{
  border-color:var(--sale-red);background:#FEF7F6}
.field [aria-invalid=true]:focus,.field.has-error input:focus{
  border-color:var(--sale-red);box-shadow:0 0 0 3px rgba(196,32,20,.14)}
.field-error{display:flex;align-items:flex-start;gap:.5rem;font-size:var(--text-micro);
  color:var(--sale-red);font-weight:600;margin-top:.6rem}
.field-error::before{content:"!";flex:0 0 auto;width:15px;height:15px;border-radius:50%;
  background:var(--sale-red);color:#fff;font-size:1.1rem;line-height:15px;text-align:center;font-weight:700}

.field-hint{margin-top:.6rem;line-height:1.45}

/* Checkboxes and radios pick up the brand colour instead of the OS blue, and
   get a hit area rather than being a 13px square with a label beside it. */
.field input[type=checkbox],.field input[type=radio],
.consent-line input[type=checkbox],.checkout-form input[type=checkbox]{
  accent-color:var(--green-accent);width:18px;height:18px;flex:0 0 auto;cursor:pointer}
.checkbox-line{display:flex;align-items:flex-start;gap:1rem;min-height:44px;
  font-size:var(--text-small);line-height:1.45;cursor:pointer}

/* A fieldset used as a group of related questions, e.g. the delivery slot. */
.field-group{border:1px solid var(--input-border);border-radius:var(--radius-card);
  padding:var(--space-4);margin-bottom:var(--space-4);background:var(--card-white)}
.field-group > legend{font-size:var(--text-small);font-weight:700;color:var(--text-primary);padding:0 .8rem}

@media (max-width:767px){
  /* 16px, not 14px. Anything under 16px makes iOS Safari zoom the page in when
     the field takes focus, and it does not zoom back out. */
  .field input[type=text],.field input[type=tel],.field input[type=email],
  .field input[type=password],.field input[type=number],.field input[type=search],
  .field input[type=url],.field input[type=date],.field input[type=time],
  .field select,.field textarea{font-size:16px}
}

/* Footer column headings: "Customer Support & Information" is the only one that
   runs to two lines on a desktop column, which pushed its list down while the
   other three started level. Reserving two lines everywhere lines all four up.
   Desktop only — on mobile the headings are accordion buttons in a single
   column and nothing needs to align with anything. */
@media (min-width:1024px){
  .footer-cols h4{min-height:4.2rem}
}

/* The category marquee runs continuously, so at any moment a tile is half in
   and half out at each end. Butted against the container edge that reads as a
   card sliced in two rather than as a row that carries on; the fade makes the
   same tiles dissolve into the page. mask-image needs the -webkit- prefix for
   Safari, which is most of this site's traffic. */
.category-marquee{
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 4rem,#000 calc(100% - 4rem),transparent 100%);
          mask-image:linear-gradient(90deg,transparent 0,#000 4rem,#000 calc(100% - 4rem),transparent 100%)}
@media (max-width:767px){
  .category-marquee{
    -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 2rem,#000 calc(100% - 2rem),transparent 100%);
            mask-image:linear-gradient(90deg,transparent 0,#000 2rem,#000 calc(100% - 2rem),transparent 100%)}
}

/* The account tabs scrolled sideways, so on a narrow screen the last one was
   sliced by the viewport edge with nothing to say it could be scrolled — it
   just looked cut off. Five tabs and a log-out link fit on two wrapped rows at
   any width, and nothing is ever hidden. */
@media (max-width:900px){
  .account-nav ul{flex-wrap:wrap;overflow-x:visible;gap:var(--space-2) 1rem}
  .account-nav li a{padding:.9rem 1.6rem}
  .account-logout{margin-top:var(--space-3)}
}

/* Narrow phones — 360px and under, which is most of the Android side of this
   market. The header's top row does not fit at 36px of logo plus three 44px
   buttons, so the lockup steps down one more notch. Everything stays on one
   row, which is the whole point. */
@media (max-width:389px){
  .logo img{height:28px}
  .header-actions{gap:.4rem}
  .site-header .container{gap:.8rem}
  .hamburger-btn{min-width:38px}
}

/* ============================================================
   Order on WhatsApp — the second button on a product card
   ============================================================

   It takes a line of its own at every width, including desktop. "Order on
   WhatsApp" is about 140px of text; a 340px card that already carries a 108px
   stepper and an Add button has nowhere to put it alongside them. Outlined
   rather than solid, so the green Add button stays the primary action and this
   reads as the alternative it is. */
.wa-btn{flex:1 0 100%;display:inline-flex;align-items:center;justify-content:center;gap:.6rem;
  min-height:40px;padding:.8rem 1.2rem;border-radius:var(--radius-pill);
  border:1px solid #25D366;background:transparent;color:#128C4A;
  font-family:var(--font-sans);font-size:var(--text-small);font-weight:600;cursor:pointer;
  transition:background-color .15s ease,color .15s ease}
.wa-btn:hover{background:#25D366;color:#fff}
.wa-btn:active{transform:var(--press-scale)}
.wa-btn svg{flex:0 0 auto}

/* The card's button row has to allow the wrap this depends on. It already does
   below 768px; above it the row was nowrap. */
.card-bottom{flex-wrap:wrap;row-gap:.8rem}

@media (max-width:479px){
  /* Same step-down the rest of the card takes at this width. The label stays —
     an unlabelled green circle beside an "Add" button is a guess, and this one
     leaves the site. */
  .wa-btn{min-height:36px;padding:.6rem .8rem;font-size:var(--text-micro);gap:.4rem}
  .wa-btn svg{width:13px;height:13px}
}

@media print{.wa-btn{display:none}}

/* "Order on WhatsApp" is 17 characters and a 171px card gives the button about
   155px, so it broke onto two lines and the button grew to 46px. Below 480px it
   says "WhatsApp" instead — beside a button that already says "Add", and with
   the mark next to it, that is not ambiguous. Both labels are in the markup and
   CSS picks one, because swapping text in JavaScript would leave the
   server-rendered card saying something different until the script ran. */
.wa-short{display:none}
@media (max-width:479px){
  .wa-long{display:none}
  .wa-short{display:inline}
}
