/* =========================================================
   Haus of Peptides — design system
   Sampled from the live site: cool grey ground, navy brand,
   Aboreto set in caps, pill buttons, generous corner radii.
   ========================================================= */

/* Self-hosted. Same files Google serves, same unicode-ranges, so the
   browser still only downloads the subsets a page actually needs —
   a Thai page pulls the Thai subset, an English one does not. */
@font-face {
  font-family: 'Aboreto';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/aboreto-400-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Aboreto';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/aboreto-400-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Anuphan';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('/assets/fonts/anuphan-300-thai.woff2') format('woff2');
  unicode-range: U+02D7, U+0303, U+0331, U+0E01-0E5B, U+200C-200D, U+25CC;
}
@font-face {
  font-family: 'Anuphan';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('/assets/fonts/anuphan-300-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Anuphan';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('/assets/fonts/anuphan-300-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Anuphan';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/anuphan-400-thai.woff2') format('woff2');
  unicode-range: U+02D7, U+0303, U+0331, U+0E01-0E5B, U+200C-200D, U+25CC;
}
@font-face {
  font-family: 'Anuphan';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/anuphan-400-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Anuphan';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/anuphan-400-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Anuphan';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/assets/fonts/anuphan-500-thai.woff2') format('woff2');
  unicode-range: U+02D7, U+0303, U+0331, U+0E01-0E5B, U+200C-200D, U+25CC;
}
@font-face {
  font-family: 'Anuphan';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/assets/fonts/anuphan-500-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Anuphan';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/assets/fonts/anuphan-500-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Anuphan';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/assets/fonts/anuphan-600-thai.woff2') format('woff2');
  unicode-range: U+02D7, U+0303, U+0331, U+0E01-0E5B, U+200C-200D, U+25CC;
}
@font-face {
  font-family: 'Anuphan';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/assets/fonts/anuphan-600-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Anuphan';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/assets/fonts/anuphan-600-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* Colour — pulled from screenshots of the live build */
  --page:   #EEEEEE;   /* page ground */
  --panel:  #E2E2E1;   /* inset section panels sit a shade darker */
  --white:  #FFFFFF;
  --ink:    #2B312F;   /* body copy */
  --ink-soft: #6B706E;
  --navy:   #00367A;   /* the brand blue: logo, product accents, buttons */
  --navy-dk:#00285C;
  --sky:    #C7DFFF;   /* badge pills */
  --sky-dk: #B0D2FF;   /* pill hover */
  --line:   #D5D5D3;
  --danger: #B4442F;
  --ok:     #2F6B45;

  /* Type */
  --display: "Aboreto", "Anuphan", serif;   /* latin only, caps only */
  --body:    "Anuphan", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono:    ui-monospace, "SFMono-Regular", "Roboto Mono", monospace;

  --step--1: clamp(0.78rem, 0.76rem + 0.1vw, 0.85rem);
  --step-0:  clamp(0.95rem, 0.92rem + 0.15vw, 1.03rem);
  --step-1:  clamp(1.1rem, 1.02rem + 0.4vw, 1.35rem);
  --step-2:  clamp(1.5rem, 1.25rem + 1.1vw, 2.1rem);
  --step-3:  clamp(2.1rem, 1.5rem + 2.8vw, 3.8rem);

  --gap: clamp(1rem, 3vw, 2rem);
  --edge: clamp(0.85rem, 3.5vw, 2rem);   /* panels are inset from the edge */
  --pad: clamp(1.1rem, 5vw, 3rem);       /* padding inside a panel */

  --radius: 20px;
  --radius-sm: 12px;
  --pill: 999px;
  --hairline: 1px solid var(--line);
}

:lang(th) { --leading: 1.75; }
:lang(en) { --leading: 1.6; }

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

body {
  margin: 0;
  background: var(--page);
  color: var(--ink);
  font-family: var(--body);
  font-size: var(--step-0);
  line-height: var(--leading, 1.6);
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; height: auto; display: block; }
a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 3px; }
:focus-visible { outline: 2px solid var(--navy); outline-offset: 3px; }

/* ---------- Layout ----------
   The site is built from rounded panels floating on the grey ground,
   inset from the viewport edge rather than running full-bleed. */

.wrap { width: 100%; max-width: 1280px; margin-inline: auto; padding-inline: var(--pad); }

.section {
  margin: var(--edge);
  padding-block: clamp(1.75rem, 4.5vw, 2.75rem);
  border-radius: var(--radius);
  background: var(--panel);
}
.section--plain { background: transparent; }
.section--navy  { background: var(--navy); color: var(--white); }
.section--white { background: var(--white); }
.stack > * + * { margin-top: var(--gap); }

/* The heading sits closer to its own cards than to the section above, so the
   two read as one block rather than three loose rows. */
@media (min-width: 900px) {
  .sec-head { margin-bottom: 1.1rem; }
}

/* ---------- Type ---------- */

.display {
  font-family: var(--display);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: .02em;
  line-height: 1.1;
}
/* Aboreto carries no Thai glyphs, and Thai has no letter case — the Thai
   headings use the body face, set light and tracked out so both languages
   share a silhouette. */
:lang(th) .display {
  font-family: var(--body);
  font-weight: 300;
  text-transform: none;
  letter-spacing: .01em;
  line-height: 1.45;
}

.h1 { font-size: var(--step-3); }
.h2 { font-size: var(--step-2); }
.h3 { font-size: var(--step-1); }
.lede { font-size: var(--step-1); max-width: 46ch; color: var(--ink-soft); }
.section--navy .lede { color: rgba(255,255,255,.8); }

.band {
  display: block;
  font-family: var(--display);
  font-size: var(--step-1);
  text-transform: uppercase;
  letter-spacing: .04em;
}
:lang(th) .band { font-family: var(--body); font-weight: 400; text-transform: none; }

.eyebrow {
  font-size: var(--step--1);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* ---------- Buttons ----------
   Outlined pill, Aboreto caps. The filled navy variant is the primary. */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  min-height: 48px;
  padding: .7rem 1.6rem;
  border: 1px solid currentColor;
  border-radius: var(--pill);
  background: transparent;
  color: var(--ink);
  font-family: var(--display);
  font-size: var(--step-0);
  text-transform: uppercase;
  letter-spacing: .06em;
  text-decoration: none;
  cursor: pointer;
  transition: background .2s ease, color .2s ease, border-color .2s ease;
}
:lang(th) .btn { font-family: var(--body); text-transform: none; letter-spacing: 0; }
.btn:hover { background: var(--ink); color: var(--page); border-color: var(--ink); }
.btn:active { transform: translateY(1px); }
.btn[disabled] { opacity: .4; pointer-events: none; }

.btn--navy { background: var(--navy); border-color: var(--navy); color: var(--white); }
.btn--navy:hover { background: var(--navy-dk); border-color: var(--navy-dk); color: var(--white); }
.btn--light { color: var(--white); border-color: rgba(255,255,255,.85); }
.btn--light:hover { background: var(--white); color: var(--ink); border-color: var(--white); }
.btn--wide { width: 100%; }
.btn--sm { min-height: 38px; padding: .3rem .9rem; font-size: var(--step--1); }

/* ---------- Header ----------
   A white pill floating over the page, overlapping the hero on the homepage. */

.masthead { position: sticky; top: 0; z-index: 40; padding: var(--edge) var(--edge) 0; }
.masthead__inner {
  display: flex; align-items: center; gap: .5rem;
  min-height: 58px;
  padding: .4rem .5rem .4rem 1.1rem;
  background: var(--white);
  border-radius: var(--pill);
  box-shadow: 0 2px 18px rgba(0,0,0,.06);
}
.masthead__logo {
  display: flex; align-items: center; gap: .5rem;
  margin-right: auto; text-decoration: none; color: var(--navy);
}
.masthead__logo svg { width: 26px; height: 26px; flex: none; }
.masthead__word {
  font-family: var(--body); font-weight: 600;
  font-size: clamp(.85rem, 3.4vw, 1.05rem);
  letter-spacing: -.01em; text-transform: uppercase; white-space: nowrap;
}
.masthead__nav { display: flex; gap: 1.25rem; font-size: var(--step--1); letter-spacing: .04em; }
.masthead__nav a { text-decoration: none; padding-block: .5rem; text-transform: lowercase; }
.masthead__nav a[aria-current="page"] { text-decoration: underline; }

/* Shop submenu. On desktop it is a hover/focus flyout; inside the mobile
   panel the nav is already a vertical list, so the categories simply sit
   indented beneath shop with no toggle to discover. */
.navgroup { position: relative; }
.navsub { display: grid; }

@media (min-width: 761px) {
  .navsub {
    position: absolute; top: 100%; left: 0; min-width: 11rem;
    background: var(--white); border-radius: var(--radius-sm);
    box-shadow: 0 10px 30px rgba(0,0,0,.12);
    padding: .35rem 0; z-index: 60;
    opacity: 0; visibility: hidden; transform: translateY(-4px);
    transition: opacity .16s ease, transform .16s ease, visibility .16s;
  }
  .navgroup:hover .navsub,
  .navgroup:focus-within .navsub {
    opacity: 1; visibility: visible; transform: translateY(0);
  }
  .navsub a { padding: .45rem 1rem; white-space: nowrap; }
}

@media (max-width: 760px) {
  .navsub { padding-left: 1rem; }
  .navsub a { font-size: var(--step--1); opacity: .8; }
}

.masthead__tools { display: flex; align-items: center; gap: .15rem; }

.icon-btn {
  display: grid; place-items: center; width: 42px; height: 42px;
  border: 0; background: none; cursor: pointer; color: var(--navy); position: relative;
}
.cart-count {
  position: absolute; top: 4px; right: 2px;
  min-width: 17px; height: 17px; padding: 0 4px;
  display: grid; place-items: center;
  background: var(--navy); color: var(--white);
  border-radius: var(--pill); font-size: .65rem; font-family: var(--body); font-weight: 600;
}
.lang-toggle {
  display: flex; border: 1px solid var(--line);
  border-radius: var(--pill); overflow: hidden; font-size: .68rem; font-weight: 600;
}
.lang-toggle a { padding: .4rem .55rem; text-decoration: none; letter-spacing: .06em; color: var(--navy); }
.lang-toggle a[aria-current="true"] { background: var(--navy); color: var(--white); }

@media (max-width: 760px) {
  .masthead__nav {
    position: absolute; inset: calc(100% + .4rem) 0 auto 0;
    flex-direction: column; gap: 0;
    background: var(--white); border-radius: var(--radius);
    box-shadow: 0 6px 24px rgba(0,0,0,.1);
    padding: .5rem 1.25rem 1rem;
    opacity: 0; visibility: hidden; transform: translateY(-8px);
    transition: opacity .2s ease, transform .2s ease, visibility .2s;
  }
  .masthead__nav[data-open="true"] { opacity: 1; visibility: visible; transform: translateY(0); }
  .masthead__nav a { padding-block: .8rem; border-bottom: var(--hairline); font-size: var(--step-0); }
  .masthead__inner { position: relative; }
}
@media (min-width: 761px) { .masthead__burger { display: none; } }

/* ---------- Hero ----------
   Full-bleed photograph in a rounded frame, copy overlaid bottom-left.
   The header pill sits on top of it. */

.hero { margin: calc((var(--edge) + 58px) * -1) var(--edge) var(--edge); }
.hero__frame {
  position: relative;
  border-radius: var(--radius);
  overflow: hidden;
  min-height: min(88vh, 720px);
  display: flex; align-items: flex-end;
}
.hero__frame > img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; z-index: 0;
}
/* Enough scrim to hold white type over a bright photograph. */
.hero__frame::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(to top, rgba(0,0,0,.58) 0%, rgba(0,0,0,.18) 45%, transparent 72%);
}
.hero__copy { position: relative; z-index: 2; padding: var(--pad); color: var(--white); max-width: 34ch; }
.hero__title { font-size: var(--step-3); margin: 0 0 .5rem; }
.hero__sub { font-family: var(--display); text-transform: uppercase; font-size: var(--step-1);
             letter-spacing: .03em; line-height: 1.25; margin: 0 0 1.5rem; color: rgba(255,255,255,.92); }
