/* ==========================================================================
   Unique Global Marketing — public styles
   White theme · curved dividers · professional · easy to read
   ========================================================================== */

:root{
  --white:#ffffff;
  --surface:#f6f8fb;
  --surface-2:#eef2f8;
  --ink:#181b20;
  --ink-soft:#2c323b;
  --muted:#5c6673;
  --line:#e6eaf1;
  --red:#c1272d;
  --red-dark:#9e1f24;
  --red-soft:#fceaeb;
  --gold:#e0a437;
  --wa:#25d366;
  --wa-dark:#1da851;
  --ok:#1f9d55; --ok-soft:#e5f6ec;
  --warn:#c9862b; --warn-soft:#fbf0dd;
  --info:#2b6cb0; --info-soft:#e6f0fa;
  --off:#8a94a3; --off-soft:#eef1f5;

  --radius-sm:10px; --radius:16px; --radius-lg:26px; --radius-xl:36px;
  --shadow-sm:0 2px 8px rgba(24,27,32,.06);
  --shadow:0 12px 30px -12px rgba(24,27,32,.18);
  --shadow-lg:0 30px 60px -25px rgba(24,27,32,.30);
  --container:1200px;
  --font:'Segoe UI',system-ui,-apple-system,Roboto,'Helvetica Neue',Arial,sans-serif;
}