:lang(th) .hero__sub { font-family: var(--body); text-transform: none; }

/* ---------- Section head ---------- */

.sec-head { display: flex; align-items: center; gap: 1rem; margin-bottom: 1.5rem; flex-wrap: wrap; }
.sec-head .btn { margin-left: auto; }

/* Section titles share a row with the VIEW ALL pill. At --step-2 a longer
   category name wraps and shoves the pill onto its own line, so step the
   heading down on narrow screens rather than letting the row break. */
@media (max-width: 619px) {
  .sec-head { gap: .6rem; margin-bottom: 1rem; flex-wrap: nowrap; }
  .sec-head .h2 { font-size: var(--step-1); }
  .sec-head .btn { flex: none; }
}

/* ---------- Product grid & rail ---------- */

.grid { display: grid; gap: clamp(.6rem, 2.2vw, 1.25rem); grid-template-columns: repeat(2, 1fr); }
@media (min-width: 760px) { .grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1040px) { .grid { grid-template-columns: repeat(4, 1fr); } }

.rail {
  display: grid; grid-auto-flow: column; grid-auto-columns: 44vw;
  gap: clamp(.6rem, 2.2vw, 1.25rem); overflow-x: auto; scroll-snap-type: x mandatory;
  margin-inline: calc(var(--pad) * -1); padding-inline: var(--pad); padding-bottom: .5rem;
  scrollbar-width: none;
}
.rail::-webkit-scrollbar { display: none; }
.rail > * { scroll-snap-align: start; }
@media (min-width: 620px) { .rail { grid-auto-columns: 32vw; } }
@media (min-width: 900px) { .rail { grid-auto-columns: 208px; } }

/* Drifting rails. transform is animated rather than scrollLeft, because
   scroll-snap-type: x mandatory snaps every programmatic scroll step back to
   the nearest card — which is why the JS version moved on desktop and sat
   still on iOS. Same technique as .marquee.

   When a rail drifts, .rail becomes a plain scroll container and the grid
   moves onto the inner track, so the animated element is a single box the
   compositor can shift without touching layout. */
.rail--drift { display: block; scroll-snap-type: none; }
.rail--drift .rail__track {
  display: grid; grid-auto-flow: column; grid-auto-columns: 44vw;
  gap: clamp(.6rem, 2.2vw, 1.25rem); width: max-content;
  animation: railDrift var(--drift-time, 40s) linear infinite alternate;
}
@media (min-width: 620px) { .rail--drift .rail__track { grid-auto-columns: 32vw; } }
@media (min-width: 900px) { .rail--drift .rail__track { grid-auto-columns: 208px; } }
.rail--drift:hover .rail__track { animation-play-state: paused; }

@keyframes railDrift { to { transform: translateX(var(--drift-end, 0px)); } }

@media (prefers-reduced-motion: reduce) {
  .rail--drift .rail__track { animation: none; }
}

/* Each card sits on its own white surface, so on the grey panel the
   separation between products is the card edge rather than a guessed gap. */
.card {
  display: flex; flex-direction: column; text-decoration: none;
  background: var(--white); border-radius: var(--radius);
  padding: .25rem .25rem .7rem; overflow: hidden;
  transition: box-shadow .2s ease, transform .2s ease;
}
.card:hover { box-shadow: 0 6px 20px rgba(0,0,0,.07); transform: translateY(-2px); }
.card__media {
  position: relative; aspect-ratio: 1;
  border-radius: 10px; overflow: hidden; background: var(--page);
}
.card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s ease; }
.card:hover .card__media img { transform: scale(1.03); }
.card__flag {
  position: absolute; top: .5rem; left: .5rem;
  background: var(--sky); color: var(--navy);
  font-size: .62rem; padding: .22rem .6rem; border-radius: var(--pill); font-weight: 500;
}
.card__save {
  font-size: .68rem; color: var(--navy); letter-spacing: .01em;
}
.card__body { padding: .7rem .55rem 0; display: flex; flex-direction: column; gap: .2rem; flex: 1; }
.card__tag { font-size: .6rem; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft); }
/* Names run from "KPV" to "CJC1295 & Ipamorelin Blend (No DAC)". Clamping to
   two lines and reserving the height keeps every price on the same baseline
   across a row, which is what makes a grid scannable. */