*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;background:#12151a}
body{
  margin:0;font-family:var(--font);color:var(--ink);background:var(--white);
  line-height:1.65;font-size:16.5px;-webkit-font-smoothing:antialiased;overflow-x:hidden;
}
img{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
h1,h2,h3,h4{line-height:1.18;margin:0;color:var(--ink);font-weight:800;letter-spacing:-.015em}
p{margin:0}
ul{margin:0;padding:0;list-style:none}
:focus-visible{outline:3px solid var(--red);outline-offset:2px;border-radius:6px}

.container{width:100%;max-width:var(--container);margin:0 auto;padding:0 22px}
.ic{width:20px;height:20px;flex:0 0 auto}
.ic-lg{width:46px;height:46px;color:var(--muted)}
.muted{color:var(--muted)}
.center{text-align:center}
section{position:relative}

.skip-link{position:absolute;left:-9999px;top:0;background:var(--red);color:#fff;padding:10px 16px;z-index:200;border-radius:0 0 8px 0}
.skip-link:focus{left:0}

/* ---------- Buttons ---------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.5em;
  font-weight:700;font-size:.98rem;line-height:1;cursor:pointer;
  padding:.85em 1.4em;border-radius:999px;border:2px solid transparent;
  transition:transform .15s ease,box-shadow .2s ease,background .2s ease,color .2s ease,border-color .2s ease;
  white-space:nowrap;text-align:center;
}
.btn .ic{width:1.15em;height:1.15em}
.btn:hover{transform:translateY(-2px)}
.btn:active{transform:translateY(0)}
.btn-sm{padding:.62em 1em;font-size:.86rem}
.btn-lg{padding:1em 1.7em;font-size:1.02rem}
.btn-primary{background:var(--red);color:#fff;box-shadow:0 10px 22px -10px var(--red)}
.btn-primary:hover{background:var(--red-dark)}
/* "WhatsApp / Contact" CTAs — quiet white/outline so they don't shout (palette: black·red·white) */
/* The price-list CTA sits at the far right of the header as just its WhatsApp mark,
   because a full sentence there was taking the width the navigation needs.
   The label appears on hover as a TOOLTIP, not by widening the button. That matters:
   in Turkish one line of header already needs 1250 of a 1280 laptop, so a label that
   pushed its siblings would overflow the row the moment the pointer arrived. A tooltip
   is out of flow, so hovering cannot change any layout. No lift either — a button that
   jumps while something appears next to it reads as two things moving at once. */
.header-cta{position:relative;padding-left:.85em;padding-right:.85em;gap:0}
.header-cta:hover,.header-cta:focus-visible{transform:none}
.header-cta .cta-label{position:absolute;top:calc(100% + 10px);right:0;z-index:2;
  padding:.45em .7em;border-radius:9px;background:var(--ink);color:#fff;
  font-size:.82rem;font-weight:600;white-space:nowrap;pointer-events:none;
  opacity:0;transform:translateY(-4px);
  transition:opacity .18s ease, transform .18s ease}
.header-cta:hover .cta-label,
.header-cta:focus-visible .cta-label{opacity:1;transform:translateY(0)}
/* Touch has no hover, so the tooltip would never show; the drawer's full-width copy
   of this button carries the words there instead. */
@media (hover:none){
  .header-cta .cta-label{display:none}
}

.btn-wa{background:#fff;color:var(--ink);border-color:var(--line)}
.btn-wa:hover{background:var(--surface);border-color:#cdd4de;color:var(--ink)}
.btn-wa .ic{color:var(--ink)}
.btn-outline{background:#fff;color:var(--ink);border-color:var(--line)}
.btn-outline:hover{border-color:var(--red);color:var(--red)}
.btn-ghost{background:rgba(255,255,255,.14);color:#fff;border-color:rgba(255,255,255,.4)}
.btn-ghost:hover{background:#fff;color:var(--red)}
/* An author display: on .btn beats the UA [hidden]{display:none}, so a .btn we
   hide with the hidden attribute (e.g. the redundant "Update cart" once JS
   auto-updates) would stay visible without this. */
.btn[hidden]{display:none}

.kicker{display:inline-block;font-weight:800;text-transform:uppercase;letter-spacing:.12em;
  font-size:.78rem;color:var(--red);margin-bottom:.6rem}
.eyebrow{display:inline-flex;align-items:center;gap:.5em;background:var(--red-soft);color:var(--red-dark);
  font-weight:700;font-size:.82rem;padding:.5em .95em;border-radius:999px;margin-bottom:1.1rem}
.eyebrow .ic{width:16px;height:16px}

.section-head{display:flex;justify-content:space-between;align-items:flex-end;gap:24px;margin-bottom:34px;flex-wrap:wrap}
.section-head.center{flex-direction:column;align-items:center;text-align:center}
.section-head h1,.section-head h2{font-size:clamp(1.7rem,3.4vw,2.4rem)}
.section-head .lead{color:var(--muted);margin-top:.5rem;max-width:52ch}
/* The "single items? -> Shop" pointer under the lead. Only rendered when the
   retail shop is switched on (index.php). */
.section-head .lead-note{margin-top:.55rem;font-size:.9rem;color:var(--muted);max-width:52ch}
.section-head .lead-note a{color:var(--red);font-weight:700;text-decoration:underline;
  text-underline-offset:2px}
.section-head .lead-note a:hover{color:var(--red-dark)}

/* ==========================================================================
   Header
   ========================================================================== */
/* The frosted glass lives on a ::before, NOT on .site-header itself: a backdrop-filter
   on the header would make it the containing block for the position:fixed mobile nav
   drawer, trapping the drawer inside the 74px header instead of the viewport. */
.site-header{position:sticky;top:0;z-index:100;border-bottom:1px solid var(--line)}
.site-header::before{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:rgba(255,255,255,.86);backdrop-filter:saturate(160%) blur(12px)}
.header-inner{display:flex;align-items:center;gap:20px;height:74px}
.brand-logo{height:46px;width:auto}
.main-nav{display:flex;align-items:center;gap:6px;margin-left:14px}
/* nowrap, or a label that no longer fits silently breaks onto two lines and the
   header looks fine while being 40px too narrow — which is exactly how the first
   measurement of this row got the breakpoint wrong. */
.main-nav>a{padding:.55em .78em;border-radius:999px;font-weight:600;color:var(--ink-soft);
  transition:.2s;white-space:nowrap}
.main-nav>a:hover{background:var(--surface);color:var(--red)}
/* Nav points at real pages now, so mark the one we're on. */
.main-nav>a.is-active{background:var(--red-soft);color:var(--red)}
.nav-actions-mobile{display:none}
.header-actions{display:flex;align-items:center;gap:12px;margin-left:auto}
.lang-switch{position:relative;display:inline-flex;background:var(--surface);border:1px solid var(--line);border-radius:999px;padding:3px}
.lang-switch .lang-opt{position:relative;z-index:2;padding:.42em .85em;font-weight:700;font-size:.82rem;color:var(--muted);border-radius:999px;transition:color .28s ease}
.lang-switch .lang-opt.is-active{color:#fff}
.lang-pill{position:absolute;top:3px;bottom:3px;left:3px;width:0;z-index:1;background:var(--red);border-radius:999px;
  transition:left .3s cubic-bezier(.34,1.2,.44,1),width .3s cubic-bezier(.34,1.2,.44,1)}
/* ---- the menu button ----
   Three bars that fold into an X, so one control both opens and closes the drawer
   (which is why the drawer lost its separate close button: the thing you pressed is
   still under your thumb). 44px because that is the smallest square a thumb hits
   reliably. The header sits above the drawer, so this stays visible and animates
   while the panel is open. */
.nav-toggle{display:none;align-items:center;justify-content:center;width:44px;height:44px;padding:0;
  background:var(--surface);border:1px solid var(--line);border-radius:12px;color:var(--ink);cursor:pointer;
  transition:background .2s ease,border-color .2s ease}
.nav-toggle:hover{background:#fff;border-color:#cdd4de}
.nav-toggle:focus-visible{outline:3px solid var(--red);outline-offset:2px}
.burger{position:relative;display:block;width:22px;height:16px}
.burger i{position:absolute;left:0;width:22px;height:2.4px;border-radius:99px;background:currentColor;
  transition:transform .3s cubic-bezier(.2,.8,.2,1), opacity .18s ease, width .3s ease, left .3s ease}
.burger i:nth-child(1){top:0}
.burger i:nth-child(2){top:6.8px}
.burger i:nth-child(3){bottom:0}
.nav-toggle[aria-expanded="true"] .burger i:nth-child(1){transform:rotate(45deg);transform-origin:top left;width:23px;left:3px}
.nav-toggle[aria-expanded="true"] .burger i:nth-child(3){transform:rotate(-45deg);transform-origin:bottom left;width:23px;left:3px}
.nav-toggle[aria-expanded="true"] .burger i:nth-child(2){transform:translateX(-12px);opacity:0}

/* Tapping beside an open drawer is how everyone closes one. The dim also says the
   page behind is out of play, which a bare white panel floating at the edge does not. */
.nav-scrim{display:none;position:fixed;inset:0;z-index:80;background:rgba(16,20,26,.42);
  opacity:0;visibility:hidden;transition:opacity .28s ease, visibility .28s ease}
body.nav-open .nav-scrim{opacity:1;visibility:visible}

/* Layering inside the header, which is one stacking context (z-index:100):
   scrim 80 < drawer 90 < the header row itself. The row has to stay on top or the
   panel would slide over the very button that closes it, and the logo and cart
   would be dimmed by the scrim they are supposed to sit above. */
.brand,.header-actions{position:relative;z-index:95}

/* ==========================================================================
   Hero
   ========================================================================== */
.hero{position:relative;padding:70px 0 130px;background:
  radial-gradient(120% 90% at 85% -10%,var(--red-soft) 0%,transparent 55%),
  linear-gradient(180deg,#fff 0%,var(--surface) 100%);overflow:hidden}
.hero-blob{position:absolute;border-radius:50%;filter:blur(10px);opacity:.5;z-index:0}
.hero-blob-1{width:420px;height:420px;background:radial-gradient(circle at 30% 30%,#fddfe1,transparent 70%);top:-120px;right:-60px}
.hero-blob-2{width:320px;height:320px;background:radial-gradient(circle at 30% 30%,#f1f3f7,transparent 70%);bottom:20px;left:-120px}
.hero-inner{position:relative;z-index:2;display:grid;grid-template-columns:1.05fr .95fr;gap:56px;align-items:center}
.hero-title{font-size:clamp(2.2rem,4.8vw,3.5rem);letter-spacing:-.02em}
.hero-sub{color:var(--muted);font-size:1.12rem;margin-top:1.1rem;max-width:52ch}
.hero-cta{display:flex;gap:14px;margin-top:1.8rem;flex-wrap:wrap}
.hero-stats{display:flex;gap:34px;margin-top:2.4rem;flex-wrap:wrap}
.hero-stats strong{display:block;font-size:1.7rem;color:var(--red);font-weight:800}
.hero-stats span{color:var(--muted);font-size:.9rem}

.hero-visual{position:relative}
.hero-card{position:relative;border-radius:var(--radius-xl);overflow:hidden;box-shadow:var(--shadow-lg);
  border:8px solid #fff;background:var(--surface-2);aspect-ratio:4/5}
.hero-card img{width:100%;height:100%;object-fit:cover}
.hero-card::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,rgba(20,22,28,.06) 0%,transparent 28%,transparent 60%,rgba(20,22,28,.36) 100%)}
.hero-card-tag{position:absolute;top:16px;left:16px;z-index:2;display:inline-flex;align-items:center;gap:.45em;
  background:rgba(255,255,255,.92);color:var(--ink);font-weight:700;font-size:.8rem;
  padding:.5em .85em;border-radius:999px;box-shadow:var(--shadow-sm)}
.hero-card-tag .ic{width:15px;height:15px;color:var(--red)}
.hero-badge{position:absolute;bottom:-24px;left:-24px;background:#fff;border-radius:var(--radius);z-index:3;
  box-shadow:var(--shadow);padding:14px 18px;display:flex;align-items:center;gap:12px}
.hero-badge .ic{width:34px;height:34px;color:var(--red)}
.hero-badge strong{display:block;font-size:.95rem}
.hero-badge span{color:var(--muted);font-size:.82rem}

.section-wave{position:absolute;left:0;right:0;bottom:-1px;line-height:0;z-index:1}
.section-wave svg{width:100%;height:80px;display:block}
.section-wave path{fill:#fff}

/* ==========================================================================
   Features
   ========================================================================== */
.features{padding:20px 0 30px;background:#fff}
.feature-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:22px;margin-top:-70px;position:relative;z-index:5}
.feature{background:#fff;border:1px solid var(--line);border-radius:var(--radius-lg);padding:26px 22px;
  box-shadow:var(--shadow-sm);transition:transform .2s,box-shadow .2s}
.feature:hover{transform:translateY(-4px);box-shadow:var(--shadow)}
.feature-ic{display:inline-flex;padding:13px;border-radius:14px;background:var(--red-soft);color:var(--red);margin-bottom:14px}
.feature-ic .ic{width:26px;height:26px}
.feature h3{font-size:1.12rem;margin-bottom:.4rem}
.feature p{color:var(--muted);font-size:.95rem}

/* ==========================================================================
   Categories
   ========================================================================== */
.categories{padding:70px 0}
.category-grid{display:grid;grid-template-columns:repeat(6,1fr);gap:16px}
.category-card{display:flex;flex-direction:column;align-items:center;gap:10px;text-align:center;
  padding:26px 14px;background:#fff;border:1px solid var(--line);border-radius:var(--radius);
  position:relative;transition:transform .2s,box-shadow .2s,border-color .2s}
.category-card:hover{transform:translateY(-4px);box-shadow:var(--shadow);border-color:var(--red-soft)}
.cat-ic{display:inline-flex;padding:14px;border-radius:50%;background:var(--surface);color:var(--red);transition:.2s}
.category-card:hover .cat-ic{background:var(--red);color:#fff}
.cat-ic .ic{width:28px;height:28px}
.cat-name{font-weight:700;font-size:.98rem}
.cat-count{position:absolute;top:12px;right:12px;min-width:22px;height:22px;padding:0 6px;border-radius:999px;
  background:var(--surface-2);color:var(--muted);font-size:.74rem;font-weight:700;display:grid;place-items:center}

/* ==========================================================================
   Products
   ========================================================================== */
/* ==========================================================================
   New arrivals strip — quiet auto-rotating row between hero and catalogue.
   Without JS it degrades to a plain clipped row of the newest products.
   ========================================================================== */
/* Opens the home page now that the hero has moved to /about.php — the soft red
   wash keeps the brand feel the hero used to carry at the top of the page. */
.newstrip{padding:40px 0 22px;background:
  radial-gradient(120% 170% at 85% -60%,var(--red-soft) 0%,transparent 60%),#fff}
.newstrip-head{display:flex;justify-content:space-between;align-items:center;gap:16px;margin-bottom:16px}
.newstrip-nav{display:flex;gap:8px;flex:0 0 auto}
/* 42px, up from 34: the controls have to be "obvious at a glance" (Baymard), and
   a 34px circle beside a now much larger card read as an afterthought. */
.newstrip-btn{display:inline-flex;align-items:center;justify-content:center;width:42px;height:42px;padding:0;
  border:1px solid var(--line);border-radius:999px;background:#fff;color:var(--muted);cursor:pointer;
  transition:color .2s,border-color .2s,background .2s}
.newstrip-btn:hover{color:var(--red);border-color:var(--red-soft);background:var(--red-soft)}
.newstrip-btn .ic{width:18px;height:18px}

/* The peeking card is cut by the viewport edge, which on its own reads as a
   clipping bug. Fading that edge makes it read as "the row continues" instead.
   A mask rather than a white gradient because the section sits on a red wash,
   not on flat white; unsupported browsers just get the hard edge back. */
.newstrip-viewport{overflow:hidden;
  -webkit-mask-image:linear-gradient(to right,#000 86%,rgba(0,0,0,.15) 100%);
  mask-image:linear-gradient(to right,#000 86%,rgba(0,0,0,.15) 100%)}
/* JS measures a card's width + this gap to size one step — keep them in sync. */
.newstrip-track{display:flex;gap:18px;transition:transform .6s cubic-bezier(.4,0,.2,1)}

/* The card IS the photo. Basis is deliberately fractional so a slice of the next
   card is always visible — that peek is the only thing telling a visitor the row
   continues, and it replaces the progress dots the research argues against. */
.nsi{flex:0 0 calc((100% - 18px * 3) / 3.4);position:relative;display:block;
  border-radius:var(--radius);overflow:hidden;background:var(--surface)}
.nsi-media{display:block;position:relative;aspect-ratio:4/3;overflow:hidden;background:var(--surface)}
.nsi-media img{display:block;width:100%;height:100%;object-fit:cover;
  transition:transform .55s cubic-bezier(.2,0,.2,1)}
/* Contained zoom: the frame holds, the photo grows inside it. */
.nsi:hover .nsi-media img{transform:scale(1.05)}
/* No category photo yet: the category's own icon on a tinted panel. An empty
   grey box reads as a broken image; this reads as a deliberate state. */
.nsi-media.is-icon{display:flex;align-items:center;justify-content:center;
  background:var(--red-soft);color:var(--red)}
.nsi-media.is-icon .ic{width:38px;height:38px}

/* The scrim is what makes white text legible over an unknown photo — the category
   images are stock and their bottom edge can be any brightness. ~.74 black where
   the text sits clears the 4.5:1 contrast floor with room to spare; it fades out
   by 68% so the top of the photo is untouched. */
.nsi-media::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(to top,rgba(0,0,0,.74) 0%,rgba(0,0,0,.42) 34%,rgba(0,0,0,0) 68%)}
.nsi-label{position:absolute;left:16px;right:16px;bottom:13px;z-index:1;
  color:#fff;font-weight:700;font-size:1rem;line-height:1.25;text-shadow:0 1px 2px rgba(0,0,0,.45)}

@media (max-width:1100px){.nsi{flex-basis:calc((100% - 18px * 2) / 2.8)}}
@media (max-width:820px){.nsi{flex-basis:calc((100% - 18px * 2) / 2.3)}}
@media (max-width:560px){.nsi{flex-basis:calc((100% - 18px) / 1.35)}}
@media (prefers-reduced-motion:reduce){
  .newstrip-track{transition:none}
  .nsi-media img,.nsi:hover .nsi-media img{transition:none;transform:none}
}

.products-section{padding:40px 0 80px;background:linear-gradient(180deg,#fff,var(--surface))}
.search-form{display:flex;align-items:center;gap:8px;background:#fff;border:1px solid var(--line);
  border-radius:999px;padding:6px 6px 6px 14px;box-shadow:var(--shadow-sm);min-width:min(360px,100%)}
.search-form .search-ic{color:var(--muted);display:inline-flex}
.search-form input{border:0;outline:0;flex:1;font-size:.95rem;background:transparent;min-width:0}
.filter-chips{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:30px}
.chip{padding:.5em 1.1em;border-radius:999px;background:#fff;border:1px solid var(--line);
  font-weight:600;font-size:.9rem;color:var(--ink-soft);transition:.2s}
.chip:hover{border-color:var(--red);color:var(--red)}
.chip.is-active{background:var(--red);border-color:var(--red);color:#fff}

.product-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:24px}
.product-card{background:#fff;border:1px solid var(--line);border-radius:var(--radius-lg);overflow:hidden;
  display:flex;flex-direction:column;transition:transform .2s,box-shadow .2s;box-shadow:var(--shadow-sm)}
.product-card:hover{transform:translateY(-5px);box-shadow:var(--shadow)}
.pc-media{position:relative;display:block;aspect-ratio:4/3;background:var(--surface-2)}
.pc-media img{width:100%;height:100%;object-fit:cover}
.pc-avail{position:absolute;top:12px;left:12px;font-size:.72rem;font-weight:700;padding:.32em .7em;border-radius:999px;
  background:#fff;box-shadow:var(--shadow-sm)}
/* Wholesale tag. Sits opposite the availability pill so the two cannot collide,
   and ink-on-white rather than red — red is the out-of-stock signal here, and a
   tag every card carries must not read as an alert. Palette stays black/red/white
   (CLAUDE.md 9b). */
.pc-wholesale{position:absolute;top:12px;right:12px;font-size:.68rem;font-weight:800;
  text-transform:uppercase;letter-spacing:.07em;padding:.34em .72em;border-radius:999px;
  background:var(--ink);color:#fff;box-shadow:var(--shadow-sm)}
/* Availability tags stay within the palette: neutral for available states, red for out-of-stock */
.avail-in_stock{color:var(--ink-soft);background:var(--surface-2)}
.avail-limited{color:var(--ink-soft);background:var(--surface-2)}
.avail-on_order{color:var(--ink-soft);background:var(--surface-2)}
.avail-out_of_stock{color:var(--red-dark);background:var(--red-soft)}
.pc-body{padding:18px;display:flex;flex-direction:column;gap:6px;flex:1}
.pc-cat{font-size:.76rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--red)}
.pc-title{font-size:1.06rem;font-weight:750}
.pc-title a:hover{color:var(--red)}
.pc-brand{color:var(--muted);font-size:.88rem}
.pc-pack{display:flex;align-items:center;gap:6px;color:var(--ink-soft);font-size:.88rem;font-weight:600}
.pc-pack .ic{width:16px;height:16px;color:var(--muted)}
.pc-actions{display:flex;gap:8px;margin-top:auto;padding-top:12px}
.pc-actions .btn{flex:1}

.empty-state{display:flex;flex-direction:column;align-items:center;gap:14px;padding:60px 20px;
  background:#fff;border:1px dashed var(--line);border-radius:var(--radius-lg);color:var(--muted)}

/* ---- Catalogue pager (index.php + shop.php, CLAUDE.md 9t) ---- */
.pager{display:flex;flex-direction:column;align-items:center;gap:14px;margin-top:38px}
.pager-count{margin:0;color:var(--muted);font-size:.85rem}
.pager-list{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;gap:6px;
  margin:0;padding:0;list-style:none}
.pager-btn,.pager-num{display:inline-flex;align-items:center;justify-content:center;gap:6px;
  min-width:40px;height:40px;padding:0 12px;border:1.5px solid var(--line);border-radius:11px;
  background:#fff;color:var(--ink);font-size:.9rem;font-weight:600;line-height:1;transition:.18s}
.pager-btn .ic{width:16px;height:16px}
.pager-num{padding:0 6px}
.pager-btn:hover,.pager-num:hover{border-color:var(--red);color:var(--red)}
.pager-num.is-active{background:var(--red);border-color:var(--red);color:#fff;cursor:default}
.pager-num.is-active:hover{color:#fff}
/* Disabled prev/next stay in place rather than disappearing: the row must not
   reflow between page 1, the middle pages and the last one. */
.pager-btn.is-disabled{opacity:.4;pointer-events:none}
.pager-gap{display:inline-flex;align-items:center;justify-content:center;min-width:22px;
  height:40px;color:var(--muted)}
@media (max-width:520px){
  /* Phones keep the numbers — they are how you get to page 8 — and drop only
     the prev/next wording, which the arrows already say. */
  .pager-btn span{display:none}
  .pager-btn{min-width:40px;padding:0 10px}
}

/* ==========================================================================
   About
   ========================================================================== */
.about{padding:90px 0}
.about-inner{display:grid;grid-template-columns:minmax(0,420px) 1fr;gap:56px;align-items:center}
.about-features-head{margin-top:64px;margin-bottom:26px}
.about .feature-grid{margin-top:0}
.about-visual{position:relative}
/* height:auto is required — the img's width/height HTML attributes otherwise leak a
   fixed presentational height and override aspect-ratio (rendering it far too tall). */
.about-visual img{display:block;width:100%;height:auto;aspect-ratio:13/14;object-fit:cover;
  border-radius:var(--radius-xl);box-shadow:var(--shadow-lg);position:relative;z-index:2}
.about-shape{position:absolute;inset:-22px -22px auto auto;width:70%;height:80%;border-radius:var(--radius-xl);
  background:linear-gradient(135deg,var(--red-soft),#f1f3f7);z-index:1}
.about-copy p{color:var(--muted);font-size:1.05rem;margin-top:.6rem}
.about-copy .btn{margin-top:1.9rem}
.about-points{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin:24px 0 28px}
.about-points li{display:flex;align-items:center;gap:10px;font-weight:600}
.about-points .ic{width:20px;height:20px;color:#fff;background:var(--red);border-radius:50%;padding:3px}

/* ==========================================================================
   CTA band
   ========================================================================== */
/* ==========================================================================
   Simple page header + contact cards (About / Contact are real pages now)
   ========================================================================== */
/* .page-head does two jobs and only one of them wants a background.
   contact.php renders it as <section class="page-head">, full-bleed, where the
   gradient reads as a page header band running edge to edge. cart, checkout,
   account-order and order-track put the same class on a <div> INSIDE a
   container, and there the identical gradient paints a grey rectangle floating
   behind the title, stopping at the column edge — which is what the owner
   reported on order-track.php. The padding is shared; the paint is scoped to
   the band. */
.page-head{padding:64px 0 12px}
section.page-head{background:
  radial-gradient(120% 100% at 85% -20%,var(--red-soft) 0%,transparent 55%),
  linear-gradient(180deg,#fff 0%,var(--surface) 100%)}
.page-head h1{font-size:clamp(1.9rem,4vw,2.8rem);margin:0}
.page-head .lead{color:var(--muted);margin-top:.6rem;max-width:56ch}

.contact-section{padding:34px 0 80px;background:linear-gradient(180deg,var(--surface),#fff)}
/* auto-fit, not a fixed 4: the email + social cards only render when those
   settings are filled in, so the row has to look right with 3 cards too. */
.contact-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:18px}
.contact-card{display:flex;flex-direction:column;align-items:flex-start;gap:.3rem;padding:26px 22px;
  background:#fff;border:1px solid var(--line);border-radius:var(--radius-lg);box-shadow:var(--shadow-sm);
  transition:transform .2s,box-shadow .2s,border-color .2s}
.contact-card:not(.is-static):hover{transform:translateY(-4px);box-shadow:var(--shadow);border-color:var(--red-soft)}
.contact-ic{display:inline-flex;padding:11px;border-radius:12px;background:var(--red-soft);color:var(--red);margin-bottom:.6rem}
.contact-card h2{font-size:1.05rem;margin:0}
.contact-card p{color:var(--muted);margin:0;overflow-wrap:anywhere}
.contact-go{display:inline-flex;align-items:center;gap:.4em;margin-top:auto;padding-top:.9rem;
  color:var(--red);font-weight:700;font-size:.85rem}
.contact-go .ic{width:15px;height:15px;transition:transform .2s}
.contact-card:hover .contact-go .ic{transform:translateX(3px)}

/* .social is built for the dark footer — lighten it for this white page. */
.contact-follow{margin-top:44px;text-align:center}
.contact-follow .social{justify-content:center}
.contact-follow .social a{background:#fff;border:1px solid var(--line);color:var(--ink-soft)}
.contact-follow .social a:hover{background:var(--red);border-color:var(--red);color:#fff}

.cta-band{padding:64px 0;background:
  radial-gradient(120% 140% at 10% 0%,#d8332f 0%,transparent 60%),
  linear-gradient(120deg,var(--red-dark),var(--red));color:#fff;position:relative;overflow:hidden}
.cta-band::after{content:"";position:absolute;right:-80px;top:-80px;width:340px;height:340px;border-radius:50%;
  background:rgba(255,255,255,.08)}
.cta-inner{position:relative;z-index:2;display:flex;justify-content:space-between;align-items:center;gap:30px;flex-wrap:wrap}
.cta-inner h2{color:#fff;font-size:clamp(1.6rem,3vw,2.2rem)}
.cta-inner p{color:rgba(255,255,255,.9);margin-top:.4rem;max-width:46ch}
.cta-actions{display:flex;gap:14px;flex-wrap:wrap}

/* ==========================================================================
   Footer
   ========================================================================== */
.site-footer{position:relative;background:#12151a;color:#c7cdd6;padding-top:70px}
.footer-wave{position:absolute;left:0;right:0;bottom:100%;margin-bottom:-2px;line-height:0;pointer-events:none}
.footer-wave svg{width:100%;height:60px;display:block}
.footer-wave path{fill:#12151a}
.footer-grid{display:grid;grid-template-columns:1.5fr 1fr 1fr 1.4fr;gap:40px;padding-bottom:40px}
.footer-logo{height:38px;width:auto;background:#fff;padding:10px 14px;border-radius:12px;margin-bottom:14px}
.footer-brand p{color:#9aa3b0;font-size:.94rem;max-width:34ch}
.footer-col h4{color:#fff;font-size:1rem;margin-bottom:16px}
.footer-col ul li{margin-bottom:10px}
.footer-col a:hover{color:#fff}
.contact-list li{display:flex;gap:10px;margin-bottom:14px;align-items:flex-start}
.contact-list .ic{width:20px;height:20px;color:var(--red);flex:0 0 auto;margin-top:2px}
.social{display:flex;gap:10px;margin-top:18px}
.social a{display:inline-flex;padding:9px;border-radius:10px;background:#1d222b;color:#fff;transition:.2s}
.social a:hover{background:var(--red)}
.footer-bottom{border-top:1px solid #232833;padding:20px 0}
.footer-bottom .container{display:flex;justify-content:space-between;gap:12px;flex-wrap:wrap;font-size:.86rem;color:#8a94a3}
.footer-since{color:#aab2be}

/* ==========================================================================
   Product detail
   ========================================================================== */
.product-detail{padding:34px 0 80px}
.breadcrumb{display:flex;align-items:center;gap:6px;flex-wrap:wrap;color:var(--muted);font-size:.9rem;margin-bottom:26px}
.breadcrumb a:hover{color:var(--red)}
.breadcrumb .sep{width:16px;height:16px;color:var(--line)}
.pd-grid{display:grid;grid-template-columns:1fr 1fr;gap:50px;align-items:start}
.pd-main{position:relative;border-radius:var(--radius-lg);overflow:hidden;background:var(--surface-2);
  border:1px solid var(--line);aspect-ratio:4/3;box-shadow:var(--shadow)}
.pd-main img{width:100%;height:100%;object-fit:cover}
.pd-thumbs{display:flex;gap:10px;margin-top:14px;flex-wrap:wrap}
.pd-thumb{padding:0;border:2px solid var(--line);border-radius:12px;overflow:hidden;cursor:pointer;background:#fff;width:88px;aspect-ratio:4/3}
.pd-thumb img{width:100%;height:100%;object-fit:cover}
.pd-thumb.is-active{border-color:var(--red)}
.pd-cat{color:var(--red);font-weight:700;text-transform:uppercase;letter-spacing:.06em;font-size:.8rem}
.pd-title{font-size:clamp(1.7rem,3.4vw,2.4rem);margin:.4rem 0}
.pd-brand{color:var(--muted);margin-bottom:.6rem}
.pd-lead{font-size:1.08rem;color:var(--ink-soft);margin-bottom:1.2rem}
.pd-quickfacts{border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;margin-bottom:24px}
.pd-quickfacts li{display:flex;justify-content:space-between;gap:16px;padding:12px 18px}
.pd-quickfacts li:nth-child(odd){background:var(--surface)}
.pd-quickfacts span{color:var(--muted)}
.pd-quickfacts em{font-style:normal;font-weight:700;text-align:right}
.avail-text{padding:.2em .7em;border-radius:999px;font-size:.85rem}
.pd-cta{display:flex;gap:12px;flex-wrap:wrap}
.pd-note{display:flex;align-items:center;gap:10px;color:var(--muted);font-size:.9rem;margin-top:16px}
.pd-note .ic{width:18px;height:18px;color:var(--ok)}

.pd-details{display:grid;grid-template-columns:1fr 1fr;gap:40px;margin-top:56px}
.pd-block h2{font-size:1.35rem;margin-bottom:16px;padding-bottom:12px;border-bottom:2px solid var(--line)}
.prose{color:var(--ink-soft)}
.spec-table{width:100%;border-collapse:collapse}
.spec-table th,.spec-table td{text-align:left;padding:12px 14px;border-bottom:1px solid var(--line);font-size:.96rem}
.spec-table th{color:var(--muted);font-weight:600;width:45%}
.spec-table tr:nth-child(even){background:var(--surface)}
.pd-related{margin-top:70px}

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width:1080px){
  .feature-grid{grid-template-columns:repeat(2,1fr);margin-top:-50px}
  .category-grid{grid-template-columns:repeat(3,1fr)}
  .product-grid{grid-template-columns:repeat(3,1fr)}
}
@media (max-width:900px){
  .hero-inner{grid-template-columns:1fr;gap:40px}
  .hero-visual{max-width:460px}
  .about-inner{grid-template-columns:1fr;gap:40px}
  .about-visual{max-width:380px;margin:0 auto}
  .pd-grid{grid-template-columns:1fr;gap:30px}
  .pd-details{grid-template-columns:1fr;gap:28px}
}
/* The CTA is icon-only at every width now (see .header-cta above), so the old
   max-width:1024 rule that hid its label has gone: it would have fought the
   hover animation for control of the same span. */
/* Nav collapses to the hamburger drawer at ≤820 (was 760). The widest language —
   Turkish, with the Shop nav item on — plus the header actions needs ~782px, so
   the full nav overflowed ~14px at 768 (iPad portrait) in TR. Collapsing a touch
   earlier fits every language. The page-layout breakpoints below stay at 760. */
/* Two steps, both MEASURED (CLAUDE.md 9x.8), in BOTH signed-out and signed-in states —
   the account button changes word when someone signs in, and in Swahili that was the
   widest label on the row. One line of header needs 1071px in English, 1176 in Turkish
   and 1179 in Swahili, so the nav folds into the drawer at 1220 and every window above
   that keeps the full row with ~40px to spare. Measuring is not optional here: the first
   attempt read 1024 off a nav that had quietly wrapped to two lines, and the second
   inflated everything by 75px on a wrong guess about the logo. */
@media (max-width:1220px){
  .nav-toggle{display:inline-flex}
  .nav-scrim{display:block}
  /* Starts under the header rather than behind it: the row above stays whole, and
     the panel reads as hanging off it instead of the logo floating on top of it.
     74px is .header-inner's height. */
  .main-nav{position:fixed;inset:74px 0 0 auto;width:min(320px,84vw);background:#fff;flex-direction:column;
    align-items:stretch;padding:22px 20px 30px;gap:6px;box-shadow:var(--shadow-lg);transform:translateX(100%);
    transition:transform .28s cubic-bezier(.2,.8,.2,1);margin:0;z-index:90;overflow-y:auto;
    border-top:1px solid var(--line)}
  .main-nav.open{transform:translateX(0)}
  .main-nav>a{padding:.9em 1em;border-radius:12px;font-size:1.05rem}
  .nav-actions-mobile{display:block;margin-top:18px;padding-top:18px;border-top:1px solid var(--line)}
  .nav-actions-mobile .btn{width:100%}
}

/* The phone header keeps only what a thumb needs on every page: the logo, the cart
   with its badge, and the menu. The language switcher and the price-list CTA move
   into the drawer, which already carried the CTA. */
@media (max-width:820px){
  .header-actions .lang-switch-header{display:none}
  .header-cta{display:none}
  .lang-switch-drawer{display:flex;width:100%;margin-top:12px}
  .lang-switch-drawer .lang-opt{flex:1;text-align:center}
}
@media (max-width:760px){
  .product-grid{grid-template-columns:repeat(2,1fr);gap:16px}
  .category-grid{grid-template-columns:repeat(2,1fr)}
  .section-head{margin-bottom:24px}
  .about-points{grid-template-columns:1fr}
  .cta-inner{flex-direction:column;align-items:flex-start}
  .footer-grid{grid-template-columns:1fr 1fr;gap:30px 24px}
  .footer-brand{grid-column:1/-1}
}
@media (max-width:460px){
  body{font-size:16px}
  .hero{padding:40px 0 110px}
  .product-grid{grid-template-columns:1fr}
  .feature-grid{grid-template-columns:1fr;margin-top:-40px}
  .pc-actions{flex-direction:column}
  .pc-actions .btn-wa span{display:inline}
  .wa-float-label{display:none}
}
/* ==========================================================================
   Motion — scroll reveals + ambient animations
   Base "hidden" states apply ONLY when JS has marked the document (.reveal-js)
   AND the visitor has not asked for reduced motion — so content is always
   visible without JS or with reduced-motion preferences.
   ========================================================================== */
@media (prefers-reduced-motion:no-preference){
  /* Single-element scroll reveals */
  .reveal-js [data-reveal]{opacity:0;transform:translateY(30px);
    transition:opacity .8s cubic-bezier(.22,.61,.36,1),transform .8s cubic-bezier(.22,.61,.36,1);
    transition-delay:var(--rd,0s);will-change:opacity,transform}
  .reveal-js [data-reveal="left"]{transform:translateX(-40px)}
  .reveal-js [data-reveal="right"]{transform:translateX(40px)}
  .reveal-js [data-reveal="scale"]{transform:scale(.93)}
  .reveal-js [data-reveal].is-revealed{opacity:1;transform:none}

  /* Staggered groups: children cascade in when the group scrolls into view */
  .reveal-js [data-reveal-group]>*{opacity:0;transform:translateY(28px);
    transition:opacity .6s cubic-bezier(.22,.61,.36,1),transform .6s cubic-bezier(.22,.61,.36,1)}
  .reveal-js [data-reveal-group].is-revealed>*{opacity:1;transform:none}
  .reveal-js [data-reveal-group].is-revealed>*:nth-child(1){transition-delay:.04s}
  .reveal-js [data-reveal-group].is-revealed>*:nth-child(2){transition-delay:.10s}
  .reveal-js [data-reveal-group].is-revealed>*:nth-child(3){transition-delay:.16s}
  .reveal-js [data-reveal-group].is-revealed>*:nth-child(4){transition-delay:.22s}
  .reveal-js [data-reveal-group].is-revealed>*:nth-child(5){transition-delay:.28s}
  .reveal-js [data-reveal-group].is-revealed>*:nth-child(6){transition-delay:.34s}
  .reveal-js [data-reveal-group].is-revealed>*:nth-child(7){transition-delay:.40s}
  .reveal-js [data-reveal-group].is-revealed>*:nth-child(n+8){transition-delay:.46s}

  /* Ambient motion: slowly drifting hero blobs, gently floating hero card */
  .hero-blob-1{animation:ug-float-a 17s ease-in-out infinite}
  .hero-blob-2{animation:ug-float-b 21s ease-in-out infinite}
  .about-shape{animation:ug-float-b 19s ease-in-out infinite}
  .hero-card{animation:ug-card-float 7.5s ease-in-out infinite}
  @keyframes ug-float-a{0%,100%{transform:translate(0,0)}50%{transform:translate(-16px,20px)}}
  @keyframes ug-float-b{0%,100%{transform:translate(0,0)}50%{transform:translate(18px,-14px)}}
  @keyframes ug-card-float{0%,100%{transform:translateY(0)}50%{transform:translateY(-9px)}}

  /* Trailing arrow nudges on hover */
  .btn .ic:last-child{transition:transform .25s ease}
  .btn:hover .ic:last-child{transform:translateX(3px)}
}
/* The left/right reveals start life at translateX(±40px), and an element sitting
   flush against the container's edge is therefore 40px past it until it reveals —
   which is real horizontal scroll for anyone who has not scrolled there yet.
   .container is max-width:1200 with 22px padding, so the content edge is at
   viewport-22 and the slide reaches viewport+18: it overflows at EVERY width below
   1200 + 2*(40-22) = 1236px, not just on phones. This was previously capped at
   900px, which left the whole 901-1235px band (tablets, small laptops) scrolling
   sideways. Slide vertically below the real threshold instead; wider screens have
   the margin to absorb it. */
@media (max-width:1235px) and (prefers-reduced-motion:no-preference){
  .reveal-js [data-reveal="left"],.reveal-js [data-reveal="right"]{transform:translateY(30px)}
}
@media (prefers-reduced-motion:reduce){
  *{animation:none!important;transition:none!important;scroll-behavior:auto!important}
}

/* =========================================================================
   RETAIL SHOP  —  the only part of the site that shows prices (CLAUDE.md 5)
   ====================================================================== */

/* -- small utilities the public side did not need until now -- */
.section{padding:56px 0}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}
.btn.full{width:100%;justify-content:center}
.flash{padding:12px 16px;border-radius:var(--radius-sm);margin-bottom:18px;font-size:.95rem;
  border:1px solid var(--line);background:var(--surface)}
.flash-success{background:var(--ok-soft);border-color:#bfe6cd;color:#14603a}
.flash-error{background:var(--red-soft);border-color:#f0c4c6;color:var(--red-dark)}
.hint{color:var(--muted);font-size:.9rem;line-height:1.5}

/* -- header cart button -- */
.cart-btn{position:relative;display:inline-flex;align-items:center;justify-content:center;
  width:42px;height:42px;border-radius:12px;border:1px solid var(--line);background:#fff;
  color:var(--ink);transition:border-color .2s,color .2s}
.cart-btn:hover,.cart-btn.is-active{border-color:var(--red);color:var(--red)}

/* Cart and account carry their word next to the mark: these customers are older and
   not phone-confident, and an outline of a box is a guessing game where "Cart" is not.
   The pair needs a pill rather than a square, and the badge moves inside it so it does
   not float over the text. */
.hdr-btn{width:auto;height:42px;padding:0 .85em;gap:.45em;border-radius:999px;font-weight:700;
  font-size:.94rem;white-space:nowrap}
.hdr-btn .ic{width:19px;height:19px;flex:0 0 auto}
.hdr-label{line-height:1}
.hdr-btn .cart-badge{position:static;top:auto;right:auto;margin-left:.15em}
.cart-badge{position:absolute;top:-6px;right:-6px;min-width:19px;height:19px;padding:0 5px;
  border-radius:999px;background:var(--red);color:#fff;font-size:.7rem;font-weight:800;
  display:flex;align-items:center;justify-content:center;line-height:1}

/* -- price on the shop card -- */
.shop-card .pc-price{margin-top:.55rem;display:flex;align-items:baseline;gap:.45rem;flex-wrap:wrap}
.pc-price-val{font-size:1.3rem;font-weight:800;color:var(--ink);letter-spacing:-.02em}
.pc-price-unit{font-size:.85rem;color:var(--muted)}
/* An unpriced product keeps its place in the grid rather than vanishing, so the
   shop still reads as complete while the owner is part-way through pricing. */
.pc-price-req{font-size:.98rem;font-weight:700;color:var(--muted)}
.shop-card .pc-actions{flex-direction:column;align-items:stretch;gap:.5rem}
.shop-card .add-form{width:100%}
.pc-incart{font-size:.8rem;color:var(--muted);text-align:center}

/* -- cart page -- */
.cart-layout{display:grid;grid-template-columns:1fr minmax(0,340px);gap:28px;align-items:start}
.cart-lines{display:flex;flex-direction:column;gap:12px}
.cart-line{display:grid;grid-template-columns:96px 1fr auto auto auto;gap:14px;align-items:center;
  padding:12px;border:1px solid var(--line);border-radius:var(--radius);background:#fff}
.cl-media img{width:96px;height:72px;object-fit:cover;border-radius:10px;display:block}
.cl-name{font-weight:700;color:var(--ink);display:block;line-height:1.3}
.cl-name:hover{color:var(--red)}
.cl-unit{font-size:.85rem;color:var(--muted);margin-top:.2rem}
.cl-qty input{width:68px;padding:8px 10px;border:1px solid var(--line);border-radius:10px;
  font:inherit;text-align:center}
.cl-total{font-weight:800;min-width:96px;text-align:right}
/* Per line remove. Quiet until you want it: a muted outline that turns red on
   hover, the same language .mc-btn-del speaks in the mini-cart, but 34px rather
   than 24 because this one is a primary control on a page you reach on a phone. */
.cl-remove{width:34px;height:34px;padding:0;flex:none;display:inline-flex;
  align-items:center;justify-content:center;border:1px solid var(--line);border-radius:9px;
  background:#fff;color:var(--muted);cursor:pointer;transition:background .15s,color .15s,border-color .15s}
.cl-remove .ic{width:16px;height:16px}
.cl-remove:hover{background:var(--red);color:#fff;border-color:var(--red)}
.cl-remove:focus-visible{outline:3px solid var(--red);outline-offset:2px}
.cart-lines-actions{display:flex;gap:10px;flex-wrap:wrap;margin-top:6px}

.cart-summary{border:1px solid var(--line);border-radius:var(--radius);background:#fff;
  padding:20px;position:sticky;top:96px;display:flex;flex-direction:column;gap:16px}
.cart-summary h2{font-size:1.05rem}
.cart-fulfil{display:flex;flex-direction:column;gap:10px}
.radio-row{display:flex;align-items:center;gap:10px;cursor:pointer;font-size:.95rem}
.radio-row input{accent-color:var(--red);width:17px;height:17px}
.cart-area select{width:100%;padding:9px 11px;border:1px solid var(--line);border-radius:10px;
  font:inherit;background:#fff;transition:opacity .2s}
.cart-area.is-dim{opacity:.45}
.cart-totals{border-top:1px solid var(--line);padding-top:14px;display:flex;flex-direction:column;gap:9px}
.ct-row{display:flex;justify-content:space-between;gap:12px;font-size:.95rem;color:var(--muted)}
.ct-total{border-top:1px solid var(--line);padding-top:11px;margin-top:3px;
  font-size:1.15rem;font-weight:800;color:var(--ink)}
.cart-pay-note{text-align:center;margin:0}

@media (max-width:900px){
  .cart-layout{grid-template-columns:1fr}
  .cart-summary{position:static}
}
@media (max-width:560px){
  /* Keep the qty + line total on one row under the name rather than letting the
     4-column grid squeeze the name to nothing. */
  .cart-line{grid-template-columns:72px 1fr auto;
    grid-template-areas:'media body body' 'qty total del';row-gap:10px}
  .cl-media{grid-area:media}
  .cl-media img{width:72px;height:54px}
  .cl-body{grid-area:body}
  .cl-qty{grid-area:qty}
  .cl-total{grid-area:total;text-align:right;align-self:center;min-width:0}
  /* Bottom right, on the row the customer is already touching to change the
     quantity, rather than up beside the name where a thumb reaching for it
     passes over the product link. */
  .cl-remove{grid-area:del}
}
/* ---- checkout: the final "are you sure" (9ah) ----
   The public twin of the admin confirm modal. Same anatomy, public palette, and
   left aligned rather than centred because the body is a LIST the customer is
   meant to read down, not a one line question. */
.order-confirm{position:fixed;inset:0;background:rgba(18,21,26,.72);z-index:220;
  display:flex;align-items:center;justify-content:center;padding:18px}
.order-confirm[hidden]{display:none}
body.oc-open{overflow:hidden}
.oc-dialog{background:#fff;border-radius:16px;width:min(460px,100%);
  max-height:calc(100vh - 36px);padding:24px 24px 20px;box-shadow:var(--shadow);
  display:flex;flex-direction:column;gap:.6rem}
/* dvh, where it exists, is the viewport MINUS the mobile browser's own chrome.
   100vh on iOS is the height with the URL bar hidden, so a full dialog sized in
   vh runs off the bottom of the screen and takes the buttons with it. Browsers
   that do not know dvh ignore this line and keep the one above. */
@supports (max-height:100dvh){ .oc-dialog{max-height:calc(100dvh - 36px)} }
.oc-title{font-size:1.16rem;margin:0;color:var(--ink)}
.oc-lead{margin:0;color:var(--muted);font-size:.9rem;line-height:1.55}
/* A long basket scrolls INSIDE the dialog so the buttons never leave the screen.
   ONLY THE LINE LIST SCROLLS, and it is the ONLY shrinkable child of the dialog.
   Two bugs came out of getting this wrong, both found by measuring rather than
   looking: with the totals inside the scroller a twelve line basket pushed the
   total 113px below the fold, and with the totals inside a wrapper that could
   itself shrink, a 380px tall screen shrank the wrapper under its own content
   and the total painted on top of the buttons.
   min-height:0 is what actually lets the list shrink: a flex item refuses to go
   below its content height without it, so the dialog would overflow rather than
   scroll. Everything else is flex:none, so there is nothing else to squash. */
.oc-lines{overflow-y:auto;min-height:0;flex:1 1 auto;padding:14px 0;
  margin-top:.4rem;border-top:1px solid var(--line)}
.oc-lines .co-lines{margin:0}
.oc-totals{flex:0 0 auto;border-top:1px solid var(--line);padding-top:12px}
.oc-totals .cart-totals{border-top:0;padding-top:0}
.oc-title,.oc-lead,.oc-foot{flex:0 0 auto}
.oc-foot{display:flex;gap:10px;justify-content:flex-end;margin-top:.5rem;flex-wrap:wrap}
.oc-foot .btn{min-width:130px;justify-content:center}
/* A phone held sideways is about 390px tall. The explanation has done its job by
   then and the list is what the customer needs the room for, so the lead line
   stands down rather than squeezing the goods into two rows. */
@media (max-height:560px){
  .oc-lead{display:none}
  .oc-lines{padding:10px 0}
}
@media (max-width:460px){
  .oc-dialog{padding:20px 18px 16px}
  /* Stacked, and the confirm button FIRST so it sits under the thumb rather
     than the one that throws the order away. */
  .oc-foot{flex-direction:column-reverse}
  .oc-foot .btn{flex:1 1 100%;width:100%}
}

.flash-stack{padding-top:18px}
.flash-stack .flash:last-child{margin-bottom:0}

/* ==========================================================================
   Customer accounts / checkout / orders  (CLAUDE.md 9h.3)
   ========================================================================== */

.section-narrow{padding:44px 0 72px}
.container-slim{max-width:960px}

/* ---- auth cards (sign in, reset, verify) ---- */
.auth-card{background:#fff;border:1px solid var(--line);border-radius:var(--radius-lg);
  padding:34px;max-width:440px;margin:0 auto;box-shadow:var(--shadow-sm)}
.auth-card h1{font-size:1.6rem;margin:0 0 .35rem}
.auth-sub{color:var(--muted);font-size:.94rem;margin:0 0 1.4rem}
.auth-note{color:var(--muted);font-size:.86rem;line-height:1.5;margin:1.2rem 0 .9rem;
  padding-top:1.2rem;border-top:1px solid var(--line)}
.auth-links{display:flex;justify-content:center;margin-top:1rem}
.auth-links a{color:var(--muted);font-size:.88rem}
.auth-links a:hover{color:var(--red)}

.auth-form{display:flex;flex-direction:column;gap:1rem}
.auth-form label,.field-grid label,.checkout-delivery label{display:flex;flex-direction:column;
  gap:.4rem;font-size:.85rem;font-weight:600;color:var(--ink-soft)}
.auth-form input,.auth-form select,.auth-form textarea,
.field-grid input,.field-grid select,.field-grid textarea,
.checkout-delivery input,.checkout-delivery select,.checkout-delivery textarea,
.card-plain > label input,.card-plain > label select,.card-plain > label textarea{
  width:100%;padding:.72rem .85rem;border:1px solid var(--line);border-radius:var(--radius-sm);
  font:inherit;font-weight:400;color:var(--ink);background:#fff}
.auth-form input:focus,.field-grid input:focus,.checkout-delivery textarea:focus,
.field-grid textarea:focus,.card-plain textarea:focus,.card-plain select:focus{
  outline:none;border-color:var(--red);box-shadow:0 0 0 3px var(--red-soft)}
.auth-form input:disabled{background:var(--surface);color:var(--muted);cursor:not-allowed}
.auth-form .check{flex-direction:row;align-items:center;gap:.55rem;font-weight:400;
  font-size:.88rem;color:var(--muted);cursor:pointer}
.auth-form .check input{width:auto;accent-color:var(--red)}

/* The native select arrow is drawn hard against the right edge, so it sat well
   outside the field's own .85rem text inset and read as misaligned. Draw our own
   chevron instead and give it the SAME inset as the text on the other side. */
.auth-form select,.field-grid select,.checkout-delivery select,
.card-plain > label select,.cart-area select{
  -webkit-appearance:none;-moz-appearance:none;appearance:none;padding-right:2.5rem;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%235A6473' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right .85rem center;background-size:14px 14px}
.cart-area select{padding-right:2.1rem;background-position:right 11px center}

/* One-time code: wide, spaced digits so a 6-digit code can be read back and
   checked against the mail at a glance. Centred, because there is nothing else
   in the field to align to. */
.code-input{font-size:1.5rem;font-weight:700;letter-spacing:.42em;text-align:center;
  text-indent:.42em;font-variant-numeric:tabular-nums}

/* ---- errors ---- */
.form-error{background:var(--red-soft);border:1px solid #f0c3c5;color:var(--red-dark);
  border-radius:var(--radius-sm);padding:.7rem .85rem;font-size:.88rem;margin-bottom:1rem}
.field-err{color:var(--red);font-size:.78rem;font-weight:600}

/* ---- generic white card used across account/checkout ---- */
.card-plain{background:#fff;border:1px solid var(--line);border-radius:var(--radius);
  padding:24px;box-shadow:var(--shadow-sm);display:flex;flex-direction:column;gap:1rem}
.card-plain h2{font-size:1.12rem;margin:0}
.card-plain > form{display:flex;flex-direction:column;gap:1rem}
.muted{color:var(--muted)}

/* Status boxes. They sit between a heading and a button often enough that the
   spacing belongs on the box itself — as a bare <p> they inherited none and
   ended up wedged against both. `margin` (not margin-top) so a box that is the
   last thing in a card is not flush against its floor either. */
.hint-ok{background:var(--ok-soft);border:1px solid #bfe3cd;color:#146c3a;
  border-radius:var(--radius-sm);padding:.7rem .85rem;margin:1.1rem 0;line-height:1.5;
  display:flex;align-items:center;gap:.4rem}
.hint-ok .ic{width:15px;height:15px;flex:none}
.hint-warn{background:var(--warn-soft);border:1px solid #ecd6a8;color:#7a5312;
  border-radius:var(--radius-sm);padding:.7rem .85rem;margin:1.1rem 0;line-height:1.5}

/* ---- status pills ---- */
.pill{display:inline-block;padding:.24em .7em;border-radius:999px;font-size:.74rem;
  font-weight:700;letter-spacing:.02em;white-space:nowrap;
  background:var(--off-soft);color:var(--off)}
.order-st-new{background:var(--info-soft);color:var(--info)}
.order-st-confirmed{background:var(--warn-soft);color:var(--warn)}
.order-st-delivered{background:var(--ok-soft);color:var(--ok)}
.order-st-cancelled{background:var(--red-soft);color:var(--red)}

/* ---- account page ---- */
.account-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,360px);gap:24px;align-items:start}
.account-main,.account-side{display:flex;flex-direction:column;gap:20px;min-width:0}

.order-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
.order-row{display:flex;align-items:center;gap:14px;padding:14px 0;border-bottom:1px solid var(--line)}
.order-row:last-child{border-bottom:0;padding-bottom:0}
.order-row-main{display:flex;flex-direction:column;gap:.2rem;min-width:0;flex:1}
.order-ref{font-weight:700;color:var(--ink)}
.order-ref:hover{color:var(--red)}
.order-meta{font-size:.8rem;color:var(--muted)}
.order-total{white-space:nowrap;font-size:.98rem}

.order-dl{display:grid;grid-template-columns:auto 1fr;gap:.5rem 1.2rem;margin:0;font-size:.92rem}
.order-dl dt{color:var(--muted);font-weight:600}
.order-dl dd{margin:0;color:var(--ink)}

/* ---- checkout: getting a returning customer to sign in ----
   Two treatments, because there are two moments. The prompt is always there, above
   the fields, for someone who knows they have an account. The alert only appears
   once the form has told them the email or phone is already taken, and it carries
   the button that resolves it — the old version said so in a red line under one
   field, which reads as "you have made a mistake" rather than "come in this way". */
.signin-prompt{display:flex;align-items:center;gap:.75rem;flex-wrap:wrap;
  margin:.2rem 0 1.1rem;padding:.7rem .9rem;border:1px solid var(--line);
  border-radius:12px;background:var(--surface);font-size:.94rem;color:var(--ink)}
.signin-prompt .btn{flex:0 0 auto}

.signin-alert{display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  margin:0 0 1.1rem;padding:14px 16px;border:1.5px solid var(--red);border-radius:14px;
  background:var(--red-soft)}
.signin-alert .sa-ic{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;
  width:40px;height:40px;border-radius:11px;background:#fff;color:var(--red)}
.signin-alert .sa-text{flex:1 1 220px;min-width:0}
.signin-alert strong{display:block;font-size:1.02rem;color:var(--ink);line-height:1.3}
.signin-alert p{margin:.2rem 0 0;font-size:.92rem;color:var(--ink-soft);line-height:1.45}
.signin-alert .btn{flex:0 0 auto}
@media (max-width:560px){
  .signin-alert .btn{width:100%}
}

/* ---- checkout ---- */
.checkout-layout{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,380px);
  gap:24px;align-items:start;margin-top:28px}
.checkout-main{display:flex;flex-direction:column;gap:20px;min-width:0}
.checkout-summary{position:sticky;top:96px;min-width:0}
.field-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1rem}
.checkout-delivery{display:flex;flex-direction:column;gap:1rem;
  padding:0 0 .4rem 27px;border-left:2px solid var(--line);margin-left:8px}
.checkout-delivery[hidden]{display:none}

.co-lines{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.6rem;
  font-size:.9rem}
.co-lines li{display:flex;gap:.6rem;align-items:baseline}
.co-qty{color:var(--muted);font-weight:700;flex:none}
.co-name{flex:1;min-width:0}
.co-name small{display:block;color:var(--muted);font-size:.78rem;font-weight:400}
.co-amt{white-space:nowrap;font-weight:600}

/* Free delivery over N items (9ae). Stated next to the choice, not left to be
   discovered in the summary, which is the mistake 9r fixed for the fee itself.
   Ink when it is a rule, red when the basket has earned it: the palette is black,
   red and white, and red is the site's "look here" colour. */
.free-ship-note{display:flex;align-items:flex-start;gap:9px;margin:12px 0 0;padding:.7em .9em;
  border:1px solid var(--line);border-radius:12px;background:var(--surface);
  color:var(--muted);font-size:.88rem;line-height:1.5}
.free-ship-note .ic{width:18px;height:18px;flex:none;margin-top:1px;color:var(--muted)}
.free-ship-note.is-earned{border-color:var(--red);background:var(--red-soft);color:var(--red);
  font-weight:600}
.free-ship-note.is-earned .ic{color:var(--red)}
/* The shortfall line is the one the customer can DO something about, so it is
   the loud one. Quiet grey was right while it only reported a rule; now that the
   rule withholds delivery, this line is the way back in. Ink on white with a red
   spine and a red icon, and the AMOUNT carries the emphasis, because "how much
   more" is the only part he has to remember. Distinct from .is-earned on purpose:
   that one is a red-tinted confirmation, this one is an instruction. */
.free-ship-note.is-goal{border-color:var(--line);border-left:4px solid var(--red);
  background:#fff;color:var(--ink);font-size:.93rem;font-weight:600;
  box-shadow:0 6px 18px -12px rgba(20,25,35,.5);
  /* Square on the left, because a 4px border bent around a 12px radius draws a
     red bracket rather than a spine. Flat left, rounded right, reads as a pulled
     out callout, which is what this is. */
  border-radius:0 12px 12px 0}
.free-ship-note.is-goal .ic{color:var(--red);width:20px;height:20px}
.free-ship-note .fsn-amt{color:var(--red);font-weight:800;white-space:nowrap}

/* Where to collect it (9aj). Indented under the pickup choice, the same 31px the
   delivery fields use, so it reads as detail belonging to the row above rather
   than a second unrelated block. */
.pickup-where{display:flex;align-items:flex-start;gap:12px;margin:0 0 14px 31px;
  padding:12px 14px;border:1px solid var(--line);border-radius:12px;background:var(--surface)}
.pickup-where[hidden]{display:none}
.pickup-where .pw-ic{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;
  width:34px;height:34px;border-radius:10px;background:#fff;color:var(--red)}
.pickup-where .pw-ic .ic{width:18px;height:18px}
.pickup-where .pw-text{display:flex;flex-direction:column;gap:2px;min-width:0}
.pickup-where .pw-label{font-size:.78rem;letter-spacing:.04em;text-transform:uppercase;
  color:var(--muted);font-weight:700}
.pickup-where .pw-addr{color:var(--ink);font-weight:650;line-height:1.4}
@media (max-width:520px){
  .pickup-where{margin-left:0}
}

/* ---- the order receipt (9ad) ----
   Narrow, monospaced, top to bottom, because everybody already knows how to read
   a till receipt. The old layout was two cards in a 960px column, which put a
   product name and its price most of a metre apart on a desktop. */
.receipt{max-width:400px;margin:0 auto;background:#fff;color:var(--ink);
  border:1px solid var(--line);border-radius:8px;padding:26px 24px 22px;
  box-shadow:0 10px 30px rgba(20,25,35,.07);position:relative;
  font-family:ui-monospace,"SF Mono",Menlo,Consolas,"Liberation Mono",monospace;
  font-size:.82rem;line-height:1.6;font-variant-numeric:tabular-nums}
/* The owner's small print, on top of every invoice-like view (9ak+): the paper
   is a record of the order, not a legal tax document, and says so itself. */
.receipt-disclaimer{margin:0 0 10px;text-align:center;color:var(--muted);
  font-size:.62rem;letter-spacing:.04em;text-transform:uppercase}
.receipt-head{text-align:center;margin-bottom:14px}
/* The wordmark keeps the brand face; everything under it is the printed part. */
.receipt-brand{font-family:var(--font);font-weight:800;letter-spacing:.06em;
  font-size:.95rem;margin:0 0 4px;color:var(--ink)}
.receipt-brand span{color:var(--red)}
.receipt-sub{margin:0;color:var(--muted);font-size:.72rem;line-height:1.5}
/* A dashed rule drawn in CSS, not typed: the house rule bans dashes in text. */
.receipt-rule{border-top:1px dashed var(--line);margin:12px 0}
.receipt-meta{margin:0;display:flex;flex-direction:column;gap:4px}
.receipt-meta>div{display:flex;gap:12px;align-items:baseline}
.receipt-meta dt{color:var(--muted);flex:none;min-width:104px}
.receipt-meta dd{margin:0;flex:1;word-break:break-word}
.receipt-lines{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:9px}
.receipt-lines li{display:flex;flex-wrap:wrap;gap:0 10px;align-items:baseline}
.rl-name{flex:1;min-width:0}
.rl-amt{flex:none;font-weight:700}
.rl-note{flex-basis:100%;color:var(--muted);font-size:.72rem;padding-left:1.2em}
.receipt-totals{display:flex;flex-direction:column;gap:5px}
.rt-row{display:flex;justify-content:space-between;gap:12px}
.rt-row span:first-child{color:var(--muted)}
.rt-total{margin-top:7px;padding-top:9px;border-top:1px solid var(--ink);font-weight:800;font-size:.95rem}
.rt-total span:first-child{color:var(--ink);text-transform:uppercase;letter-spacing:.04em}
.receipt-foot{margin:0;text-align:center;color:var(--muted);font-size:.72rem;line-height:1.55}
.receipt-thanks{margin-top:6px;color:var(--ink);font-weight:700}
.receipt-actions{max-width:400px;margin:34px auto 0;display:flex;gap:10px;flex-wrap:wrap;
  justify-content:center}

/* The other receipts, so a customer can move between them without going back to
   his account page and in again. Two columns on a desktop; on a phone the list
   drops BELOW the paper, because he tapped one order and that is what he came
   for. The markup order is list first, so `order` does the moving. */
/* THREE columns, and the empty third one is the point: with only "list, paper"
   the pair is centred as a unit and the receipt sits right of centre. A mirror
   column puts the paper on the page's centre line and leaves the list at the
   left edge, which is what the owner asked for. */
.receipt-layout{display:grid;gap:30px;align-items:start;
  grid-template-columns:1fr minmax(0,400px) 1fr}
.receipt-side{order:1;grid-column:1;justify-self:start;width:250px;position:sticky;top:96px}
.receipt-layout>.receipt,.receipt-layout>.receipt-actions{order:2;grid-column:2}
/* The download, at the paper's right hand: it lives in the mirror column 9ad
   left empty for centring, so it costs the layout nothing. */
.receipt-dl{order:2;grid-column:3;justify-self:start;position:sticky;top:96px}
.rs-title{font-size:.95rem;margin:0 0 10px}
.rs-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px}
.rs-item{display:grid;grid-template-columns:1fr auto;gap:2px 10px;padding:.7em .85em;
  border:1px solid var(--line);border-radius:12px;background:#fff;text-decoration:none;
  color:var(--ink);transition:border-color .15s,background .15s}
.rs-item:hover{border-color:var(--ink)}
.rs-ref{font-weight:700;font-size:.86rem;letter-spacing:.02em}
.rs-amt{font-weight:700;font-size:.86rem;text-align:right}
.rs-meta,.rs-st{color:var(--muted);font-size:.76rem}
.rs-st{text-align:right}
/* The one you are looking at. Red border and tint, which is the same "this is
   selected" language the category chips and the checkout radios already use. */
.rs-item.is-current{border-color:var(--red);background:var(--red-soft)}
.rs-item.is-current .rs-ref,.rs-item.is-current .rs-amt{color:var(--red)}
/* 250 + 400 + 250 plus two gaps plus the container's padding needs about
   1010px. Below that the mirror column has nowhere to live, so the list goes
   under the paper rather than shoving it off centre. */
@media (max-width:1010px){
  .receipt-layout{grid-template-columns:minmax(0,400px);justify-content:center}
  .receipt-side{width:auto}
  .receipt-layout>.receipt,.receipt-layout>.receipt-actions{grid-column:1}
  /* Paper first, list after it. */
  .receipt-side{order:3;position:static;margin-top:8px}
  .receipt-actions{margin-top:26px}
  /* The download lands between the paper and the actions row (DOM order). */
  .receipt-dl{grid-column:1;position:static;justify-self:center;margin-top:4px}
}
@media (max-width:460px){
  /* The label column narrows but stays a column: stacking label over value made
     the paper twice as long and stopped reading like a receipt. */
  .receipt{padding:22px 16px 18px;font-size:.78rem}
  .receipt-meta dt{min-width:86px}
  .receipt-meta>div{gap:8px}
}

/* Printing one leaves the paper and nothing else, so "save as PDF" gives the
   customer the receipt rather than a screenshot of a web page. */
@media print{
  .site-header,.site-footer,.receipt-actions,.receipt-side,.receipt-dl,.nav-scrim,.cta-band,.wave,.toast{display:none!important}
  body{background:#fff}
  .section{padding:0!important}
  .receipt-layout{display:block}
  .receipt{max-width:none;width:100%;border:0;box-shadow:none;padding:0;font-size:11pt}
  [data-reveal]{opacity:1!important;transform:none!important}
}

/* ---- order notifications on a phone (9ac) ----
   Written for one thumb: the steps are a numbered list at reading size, the
   button is full width, and nothing is smaller than the body text. The person
   this page is for is not a phone enthusiast. */
.notify-card{max-width:520px;margin:0 auto;display:flex;flex-direction:column;gap:1rem}
.notify-step h2{font-size:1.05rem;margin:0 0 .6rem}
.notify-list{margin:0;padding-left:1.3em;display:flex;flex-direction:column;gap:.55rem;
  color:var(--muted);line-height:1.6}
.notify-list li{padding-left:.2em}
.notify-ios{border-left:3px solid var(--red);padding-left:14px}
.notify-name{display:block;font-weight:600;font-size:.9rem;margin-top:.2rem}
.notify-name input{width:100%;margin-top:6px;padding:.8em .9em;border:1px solid var(--line);
  border-radius:12px;font:inherit;background:#fff;color:var(--ink)}
.notify-name input:focus{outline:0;border-color:var(--red);box-shadow:0 0 0 3px var(--red-soft)}
.notify-status{margin:0;padding:.8em 1em;border-radius:12px;background:var(--surface);
  font-size:.95rem;line-height:1.55}
.notify-status[hidden]{display:none}
/* Ink, not green: the palette is black, red and white (rule 2), and red is kept
   for something being wrong, which is why only the bad state is red. */
.notify-status--good{border:1px solid var(--ink);color:var(--ink);background:#fff;font-weight:600}
.notify-status--bad{border:1px solid var(--red);color:var(--red);background:#fff}
/* The owner asked for this screen to read centred (9am). The heading, lead,
   card titles, name label and status centre; the numbered steps deliberately
   stay left aligned, because centred list rows with markers ragged on both
   sides are harder to read, and these three lines are the whole instruction. */
.page-notify .page-head{text-align:center}
.page-notify .notify-step h2{text-align:center}
.page-notify .notify-name{text-align:center}
.page-notify .notify-status{text-align:center}
.page-notify .notify-card .hint-warn{text-align:center}

/* ---- order confirmation ---- */
.order-done{background:#fff;border:1px solid var(--line);border-radius:var(--radius-lg);
  padding:38px 34px;max-width:520px;margin:0 auto;text-align:center;box-shadow:var(--shadow-sm);
  display:flex;flex-direction:column;gap:.9rem;align-items:center}
.order-done-mark{width:64px;height:64px;border-radius:50%;background:var(--ok-soft);color:var(--ok);
  display:grid;place-items:center}
.order-done-mark .ic-lg{width:30px;height:30px}
.order-done h1{font-size:1.5rem;margin:0}
/* The order code is the one thing on this page worth keeping, so it is the
   biggest thing on the card. Letter-spacing adds a trailing gap after the last
   character, which pushes centred text visibly left, so the same amount comes
   back as text-indent (the same fix the mail template needed, 9s.5). */
.order-code{width:100%;padding:16px 14px;border:1px solid var(--line);border-radius:var(--radius);
  background:var(--surface);display:flex;flex-direction:column;align-items:center;gap:4px}
.order-code-label{font-size:.76rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:var(--muted)}
.order-code-val{font-size:clamp(1.6rem,7vw,2.15rem);line-height:1.15;color:var(--ink);
  letter-spacing:.1em;text-indent:.1em;font-variant-numeric:tabular-nums;word-break:break-all}
.order-code-hint{margin:0}
/* The copy button sits on its own row so it cannot collide with the centred
   label under it — in Turkish and Swahili an absolutely positioned button does,
   at phone width. Success is INK, not green: the palette is black, red and white
   (rule 2), and red stays reserved for something being wrong, which is why the
   failure state is the one that turns red. */
.order-code-top{width:100%;display:flex;justify-content:flex-end}
.order-code-copy{display:inline-flex;align-items:center;gap:6px;padding:.34em .72em;
  border:1px solid var(--line);border-radius:999px;background:#fff;cursor:pointer;
  font:inherit;font-size:.76rem;font-weight:700;color:var(--muted);line-height:1.4;
  transition:border-color .15s,color .15s}
.order-code-copy:hover{border-color:var(--ink);color:var(--ink)}
.order-code-copy .ic{width:14px;height:14px}
.order-code-copy .copy-ic{display:inline-flex}
.order-code-copy .copy-ic[hidden]{display:none}
.order-code-copy.is-copied{border-color:var(--ink);color:var(--ink)}
.order-code-copy.is-copy-failed{border-color:var(--red);color:var(--red)}
.order-done-next{color:var(--muted);font-size:.92rem;line-height:1.6;margin:0 0 .4rem}
.order-done .btn.full{margin-top:.3rem}
.order-done-links{display:flex;gap:10px;flex-wrap:wrap;justify-content:center;margin-top:.5rem}

@media (max-width:980px){
  .account-grid,.checkout-layout{grid-template-columns:1fr}
  .checkout-summary{position:static}
}
@media (max-width:560px){
  .field-grid{grid-template-columns:1fr}
  .auth-card,.order-done{padding:26px 20px}
  .order-row{flex-wrap:wrap}
  .order-total{margin-left:auto}
}

/* The account button is the one that no longer fits: logo + cart + account +
   three languages + hamburger overflowed the viewport at 390 (measured: 17px of
   horizontal scroll on every page, gone the moment this button was removed).
   Below the hamburger breakpoint it lives in the drawer instead — see
   .nav-actions-mobile in header.php. The cart stays, because its badge is the
   thing people look for. */
@media (max-width:560px){
  .account-btn{display:none}
}
.nav-account{margin-bottom:10px}

/* ==========================================================================
   Retail extras — qty control, mini-cart, shop layout, retail detail price,
   checkout "when", order tracking, new status.  (2026-07-17)
   ========================================================================== */

/* Danger button (order-tracking cancel). Neutral until hover, then red — a
   cancel that shouts before you touch it invites a mis-click. */
.btn-danger{background:#fff;color:var(--red);border-color:var(--red-soft)}
.btn-danger:hover{background:var(--red);color:#fff;border-color:var(--red)}

/* On-the-way status pill (public). Neutral slate so it reads as "in progress"
   between the amber "confirmed" and the green "delivered". */
.order-st-shipped{background:#eef1f5;color:#41506a}
.pill-lg{font-size:.9rem;padding:.4em 1em}

/* ---- quantity control (shop card + detail) ---- */
.qty-row{display:flex;gap:8px;align-items:stretch}
.qty-field{display:flex}
.qty-field input{width:64px;text-align:center;border:1.5px solid var(--line);border-radius:12px;
  font:inherit;font-size:.95rem;padding:.5em .4em;color:var(--ink);background:#fff}
.qty-field input:focus{outline:none;border-color:var(--red)}
.qty-row .btn{flex:1 1 auto}
.pd-add .qty-row{max-width:320px}

/* ---- shop two-column layout: grid + sticky mini-cart ----
   Narrow sidebar + a wide gap so the product cards keep real width; the
   mini-cart itself is capped and pushed to the right edge of its column. */
.shop-layout{display:grid;grid-template-columns:minmax(0,1fr) 244px;gap:30px;align-items:start}
.shop-side{position:sticky;top:96px}
/* Shop grid sizes to the space it actually has (auto-fill), not a fixed 4 — the
   sidebar used to squeeze it into 4 cramped columns. Beats the shared
   .product-grid media queries on specificity, so it governs at every width.
   minmax tuned for ~4 columns on a full desktop (fewer as the screen narrows),
   with the same 4:3 image as the home cards — just smaller type. */
.page-shop .product-grid{grid-template-columns:repeat(auto-fill,minmax(192px,1fr));gap:16px}
/* Compact shop cards — tighter body, smaller type, a short "Add" label + narrow
   qty field so the add row fits a ~160px card. Scoped to the shop; the wholesale
   home cards are untouched. */
.page-shop .shop-card .pc-body{padding:11px 12px;gap:4px}
.page-shop .shop-card .pc-title{font-size:.9rem;line-height:1.22}
.page-shop .shop-card .pc-brand{font-size:.76rem}
.page-shop .shop-card .pc-price{margin-top:.35rem}
.page-shop .shop-card .pc-price-val{font-size:1.02rem}
.page-shop .shop-card .pc-price-unit{font-size:.74rem}
.page-shop .shop-card .pc-actions{padding-top:9px;gap:.4rem}
.page-shop .shop-card .qty-field input{width:42px;padding:.42em .2em;border-radius:9px;font-size:.88rem}
.page-shop .shop-card .qty-row{gap:6px}
.page-shop .shop-card .btn-sm{padding:.5em .55em;font-size:.8rem;gap:.3em}
.page-shop .shop-card .pc-avail{top:8px;left:8px;font-size:.66rem;padding:.28em .55em}
.page-shop .shop-card .pc-incart{font-size:.74rem}

.mini-cart{background:#fff;border:1px solid var(--line);border-radius:var(--radius);
  box-shadow:var(--shadow-sm);padding:13px;overflow:hidden;max-width:244px;margin-left:auto}
.mc-head{display:flex;align-items:center;justify-content:space-between;
  padding-bottom:11px;border-bottom:1px solid var(--line);margin-bottom:11px}
.mc-title{display:inline-flex;align-items:center;gap:7px;font-weight:800;font-size:.98rem}
.mc-title .ic{width:17px;height:17px;color:var(--red)}
.mc-count{min-width:21px;height:21px;padding:0 6px;border-radius:999px;background:var(--red);
  color:#fff;font-size:.76rem;font-weight:700;display:inline-flex;align-items:center;justify-content:center}
.mc-empty{color:var(--muted);font-size:.88rem;margin:6px 0}
.mc-lines{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:11px;
  max-height:44vh;overflow-y:auto}
.mc-line{display:grid;grid-template-columns:40px 1fr auto;gap:8px;align-items:center}
.mc-media{display:block;border-radius:8px;overflow:hidden;border:1px solid var(--line)}
.mc-media img{width:40px;height:31px;object-fit:cover;display:block}
.mc-body{min-width:0}
.mc-name{display:block;font-size:.82rem;font-weight:700;color:var(--ink);line-height:1.2;
  margin-bottom:5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mc-row{display:flex;align-items:center;justify-content:space-between;gap:6px}
.mc-amt{font-size:.78rem;font-weight:700;white-space:nowrap;color:var(--ink)}
/* Per-line stepper: − qty + in a single bordered pill, remove sits apart. */
.mc-stepper{display:inline-flex;align-items:center;border:1px solid var(--line);border-radius:8px;overflow:hidden}
.mc-stepper form{display:flex;margin:0}
.mc-q{min-width:20px;text-align:center;font-size:.79rem;font-weight:700;color:var(--ink)}
.mc-del-form{margin:0}
.mc-btn{width:24px;height:24px;padding:0;border:1px solid var(--line);border-radius:7px;background:#fff;
  color:var(--muted);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;transition:.15s}
.mc-btn .ic{width:13px;height:13px}
.mc-btn:hover{border-color:var(--red);color:var(--red)}
/* The "−" at quantity 1: nowhere lower to go, and it must not look clickable. */
.mc-btn:disabled{opacity:.35;cursor:default;pointer-events:none}
.mc-btn-del:hover{background:var(--red);color:#fff;border-color:var(--red)}
/* Stepper buttons share the pill's border, so drop their own; slightly narrower. */
.mc-stepper .mc-btn{border:0;border-radius:0;width:22px}
.mc-stepper .mc-btn:hover{background:var(--red-soft)}
.mc-foot{border-top:1px solid var(--line);margin-top:13px;padding-top:12px}
.mc-sub{display:flex;justify-content:space-between;font-size:.95rem;margin-bottom:3px}
.mc-note{font-size:.75rem;color:var(--muted);margin:.2rem 0 .7rem}
.mc-foot-links{display:flex;justify-content:space-between;align-items:center;margin-top:9px}
.mc-foot-links a{font-size:.8rem;color:var(--muted)}
.mc-foot-links a:hover{color:var(--red)}
.mc-clear{background:none;border:none;padding:0;font:inherit;font-size:.8rem;color:var(--muted);
  cursor:pointer;text-decoration:underline}
.mc-clear:hover{color:var(--red)}

/* Toast shown after an AJAX add-to-cart. */
.cart-toast{position:fixed;left:50%;bottom:24px;transform:translate(-50%,20px);
  background:var(--ink);color:#fff;padding:.7em 1.2em;border-radius:12px;font-size:.9rem;
  font-weight:600;box-shadow:var(--shadow);opacity:0;pointer-events:none;z-index:300;
  transition:opacity .2s,transform .2s;max-width:90vw}
.cart-toast.show{opacity:1;transform:translate(-50%,0)}
.cart-toast.is-error{background:var(--red)}

/* ---- retail detail page price + add ---- */
.pd-price{display:flex;align-items:baseline;gap:.5rem;flex-wrap:wrap;margin:.4rem 0 1rem}
.pd-price-val{font-size:1.7rem;font-weight:800;color:var(--ink);letter-spacing:-.02em}
.pd-price-unit{font-size:.95rem;color:var(--muted)}
.pd-price-req{font-size:1.05rem;font-weight:700;color:var(--muted);margin:.4rem 0 1rem}
.pd-add{margin:.2rem 0 .3rem}

/* ---- checkout: delivery/pickup + when as a plain radio list ----
   Deliberately a LIST, not two side-by-side cards: the cards carried no radio
   and no price, so nothing said "these are the choices" or "this one costs
   more". Stacked rows with a real radio dot on the left and the fee on the
   right read as a form the moment you look at them. */
.fulfil-options{margin-bottom:14px;border:1.5px solid var(--line);border-radius:14px;
  background:#fff;overflow:hidden}
.fulfil-option{position:relative;display:block;cursor:pointer;margin:0}
.fulfil-option + .fulfil-option .fo-body{border-top:1px solid var(--line)}
/* The native radio is kept (focusable, keyboard-operable) and drawn as .fo-radio. */
.fulfil-option input{position:absolute;opacity:0;width:0;height:0;margin:0}
.fo-body{display:flex;align-items:center;gap:12px;padding:13px 16px;
  background:#fff;transition:background .16s}
.fulfil-option:hover .fo-body{background:var(--surface)}
.fulfil-option input:focus-visible ~ .fo-body{outline:3px solid var(--red);outline-offset:-3px}
.fulfil-option input:checked ~ .fo-body{background:var(--red-soft)}
.fo-radio{flex:0 0 auto;position:relative;width:19px;height:19px;border-radius:50%;
  border:2px solid #b6c0cd;background:#fff;transition:border-color .16s}
.fulfil-option:hover .fo-radio{border-color:#8e9aab}
.fulfil-option input:checked ~ .fo-body .fo-radio{border-color:var(--red)}
.fulfil-option input:checked ~ .fo-body .fo-radio::after{content:"";position:absolute;
  inset:3px;border-radius:50%;background:var(--red)}
.fo-text{display:flex;align-items:baseline;flex-wrap:wrap;gap:2px 8px;flex:1 1 auto;min-width:0}
.fo-title{font-weight:750;font-size:.98rem;color:var(--ink);line-height:1.25}
.fo-desc{font-size:.82rem;color:var(--muted);line-height:1.3}
.fo-fee{flex:0 0 auto;font-weight:750;font-size:.92rem;color:var(--ink);white-space:nowrap}
.fulfil-option input:checked ~ .fo-body .fo-fee{color:var(--red)}

/* No delivery areas configured: one way to receive the order, so it is stated
   rather than offered as a choice of one. */
.fulfil-only{display:flex;align-items:center;gap:12px;margin-bottom:14px;padding:14px 16px;
  border:1.5px solid var(--line);border-radius:14px;background:var(--surface)}
.fulfil-only .fo-ic{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;
  width:40px;height:40px;border-radius:11px;background:#fff;color:var(--ink-soft)}
.fulfil-only .fo-ic .ic{width:20px;height:20px}
.fulfil-only .fo-text{flex-direction:column;align-items:flex-start;gap:2px;flex-wrap:nowrap}
/* On a phone the icon and the nowrap fee leave the description about 145px to
   live in, which turns a sentence into a six-line column. The fee drops to its
   own row, indented to the text's own left edge (40px icon + 12px gap), so the
   sentence gets the rest of the width. It only ever states one price, so nothing
   is lost by moving it.
   The flex-basis:0 is load-bearing: flex-wrap breaks a line BEFORE it shrinks a
   flexible item, so with the default auto basis the text's max-content width
   pushes it off the icon's row entirely and the icon is left sitting alone. */
@media (max-width:560px){
  .fulfil-only{align-items:flex-start;flex-wrap:wrap;row-gap:8px}
  .fulfil-only .fo-text{flex:1 1 0}
  .fulfil-only .fo-fee{flex:0 0 100%;padding-left:52px}
}

/* Delivery-only fields (area + address). Indented under the list so they read as
   details belonging to the row above, not a second, unrelated block. */
.checkout-delivery{display:flex;flex-direction:column;gap:12px;margin:0 0 14px 31px;
  padding:14px;border:1px solid var(--line);border-radius:12px;background:var(--surface)}
.checkout-delivery label{margin:0}
.field-note{display:block;margin-top:4px}

/* ---- checkout: picking the delivery day ----
   A date field asks the customer to translate "Thursday" into 2026-08-24 before
   they can answer. Nearly every order wants a day inside the coming week, so the
   week is laid out as one-tap chips and the field itself only comes out for dates
   further away. The chips are progressive enhancement: without JS the plain input
   is what shows, and it is the only control that posts either way. */
.checkout-when-date{margin-top:12px;margin-left:31px}
.dayp-label{display:block;font-weight:700;font-size:.9rem;color:var(--ink);margin-bottom:8px}

.dayp{display:none}                          /* revealed by main.js */
.dayp-ready .dayp{display:flex;gap:8px;flex-wrap:wrap}
.dayp-ready .dayp-native{display:none}
.dayp-ready.dayp-open .dayp-native{display:block;margin-top:12px}

.dayp-chip{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;
  min-width:74px;padding:9px 12px;border:1.5px solid var(--line);border-radius:13px;
  background:#fff;font:inherit;color:var(--ink);cursor:pointer;
  transition:border-color .16s, background .16s, transform .12s}
.dayp-chip:hover{border-color:#8e9aab;background:var(--surface)}
.dayp-chip:active{transform:translateY(1px)}
.dayp-chip:focus-visible{outline:3px solid var(--red);outline-offset:2px}
.dayp-dow{font-weight:750;font-size:.88rem;line-height:1.2}
.dayp-day{font-size:.78rem;color:var(--muted);line-height:1.2}

/* Selected: red like every other committed choice on this page, and the muted
   sub-line goes red too, or it reads as disabled inside a filled chip. */
.dayp-chip[aria-pressed="true"]{border-color:var(--red);background:var(--red-soft)}
.dayp-chip[aria-pressed="true"] .dayp-dow{color:var(--red)}
.dayp-chip[aria-pressed="true"] .dayp-day{color:var(--red)}

/* "Another date" is an escape hatch, not a day: dashed, so it does not read as
   the eighth option in the week. */
.dayp-chip-other{border-style:dashed;min-width:auto;color:var(--ink-soft)}
.dayp-chip-other .dayp-ic{display:inline-flex}
.dayp-chip-other .ic{width:18px;height:18px}
.dayp-chip-other[aria-pressed="true"]{border-style:solid}

.dayp-native input[type=date]{max-width:220px}
.dayp-ready .dayp-native-text{display:block;font-size:.82rem;color:var(--muted);margin-bottom:4px}

@media (max-width:520px){
  .checkout-delivery{margin-left:0}
  .checkout-when-date{margin-left:0}
  /* One swipeable row beats a wrapped block of eight taps on a phone: the week
     stays in one line and the thumb scrolls it, snapping chip to chip. */
  .dayp-ready .dayp{flex-wrap:nowrap;overflow-x:auto;scroll-snap-type:x mandatory;
    margin:0 -16px;padding:2px 16px 6px;-webkit-overflow-scrolling:touch}
  .dayp-chip{scroll-snap-align:start;flex:0 0 auto}
  .dayp::-webkit-scrollbar{height:0}
}

/* ---- order tracking ---- */
.track-card .track-top{display:flex;justify-content:space-between;align-items:flex-start;gap:16px;flex-wrap:wrap}
.track-ref{margin:0 0 2px;font-size:1.05rem}
.track-status-note{background:var(--surface);border-radius:12px;padding:.7em 1em;
  color:var(--ink-soft);font-size:.95rem;margin:14px 0}
.track-lines{list-style:none;margin:0 0 6px;padding:0;display:flex;flex-direction:column;gap:10px}
.track-line{display:flex;justify-content:space-between;align-items:center;gap:12px;
  border-bottom:1px solid var(--line);padding-bottom:10px}
.tl-name{display:flex;flex-direction:column;font-weight:700;font-size:.95rem}
.tl-name small{font-weight:400;color:var(--muted)}
.tl-unit-price{font-weight:600;color:var(--muted);font-size:.82rem}
.tl-qty input{width:70px;text-align:center;border:1.5px solid var(--line);border-radius:10px;
  padding:.45em;font:inherit;background:#fff}
.tl-qty input:focus{outline:none;border-color:var(--red)}
.track-cancel{margin-top:16px;border-top:1px solid var(--line);padding-top:14px}
.track-cancel summary{cursor:pointer;color:var(--red);font-weight:600;font-size:.92rem}
.track-cancel .btn-danger{margin-top:8px}
.track-support{margin-top:16px}
.track-support-num{display:flex;align-items:center;gap:8px;font-weight:700;font-size:1.05rem}
.track-support-num .ic{color:var(--red);width:20px;height:20px}
.track-again{margin-top:16px;text-align:center}
.order-done-registered{margin:10px 0 6px}

@media (max-width:820px){
  .shop-layout{grid-template-columns:1fr}
  /* Below the grid on a phone, so it does not eat a column; not sticky there,
     and full-width (drop the desktop right-align cap). */
  .shop-side{position:static;order:2;margin-top:8px}
  .mini-cart{max-width:none;margin-left:0}
}