.card__name {
  font-size: clamp(.82rem, 3.1vw, .95rem); font-weight: 500;
  text-transform: uppercase; letter-spacing: .01em; line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; min-height: calc(2 * 1.3em);
}
.card__strengths { font-size: .68rem; color: var(--ink-soft); letter-spacing: .06em; }
.card__price {
  margin-top: auto; padding-top: .45rem;
  font-size: clamp(.88rem, 3.4vw, 1.05rem); font-weight: 600; color: var(--ink);
}
.card__out { color: var(--danger); font-size: var(--step--1); }

/* ---------- Lucky bag drop ---------- */

.luckybag-countdown { display: flex; gap: 1.5rem; margin: 1.25rem 0 1.5rem; }
.luckybag-countdown[hidden] { display: none; }
.luckybag-countdown__unit {
  display: flex; flex-direction: column; align-items: center; min-width: 3.2rem;
}
.luckybag-countdown__unit span {
  font-family: var(--mono); font-size: clamp(1.3rem, 4vw, 1.8rem); font-weight: 600;
}
.luckybag-countdown__unit label {
  font-size: .62rem; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft);
}
.section--navy .luckybag-countdown__unit label { color: rgba(255,255,255,.7); }

/* Reduced opacity and no pointer events — the card reads as present but not
   yet interactive, rather than as broken or missing. This applies to the
   card itself, so it keeps working at every width regardless of how the
   surrounding grid below is laid out. */
.luckybag-card.is-locked { opacity: .45; pointer-events: none; }
.luckybag-card__desc { font-size: var(--step--1); color: var(--ink-soft); line-height: 1.5; }
.luckybag-card [data-luckybag-buy] { margin-top: .6rem; align-self: flex-start; }

/* Three fixed cards, not an open-ended product list — .rail's drift/snap
   behaviour (driftRails in app.js targets any .rail whose content overflows)
   is built for scrolling through a catalogue, and three cards on any normal
   width always overflow it, so it was drifting and snapping instead of just
   sitting still. A dedicated grid, the same shape as .tiles, keeps all
   three on screen with no scroll at all. */
.luckybag-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(.6rem, 2.2vw, 1.25rem); }

@media (max-width: 619px) {
  .luckybag-grid { gap: .35rem; margin-inline: calc(var(--pad) * -0.6); }
  /* At roughly 115px per card on a 390px screen the full description can't
     fit — it belongs on the product page, not three times over in a row
     this narrow. Name, price, stock and the button still show. */
  .luckybag-card__desc { display: none; }
}

/* ---------- Category tiles ---------- */

.tiles { display: grid; gap: clamp(.6rem, 2.2vw, 1.25rem); grid-template-columns: repeat(3, 1fr); }
.tile {
  background: var(--white); border-radius: var(--radius);
  padding: .5rem .5rem .8rem;
  display: grid; gap: .7rem; justify-items: center; text-decoration: none;
  transition: box-shadow .2s ease, transform .2s ease;
}
.tile:hover { box-shadow: 0 6px 22px rgba(0,0,0,.08); transform: translateY(-2px); }
/* Portrait crop — three across a 390px screen leaves roughly 105px each,
   and a 4:3 landscape crop at that width shows almost nothing usable. */
.tile img { width: 100%; border-radius: 10px; aspect-ratio: 3/4; object-fit: cover; }
.tile__label {
  font-size: var(--step--1); letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink); text-align: center; line-height: 1.3;
}
@media (min-width: 700px) {
  .tile { padding: .75rem .75rem 1.1rem; gap: 1rem; }
  .tile img { aspect-ratio: 4/5; }
  .tile__label { font-size: var(--step-0); }
}

/* On a phone, three tiles across a 390px screen leaves each about 110px wide.
   Scroll them instead, one nearly-full-width card at a time. The sliver of
   the next card is the affordance — it tells you the row moves. */
@media (max-width: 619px) {
  .tiles { gap: .3rem; margin-inline: calc(var(--pad) * -0.6); }
  .tile { padding: .2rem .2rem .5rem; gap: .45rem; }
  .tile img { aspect-ratio: 3/4; }
  .tile__label { font-size: .68rem; letter-spacing: .08em; }
}

/* ---------- Product detail ---------- */

.pdp { display: grid; gap: var(--gap); }
@media (min-width: 900px) {
  .pdp { grid-template-columns: 1fr 1fr; gap: clamp(2rem, 5vw, 4rem); align-items: start; }
  .pdp__buy { position: sticky; top: 100px; }
}
.pdp__media { background: var(--white); border-radius: var(--radius); overflow: hidden; aspect-ratio: 1; }
.pdp__media img { width: 100%; height: 100%; object-fit: cover; }

.spec { width: 100%; border-collapse: collapse; font-size: var(--step--1); }
.spec th, .spec td { text-align: left; padding: .7rem 0; border-bottom: var(--hairline); vertical-align: top; }
.spec th { letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft); font-weight: 400; width: 40%; }

.buybar {
  position: fixed; inset: auto var(--edge) var(--edge) var(--edge); z-index: 30;
  display: flex; gap: .6rem; align-items: center;
  padding: .55rem .55rem .55rem 1.1rem;
  background: var(--white); border-radius: var(--pill);
  box-shadow: 0 4px 24px rgba(0,0,0,.14);
}
.buybar__price { font-weight: 500; }
.buybar .btn { flex: 1; }
@media (min-width: 900px) { .buybar { display: none; } }

/* ---------- Strength / pack chips ---------- */

.chips { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .6rem; }
.chip {
  min-height: 44px; padding: .55rem 1.1rem;
  border: 1px solid var(--line); border-radius: var(--pill);
  background: var(--white); color: inherit; font: inherit; font-size: var(--step--1); cursor: pointer;
}
.chip[aria-pressed="true"] { background: var(--navy); color: var(--white); border-color: var(--navy); }
.chip[disabled] { opacity: .35; text-decoration: line-through; pointer-events: none; }
.chip--pack {
  display: flex; flex-direction: column; align-items: flex-start; gap: .15rem;
  padding: .7rem 1.1rem; min-width: 8.5rem; border-radius: var(--radius-sm);
}
.chip__label { font-weight: 600; }
.chip__each { font-size: .72rem; opacity: .75; }
.chip__note { font-size: .72rem; font-style: italic; opacity: .8; }
.chip__save {
  font-size: .64rem; letter-spacing: .08em; text-transform: uppercase;
  background: var(--sky); color: var(--navy); padding: .15rem .5rem;
  border-radius: var(--pill); margin-top: .2rem;
}

/* ---------- Multi-buy ladder ---------- */

.tiers { display: grid; gap: .5rem; margin-top: .6rem; }
.tier {
  display: grid; align-items: center; gap: .25rem .75rem;
  grid-template-columns: auto 1fr auto;
  grid-template-areas: "qty unit total" "save save save";
  width: 100%; min-height: 58px; padding: .8rem 1.1rem;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--white); color: inherit; font: inherit;
  text-align: left; cursor: pointer; position: relative;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.tier:hover { border-color: var(--navy); }
.tier[aria-checked="true"] { border-color: var(--navy); box-shadow: inset 0 0 0 1px var(--navy); }
.tier__qty   { grid-area: qty; font-weight: 600; }
.tier__unit  { grid-area: unit; font-size: var(--step--1); color: var(--ink-soft); }
.tier__total { grid-area: total; font-weight: 600; }
.tier__save  {
  grid-area: save; justify-self: start;
  font-size: .68rem; letter-spacing: .08em; text-transform: uppercase;
  background: var(--sky); color: var(--navy); padding: .2rem .55rem; border-radius: var(--pill);
}
.tier__save--none { display: none; }
.tier__best {
  position: absolute; top: -9px; right: 1rem;
  font-size: .62rem; letter-spacing: .1em; text-transform: uppercase;
  background: var(--navy); color: var(--white); padding: .2rem .6rem; border-radius: var(--pill);
}
.saved-line { font-size: var(--step--1); color: var(--navy); font-weight: 500; margin: 0; }

.nudge {
  width: 100%; text-align: left; padding: .75rem 1.1rem; margin-top: .25rem;
  border: 1px dashed var(--navy); border-radius: var(--radius-sm);
  background: rgba(0,54,122,.05); color: var(--navy);
  font: inherit; font-size: var(--step--1); cursor: pointer;
}
.nudge:hover { background: rgba(0,54,122,.1); }

/* ---------- Quantity stepper ---------- */

.stepper { display: flex; margin-top: .6rem; max-width: 11rem; }
.stepper__btn {
  width: 52px; min-height: 52px; flex: none;
  border: 1px solid var(--line); background: var(--white); color: inherit;
  font: inherit; font-size: 1.3rem; cursor: pointer;
}
.stepper__btn:first-child { border-radius: var(--pill) 0 0 var(--pill); }
.stepper__btn:last-child  { border-radius: 0 var(--pill) var(--pill) 0; }
.stepper__btn:hover { background: var(--page); }
.stepper__input {
  width: 100%; min-height: 52px; text-align: center;
  border: 1px solid var(--line); border-inline: 0; background: var(--white);
  color: inherit; font: inherit; font-size: 16px;
}
.stepper__input::-webkit-outer-spin-button,
.stepper__input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.stepper__input { -moz-appearance: textfield; }

/* ---------- Add-ons ---------- */

.addons { display: grid; gap: .5rem; }
.addon {
  display: flex; align-items: center; gap: .8rem;
  padding: .6rem; background: var(--white); border-radius: var(--radius-sm);
}
.addon img { width: 56px; height: 56px; object-fit: cover; border-radius: 8px; flex: none; background: var(--page); }
.addon__name { flex: 1; font-size: var(--step--1); line-height: 1.35; }
.addon__btn { flex: none; }

/* ---------- Marquee ---------- */

.marquee {
  margin: var(--edge); padding-block: .9rem;
  border-radius: var(--pill); background: var(--navy); color: var(--white); overflow: hidden;
}
.marquee__track { display: flex; width: max-content; animation: marquee 38s linear infinite; }
.marquee:hover .marquee__track { animation-play-state: paused; }
.marquee__item {
  font-size: var(--step--1); letter-spacing: .14em; text-transform: uppercase;
  padding-inline: 1.5rem; white-space: nowrap;
}
@keyframes marquee { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  .marquee__track { animation: none; width: 100%; justify-content: center; }
  .marquee__item + .marquee__item { display: none; }
}

/* ---------- Forms ---------- */

.field { display: block; margin-bottom: 1rem; }
.field > span { display: block; font-size: var(--step--1); letter-spacing: .1em;
                text-transform: uppercase; color: var(--ink-soft); margin-bottom: .4rem; }
.input, .select, .textarea {
  width: 100%; min-height: 48px; padding: .7rem 1rem;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--white); color: var(--ink); font: inherit; font-size: 16px;
}
.textarea { min-height: 96px; resize: vertical; }
.input:focus, .select:focus, .textarea:focus {
  border-color: var(--navy); outline: none; box-shadow: 0 0 0 3px rgba(0,54,122,.15);
}
.checkbox { display: flex; gap: .6rem; align-items: flex-start; font-size: var(--step--1); }
.checkbox input { width: 20px; height: 20px; margin-top: 2px; accent-color: var(--navy); flex: none; }
.hint { font-size: var(--step--1); color: var(--ink-soft); }
.error { color: var(--danger); font-size: var(--step--1); }

/* ---------- Order code ---------- */

.ordercode {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  width: 100%; padding: 1.2rem 1.4rem;
  background: var(--navy); color: var(--white);
  border: 0; border-radius: var(--radius); cursor: pointer; text-align: left;
}
.ordercode__label { font-size: .64rem; letter-spacing: .16em; text-transform: uppercase;
                    opacity: .7; display: block; margin-bottom: .25rem; }
.ordercode__value {
  font-family: var(--mono); font-weight: 600;
  font-size: clamp(1.6rem, 8vw, 2.4rem); letter-spacing: .22em; line-height: 1;
  font-variant-numeric: tabular-nums slashed-zero;
}
.ordercode__copy { font-size: .66rem; letter-spacing: .12em; text-transform: uppercase;
                   border: 1px solid currentColor; padding: .45rem .7rem;
                   border-radius: var(--pill); flex: none; }
.ordercode[data-copied="true"] { background: var(--ok); }

.copyrow {
  display: flex; align-items: center; gap: .75rem; width: 100%;
  padding: .9rem 0; border-bottom: var(--hairline);
  background: none; border-inline: 0; border-top: 0;
  cursor: pointer; text-align: left; font: inherit; color: inherit;
}
.copyrow__k { font-size: var(--step--1); letter-spacing: .1em; text-transform: uppercase;
              color: var(--ink-soft); width: 34%; flex: none; }
.copyrow__v { font-family: var(--mono); font-size: var(--step-0); word-break: break-word; }
.copyrow__i { margin-left: auto; font-size: .64rem; letter-spacing: .1em;
              text-transform: uppercase; color: var(--ink-soft); flex: none; }
.copyrow[data-copied="true"] .copyrow__i { color: var(--ok); }

/* ---------- Slip upload ---------- */

.dropzone {
  display: grid; place-items: center; gap: .5rem; text-align: center;
  padding: 2.25rem 1rem; border: 1px dashed var(--line);
  border-radius: var(--radius); background: var(--white); cursor: pointer;
}
.dropzone[data-has-file="true"] { border-style: solid; border-color: var(--navy); }
.dropzone img { max-height: 220px; width: auto; border-radius: var(--radius-sm); }

/* ---------- Status & timeline ---------- */

.status { display: inline-flex; align-items: center; gap: .4rem;
          font-size: var(--step--1); letter-spacing: .06em; text-transform: uppercase;
          padding: .3rem .75rem; border-radius: var(--pill); border: 1px solid currentColor; }
.status--awaiting_payment { color: #8A6D1F; }
.status--slip_uploaded    { color: var(--navy); }
.status--paid             { color: var(--ok); }
.status--on_hold          { color: #8A6D1F; }
.status--shipped          { color: var(--navy); }
.status--completed        { color: var(--ok); }
.status--on_hold { color: #8A6D1F; }
.status--cancelled, .status--rejected { color: var(--danger); }

.timeline { list-style: none; margin: 0; padding: 0; }
.timeline li { position: relative; padding: 0 0 1.25rem 1.6rem; border-left: 1px solid var(--line); }
.timeline li:last-child { border-left-color: transparent; padding-bottom: 0; }
.timeline li::before { content: ""; position: absolute; left: -5px; top: .45rem;
                       width: 9px; height: 9px; border-radius: 50%; background: var(--line); }
.timeline li[data-done="true"]::before { background: var(--navy); }
.timeline time { display: block; font-size: var(--step--1); color: var(--ink-soft); }

/* ---------- Tables (admin) ---------- */

.table { width: 100%; border-collapse: collapse; font-size: var(--step--1); }
.table th, .table td { padding: .75rem .6rem; border-bottom: var(--hairline);
                       text-align: left; vertical-align: middle; }
.table th { letter-spacing: .1em; text-transform: uppercase; font-weight: 400; color: var(--ink-soft); }
.table tr:hover td { background: rgba(0,54,122,.04); }
.table__scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.table--reorder tbody tr { cursor: grab; }
.table--reorder tbody tr.is-dragging { opacity: .4; background: var(--sky); }
.drag-cell { white-space: nowrap; width: 1%; }
.drag-handle { color: var(--ink-soft); font-size: 1.1rem; letter-spacing: -.1em; margin-right: .35rem; cursor: grab; }
.reorder-btns { display: inline-flex; gap: .15rem; }
.reorder-btns .btn { min-height: 32px; width: 32px; padding: 0; font-size: .8rem; }

.section-row { background: var(--white); border-radius: var(--radius-sm);
               padding: .9rem; margin-bottom: .75rem; cursor: grab; }
.section-row.is-dragging { opacity: .4; background: var(--sky); }
.section-row__head { display: flex; gap: .5rem; align-items: center;
                     flex-wrap: wrap; margin-bottom: .6rem; }
.section-row input, .section-row textarea, .section-row select { font-size: var(--step--1); }

/* ---------- Prose ---------- */

.prose { max-width: 68ch; }
.prose h2 { margin: 2.25rem 0 .5rem; }
.prose p  { margin: 0 0 .9rem; }
.prose ul { margin: 0 0 1.1rem; padding-left: 1.1rem; }
.prose li { margin-bottom: .35rem; }

/* ---------- Misc ---------- */

.notice { padding: 1rem 1.2rem; border-radius: var(--radius-sm);
          background: rgba(0,54,122,.06); font-size: var(--step--1); }
.empty { text-align: center; padding: 4rem 1rem; color: var(--ink-soft); }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden;
                   clip: rect(0 0 0 0); white-space: nowrap; }

/* ---------- Footer ---------- */

.footer {
  margin: var(--edge);
  padding: clamp(1.4rem, 4vw, 3rem) 0;
  border-radius: var(--radius);
  background: var(--navy); color: var(--white);
}

/* Policy links used to stack vertically, each carrying .5rem of block
   padding for a 44px touch target — five links became five tall rows and
   most of a phone screen. Wrapping them into a row keeps every target the
   same size and reclaims the height. */
.footer__inner { display: grid; gap: 1.4rem; grid-template-columns: 1fr; }
@media (min-width: 640px) {
  .footer__inner { grid-template-columns: 1.3fr 1fr 1fr; gap: 2rem; }
}
.footer__word { margin: 0 0 .3rem; }
.footer__note { color: rgba(255,255,255,.7); margin: 0; max-width: 34ch; }
.footer .band { margin: 0 0 .1rem; color: rgba(255,255,255,.6); }
.footer__links { display: flex; flex-wrap: wrap; gap: 0 1.15rem; }
.footer a {
  color: rgba(255,255,255,.85);
  display: inline-block;
  padding-block: .45rem;
}
.footer__legal {
  margin-top: 1.2rem;
  font-size: .72rem;
  color: rgba(255,255,255,.55);
}

/* ---------- Print: packing slip ---------- */

@media print {
  body { background: #fff; }
  .masthead, .buybar, .no-print, .footer { display: none !important; }
  @page { size: A5; margin: 0; }
}

/* ---------- Toast ----------
   Fixed above the safe area so it clears the iOS home indicator and any
   sticky buy bar. Slides rather than appears, so the eye catches it. */
.toast {
  position: fixed; z-index: 60;
  left: var(--edge); right: var(--edge);
  bottom: calc(var(--edge) + env(safe-area-inset-bottom));
  display: flex; align-items: center; gap: .9rem;
  padding: .9rem 1.1rem;
  background: var(--ink); color: var(--white);
  border: 1px solid rgba(255,255,255,.16);
  border-radius: var(--radius);
  box-shadow: 0 10px 34px rgba(0,0,0,.34);
  font-size: var(--step-0);
  opacity: 0; transform: translateY(14px);
  transition: opacity .3s ease, transform .3s ease;
}
.toast[data-show="true"] { opacity: 1; transform: translateY(0); }
/* Errors don't auto-dismiss (see toast.js), so they also need to read as
   distinct from a routine confirmation at a glance. */
.toast--error { background: var(--danger); border-color: rgba(255,255,255,.3); }
.toast__msg { flex: 1; line-height: 1.4; }
.toast__action {
  flex: none; color: var(--white);
  border: 1px solid rgba(255,255,255,.7); border-radius: var(--pill);
  padding: .45rem 1rem; text-decoration: none; white-space: nowrap;
  font-size: var(--step--1);
}
.toast__action:hover { background: var(--white); color: var(--navy); border-color: var(--white); }
.toast__close {
  flex: none; width: 28px; height: 28px;
  border: 0; background: none; color: rgba(255,255,255,.75);
  font-size: 1.3rem; line-height: 1; cursor: pointer;
}
.toast__close:hover { color: var(--white); }
@media (min-width: 640px) {
  .toast { left: auto; right: var(--edge); max-width: 26rem; }
}
@media (prefers-reduced-motion: reduce) {
  .toast { transition: opacity .2s ease; transform: none; }
  .toast[data-show="true"] { transform: none; }
}

/* An unticked age confirmation is the one field people skim past, so it gets
   a visible state rather than only an error line further up the form. */
.checkbox--invalid {
  color: var(--danger);
  outline: 2px solid var(--danger);
  outline-offset: 6px;
  border-radius: 4px;
}
.checkbox--invalid input { accent-color: var(--danger); }

/* The state after a slip lands: a plain confirmation rather than an upload
   box the customer has already finished with. */
.slip-confirmed {
  margin-top: .75rem; padding: 1.1rem 1.2rem;
  background: rgba(0,54,122,.06); border-radius: var(--radius);
  display: grid; gap: 1rem; justify-items: start;
}
.slip-confirmed p { margin: 0; max-width: 46ch; }
.slip-confirmed__img {
  max-width: 100%; max-height: 260px; width: auto;
  border-radius: var(--radius-sm); border: var(--hairline); background: var(--white);
}

/* ===================== mobile-audit =====================
   Fixes from testing the live site at 390px.
   ======================================================== */

/* 1. The sticky buy bar is fixed, so it sits over whatever is beneath it.
      Reserve its height at the end of the page rather than letting it
      cover the footer. */
@media (max-width: 899px) {
  body:has(.buybar) { padding-bottom: 5.5rem; }
}

/* 2. Thumb targets. The language toggle and footer links were well under
      the 44px that makes a tap reliable on a phone. */
.lang-toggle a {
  min-height: 44px;
  display: flex; align-items: center;
  padding-inline: .85rem;
}

/* 3. The footer used desktop column spacing at every width, which made it
      nearly three screens tall on a phone. */
@media (max-width: 720px) {
  .footer { padding-block: 2rem; }
  .footer .wrap { gap: 1.5rem !important; }
  .footer .band { margin-bottom: .25rem; }
}

/* 4. Anchor links would otherwise land underneath the sticky header. */
:target { scroll-margin-top: 5.5rem; }

/* 5. Long product names could push the price out of alignment in the
      buy bar; keep the price fixed and let the button flex. */
.buybar__price { flex: none; white-space: nowrap; }

/* 6. iOS momentum scrolling in the rails, and a hint that they scroll:
      a soft fade at the right edge on touch devices. */
@media (hover: none) {
  .rail { -webkit-overflow-scrolling: touch; }
}

/* 7. Tapping a card on a touch device shouldn't leave a stuck hover state. */
@media (hover: none) {
  .card:hover { box-shadow: none; transform: none; }
  .card:hover .card__media img { transform: none; }
  .tile:hover { box-shadow: none; transform: none; }
}

/* 8. The toast sits above the buy bar rather than on top of it. */
@media (max-width: 899px) {
  body:has(.buybar) .toast {
    bottom: calc(var(--edge) + 4.6rem + env(safe-area-inset-bottom));
  }
}

/* ---------- Shop filters ----------
   A filter is navigation, not a call to action, so these are quieter and
   smaller than a .btn — but still 40px tall, which is a reliable tap. */
.filter-pill {
  display: inline-flex; align-items: center; gap: .45rem;
  min-height: 40px; padding: .35rem .9rem;
  border: 1px solid var(--line); border-radius: var(--pill);
  background: var(--white); color: var(--ink);
  font-family: var(--body); font-size: var(--step--1);
  letter-spacing: .02em; cursor: pointer; white-space: nowrap;
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.filter-pill:hover { border-color: var(--navy); }
.filter-pill[aria-pressed="true"] {
  background: var(--navy); border-color: var(--navy); color: var(--white);
}
.filter-pill__n {
  font-size: .68rem; font-variant-numeric: tabular-nums;
  padding: .1rem .4rem; border-radius: var(--pill);
  background: var(--page); color: var(--ink-soft);
}
.filter-pill[aria-pressed="true"] .filter-pill__n {
  background: rgba(255,255,255,.22); color: var(--white);
}

/* Scrolls on a phone rather than wrapping to a second row. */
.filters-row {
  display: flex; gap: .5rem; overflow-x: auto; scrollbar-width: none;
  margin-inline: calc(var(--pad) * -1); padding-inline: var(--pad);
  padding-block: .25rem;
}
.filters-row::-webkit-scrollbar { display: none; }

/* Admin category chips */
.cat-chip {
  display: inline-block; font-size: .66rem; letter-spacing: .06em;
  text-transform: uppercase; padding: .18rem .5rem;
  border-radius: var(--pill); background: var(--page); color: var(--ink-soft);
}
.cat-chip--best { background: var(--sky); color: var(--navy); margin-top: .25rem; }

/* A deactivated account still needs reading — dimmed, not hidden. */
.row--disabled td { opacity: .55; }
.cat-chip--off { background: rgba(180,68,47,.12); color: var(--danger); }

/* ---------- Account prompt ---------- */

.authpill {
  display: inline-flex; align-items: center; gap: .45rem;
  padding: .42rem .85rem; border-radius: var(--pill);
  background: var(--sky); color: var(--navy);
  font: inherit; font-size: var(--step--1); font-weight: 500;
  border: 0; text-decoration: none; cursor: pointer; line-height: 1.35;
}
.authpill:hover { background: var(--sky-dk); }
.authpill svg { width: 15px; height: 15px; flex: none; }
.authpill[hidden] { display: none; }

/* Sits above the buy button, below the price. Hidden once signed in —
   a logged-in customer has no use for it and it would only crowd the
   quantity nudge, which is the block that earns money. */
.authpill--product { margin: .1rem 0 .85rem; }

/* Rails with fewer than six cards don't overflow, so they sit left with dead
   space beside them while their neighbours scroll — which reads as broken
   rather than simply short. Centre them instead. Desktop only; on mobile
   every rail scrolls regardless of length. */
@media (min-width: 900px) {
  .rail:not(:has(> :nth-child(6))) { justify-content: center; }
}

/* Floats above the content editor while it scrolls. Admin-only, so it never
   appears on the storefront. */
.savefloat {
  position: sticky; bottom: 1rem; float: right;
  margin-top: 1rem; z-index: 20;
  box-shadow: 0 6px 20px rgba(0,0,0,.18);
}

/* Cart heading row. The pill sits beside the title on wide screens and drops
   below it on narrow ones rather than squeezing the heading. */
.carthead {
  display: flex; align-items: center; gap: .75rem; flex-wrap: wrap;
}
.carthead .authpill { margin-left: auto; }
@media (max-width: 479px) {
  .carthead .authpill { margin-left: 0; }
}

/* The editor was tall enough to lose the save button below the fold and wide
   enough to read as a page rather than a dialog. Cap it and scroll the body
   inside, so the save row stays put. */
[data-product-dialog][open] {
  width: min(720px, 92vw);
  max-height: 85vh;
  display: flex;
  flex-direction: column;
}
[data-product-dialog] form { overflow-y: auto; flex: 1; min-height: 0; }
