/* classic: filled in by Tasks 0.10-0.13 */

/* ── _base/reset.css, inlined ──────────────────────────────────────────────
   ServeThemeCSS (internal/storefront/handler.go) serves ONLY this file per
   theme — there is no per-theme hashed route for _base/*.css, so a theme
   that needs the shared reset/contract scaffolding inlines it here rather
   than adding a second unguarded <link>. See task-0.11-report.md.
   Remove this block if _base ever gets linked directly. */
.sf :where(a, button) { color: inherit; }
.sf :where(a) { text-decoration: none; }
.sf :where(button) { font: inherit; }
.sf :where(img, svg) { display: block; max-width: 100%; }
.sf :where(*, *::before, *::after) { box-sizing: border-box; }
.sf { margin-inline: 0; padding-inline: 0; }
@media (prefers-reduced-motion: reduce) {
  .sf *, .sf *::before, .sf *::after {
    transition: none !important;
    animation: none !important;
  }
}

/* ── home.html: page shell + banner (Task 0.11) ──────────────────────────── */
.sf-home {
  min-height: 100vh; /* min-h-screen */
  transition: background-color 150ms ease;
  background-image: linear-gradient(to bottom right, #f8fafc, #ffffff, #f1f5f9); /* from-slate-50 via-white to-slate-100 */
}
.sf-home--dark {
  background-image: linear-gradient(to bottom right, #020617, #0f172a, #020617); /* from-slate-950 via-slate-900 to-slate-950 */
}

.sf-banner { width: 100%; }
.sf-banner__img { display: block; width: 100%; height: auto; }

/* ── home.html: filter bar (search count + sort dropdown) (Task 0.11) ──────
   .storefront-sticky-below-nav (kept as-is, an existing non-Tailwind class
   driven by storefront-nav-offset.js) still supplies `position:sticky` and
   the measured `top` offset — see internal/storefront/CLAUDE.md's sticky-bar
   rule; this stylesheet only adds the remaining utility-equivalent styling. */
.sf-filterbar {
  position: sticky; /* the "sticky" Tailwind utility, previously alongside storefront-sticky-below-nav —
                        that class supplies only `top`, not `position`; dropping this one would still
                        pass the pixel harness (it never scrolls) but breaks the actual sticky behavior
                        gh-1295 depends on. See internal/storefront/home_banner_layout_test.go. */
  z-index: 40;
  backdrop-filter: blur(24px);
  -webkit-backdrop-filter: blur(24px);
  border-bottom: 1px solid #e2e8f0; /* border-slate-200 */
  padding-block: 1rem;
  transition: background-color 150ms ease, border-color 150ms ease;
  background-color: rgba(255, 255, 255, 0.8); /* bg-white/80 */
}
.sf-filterbar--dark {
  background-color: rgba(15, 23, 42, 0.8); /* bg-slate-900/80 */
  border-bottom-color: #1e293b; /* border-slate-800 */
}

.sf-filterbar__inner {
  max-width: 80rem;
  margin-inline: auto;
  padding-inline: 1rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1rem;
}

.sf-filterbar__count {
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 500;
  color: #475569; /* text-slate-600 — dark:text-slate-400 was dead, see nav note */
}

.sf-filterbar__sort { position: relative; }

.sf-filterbar__sort-toggle {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding-inline: 1rem;
  padding-block: 0.5rem;
  border-radius: 0.5rem;
  border: 1px solid #e2e8f0; /* border-slate-200 */
  background-color: #ffffff;
  color: #334155; /* text-slate-700 */
  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
}
.sf-filterbar__sort-toggle--dark {
  border-color: #334155; /* border-slate-700 */
  background-color: #1e293b; /* bg-slate-800 */
  color: #cbd5e1; /* text-slate-300 */
}

.sf-filterbar__sort-icon {
  width: 1rem;
  height: 1rem;
  transition: transform 150ms ease;
}

.sf-filterbar__sort-menu {
  position: absolute;
  left: 0;
  margin-top: 0.5rem;
  width: 12rem; /* w-48 */
  border-radius: 0.5rem;
  border: 1px solid #e2e8f0; /* border-slate-200 */
  box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); /* shadow-lg */
  z-index: 50;
  background-color: #ffffff;
}
.sf-filterbar__sort-menu--rtl { left: auto; right: 0; }
.sf-filterbar__sort-menu--dark {
  background-color: #1e293b; /* bg-slate-800 */
  border-color: #334155; /* border-slate-700 */
}

.sf-filterbar__sort-link {
  display: block;
  width: 100%;
  text-align: left;
  padding-inline: 1rem;
  padding-block: 0.5rem;
  font-size: 0.875rem;
  line-height: 1.25rem;
}
.sf-filterbar__sort-link:hover { background-color: #f1f5f9; } /* hover:bg-slate-100 — dark:hover:bg-slate-700 was dead */
.sf-filterbar__sort-link--rtl { text-align: right; }
.sf-filterbar__sort-link--active { font-weight: 700; color: var(--brand); }

/* ── home.html: main content wrapper + product grid (Task 0.11) ────────────
   .sf-grid CSS reproduces the previous "grid grid-cols-2 md:grid-cols-3
   lg:grid-cols-4 gap-4 md:gap-6" utility set exactly. */
.sf-main {
  max-width: 80rem; /* max-w-7xl */
  margin-inline: auto;
  padding-inline: 1rem;
  padding-block: 3rem; /* py-12 */
}

.sf-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
}
@media (min-width: 768px) {
  .sf-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.5rem; }
}
@media (min-width: 1024px) {
  .sf-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.sf-grid__empty { grid-column: 1 / -1; text-align: center; padding-block: 5rem; } /* col-span-full py-20 */
.sf-grid__empty-text {
  color: #475569; /* text-slate-600 — dark:text-slate-400 was dead, see nav note */
  font-size: 1.125rem;
  line-height: 1.75rem;
}

.sf-grid__more { grid-column: 1 / -1; padding-block: 2rem; text-align: center; color: #9ca3af; } /* text-gray-400 */
.sf-grid__load-trigger { grid-column: 1 / -1; padding-block: 2rem; text-align: center; color: #9ca3af; } /* converted from: col-span-full py-8 text-center text-gray-400 */

/* ── product card (Task 0.11) — shared by home.html's initial render AND
   partials/product_list.html's HTMX swap. The two markups are NOT identical:
   product_list.html's card carries an inline `border-color: transparent`
   plus an Alpine @mouseenter/@mouseleave pair that paints the border/shadow
   from the store's MainColor at runtime (untouched here, not a Tailwind
   utility); home.html's card instead gets a static focus-visible ring. Both
   keep working unmodified — this stylesheet only replaces what were plain
   utility classes in both files. object-fit:cover (not contract.css's
   suggested contain) is deliberate: it is what today's markup renders and
   Task 0.11 must not change a pixel. */
.sf-card-wrap { height: 100%; border-radius: 0.75rem; }
.sf-card-link { height: 100%; display: block; }

.sf-card {
  height: 100%;
  border-radius: 0.75rem;
  border: 1px solid #e2e8f0; /* border-slate-200 */
  overflow: hidden;
  display: flex;
  flex-direction: column;
  background-color: rgba(255, 255, 255, 0.5); /* bg-white/50 */
  transition: box-shadow 150ms ease, background-color 150ms ease, border-color 150ms ease;
}
.sf-card--dark {
  background-color: rgba(30, 41, 59, 0.5); /* bg-slate-800/50 */
  border-color: #334155; /* border-slate-700 */
}
.sf-card:hover { box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); } /* hover:shadow-lg */
.sf-card:focus-visible { box-shadow: 0 0 0 2px var(--brand); } /* focus-visible:ring-2 ring-brand-600 (home.html only) — ring-brand-600 is remapped to var(--brand) per-store by base.html, so this must not hardcode the default hex */

.sf-card__pad {
  position: relative;
  height: 8rem; /* h-32 */
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background-color: #f3f4f6; /* bg-gray-100 — dark:bg-slate-700 was dead, see nav note */
}
@media (min-width: 768px) {
  .sf-card__pad { height: 10rem; } /* md:h-40 */
}

.sf-card__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 500ms ease; /* duration-500 */
}
.sf-card-wrap:hover .sf-card__img { transform: scale(1.1); } /* group-hover:scale-110 */

.sf-card__placeholder { font-size: 2.25rem; line-height: 2.5rem; } /* text-4xl */

.sf-card__badge {
  position: absolute;
  top: 0.5rem;
  left: 0.5rem;
  background-color: #ef4444; /* bg-red-500 */
  color: #ffffff;
  padding-inline: 0.5rem;
  padding-block: 0.25rem;
  border-radius: 0.5rem;
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 700;
}

.sf-card__like {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  padding: 0.375rem;
  border-radius: 9999px;
  background-color: rgba(255, 255, 255, 0.8);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  transition: background-color 150ms ease;
}
.sf-card__like:hover { background-color: #ffffff; }

.sf-card__like-icon { width: 1.25rem; height: 1.25rem; }

.sf-card__body { padding: 0.75rem; flex: 1 1 0%; display: flex; flex-direction: column; }

.sf-card__name {
  font-size: 0.75rem; /* text-xs */
  line-height: 1rem;
  font-weight: 700;
  color: #0f172a; /* text-slate-900 — dark:text-white was dead, see nav note */
  margin-bottom: 0.25rem;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-align: left;
}
@media (min-width: 768px) {
  .sf-card__name { font-size: 0.875rem; line-height: 1.25rem; } /* md:text-sm */
}
.sf-card__name--rtl { text-align: right; }

.sf-card__desc {
  font-size: 0.75rem;
  line-height: 1rem;
  color: #475569; /* text-slate-600 — dark:text-slate-400 was dead, see nav note */
  margin-bottom: 0.75rem;
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-align: left;
}
.sf-card__desc--rtl { text-align: right; }

.sf-card__price-row-wrap {
  margin-top: auto;
  padding-top: 0.75rem;
  border-top: 1px solid #e2e8f0; /* border-slate-200 — dark:border-slate-700 was dead, see nav note */
}

.sf-card__price-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}

.sf-card__price { font-size: 1.125rem; line-height: 1.75rem; font-weight: 700; } /* text-lg */
@media (min-width: 768px) {
  .sf-card__price { font-size: 1.25rem; line-height: 1.75rem; } /* md:text-xl */
}

.sf-card__was { font-size: 0.75rem; line-height: 1rem; color: #64748b; text-decoration: line-through; } /* text-xs text-slate-500 */
@media (min-width: 768px) {
  .sf-card__was { font-size: 0.875rem; line-height: 1.25rem; } /* md:text-sm */
}

.sf-card__cta {
  display: block;
  width: 100%;
  margin-top: 0.75rem;
  padding-block: 0.5rem;
  border-radius: 0.5rem;
  color: #ffffff;
  font-weight: 600;
  font-size: 0.75rem;
  line-height: 1rem;
  text-align: center;
  transition: box-shadow 150ms ease;
  /* No border rule here: neither the home.html <span> nor product_list.html's
     <button> ever carried a border utility class — leave the browser's own
     default (none, for a <button> under this repo's Tailwind preflight)
     alone rather than assert a value the pre-conversion markup never set. */
}
@media (min-width: 768px) {
  .sf-card__cta { font-size: 0.875rem; line-height: 1.25rem; } /* md:text-sm */
}
.sf-card__cta--hoverable:hover { box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); } /* hover:shadow-lg, product_list.html only */

/* ── home.html: classic nav (Task 0.11) ─────────────────────────────────────
   Reproduces the previous "sticky top-0 z-50 backdrop-blur-xl border-b
   transition-colors {IsDark? bg-slate-900/80 border-slate-800 : bg-white/80
   border-slate-200}" utility set exactly. Several `{{ if .IsDark }}
   dark:...{{ end }}` fragments in the pre-conversion markup were DEAD CODE —
   Tailwind's `dark:` variant needs a `.dark` ancestor class
   (darkMode:"class" in tailwind.config.js) and nothing in this codebase ever
   adds one, so those fragments never painted a pixel; they are dropped here,
   not ported. The if/else literal-class-swap sites (nav/search-box
   background, search input text/placeholder) ARE real (plain conditional
   classes, no `dark:` prefix) and keep their --dark modifier so this stays
   correct if IsDark is ever wired to true. */
.sf-nav {
  backdrop-filter: blur(24px);
  -webkit-backdrop-filter: blur(24px);
  border-bottom: 1px solid #e2e8f0; /* border-slate-200 */
  background-color: rgba(255, 255, 255, 0.8); /* bg-white/80 */
  transition: background-color 150ms ease, border-color 150ms ease;
}
.sf-nav--dark {
  background-color: rgba(15, 23, 42, 0.8); /* bg-slate-900/80 */
  border-bottom-color: #1e293b; /* border-slate-800 */
}
/* home.html's nav is "sticky top-0 z-50"; product_v2.html's (Task 0.12) never
   was — its header wrapper scrolls away. Split out so .sf-nav stays shared
   without silently making the product nav sticky (invisible to a static
   pixel screenshot, per the Task 0.11/0.12 sticky-bar lesson). */
.sf-nav--sticky {
  position: sticky;
  top: 0;
  z-index: 50;
}

.sf-nav__inner {
  max-width: 80rem; /* max-w-7xl */
  margin-inline: auto;
  padding-inline: 1rem;
  padding-block: 1rem;
}

.sf-nav__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.sf-nav__logo {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-shrink: 0;
}

.sf-nav__logo-img {
  height: 3.5rem; /* h-14 */
  width: auto;
  object-fit: contain;
}
@media (min-width: 640px) {
  .sf-nav__logo-img { height: 3rem; } /* sm:h-12 */
}

.sf-nav__logo-badge {
  width: 3rem;
  height: 3rem;
  border-radius: 0.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #ffffff;
  font-weight: 700;
}

.sf-nav__logo-name {
  font-size: 1.25rem;
  line-height: 1.75rem;
  font-weight: 700;
  color: #0f172a; /* text-slate-900 — dark:text-white was dead, see note above */
}

.sf-nav__search {
  display: none;
  flex: 1 1 0%;
  max-width: 28rem; /* max-w-md */
  margin-inline: 1rem;
}
@media (min-width: 768px) {
  .sf-nav__search { display: block; }
}

.sf-nav__search-box {
  position: relative;
  border-radius: 0.5rem;
  border: 1px solid #e2e8f0; /* border-slate-200 */
  background-color: #ffffff;
  transition: background-color 150ms ease, border-color 150ms ease;
}
.sf-nav__search-box--dark {
  border-color: #334155; /* border-slate-700 */
  background-color: #1e293b; /* bg-slate-800 */
}

.sf-nav__search-input {
  width: 100%;
  padding-left: 2.5rem; /* pl-10 */
  padding-right: 1rem; /* pr-4 */
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
  border-radius: 0.5rem;
  outline: none;
  font-size: 0.875rem;
  line-height: 1.25rem;
  text-align: left;
  background-color: transparent;
  color: #0f172a; /* text-slate-900 */
}
.sf-nav__search-input::placeholder { color: #64748b; } /* placeholder-slate-500 */
.sf-nav__search-input--rtl { text-align: right; }
.sf-nav__search-input--dark { color: #ffffff; }
.sf-nav__search-input--dark::placeholder { color: #94a3b8; } /* placeholder-slate-400 */

.sf-nav__search-icon {
  position: absolute;
  left: 0.75rem;
  top: 50%;
  transform: translateY(-50%);
  width: 1rem;
  height: 1rem;
  color: #94a3b8; /* text-slate-400 */
  pointer-events: none;
}

.sf-nav__search-toggle-wrap {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
@media (min-width: 768px) {
  .sf-nav__search-toggle-wrap { display: none; }
}

.sf-nav__search-toggle {
  padding: 0.5rem;
}

.sf-nav__search-toggle-icon {
  width: 1.25rem;
  height: 1.25rem;
  color: #0f172a; /* text-slate-900 — dark:text-white was dead, see note above */
}

.sf-nav__search-mobile {
  margin-top: 1rem;
}
@media (min-width: 768px) {
  .sf-nav__search-mobile { display: none; }
}

.sf-nav__search-mobile-input {
  width: 100%;
  padding-inline: 1rem;
  padding-block: 0.5rem;
  border-radius: 0.5rem;
  outline: none;
  font-size: 0.875rem;
  line-height: 1.25rem;
  background-color: #f9fafb; /* bg-gray-50 — dark:bg-slate-800/text-white was dead, see note above */
}

/* ── product_v2.html: classic nav (Task 0.12) ───────────────────────────────
   Shares .sf-nav (minus --sticky) and the logo-badge/logo-img/logo-name and
   search-box/search-input/search-icon rules above — those utility sets were
   byte-identical between home.html's pre-conversion nav and this one. Only
   the container/row metrics and the logo's wrapper nesting genuinely differ
   (no mobile search toggle exists on the product nav at all — never did),
   so only those get their own classes, prefixed sf-pnav to make clear they
   are NOT a second definition of sf-nav__inner/sf-nav__row. */
.sf-pnav__container {
  max-width: 80rem; /* max-w-7xl */
  margin-inline: auto;
  padding-inline: 1rem; /* px-4 */
}
@media (min-width: 640px) {
  .sf-pnav__container { padding-inline: 1.5rem; } /* sm:px-6 */
}
@media (min-width: 1024px) {
  .sf-pnav__container { padding-inline: 2rem; } /* lg:px-8 */
}

.sf-pnav__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 4rem; /* h-16 */
  gap: 1rem;
}

.sf-pnav__logo-wrap {
  flex-shrink: 0;
  display: flex;
  align-items: center;
}

.sf-pnav__logo-fallback {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* ── product_v2.html: page shell + main layout (Task 0.12) ──────────────────
   NOT reusing .sf-home — same "min-h-screen transition-colors" base but a
   different gradient (bg-gradient-to-b, 2 stops here vs bg-gradient-to-br,
   3 stops on home.html), so a shared class would either change one page's
   gradient or need a modifier per axis. Kept separate on purpose. */
.sf-product {
  min-height: 100vh; /* min-h-screen */
  transition: background-color 150ms ease; /* transition-colors */
  background-image: linear-gradient(to bottom, #f8fafc, #ffffff); /* from-slate-50 to-white */
}
.sf-product--dark {
  background-image: linear-gradient(to bottom, #020617, #0f172a); /* from-slate-950 to-slate-900 */
}

.sf-product__header {
  position: relative;
  z-index: 50;
  width: 100%;
  display: flex;
  flex-direction: column;
}

.sf-product__main {
  max-width: 64rem; /* max-w-5xl */
  margin-inline: auto;
  padding-inline: 1rem; /* px-4 */
  padding-block: 1rem; /* py-4 */
}
@media (min-width: 640px) {
  .sf-product__main { padding-inline: 1.5rem; padding-block: 2rem; } /* sm:px-6 sm:py-8 */
}

.sf-product__layout {
  display: grid;
  grid-template-columns: repeat(1, minmax(0, 1fr));
  gap: 1rem; /* gap-4 */
  margin-bottom: 2.5rem; /* mb-10 */
}
@media (min-width: 640px) {
  .sf-product__layout { gap: 2rem; margin-bottom: 4rem; } /* sm:gap-8 sm:mb-16 */
}
@media (min-width: 1024px) {
  .sf-product__layout { grid-template-columns: repeat(2, minmax(0, 1fr)); } /* lg:grid-cols-2 */
}

/* ── product_v2.html: image gallery (Task 0.12) ── */
.sf-product__gallery { display: flex; flex-direction: column; }
.sf-product__gallery > * + * { margin-top: 1rem; } /* space-y-4 */

.sf-product__gallery-frame {
  position: relative;
  overflow: hidden;
  border-radius: 1rem; /* rounded-2xl */
  border: 1px solid #e2e8f0; /* border-slate-200 */
  aspect-ratio: 1 / 1; /* aspect-square */
}

.sf-product__gallery-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity 300ms ease; /* transition-opacity duration-300 */
}

.sf-product__gallery-placeholder {
  display: flex;
  height: 100%;
  width: 100%;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  background-color: #f1f5f9; /* bg-slate-100 — dark:bg-slate-900 was dead, see nav note */
  color: #94a3b8; /* text-slate-400 — dark:text-slate-500 was dead, see nav note */
}
.sf-product__gallery-placeholder-icon { width: 5rem; height: 5rem; } /* h-20 w-20 */
.sf-product__gallery-placeholder-text { font-size: 0.875rem; line-height: 1.25rem; font-weight: 600; } /* text-sm font-semibold */

.sf-product__gallery-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 2rem; /* w-8 */
  height: 2rem; /* h-8 */
  border-radius: 9999px;
  background-color: rgba(255, 255, 255, 0.8); /* bg-white/80 */
  backdrop-filter: blur(4px); /* backdrop-blur-sm */
  -webkit-backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #334155; /* text-slate-700 */
  transition: background-color 150ms ease;
  box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); /* shadow-sm */
}
.sf-product__gallery-nav:hover { background-color: #ffffff; }
.sf-product__gallery-nav--prev { left: 0.5rem; } /* left-2 */
.sf-product__gallery-nav--next { right: 0.5rem; } /* right-2 */
.sf-product__gallery-nav-icon { width: 1rem; height: 1rem; } /* w-4 h-4 */

/* Physical (not logical) left/right below: the pre-conversion markup used
   Tailwind's physical `right-3`/`top-3` utilities and forces dir="ltr" on
   the counter regardless of page direction — an inset-inline-end here would
   flip under rtl and change behavior this conversion must not touch. */
.sf-product__gallery-counter {
  position: absolute;
  bottom: 0.75rem;
  right: 0.75rem;
  padding-inline: 0.625rem; /* px-2.5 */
  padding-block: 0.25rem; /* py-1 */
  border-radius: 9999px;
  background-color: rgba(0, 0, 0, 0.5); /* bg-black/50 */
  color: #ffffff;
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 500;
}

.sf-product__gallery-autoplay { position: absolute; top: 0.75rem; right: 0.75rem; }
.sf-product__gallery-autoplay-dot {
  width: 0.5rem; /* w-2 */
  height: 0.5rem; /* h-2 */
  border-radius: 9999px;
  animation: sf-product-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; /* animate-pulse */
}
@keyframes sf-product-pulse { 50% { opacity: 0.5; } }

.sf-product__thumbs {
  display: flex;
  gap: 0.5rem; /* gap-2 */
  overflow-x: auto;
  padding-bottom: 0.5rem; /* pb-2 */
}

.sf-product__thumb {
  width: 3.5rem; /* w-14 */
  height: 3.5rem; /* h-14 */
  flex-shrink: 0;
  border-radius: 0.5rem; /* rounded-lg */
  border-width: 2px;
  border-style: solid;
  overflow: hidden;
  transition: all 150ms ease; /* transition-all */
}
.sf-product__thumb-img { width: 100%; height: 100%; object-fit: cover; }

/* ── product_v2.html: buy box (Task 0.12) — contract, LOCKED, single instance ── */
.sf-buybox {
  border-radius: 1rem; /* rounded-2xl */
  border: 1px solid #e2e8f0; /* border-slate-200 */
  padding: 0.75rem; /* p-3 */
  background-color: rgba(255, 255, 255, 0.5); /* bg-white/50 */
}
@media (min-width: 640px) {
  .sf-buybox { padding: 1.25rem; } /* sm:p-5 */
}
.sf-buybox > * + * { margin-top: 0.75rem; } /* space-y-3 */
@media (min-width: 640px) {
  .sf-buybox > * + * { margin-top: 1.25rem; } /* sm:space-y-5 */
}

.sf-buybox__title { font-size: 1.25rem; line-height: 1.75rem; font-weight: 700; color: #0f172a; margin-bottom: 0.5rem; } /* text-xl font-bold text-slate-900 mb-2 */
@media (min-width: 640px) {
  .sf-buybox__title { font-size: 1.5rem; line-height: 2rem; } /* sm:text-2xl */
}
.sf-buybox__desc { color: #64748b; margin-bottom: 0.75rem; } /* text-slate-500 mb-3 */

.sf-buybox__price-row { display: flex; align-items: flex-end; gap: 0.75rem; } /* flex items-end gap-3 */
.sf-buybox__price { font-size: 1.5rem; line-height: 2rem; font-weight: 900; } /* text-2xl font-black */
@media (min-width: 640px) {
  .sf-buybox__price { font-size: 1.875rem; line-height: 2.25rem; } /* sm:text-3xl */
}
.sf-buybox__compare { font-size: 0.875rem; line-height: 1.25rem; color: #94a3b8; text-decoration: line-through; font-weight: 500; } /* text-sm text-slate-400 line-through font-medium */
@media (min-width: 640px) {
  .sf-buybox__compare { font-size: 1rem; line-height: 1.5rem; } /* sm:text-base */
}
.sf-buybox__discount {
  padding-inline: 0.5rem; /* px-2 */
  padding-block: 0.125rem; /* py-0.5 */
  background-color: #fee2e2; /* bg-red-100 */
  color: #dc2626; /* text-red-600 */
  font-size: 10px;
  font-weight: 700;
  border-radius: 9999px;
}
@media (min-width: 640px) {
  .sf-buybox__discount { font-size: 0.75rem; line-height: 1rem; } /* sm:text-xs */
}

/* ── product_v2.html: trust badges (Task 0.12) ── */
.sf-product__trust {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr)); /* grid-cols-2 */
  grid-auto-rows: 1fr; /* auto-rows-fr */
  align-items: stretch;
  gap: 1rem;
  padding-block: 0.5rem;
  border-top: 1px solid #e2e8f0; /* border-slate-200 */
}
@media (min-width: 640px) {
  .sf-product__trust { grid-template-columns: repeat(4, minmax(0, 1fr)); } /* sm:grid-cols-4 */
}

.sf-product__trust-item {
  display: flex;
  height: 100%;
  min-height: 9rem; /* min-h-36 */
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  text-align: center;
  padding: 1rem;
  border-radius: 0.75rem; /* rounded-xl */
  border: 1px solid #f1f5f9; /* border-slate-100 */
  box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); /* shadow-sm */
  background-color: #ffffff;
}

.sf-product__trust-icon-wrap {
  margin-bottom: 0.75rem;
  display: flex;
  height: 3rem; /* h-12 */
  width: 3rem; /* w-12 */
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
  box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); /* shadow-sm */
  background-color: #ffffff;
}
.sf-product__trust-icon { width: 1.5rem; height: 1.5rem; } /* w-6 h-6 */

/* text-sm sets its own line-height (1.25rem), but leading-tight (1.25,
   unitless) is also on this element and sits AFTER .text-sm in output.css,
   so it wins the cascade at equal specificity — confirmed against the
   compiled stylesheet (same trap as .sf-product__trust-desc above). Using
   the flat 1.25rem here shifted this text by ~2.5px and cascaded a 1px
   layout diff through everything below it in the pixel harness. */
.sf-product__trust-title {
  width: 100%;
  min-height: 2.5rem; /* min-h-10 */
  font-weight: 700;
  font-size: 0.875rem; /* text-sm */
  line-height: 1.25; /* leading-tight wins the cascade over text-sm's 1.25rem */
  color: #0f172a; /* text-slate-900 */
  margin-bottom: 0.25rem;
}
/* text-[10px] carries no line-height of its own; leading-tight (1.25, a
   unitless ratio) applies unopposed at this width. At sm:text-xs (>=640px)
   leading-tight loses the line-height cascade — output.css puts .sm\:text-xs
   after .leading-tight, so line-height becomes the flat 1rem text-xs sets.
   Confirmed against the compiled stylesheet rather than assumed. */
.sf-product__trust-desc {
  width: 100%;
  font-size: 10px; /* text-[10px] */
  line-height: 1.25; /* leading-tight */
  color: #64748b; /* text-slate-500 */
}
@media (min-width: 640px) {
  .sf-product__trust-desc { font-size: 0.75rem; line-height: 1rem; } /* sm:text-xs wins the line-height cascade */
}

/* ── partials/variants.html: variant picker key groups (Task 0.12) ──────────
   See variants.html's comment on this class: reproduces the 12px spacing a
   pre-conversion `<template x-for>` sibling accidentally gave every key
   group (including the first) via space-y-3's `:not([hidden]) ~
   :not([hidden])` selector. Unconditional on purpose — matches the old
   behavior exactly rather than "fixing" a first-child exception nothing
   relied on visually. */
.sf-variant-group { margin-top: 0.75rem; }

/* Task 0.13: the label/select/chevron/swatch-dot leftovers only — the
   dynamic :class array on .sf-variant is untouched, see variants.html's
   comment at this call site. */
.sf-variant-group__label { display: block; font-size: 0.875rem; line-height: 1.25rem; font-weight: 700; margin-bottom: 0.5rem; color: #334155; } /* block text-sm font-bold mb-2 text-slate-700 */
.sf-variant-select-wrap { position: relative; } /* relative */
.sf-variant-select {
  width: 100%;
  min-height: 2.75rem; /* min-h-11 */
  appearance: none;
  border-radius: 0.5rem; /* rounded-lg */
  border: 1px solid #e2e8f0; /* border-slate-200 */
  background-color: #ffffff;
  padding-inline: 0.75rem; /* px-3 */
  padding-block: 0.625rem; /* py-2.5 */
  padding-inline-end: 2.5rem; /* pl-10/pr-10 per dir — the chevron sits at the END, opposite text-align:start */
  text-align: start; /* text-right/text-left per dir */
  font-size: 0.875rem; /* text-sm */
  line-height: 1.25rem;
  font-weight: 700;
  color: #334155; /* text-slate-700 */
  outline: none;
  transition: border-color 150ms ease, box-shadow 150ms ease;
}
.sf-variant-select:focus { border-color: var(--brand); box-shadow: 0 0 0 2px var(--brand); } /* focus:border-brand-500 focus:ring-2 focus:ring-brand-500 */
.sf-variant-select-chevron { position: absolute; inset-inline-end: 0.75rem; top: 50%; transform: translateY(-50%); color: #94a3b8; pointer-events: none; } /* absolute (right-3/left-3 per dir → inset-inline-end) top-1/2 -translate-y-1/2 text-slate-400 pointer-events-none */
.sf-variant-select-chevron-icon { width: 1rem; height: 1rem; } /* h-4 w-4 */
.sf-variant-buttons-row { display: flex; flex-wrap: wrap; gap: 0.5rem; } /* flex flex-wrap gap-2 */
.sf-variant-swatch-dot { width: 1.25rem; height: 1.25rem; border-radius: 9999px; border: 1px solid rgb(0 0 0 / 0.1); flex-shrink: 0; } /* w-5 h-5 rounded-full border border-black/10 shrink-0 */

/* ── partials/order_form.html: COD order form (Task 0.12) ────────────────────
   Only the contract-required sections converted (.sf-of wrapper, .sf-of__qty,
   .sf-of__summary) plus the delivery-fee-unknown modifier. Everything else in
   this partial — the sold-out badge, upsell cards, submit/add-to-cart buttons
   — stays on its pre-conversion Tailwind classes: none of it is part of the
   sf-of__* contract, and its Alpine :class bindings are dense enough (colors
   keyed off FormTheme/MainColor at runtime) that converting it carries far
   more regression risk than the "highest-risk conversion" budget for this
   task affords. checkout_fields.html/custom_fields.html similarly got
   ADDITIVE sf-of__field/sf-of__dtype markers only — see those files' own
   comments — not a full class rewrite. */
.sf-of {
  background-color: #ffffff; /* bg-white */
  padding: 0.75rem; /* p-3 */
  /* border-color/width/radius stay on the inline style attribute — FormTheme
     is per-store/per-LP runtime configuration, not a Tailwind utility. */
}

.sf-of__qty { display: flex; align-items: center; justify-content: space-between; }
.sf-of__qty-label { font-weight: 700; font-size: 0.875rem; line-height: 1.25rem; color: #334155; } /* font-bold text-sm text-slate-700 */
.sf-of__qty-control { display: flex; align-items: center; gap: 0.75rem; }
.sf-of__qty-btn {
  width: 2rem; /* w-8 */
  height: 2rem; /* h-8 */
  border-radius: 0.5rem; /* rounded-lg */
  border: 1px solid #e2e8f0; /* border-slate-200 */
  transition: background-color 150ms ease; /* transition */
  display: flex;
  align-items: center;
  justify-content: center;
  color: #475569; /* text-slate-600 */
  font-size: 0.875rem; /* text-sm */
  line-height: 1.25rem; /* text-sm bundles this — omitting it left the glyph inheriting
                            html's line-height:1.5 (21px) instead of 20px, shifting the
                            +/- glyph's flex-centered vertical position by a sub-pixel
                            amount; caught by the pixel harness, not by any Go/JS test. */
  font-weight: 700;
}
.sf-of__qty-btn:hover { background-color: #f1f5f9; } /* hover:bg-slate-100 */
.sf-of__qty-value { font-size: 0.875rem; line-height: 1.25rem; font-weight: 700; width: 1.5rem; text-align: center; } /* text-sm font-bold w-6 text-center */

.sf-of__summary {
  border-radius: 0.75rem; /* rounded-xl */
  border: 1px solid #e2e8f0; /* border-slate-200 */
  padding: 0.75rem; /* p-3 */
  background-color: #f8fafc; /* bg-slate-50 */
}
.sf-of__summary > * + * { margin-top: 0.375rem; } /* space-y-1.5 — real persistent DOM rows, no phantom-sibling risk (contrast variants.html's fix above) */
.sf-of__summary--pending {} /* contract modifier — classic gives it no styling; see order_form.html's comment */

/* ── product_v2.html: similar products strip (Task 0.12) ─────────────────── */
.sf-product__similar { margin-top: 3rem; padding-top: 3rem; border-top: 1px solid #e2e8f0; } /* mt-12 pt-12 border-slate-200 */
.sf-product__similar-title { font-size: 1.5rem; line-height: 2rem; font-weight: 700; margin-bottom: 1.5rem; color: #0f172a; } /* text-2xl font-bold mb-6 text-slate-900 */
.sf-product__similar-scroller {
  display: flex;
  overflow-x: auto;
  gap: 1rem; /* gap-4 */
  scroll-snap-type: x mandatory; /* snap-x snap-mandatory */
  padding-bottom: 0.5rem; /* pb-2 */
}
.sf-product__similar-card {
  display: block;
  scroll-snap-align: center; /* snap-center */
  flex-shrink: 0;
  width: 200px; /* w-[200px] */
}
@media (min-width: 640px) {
  .sf-product__similar-card { width: 16rem; } /* sm:w-64 */
}
.sf-product__similar-frame {
  border-radius: 0.75rem; /* rounded-xl */
  overflow: hidden;
  border: 1px solid #e2e8f0; /* border-slate-200 */
  transition: border-color 150ms ease, box-shadow 150ms ease; /* transition-all, scoped to what brand-hover-border (base.html) actually animates */
}
.sf-product__similar-thumb {
  height: 8rem; /* h-32 */
  background-color: #f3f4f6; /* bg-gray-100 */
  position: relative;
  overflow: hidden;
}
@media (min-width: 768px) {
  .sf-product__similar-thumb { height: 10rem; } /* md:h-40 */
}
.sf-product__similar-img { width: 100%; height: 100%; object-fit: cover; transition: transform 150ms ease; } /* transition-transform */
.sf-product__similar-card:hover .sf-product__similar-img { transform: scale(1.1); } /* group-hover:scale-110 */
.sf-product__similar-placeholder { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 1.5rem; line-height: 2rem; }
.sf-product__similar-badge {
  position: absolute;
  top: 0.5rem;
  left: 0.5rem;
  background-color: #ef4444; /* bg-red-500 */
  color: #ffffff;
  padding-inline: 0.5rem; /* px-2 */
  padding-block: 0.25rem; /* py-1 */
  border-radius: 0.5rem; /* rounded-lg */
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 700;
}
.sf-product__similar-body { padding: 0.75rem; } /* p-3 */
.sf-product__similar-name {
  font-weight: 700;
  font-size: 0.875rem;
  line-height: 1.25rem; /* text-sm */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap; /* truncate */
  color: #0f172a; /* text-slate-900 — dark:text-white was dead, see nav note */
}
.sf-product__similar-price-row { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; margin-top: 0.25rem; } /* mt-1 */
.sf-product__similar-price { font-weight: 700; font-size: 0.875rem; line-height: 1.25rem; } /* font-bold text-sm */
.sf-product__similar-compare { font-size: 0.75rem; line-height: 1rem; color: #94a3b8; text-decoration: line-through; } /* text-xs text-slate-400 line-through */
.sf-product__similar-cta {
  width: 100%;
  margin-top: 0.5rem; /* mt-2 */
  padding-block: 0.375rem; /* py-1.5 */
  border-radius: 0.5rem; /* rounded-lg */
  color: #ffffff;
  font-weight: 600;
  font-size: 0.75rem;
  line-height: 1rem;
  transition: box-shadow 150ms ease; /* transition-all */
}

/* ── cart_page.html (Task 0.13) ─────────────────────────────────────────── */
.sf-cart { max-width: 48rem; margin-inline: auto; padding-inline: 1rem; padding-block: 2rem; } /* max-w-3xl mx-auto px-4 py-8 */
.sf-cart__back { display: inline-flex; align-items: center; gap: 0.5rem; font-size: 0.875rem; line-height: 1.25rem; color: #64748b; margin-bottom: 1.5rem; } /* text-sm text-slate-500 mb-6 */
.sf-cart__back:hover { color: #334155; } /* hover:text-slate-700 */
.sf-cart__back-icon { width: 1rem; height: 1rem; } /* w-4 h-4 */
[dir="rtl"] .sf-cart__back-icon { transform: rotate(180deg); } /* rtl:rotate-180 */
.sf-cart__title { font-size: 1.5rem; line-height: 2rem; font-weight: 700; margin-bottom: 1.5rem; } /* text-2xl font-bold mb-6 */

.sf-cart__success { text-align: center; padding-block: 4rem; border-radius: 1rem; border: 1px solid #a7f3d0; background-color: #ecfdf5; } /* py-16 rounded-2xl border-emerald-200 bg-emerald-50 */
.sf-cart__success--dark { border-color: rgba(6, 78, 59, 0.5); background-color: rgba(6, 78, 59, 0.2); } /* border-emerald-900/50 bg-emerald-900/20 */
.sf-cart__success-icon { width: 3rem; height: 3rem; margin-inline: auto; margin-bottom: 1rem; color: #10b981; } /* w-12 h-12 mx-auto mb-4 text-emerald-500 */
.sf-cart__success-title { font-weight: 700; font-size: 1.125rem; line-height: 1.75rem; margin-bottom: 0.5rem; } /* font-bold text-lg mb-2 */
.sf-cart__success-hint { font-size: 0.875rem; line-height: 1.25rem; color: #64748b; margin-bottom: 1.5rem; } /* text-sm text-slate-500 mb-6 */
.sf-cart__success-actions { display: flex; flex-direction: column; align-items: center; gap: 0.75rem; } /* flex flex-col items-center gap-3 */

.sf-cart__track-btn { display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem; padding-inline: 1.5rem; padding-block: 0.75rem; border-radius: 0.75rem; font-weight: 700; color: #ffffff; } /* inline-flex items-center justify-center gap-2 px-6 py-3 rounded-xl font-bold text-white */
.sf-cart__track-icon { width: 1rem; height: 1rem; } /* w-4 h-4 */
.sf-cart__track-hint { font-size: 0.75rem; line-height: 1rem; color: #64748b; } /* text-xs text-slate-500 */

.sf-cart__continue { display: inline-block; padding-inline: 1.5rem; padding-block: 0.75rem; border-radius: 0.75rem; font-weight: 700; } /* inline-block px-6 py-3 rounded-xl font-bold */
.sf-cart__continue--filled { color: #ffffff; } /* text-white — background comes from the store's inline brand-color style */
.sf-cart__continue--ghost { color: #334155; border: 1px solid #cbd5e1; } /* text-slate-700 border border-slate-300 */
.sf-cart__continue--ghost-dark { color: #e2e8f0; border-color: #334155; } /* text-slate-200 border-slate-700 */

.sf-cart__empty { text-align: center; padding-block: 4rem; border-radius: 1rem; border: 1px solid #e2e8f0; background-color: #ffffff; } /* py-16 rounded-2xl border-slate-200 bg-white */
.sf-cart__empty--dark { border-color: #1e293b; background-color: rgba(15, 23, 42, 0.5); } /* border-slate-800 bg-slate-900/50 */
.sf-cart__empty-text { color: #64748b; margin-bottom: 1rem; } /* text-slate-500 mb-4 */

.sf-cart__lines { border-radius: 1rem; border: 1px solid #e2e8f0; overflow: hidden; margin-bottom: 1.5rem; background-color: #ffffff; } /* rounded-2xl border overflow-hidden mb-6 border-slate-200 bg-white */
.sf-cart__lines--dark { border-color: #1e293b; background-color: rgba(15, 23, 42, 0.5); } /* border-slate-800 bg-slate-900/50 */

.sf-cart__line { display: flex; gap: 0.75rem; padding: 1rem; border-bottom: 1px solid #f1f5f9; } /* flex gap-3 p-4 border-b border-slate-100 */
.sf-cart__line:last-child { border-bottom: none; } /* last:border-b-0 */
.sf-cart__line--dark { border-bottom-color: #1e293b; } /* border-slate-800 */
.sf-cart__line-img { width: 4rem; height: 4rem; border-radius: 0.5rem; overflow: hidden; flex-shrink: 0; background-color: #f1f5f9; } /* w-16 h-16 rounded-lg overflow-hidden flex-shrink-0 bg-slate-100 — dark:bg-slate-800 was dead */
.sf-cart__line-img-el { width: 100%; height: 100%; object-fit: cover; } /* w-full h-full object-cover */
.sf-cart__line-body { flex: 1 1 0%; min-width: 0; } /* flex-1 min-w-0 */
.sf-cart__line-name { font-weight: 600; font-size: 0.875rem; line-height: 1.25rem; } /* font-semibold text-sm */
.sf-cart__line-variant { font-size: 0.75rem; line-height: 1rem; color: #64748b; } /* text-xs text-slate-500 */
.sf-cart__line-controls { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.5rem; } /* flex items-center gap-2 mt-2 */
.sf-cart__qty-btn { width: 1.75rem; height: 1.75rem; border-radius: 0.25rem; border: 1px solid currentColor; display: flex; align-items: center; justify-content: center; } /* w-7 h-7 rounded border (bare, no color utility — Tailwind v3 default border-color is currentColor) flex items-center justify-center */
.sf-cart__qty-value { font-size: 0.875rem; line-height: 1.25rem; width: 1.5rem; text-align: center; } /* text-sm w-6 text-center */
.sf-cart__remove { margin-inline-start: auto; font-size: 0.75rem; line-height: 1rem; color: #ef4444; } /* ms-auto text-xs text-red-500 */
.sf-cart__remove:hover { text-decoration: underline; } /* hover:underline */
.sf-cart__line-price { font-size: 0.875rem; line-height: 1.25rem; font-weight: 700; white-space: nowrap; } /* text-sm font-bold whitespace-nowrap */

.sf-cart__unavailable { margin-bottom: 1.5rem; padding: 1rem; border-radius: 0.75rem; border: 1px solid #fcd34d; background-color: #fffbeb; color: #78350f; font-size: 0.875rem; line-height: 1.25rem; } /* mb-6 p-4 rounded-xl border-amber-300 bg-amber-50 text-amber-900 text-sm */
.sf-cart__unavailable-title { font-weight: 600; margin-bottom: 0.25rem; } /* font-semibold mb-1 */
.sf-cart__unavailable-list { list-style-type: disc; list-style-position: inside; } /* list-disc list-inside */

.sf-cart__form { display: flex; flex-direction: column; gap: 0.75rem; border-radius: 1rem; border: 1px solid #e2e8f0; padding: 1rem; background-color: #ffffff; } /* space-y-3 rounded-2xl border p-4 border-slate-200 bg-white — no phantom <template> siblings in this form, gap is a safe 1:1 swap for space-y-3 */
.sf-cart__form--dark { border-color: #1e293b; background-color: rgba(15, 23, 42, 0.5); } /* border-slate-800 bg-slate-900/50 */

.sf-cart__totals { padding-top: 0.75rem; border-top: 1px solid #f1f5f9; font-size: 0.875rem; line-height: 1.25rem; display: flex; flex-direction: column; gap: 0.25rem; } /* pt-3 border-t border-slate-100 space-y-1 text-sm */
.sf-cart__totals--dark { border-top-color: #1e293b; } /* border-slate-800 */
.sf-cart__totals-row { display: flex; justify-content: space-between; } /* flex justify-between */
.sf-cart__totals-row--total { font-weight: 700; font-size: 1rem; line-height: 1.5rem; padding-top: 0.25rem; } /* font-bold text-base pt-1 */
.sf-cart__delivery-pending { color: #94a3b8; } /* text-slate-400 */

.sf-cart__error { font-size: 0.875rem; line-height: 1.25rem; color: #dc2626; } /* text-sm text-red-600 */

.sf-cart__submit { width: 100%; padding-block: 0.75rem; border-radius: 0.75rem; font-weight: 700; color: #ffffff; } /* w-full py-3 rounded-xl font-bold text-white */
.sf-cart__submit:disabled { opacity: 0.6; cursor: not-allowed; } /* disabled:opacity-60 disabled:cursor-not-allowed */

/* ── partials/cart.html: navbar toggle + slide-over drawer (Task 0.13) ────
   Renders on every page except /cart itself (base.html: {{ if not .OnCartPage }}).
   x-transition:enter/leave attribute VALUES on the <aside> below are left on
   raw Tailwind transform utilities (translate-x-full, rtl:-translate-x-full,
   transition/ease/duration) — those are Alpine directive values, not a
   class="..." attribute, so the zero-Tailwind grep never sees them, but they
   still resolve through compiled output.css. Flagged in task-0.13-report.md
   as a residual dependency for a future task. */
.sf-cart-root { display: contents; } /* contents */
.sf-cart-toggle {
  position: fixed; /* fixed */
  inset-block-start: 1rem; /* top-4 */
  inset-inline-end: 1rem; /* end-4 */
  z-index: 60; /* z-[60] */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem; /* w-12 */
  height: 3rem; /* h-12 */
  border-radius: 9999px; /* rounded-full */
  box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); /* shadow-lg */
  border: 1px solid #e2e8f0; /* border-slate-200 */
  background-color: #ffffff; /* bg-white */
  color: #0f172a; /* text-slate-900 */
  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease; /* transition-colors */
}
.sf-cart-toggle--dark { background-color: #1e293b; border-color: #334155; color: #ffffff; } /* bg-slate-800 border-slate-700 text-white */
.sf-cart-toggle__icon { width: 1.5rem; height: 1.5rem; } /* w-6 h-6 */
.sf-cart-badge {
  position: absolute;
  inset-block-start: -0.25rem; /* -top-1 */
  inset-inline-end: -0.25rem; /* -end-1 */
  min-width: 1.25rem; /* min-w-[1.25rem] */
  height: 1.25rem; /* h-5 */
  padding-inline: 0.25rem; /* px-1 */
  border-radius: 9999px; /* rounded-full */
  background-color: #ef4444; /* bg-red-500 */
  color: #ffffff;
  font-size: 0.75rem; /* text-xs */
  line-height: 1rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
.sf-cart-overlay { position: fixed; inset: 0; z-index: 70; } /* fixed inset-0 z-[70] */
.sf-cart-backdrop { position: absolute; inset: 0; background-color: rgb(0 0 0 / 0.4); } /* absolute inset-0 bg-black/40 */
.sf-cart-drawer {
  position: absolute;
  inset-block-start: 0; /* top-0 */
  inset-inline-end: 0; /* end-0 */
  height: 100%; /* h-full */
  width: 100%; /* w-full */
  max-width: 28rem; /* max-w-md */
  display: flex;
  flex-direction: column;
  box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25); /* shadow-2xl */
  background-color: #ffffff; /* bg-white */
  color: #0f172a; /* text-slate-900 */
}
.sf-cart-drawer--dark { background-color: #0f172a; color: #ffffff; } /* bg-slate-900 text-white */
.sf-cart-drawer__header { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; padding-inline: 1rem; padding-block: 1rem; border-bottom: 1px solid #e2e8f0; } /* flex items-center justify-between gap-3 px-4 py-4 border-b border-slate-200 */
.sf-cart-drawer__header--dark { border-bottom-color: #1e293b; } /* border-slate-800 */
.sf-cart-drawer__title { font-weight: 700; font-size: 1.125rem; line-height: 1.75rem; } /* font-bold text-lg */
.sf-cart-drawer__close { padding: 0.5rem; border-radius: 0.5rem; } /* p-2 rounded-lg */
.sf-cart-drawer__close:hover { background-color: rgb(0 0 0 / 0.05); } /* hover:bg-black/5 — dark:hover:bg-white/10 was dead */
.sf-cart-drawer__close-icon { width: 1.25rem; height: 1.25rem; } /* w-5 h-5 */
.sf-cart-drawer__body { flex: 1 1 0%; overflow-y: auto; padding-inline: 1rem; padding-block: 0.75rem; } /* flex-1 overflow-y-auto px-4 py-3 */
.sf-cart-drawer__empty { text-align: center; font-size: 0.875rem; line-height: 1.25rem; color: #64748b; padding-block: 2.5rem; } /* text-center text-sm text-slate-500 py-10 */
.sf-cart-drawer__line { display: flex; gap: 0.75rem; padding-block: 0.75rem; border-bottom: 1px solid #f1f5f9; } /* flex gap-3 py-3 border-b border-slate-100 */
.sf-cart-drawer__line--dark { border-bottom-color: #1e293b; } /* border-slate-800 */
.sf-cart-drawer__line-img { width: 4rem; height: 4rem; border-radius: 0.5rem; overflow: hidden; flex-shrink: 0; background-color: #f1f5f9; } /* w-16 h-16 rounded-lg overflow-hidden flex-shrink-0 bg-slate-100 — dark:bg-slate-800 was dead */
.sf-cart-drawer__line-img-el { width: 100%; height: 100%; object-fit: cover; } /* w-full h-full object-cover */
.sf-cart-drawer__line-body { flex: 1 1 0%; min-width: 0; } /* flex-1 min-w-0 */
.sf-cart-drawer__line-name { font-weight: 600; font-size: 0.875rem; line-height: 1.25rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* font-semibold text-sm truncate */
.sf-cart-drawer__line-variant { font-size: 0.75rem; line-height: 1rem; color: #64748b; } /* text-xs text-slate-500 */
.sf-cart-drawer__line-price { font-size: 0.875rem; line-height: 1.25rem; font-weight: 700; margin-top: 0.25rem; } /* text-sm font-bold mt-1 */
.sf-cart-drawer__line-controls { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.5rem; } /* flex items-center gap-2 mt-2 */
.sf-cart-drawer__qty-btn { width: 1.75rem; height: 1.75rem; border-radius: 0.25rem; border: 1px solid #cbd5e1; display: flex; align-items: center; justify-content: center; } /* w-7 h-7 rounded border-slate-300 flex items-center justify-center */
.sf-cart-drawer__qty-btn--dark { border-color: #334155; } /* border-slate-700 */
.sf-cart-drawer__qty-value { font-size: 0.875rem; line-height: 1.25rem; font-weight: 500; width: 1.5rem; text-align: center; } /* text-sm font-medium w-6 text-center */
.sf-cart-drawer__remove { margin-inline-start: auto; font-size: 0.75rem; line-height: 1rem; color: #ef4444; } /* ms-auto text-xs text-red-500 */
.sf-cart-drawer__remove:hover { text-decoration: underline; } /* hover:underline */
.sf-cart-drawer__footer { padding-inline: 1rem; padding-block: 1rem; border-top: 1px solid #e2e8f0; } /* px-4 py-4 border-t border-slate-200 */
.sf-cart-drawer__footer--dark { border-top-color: #1e293b; } /* border-slate-800 */
.sf-cart-drawer__subtotal-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.75rem; } /* flex items-center justify-between mb-3 */
.sf-cart-drawer__subtotal-label { font-size: 0.875rem; line-height: 1.25rem; color: #64748b; } /* text-sm text-slate-500 */
.sf-cart-drawer__subtotal-value { font-weight: 700; } /* font-bold */
.sf-cart-drawer__checkout { display: block; width: 100%; text-align: center; padding-block: 0.75rem; border-radius: 0.75rem; font-weight: 700; color: #ffffff; } /* block w-full text-center py-3 rounded-xl font-bold text-white */

/* ── order_tracking.html (Task 0.13) ────────────────────────────────────────
   No pixel harness coverage exists for /track (0.8's spec never included
   it). Verified instead by: go test ./internal/storefront/... (order_tracking
   Go suite pins the rendered bytes it cares about), a structural diff
   (identical tag multiset + data-testid/data-step/data-state sequence
   pre/post), and a manual curl of the fixture tracking page in both ar (rtl)
   and fr (ltr) — see task-0.13-report.md.
   Two Go conditionals collapsed into a single logical-property rule instead
   of a per-dir ternary — {{if eq .Dir "rtl"}}text-left{{else}}text-right{{end}}
   and the connector's left-3/right-3 swap — since text-align:end and
   inset-inline-start already resolve identically per `dir` with no branch. */
.sf-track { min-height: 100vh; transition: background-color 150ms ease; background-color: #f8fafc; } /* min-h-screen transition-colors bg-slate-50 */
.sf-track--dark { background-color: #020617; } /* bg-slate-950 */

.sf-track__header { border-bottom: 1px solid #e2e8f0; transition: background-color 150ms ease, border-color 150ms ease; background-color: #ffffff; } /* border-b transition-colors bg-white border-slate-200 */
.sf-track__header--dark { background-color: #0f172a; border-bottom-color: #1e293b; } /* bg-slate-900 border-slate-800 */
.sf-track__header-inner { max-width: 42rem; margin-inline: auto; padding-inline: 1rem; padding-block: 1rem; } /* max-w-2xl mx-auto px-4 py-4 */
.sf-track__logo { display: flex; align-items: center; gap: 0.5rem; } /* flex items-center gap-2 */
.sf-track__logo-img { height: 2.5rem; width: auto; object-fit: contain; } /* h-10 w-auto object-contain */
.sf-track__logo-fallback { width: 2.5rem; height: 2.5rem; border-radius: 0.5rem; display: flex; align-items: center; justify-content: center; color: #ffffff; font-weight: 700; } /* w-10 h-10 rounded-lg flex items-center justify-center text-white font-bold */
.sf-track__logo-name { font-size: 1.125rem; line-height: 1.75rem; font-weight: 700; color: #0f172a; } /* text-lg font-bold text-slate-900 */
.sf-track__logo-name--dark { color: #ffffff; } /* text-white */

.sf-track__main { max-width: 42rem; margin-inline: auto; padding-inline: 1rem; padding-block: 1.5rem; } /* max-w-2xl mx-auto px-4 py-6 */
@media (min-width: 640px) { .sf-track__main { padding-block: 2.5rem; } } /* sm:py-10 */
.sf-track__heading { font-size: 1.5rem; line-height: 2rem; font-weight: 700; margin-bottom: 1.5rem; color: #0f172a; } /* text-2xl font-bold mb-6 text-slate-900 */
@media (min-width: 640px) { .sf-track__heading { font-size: 1.875rem; line-height: 2.25rem; } } /* sm:text-3xl */
.sf-track__heading--dark { color: #ffffff; } /* text-white */

.sf-track__section { border-radius: 1rem; border: 1px solid #e2e8f0; padding: 1rem; margin-bottom: 1rem; transition: background-color 150ms ease, border-color 150ms ease; background-color: #ffffff; } /* rounded-2xl border p-4 mb-4 transition-colors bg-white border-slate-200 */
@media (min-width: 640px) { .sf-track__section { padding: 1.25rem; } } /* sm:p-5 */
.sf-track__section--dark { background-color: #0f172a; border-color: #1e293b; } /* bg-slate-900 border-slate-800 */

.sf-track__summary-row { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 0.75rem; } /* flex flex-wrap items-start justify-between gap-3 */
.sf-track__label { font-size: 0.75rem; line-height: 1rem; text-transform: uppercase; letter-spacing: 0.025em; color: #64748b; } /* text-xs uppercase tracking-wide text-slate-500 */
.sf-track__label--dark { color: #94a3b8; } /* text-slate-400 */
.sf-track__order-number { font-size: 1.125rem; line-height: 1.75rem; font-weight: 700; color: #0f172a; } /* text-lg font-bold text-slate-900 */
.sf-track__order-number--dark { color: #ffffff; } /* text-white */
.sf-track__summary-right { text-align: end; } /* {{if rtl}}text-left{{else}}text-right{{end}} — text-align:end is the dir-aware equivalent */
.sf-track__placed-value { font-size: 0.875rem; line-height: 1.25rem; font-weight: 500; color: #334155; } /* text-sm font-medium text-slate-700 */
.sf-track__placed-value--dark { color: #e2e8f0; } /* text-slate-200 */

.sf-track__status { margin-top: 1rem; display: inline-flex; align-items: center; gap: 0.5rem; border-radius: 9999px; padding-inline: 0.75rem; padding-block: 0.375rem; font-size: 0.875rem; line-height: 1.25rem; font-weight: 600; } /* mt-4 inline-flex items-center gap-2 rounded-full px-3 py-1.5 text-sm font-semibold */
.sf-track__status--bad { background-color: #ffe4e6; color: #be123c; } /* bg-rose-100 text-rose-700 */
.sf-track__status--delivered { background-color: #d1fae5; color: #047857; } /* bg-emerald-100 text-emerald-700 */
.sf-track__status--pending { background-color: #f1f5f9; color: #334155; } /* bg-slate-100 text-slate-700 */
.sf-track__status-dot { width: 0.5rem; height: 0.5rem; border-radius: 9999px; display: inline-block; } /* w-2 h-2 rounded-full */
.sf-track__status-dot--bad { background-color: #f43f5e; } /* bg-rose-500 */
.sf-track__status-dot--delivered { background-color: #10b981; } /* bg-emerald-500 */
.sf-track__status-dot--pending { background-color: #64748b; } /* bg-slate-500 */

.sf-track__timeline { position: relative; } /* relative */
.sf-track__step { display: flex; gap: 0.75rem; padding-bottom: 1.25rem; position: relative; } /* flex gap-3 pb-5 relative */
.sf-track__step:last-child { padding-bottom: 0; } /* last:pb-0 */
.sf-track__connector { position: absolute; top: 1.5rem; bottom: 0; width: 1px; inset-inline-start: 0.75rem; background-color: #e2e8f0; } /* absolute top-6 bottom-0 w-px (left-3/right-3 per dir → inset-inline-start) bg-slate-200 */
.sf-track__connector--dark { background-color: #334155; } /* bg-slate-700 */
.sf-track__connector--done { background-color: #34d399; } /* bg-emerald-400 */

.sf-track__step-marker { position: relative; z-index: 10; flex-shrink: 0; width: 1.5rem; height: 1.5rem; border-radius: 9999px; display: flex; align-items: center; justify-content: center; } /* relative z-10 flex-shrink-0 w-6 h-6 rounded-full flex items-center justify-center */
.sf-track__step-marker--done { background-color: #10b981; } /* bg-emerald-500 */
.sf-track__step-marker--current { background-color: var(--brand); } /* bg-brand-600 — dynamic per-store color, see base.html's remap table */
.sf-track__step-marker--upcoming { background-color: #e2e8f0; } /* bg-slate-200 */
.sf-track__step-marker--upcoming-dark { background-color: #334155; } /* bg-slate-700 */
.sf-track__step-marker-check { width: 0.875rem; height: 0.875rem; color: #ffffff; } /* w-3.5 h-3.5 text-white */
.sf-track__step-marker-dot { width: 0.5rem; height: 0.5rem; border-radius: 9999px; background-color: #ffffff; } /* w-2 h-2 rounded-full bg-white */

.sf-track__step-body { min-width: 0; padding-top: 0.125rem; } /* min-w-0 pt-0.5 */
.sf-track__step-title { font-size: 0.875rem; line-height: 1.25rem; font-weight: 600; } /* text-sm font-semibold */
.sf-track__step-title--upcoming { color: #94a3b8; } /* text-slate-400 */
.sf-track__step-title--upcoming-dark { color: #64748b; } /* text-slate-500 */
.sf-track__step-title--active { color: #0f172a; } /* text-slate-900 */
.sf-track__step-title--active-dark { color: #ffffff; } /* text-white */
.sf-track__step-date { font-size: 0.75rem; line-height: 1rem; margin-top: 0.125rem; color: #64748b; } /* text-xs mt-0.5 text-slate-500 */
.sf-track__step-date--dark { color: #94a3b8; } /* text-slate-400 */

.sf-track__items-heading { font-size: 0.875rem; line-height: 1.25rem; font-weight: 700; margin-bottom: 0.75rem; color: #0f172a; } /* text-sm font-bold mb-3 text-slate-900 */
.sf-track__items-heading--dark { color: #ffffff; } /* text-white */
.sf-track__items-list > * + * { border-top: 1px solid #f1f5f9; } /* divide-y divide-slate-100 */
.sf-track__items-list--dark > * + * { border-top-color: #1e293b; } /* divide-slate-800 */
.sf-track__item { display: flex; align-items: center; gap: 0.75rem; padding-block: 0.75rem; } /* flex items-center gap-3 py-3 */
.sf-track__item-img { width: 3rem; height: 3rem; border-radius: 0.5rem; object-fit: cover; flex-shrink: 0; background-color: #f1f5f9; } /* w-12 h-12 rounded-lg object-cover flex-shrink-0 bg-slate-100 */
.sf-track__item-img--dark { background-color: #1e293b; } /* bg-slate-800 */
.sf-track__item-body { min-width: 0; flex: 1 1 0%; } /* min-w-0 flex-1 */
.sf-track__item-name { font-size: 0.875rem; line-height: 1.25rem; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #0f172a; } /* text-sm font-medium truncate text-slate-900 */
.sf-track__item-name--dark { color: #ffffff; } /* text-white */
.sf-track__item-meta { font-size: 0.75rem; line-height: 1rem; color: #64748b; } /* text-xs text-slate-500 */
.sf-track__item-meta--dark { color: #94a3b8; } /* text-slate-400 */
.sf-track__item-price { font-size: 0.875rem; line-height: 1.25rem; font-weight: 600; white-space: nowrap; color: #0f172a; } /* text-sm font-semibold whitespace-nowrap text-slate-900 */
.sf-track__item-price--dark { color: #ffffff; } /* text-white */

.sf-track__totals { margin-top: 0.75rem; padding-top: 0.75rem; border-top: 1px solid #f1f5f9; font-size: 0.875rem; line-height: 1.25rem; display: flex; flex-direction: column; gap: 0.375rem; } /* mt-3 pt-3 border-t border-slate-100 space-y-1.5 text-sm */
.sf-track__totals--dark { border-top-color: #1e293b; } /* border-slate-800 */
.sf-track__totals-row { display: flex; justify-content: space-between; } /* flex justify-between */
.sf-track__totals-label { color: #64748b; } /* text-slate-500 */
.sf-track__totals-label--dark { color: #94a3b8; } /* text-slate-400 */
.sf-track__totals-value { color: #334155; } /* text-slate-700 */
.sf-track__totals-value--dark { color: #e2e8f0; } /* text-slate-200 */
.sf-track__totals-row--grand { padding-top: 0.375rem; border-top: 1px solid #f1f5f9; } /* pt-1.5 border-t border-slate-100 */
.sf-track__totals-row--grand-dark { border-top-color: #1e293b; } /* border-slate-800 */
.sf-track__totals-label--bold { font-weight: 700; color: #0f172a; } /* font-bold text-slate-900 */
.sf-track__totals-label--bold-dark { color: #ffffff; } /* text-white */
.sf-track__totals-value--bold { font-weight: 700; color: #0f172a; } /* font-bold text-slate-900 */
.sf-track__totals-value--bold-dark { color: #ffffff; } /* text-white */

.sf-track__delivery-list { display: flex; flex-direction: column; gap: 0.5rem; font-size: 0.875rem; line-height: 1.25rem; } /* space-y-2 text-sm */
.sf-track__delivery-row { display: flex; justify-content: space-between; gap: 1rem; } /* flex justify-between gap-4 */
.sf-track__delivery-value { font-weight: 500; text-align: end; color: #334155; } /* font-medium text-end text-slate-700 */
.sf-track__delivery-value--dark { color: #e2e8f0; } /* text-slate-200 */

.sf-track__contact { display: flex; align-items: center; justify-content: center; gap: 0.5rem; width: 100%; border-radius: 0.75rem; padding-inline: 1rem; padding-block: 0.875rem; color: #ffffff; font-weight: 600; transition: background-color 150ms ease; } /* flex items-center justify-center gap-2 w-full rounded-xl px-4 py-3.5 text-white font-semibold transition-colors */
.sf-track__contact--whatsapp { background-color: #25D366; }
.sf-track__contact--whatsapp:hover { background-color: #1da851; }
.sf-track__contact--phone { background-color: var(--brand); } /* bg-brand-600 — dynamic per-store color */
.sf-track__contact--phone:hover { background-color: color-mix(in srgb, var(--brand) 82%, black); } /* hover:bg-brand-700 — matches base.html's .hover\:bg-brand-700 remap */
.sf-track__contact-icon { width: 1.25rem; height: 1.25rem; } /* w-5 h-5 */

.sf-track__hint { margin-top: 1rem; text-align: center; font-size: 0.75rem; line-height: 1rem; color: #94a3b8; } /* mt-4 text-center text-xs text-slate-400 */
.sf-track__hint--dark { color: #64748b; } /* text-slate-500 */

/* ── product_v2.html: description, sticky mobile CTA, success modal
   leftovers from Task 0.12 (Task 0.13) ─────────────────────────────────────
   dark:* utilities throughout this section were confirmed DEAD: every one
   was wrapped in {{ if .IsDark }} in the pre-conversion markup, AND
   individually gated by Tailwind's darkMode:"class" on a literal
   class="dark" ancestor that nothing in this codebase ever sets — so
   dropped rather than ported, per the house dark:-is-dead rule. The one
   exception is the success modal panel's bare `border` (see
   .sf-product__modal-panel--dark-border below): that one was NOT dark:
   -prefixed, so it was live only when the Go .IsDark branch was taken. */
.sf-product__description { display: flex; flex-direction: column; gap: 2rem; padding-top: 1.5rem; border-top: 1px solid #e2e8f0; } /* space-y-8 pt-6 border-t border-slate-200 */
.sf-product__description-body { color: #475569; line-height: 1.625; } /* text-slate-600 leading-relaxed */
.sf-product__description-body--rtl { text-align: right; font-family: Inter, Poppins, "Noto Sans Arabic", sans-serif; } /* text-right font-arabic */
.sf-product__description-images { display: flex; flex-direction: column; } /* flex flex-col gap-0 (gap-0 is a no-op) */
.sf-product__description-image-wrap { overflow: hidden; } /* overflow-hidden */
.sf-product__description-image { width: 100%; height: auto; object-fit: cover; } /* w-full h-auto object-cover */

/* Task 0.13 follow-up #3 from task-0.12-report.md: x-show="showStickyButton"
   is scroll-gated JS state, false in every pixel-harness capture — a static
   screenshot cannot see position:fixed being dropped here. Pinned directly
   by TestProductStickyMobileCTAIsFixedPositioned (0.11's
   .sf-filterbar/position:sticky pattern). */
.sf-product__sticky-cta {
  position: fixed; /* fixed */
  inset-block-end: 0; /* bottom-0 */
  inset-inline: 0; /* inset-x-0 */
  padding: 1rem; /* p-4 */
  background-color: rgb(255 255 255 / 0.8); /* bg-white/80 */
  backdrop-filter: blur(16px); /* backdrop-blur-lg */
  border-top: 1px solid currentColor; /* border-t (bare, no color utility — currentColor) */
  z-index: 40; /* z-40 */
}
@media (min-width: 1024px) { .sf-product__sticky-cta { display: none; } } /* lg:hidden */
.sf-product__sticky-cta-btn { width: 100%; padding-block: 1rem; border-radius: 1rem; color: #ffffff; font-weight: 700; box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); display: flex; align-items: center; justify-content: center; gap: 0.5rem; } /* w-full py-4 rounded-2xl text-white font-bold shadow-lg flex items-center justify-center gap-2 */
.sf-product__sticky-cta-icon { width: 1.25rem; height: 1.25rem; } /* w-5 h-5 */

.sf-product__modal-overlay { position: fixed; inset: 0; z-index: 50; display: flex; align-items: center; justify-content: center; padding: 1rem; } /* fixed inset-0 z-50 flex items-center justify-center p-4 */
.sf-product__modal-backdrop { position: fixed; inset: 0; background-color: rgb(0 0 0 / 0.5); backdrop-filter: blur(4px); } /* fixed inset-0 bg-black/50 backdrop-blur-sm */
.sf-product__modal-panel { position: relative; width: 100%; max-width: 28rem; border-radius: 1rem; box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25); padding: 2rem; background-color: #ffffff; } /* relative w-full max-w-md rounded-2xl shadow-2xl p-8 bg-white */
.sf-product__modal-panel--dark-border { border: 1px solid currentColor; } /* the one LIVE dark-only class: bare `border`, added only when .IsDark */
.sf-product__modal-panel--rtl { font-family: Inter, Poppins, "Noto Sans Arabic", sans-serif; } /* font-arabic */
.sf-product__modal-icon-wrap { display: flex; justify-content: center; margin-bottom: 1.5rem; } /* flex justify-center mb-6 */
.sf-product__modal-icon-badge { position: relative; margin-inline: auto; display: flex; height: 6rem; width: 6rem; align-items: center; justify-content: center; border-radius: 9999px; background-color: rgb(236 253 245 / 0.95); box-shadow: 0 18px 45px -24px rgba(16,185,129,0.85); } /* relative mx-auto flex h-24 w-24 items-center justify-center rounded-full bg-emerald-50/95 shadow-[0_18px_45px_-24px_rgba(16,185,129,0.85)] */
.sf-product__modal-icon-ring { position: absolute; inset: 0; border-radius: 9999px; border: 1px solid rgb(167 243 208 / 0.8); } /* absolute inset-0 rounded-full border border-emerald-200/80 */
.sf-product__modal-icon-core { position: relative; display: flex; height: 4rem; width: 4rem; align-items: center; justify-content: center; border-radius: 9999px; background-color: #10b981; color: #ffffff; box-shadow: 0 16px 32px -20px rgba(16,185,129,0.9); outline: 1px solid rgb(255 255 255 / 0.7); } /* relative flex h-16 w-16 items-center justify-center rounded-full bg-emerald-500 text-white shadow-[0_16px_32px_-20px_rgba(16,185,129,0.9)] ring-1 ring-white/70 */
.sf-product__modal-icon-check { height: 2.25rem; width: 2.25rem; } /* h-9 w-9 */
.sf-product__modal-body { text-align: center; display: flex; flex-direction: column; gap: 0.75rem; } /* text-center space-y-3 */
.sf-product__modal-title { font-size: 1.5rem; line-height: 2rem; font-weight: 700; color: #0f172a; } /* text-2xl font-bold text-slate-900 */
.sf-product__modal-subtitle { color: #475569; font-size: 0.875rem; line-height: 1.25rem; } /* text-slate-600 text-sm */
.sf-product__modal-actions { margin-top: 2rem; display: flex; flex-direction: column; gap: 0.75rem; } /* mt-8 space-y-3 */
.sf-product__modal-track-btn { width: 100%; display: flex; align-items: center; justify-content: center; gap: 0.5rem; padding-inline: 1.5rem; padding-block: 0.75rem; border-radius: 0.5rem; font-weight: 700; font-size: 0.875rem; line-height: 1.25rem; transition: box-shadow 150ms ease; color: #ffffff; box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); } /* w-full flex items-center justify-center gap-2 px-6 py-3 rounded-lg font-bold text-sm transition-all text-white shadow-lg */
.sf-product__modal-track-icon { width: 1rem; height: 1rem; } /* w-4 h-4 */
.sf-product__modal-hint { font-size: 0.75rem; line-height: 1rem; text-align: center; color: #64748b; } /* text-xs text-center text-slate-500 */
.sf-product__modal-secondary { width: 100%; display: flex; align-items: center; justify-content: center; padding-inline: 1.5rem; padding-block: 0.75rem; border-radius: 0.5rem; font-weight: 700; font-size: 0.875rem; line-height: 1.25rem; transition: background-color 150ms ease; background-color: #f1f5f9; color: #0f172a; } /* w-full flex items-center justify-center px-6 py-3 rounded-lg font-bold text-sm transition-all bg-slate-100 text-slate-900 */
.sf-product__modal-secondary:hover { background-color: #e2e8f0; } /* hover:bg-slate-200 */
.sf-product__modal-secondary--elevated { gap: 0.5rem; box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); } /* the "continue shopping" link only: gap-2 shadow-sm — the close <button> has neither */

/* ── partials/checkout_fields.html + custom_fields.html: FULL conversion
   (Task 0.13) — 0.12 left these two with ADDITIVE sf-of__field/sf-of__dtype
   markers only, alongside the original Tailwind utilities (see
   task-0.12-report.md's concern #2). Both dir-based ternaries (icon/chevron
   left-3 vs right-3, and the text/select inputs' pl-10/pr-10 pair) collapse
   into inset-inline-start/end and padding-inline-start/end — pure physical
   mirrors of one rule, no branch needed; verified in both languages. */
.sf-of__row { display: grid; grid-template-columns: repeat(1, minmax(0, 1fr)); gap: 0.75rem; } /* grid grid-cols-1 gap-3 */
@media (min-width: 640px) { .sf-of__row { grid-template-columns: repeat(2, minmax(0, 1fr)); } } /* sm:grid-cols-2 */
.sf-of__row--2col { grid-template-columns: repeat(2, minmax(0, 1fr)); } /* grid-cols-2, unconditionally — the location row, unlike the name/phone row above */
/* NOT display:flex — .sf-of__field's first child is an inline <label> (no
   block/flex class of its own). A flex container promotes it to a flex item
   with a content-only box, dropping the extra "strut" height an inline
   element gets from its block-context line box — 8px per field, caught by
   the pixel harness (46207px diff / 24px shorter page), not by any Go test.
   `> * + *` reproduces space-y-1's margin exactly, in the same block
   context, so the label keeps its original (if slightly odd) sizing. */
.sf-of__field > * + * { margin-top: 0.25rem; } /* space-y-1 */
.sf-of__label { font-size: 0.75rem; line-height: 1rem; font-weight: 700; color: #334155; } /* text-xs font-bold text-slate-700 */
.sf-of__required { color: #ef4444; } /* text-red-500 */

.sf-of__input-wrap { position: relative; } /* relative */
.sf-of__input-icon { position: absolute; inset-inline-start: 0.75rem; top: 50%; transform: translateY(-50%); color: #94a3b8; } /* absolute (left-3/right-3 per dir → inset-inline-start) top-1/2 -translate-y-1/2 text-slate-400 */
.sf-of__input-icon--muted { pointer-events: none; } /* pointer-events-none — the state/city select icons only, they'd otherwise block opening the <select> */
.sf-of__input-icon-svg { width: 1rem; height: 1rem; } /* w-4 h-4 */
.sf-of__select-chevron { position: absolute; inset-inline-end: 0.75rem; top: 50%; transform: translateY(-50%); color: #94a3b8; pointer-events: none; } /* absolute (right-3/left-3 per dir → inset-inline-end) top-1/2 -translate-y-1/2 text-slate-400 pointer-events-none */

.sf-of__input {
  width: 100%;
  min-height: 2.75rem; /* min-h-11 (custom_fields' shape) */
  padding-inline: 1rem; /* px-4 */
  padding-block: 0.625rem; /* py-2.5 */
  border-radius: 0.75rem; /* rounded-xl */
  border: 1px solid #e2e8f0; /* border-slate-200 */
  background-color: #f8fafc; /* bg-slate-50 */
  outline: none;
  transition: border-color 150ms ease, box-shadow 150ms ease; /* transition-all */
  text-align: start; /* text-right/text-left per dir — both wanted the START edge */
}
.sf-of__input:focus { border-color: var(--brand); box-shadow: 0 0 0 1px var(--brand); } /* focus:border-brand-500 focus:ring-1 focus:ring-brand-500 */
.sf-of__input:disabled { opacity: 0.5; } /* disabled:opacity-50 */
.sf-of__input--error { border-color: #ef4444; } /* :class="errors.x ? 'border-red-500...' */
.sf-of__input--error:focus { border-color: #ef4444; box-shadow: 0 0 0 1px #ef4444; } /* focus:border-red-500 focus:ring-red-500 */
.sf-of__input--icon { padding-inline-start: 2.5rem; min-height: 0; } /* checkout_fields' name/phone: pl-10/pr-10 pl-4/pr-4, no min-h-11 in the original */
.sf-of__input--select { padding-inline-start: 2.5rem; padding-inline-end: 2.5rem; min-height: 0; appearance: none; } /* checkout_fields' state/city: pl-10 pr-10 appearance-none, no min-h-11 */
.sf-of__error { color: #ef4444; font-size: 0.75rem; line-height: 1rem; margin-top: 0.25rem; } /* text-red-500 text-xs mt-1 */

.sf-of__dtype-label { display: block; font-size: 0.875rem; line-height: 1.25rem; font-weight: 700; margin-bottom: 0.5rem; color: #1e293b; } /* block text-sm font-bold mb-2 text-slate-800 */
.sf-of__dtype-row { display: flex; gap: 0.75rem; } /* flex gap-3 */
.sf-of__dtype-btn {
  flex: 1 1 0%;
  padding-block: 0.625rem; /* py-2.5 */
  padding-inline: 0.75rem; /* px-3 */
  border-radius: 0.75rem; /* rounded-xl */
  font-weight: 600; /* font-semibold */
  font-size: 0.75rem; /* text-xs */
  line-height: 1rem;
  transition: border-color 150ms ease, background-color 150ms ease, color 150ms ease; /* transition */
  border-width: 2px; /* border-2 */
  border-style: solid;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.375rem; /* gap-1.5 */
}
.sf-of__dtype-btn--active { border-color: var(--brand); background-color: color-mix(in srgb, var(--brand) 8%, white); color: var(--brand); } /* border-brand-600 bg-brand-50 text-brand-600 */
.sf-of__dtype-btn--inactive { border-color: #e2e8f0; color: #475569; } /* border-slate-200 text-slate-600 */
.sf-of__dtype-btn--inactive:hover { border-color: #cbd5e1; } /* hover:border-slate-300 */
.sf-of__dtype-icon { width: 1.25rem; height: 1.25rem; } /* w-5 h-5 */

.sf-of__custom-fields { display: flex; flex-direction: column; gap: 0.75rem; } /* space-y-3 */
.sf-of__custom-label { display: block; } /* block */
.sf-of__custom-label > * + * { margin-top: 0.25rem; } /* space-y-1 between the label text and its input/textarea */
.sf-of__char-count { font-size: 0.75rem; line-height: 1rem; color: #94a3b8; text-align: end; } /* text-xs text-slate-400 text-left/text-right per dir — both wanted the END edge (opposite of .sf-of__input's start) */
.sf-of__hint { font-size: 0.75rem; line-height: 1rem; color: #94a3b8; } /* text-xs text-slate-400 */
.sf-of__bounds-hint { font-size: 0.75rem; line-height: 1rem; color: #94a3b8; } /* text-xs text-slate-400 — #1392's numberBoundsHint() text, kept a distinct class from .sf-of__hint despite identical rules today since the two mark unrelated hints (quantity vs. number bounds) */

/* ── partials/footer.html (Task 0.13) — renders on EVERY page via
   layouts/base.html. Confirmed and dropped as dead: every dark:-prefixed
   utility here (Go-if-wrapped OR bare) needs a literal class="dark"
   ancestor Tailwind's darkMode:"class" requires, which nothing in this
   codebase ever sets. Also confirmed: hover:text-brand-600,
   hover:border-brand-500 and hover:text-brand-500 have NO entry in
   base.html's brand remap table (unlike the non-hover/focus variants), so
   they use the STATIC Tailwind brand hex — replicated as literal
   #059669/#10b981 below, not var(--brand). */
.sf-footer { border-top: 1px solid #e2e8f0; transition: background-color 150ms ease, border-color 150ms ease; } /* border-t transition-colors border-slate-200 */
.sf-footer--default { margin-top: 5rem; background-color: rgba(248, 250, 252, 0.5); } /* mt-20 bg-slate-50/50 */
.sf-footer--lp { margin-top: 0; background-color: #ffffff; } /* mt-0 bg-white */
.sf-footer--product-padded { padding-bottom: 6rem; } /* pb-24 */
@media (min-width: 1024px) { .sf-footer--product-padded { padding-bottom: 0; } } /* lg:pb-0 */
.sf-footer__inner { margin-inline: auto; padding-inline: 1rem; } /* mx-auto px-4 */
.sf-footer__inner--default { max-width: 80rem; padding-block: 3rem; } /* max-w-7xl py-12 */
.sf-footer__inner--lp { max-width: 35rem; padding-block: 2.5rem; } /* max-w-[560px] py-10 */
.sf-footer__main { margin-bottom: 2rem; } /* mb-8 */
.sf-footer__brand { display: flex; flex-direction: column; align-items: center; gap: 1rem; text-align: center; } /* flex flex-col items-center gap-4 text-center */
.sf-footer__logo { height: 3.5rem; width: auto; object-fit: contain; } /* h-14 w-auto object-contain */
.sf-footer__name { font-size: 1.125rem; line-height: 1.75rem; font-weight: 700; margin-bottom: 0.5rem; color: #0f172a; } /* text-lg font-bold mb-2 text-slate-900 */
.sf-footer__desc { font-size: 0.875rem; line-height: 1.25rem; color: #475569; margin-bottom: 1rem; } /* text-sm text-slate-600 mb-4 */
.sf-footer__social { display: flex; align-items: center; justify-content: center; gap: 0.75rem; } /* flex items-center justify-center gap-3 */
.sf-footer__social-link { display: inline-flex; height: 2.75rem; width: 2.75rem; align-items: center; justify-content: center; border-radius: 9999px; border: 1px solid #e2e8f0; background-color: #ffffff; color: #64748b; transition: border-color 150ms ease, color 150ms ease; } /* inline-flex h-11 w-11 items-center justify-center rounded-full border-slate-200 bg-white text-slate-500 transition */
.sf-footer__social-link:hover { border-color: #10b981; color: #10b981; } /* hover:border-brand-500 hover:text-brand-500 (static hex, no remap entry) */
.sf-footer__track-wrap { margin-bottom: 1.5rem; text-align: center; } /* mb-6 text-center */
.sf-footer__track-link { font-size: 0.875rem; line-height: 1.25rem; font-weight: 500; color: #475569; transition: color 150ms ease; } /* text-sm font-medium text-slate-600 transition-colors */
.sf-footer__track-link:hover { color: #059669; } /* hover:text-brand-600 (static hex, no remap entry) */
.sf-footer__copyright { padding-top: 2rem; border-top: 1px solid #e2e8f0; text-align: center; font-size: 0.75rem; line-height: 1rem; color: #475569; } /* pt-8 border-t border-slate-200 text-center text-xs text-slate-600 */
@media (min-width: 768px) { .sf-footer__copyright { font-size: 0.875rem; line-height: 1.25rem; } } /* md:text-sm */
.sf-footer__copyright-link { font-weight: 600; transition: color 150ms ease; } /* font-semibold transition-colors */
.sf-footer__copyright-link:hover { color: #059669; } /* hover:text-brand-600 (static hex, no remap entry) */

/* ── partials/announcement_bar.html (Task 0.13) — renders on home.html,
   order_lookup.html, order_tracking.html, product_v2.html.
   announcement-bar-viewport/-track/-scroll-segment/-item are UNTOUCHED —
   already non-Tailwind, styled in static/input.css, selected by literal
   class name in announcement-bar.js. */
.sf-announcement { width: 100%; overflow: hidden; padding-block: 0.625rem; border-bottom: 1px solid rgba(255, 255, 255, 0.1); color: #ffffff; } /* w-full overflow-hidden py-2.5 border-b border-white/10 text-white */
.sf-visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border-width: 0; } /* sr-only */
.sf-announcement__text { font-size: 0.875rem; line-height: 1.25rem; font-weight: 500; } /* text-sm font-medium */
.sf-announcement__static {
  width: 100%; /* container */
  margin-inline: auto; /* mx-auto */
  padding-inline: 1rem; /* px-4 (overrides container's own responsive padding) */
  display: flex;
  justify-content: center;
  align-items: center;
}
@media (min-width: 640px) { .sf-announcement__static { max-width: 640px; } } /* container's sm breakpoint */
@media (min-width: 768px) { .sf-announcement__static { max-width: 768px; } } /* container's md breakpoint */
@media (min-width: 1024px) { .sf-announcement__static { max-width: 1024px; } } /* container's lg breakpoint */
@media (min-width: 1280px) { .sf-announcement__static { max-width: 1280px; } } /* container's xl/2xl breakpoint — this repo's tailwind.config.js pins 2xl to the same 1280px as xl */
.sf-announcement__static-text { font-size: 0.875rem; line-height: 1.25rem; font-weight: 500; text-align: center; } /* text-sm font-medium text-center */

/* ── partials/sticky_contact.html (Task 0.13) — renders on home.html,
   product_v2.html, landing_page.html. */
.sf-sticky-contact { position: fixed; inset-inline-end: 1rem; z-index: 50; display: flex; flex-direction: column; gap: 0.75rem; } /* fixed (left-4/right-4 per dir → inset-inline-end) z-50 flex flex-col gap-3 */
.sf-sticky-contact--lp { inset-block-end: 6rem; } /* bottom-24 lg:bottom-24 — same value at every width */
.sf-sticky-contact--product { inset-block-end: 5rem; } /* bottom-20 */
@media (min-width: 1024px) { .sf-sticky-contact--product { inset-block-end: 1.5rem; } } /* lg:bottom-6 */
.sf-sticky-contact--default { inset-block-end: 1.5rem; } /* bottom-6 */
.sf-sticky-contact__btn { width: 3rem; height: 3rem; border-radius: 9999px; color: #ffffff; display: flex; align-items: center; justify-content: center; box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); transition: background-color 150ms ease, transform 150ms ease; } /* w-12 h-12 rounded-full text-white flex items-center justify-center shadow-lg transition-all */
.sf-sticky-contact__btn:hover { transform: scale(1.1); } /* hover:scale-110 */
.sf-sticky-contact__btn--phone { background-color: #3b82f6; } /* bg-blue-500 */
.sf-sticky-contact__btn--phone:hover { background-color: #2563eb; } /* hover:bg-blue-600 */
.sf-sticky-contact__btn--whatsapp { background-color: #22c55e; } /* bg-green-500 */
.sf-sticky-contact__btn--whatsapp:hover { background-color: #16a34a; } /* hover:bg-green-600 */
.sf-sticky-contact__icon { width: 1.5rem; height: 1.5rem; } /* w-6 h-6 */

/* ── partials/order_form.html (Task 0.13 fix round) — the "40 hits" left
   behind by 0.12's sf-of contract markers. Two :style bindings on the
   upsell card/checkbox (border-color/background-color from .MainColor) are
   UNCHANGED from before this pass — see order_form.html's own comment on
   why re-deriving them as a {{ json ... }} pipeline would reopen the
   variants.html ZgotmplZ regression. dark:-prefixed / Go-if-wrapped-dark
   utilities confirmed dead per the established pattern, dropped. The
   add-to-cart button's IsDark branch is a genuine exception — it picks
   between two literal, non-"dark:"-prefixed class sets directly, so both
   are implemented for real below. */
.sf-of__form { display: flex; flex-direction: column; gap: 0.75rem; } /* space-y-3 */
.sf-of__soldout { display: inline-flex; align-items: center; gap: 0.375rem; border-radius: 9999px; background-color: #dc2626; padding-inline: 0.75rem; padding-block: 0.25rem; font-size: 0.75rem; line-height: 1rem; font-weight: 600; color: #ffffff; } /* inline-flex items-center gap-1.5 rounded-full bg-red-600 px-3 py-1 text-xs font-semibold text-white */
.sf-of__soldout-icon { width: 0.875rem; height: 0.875rem; } /* w-3.5 h-3.5 */

.sf-of__upsells { display: flex; flex-direction: column; } /* space-y-2 wrapper */
.sf-of__upsells > * + * { margin-top: 0.5rem; } /* space-y-2 */
.sf-of__upsells-header { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.25rem; } /* flex items-center gap-2 mb-1 */
.sf-of__upsells-header-icon { width: 1rem; height: 1rem; color: #f59e0b; } /* w-4 h-4 text-amber-500 */
.sf-of__upsells-title { font-size: 0.875rem; line-height: 1.25rem; font-weight: 700; color: #0f172a; } /* text-sm font-bold text-slate-900 */

.sf-of__upsell { position: relative; overflow: hidden; padding: 0.75rem; border-width: 2px; border-style: solid; border-radius: 0.75rem; cursor: pointer; transition: border-color 200ms ease, background-color 200ms ease; } /* relative overflow-hidden p-3 border-2 rounded-xl cursor-pointer transition-all duration-200 */
.sf-of__upsell--inactive { border-color: #e2e8f0; } /* border-slate-200 (active branch's border/bg comes from the :style binding) */
.sf-of__upsell--inactive:hover { border-color: #cbd5e1; background-color: #f8fafc; } /* hover:border-slate-300 hover:bg-slate-50 */
.sf-of__upsell-tag { position: absolute; top: 0; inset-inline-end: 0; border-end-start-radius: 0.75rem; background-image: linear-gradient(to right, #f59e0b, #f97316); color: #ffffff; font-size: 0.75rem; line-height: 1rem; font-weight: 700; padding-inline: 0.75rem; padding-block: 0.375rem; box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); z-index: 10; } /* absolute top-0 (left-0 rounded-br-xl / right-0 rounded-bl-xl per dir → inset-inline-end + border-end-start-radius) bg-gradient-to-r from-amber-500 to-orange-500 text-white text-xs font-bold px-3 py-1.5 shadow-lg z-10 */
.sf-of__upsell-body { display: flex; align-items: center; gap: 0.75rem; } /* flex items-center gap-3 */
.sf-of__upsell-check { width: 1.25rem; height: 1.25rem; border-radius: 9999px; border-width: 2px; border-style: solid; flex-shrink: 0; display: flex; align-items: center; justify-content: center; transition: border-color 150ms ease, background-color 150ms ease; } /* w-5 h-5 rounded-full border-2 flex-shrink-0 flex items-center justify-center transition-colors */
.sf-of__upsell-check--inactive { border-color: #cbd5e1; } /* border-slate-300 (active branch's border/bg comes from the :style binding) */
.sf-of__upsell-check-icon { width: 0.75rem; height: 0.75rem; color: #ffffff; } /* w-3 h-3 text-white */
.sf-of__upsell-content { flex: 1 1 0%; } /* flex-1 */
.sf-of__upsell-row { display: flex; justify-content: space-between; align-items: flex-start; gap: 0.75rem; } /* flex justify-between items-start gap-3 */
.sf-of__upsell-left { flex: 1 1 0%; } /* flex-1 */
.sf-of__upsell-name { font-weight: 700; font-size: 0.875rem; line-height: 1.25rem; color: #0f172a; } /* font-bold text-sm text-slate-900 */
.sf-of__upsell-badges { display: flex; align-items: center; gap: 0.375rem; margin-top: 0.375rem; flex-wrap: wrap; } /* flex items-center gap-1.5 mt-1.5 flex-wrap */
.sf-of__upsell-badge--shipping { display: inline-flex; align-items: center; gap: 0.25rem; font-size: 0.625rem; line-height: 0.75rem; font-weight: 700; padding-inline: 0.5rem; padding-block: 0.125rem; border-radius: 0.25rem; background-color: #dcfce7; color: #15803d; } /* inline-flex items-center gap-1 text-[10px] font-bold px-2 py-0.5 rounded bg-green-100 text-green-700 */
.sf-of__upsell-badge-icon { width: 0.625rem; height: 0.625rem; } /* w-2.5 h-2.5 */
.sf-of__upsell-badge--saving { font-size: 0.625rem; line-height: 0.75rem; font-weight: 700; padding-inline: 0.5rem; padding-block: 0.125rem; border-radius: 0.25rem; background-color: #fef3c7; color: #b45309; } /* text-[10px] font-bold px-2 py-0.5 rounded bg-amber-100 text-amber-700 */
.sf-of__upsell-price-col { flex-shrink: 0; text-align: end; } /* flex-shrink-0 text-left/text-right per dir — both wanted the END edge */
.sf-of__upsell-price { font-weight: 900; font-size: 1rem; line-height: 1.5rem; } /* font-black text-base */
.sf-of__upsell-price--best { margin-top: 1rem; } /* :class="offer.isBestOffer ? 'mt-4' : ''" */
.sf-of__upsell-compare { font-size: 0.625rem; line-height: 0.75rem; color: #64748b; text-decoration: line-through; } /* text-[10px] text-slate-500 line-through */

.sf-of__summary-row { display: flex; justify-content: space-between; align-items: center; font-size: 0.75rem; line-height: 1rem; color: #475569; } /* flex justify-between items-center text-xs text-slate-600 */
.sf-of__summary-value { font-weight: 500; color: #0f172a; } /* font-medium text-slate-900 */
/* margin-bottom ONLY (not margin-block): .sf-of__summary's pre-existing
   `> * + * { margin-top: 0.375rem }` rule (0.12, product-card section above)
   already gives every row — including this divider — a 6px margin-top via
   the cascade (later-wins at equal specificity beats the divider's own
   0.25rem/4px, since that rule comes first in file order). The original
   Tailwind markup had exactly this asymmetry: `my-1` (4px/4px) lost its
   margin-top half to the same custom rule, keeping only margin-bottom.
   Setting margin-block here (a fix-round first attempt) collapsed both to
   4px and cost the pixel harness 2px on the whole page — measured via a
   controlled git-show A/B against the last-committed blob, same method as
   the earlier .sf-of__field regression. */
.sf-of__summary-divider { border-top: 1px dashed #e2e8f0; margin-bottom: 0.25rem; } /* border-t border-dashed border-slate-200 my-1 (margin-top half overridden by .sf-of__summary's own cascade, see above) */
.sf-of__summary-total-row { display: flex; justify-content: space-between; align-items: center; font-size: 0.875rem; line-height: 1.25rem; font-weight: 700; color: #0f172a; } /* flex justify-between items-center text-sm font-bold text-slate-900 */
.sf-of__summary-total-value { font-size: 1rem; line-height: 1.5rem; } /* text-base */

.sf-of__form-error { font-size: 0.875rem; line-height: 1.25rem; font-weight: 700; text-align: center; color: #b91c1c; background-color: #fee2e2; border-radius: 0.75rem; padding-inline: 1rem; padding-block: 0.75rem; border: 1px solid #fecaca; } /* text-sm font-bold text-center text-red-700 bg-red-100 rounded-xl px-4 py-3 border border-red-200 */

.sf-of__actions { display: flex; gap: 0.5rem; } /* flex gap-2 */
.sf-of__add-to-cart { position: relative; flex-shrink: 0; width: 3.25rem; display: flex; align-items: center; justify-content: center; transition: background-color 150ms ease, color 150ms ease; } /* relative flex-shrink-0 w-[52px] flex items-center justify-center transition-colors */
.sf-of__add-to-cart:disabled { opacity: 0.5; cursor: not-allowed; } /* disabled:opacity-50 disabled:cursor-not-allowed */
.sf-of__add-to-cart--light { background-color: #f1f5f9; color: #475569; } /* bg-slate-100 text-slate-600 — the genuinely-live .IsDark=false branch */
.sf-of__add-to-cart--dark { background-color: #1e293b; color: #cbd5e1; } /* bg-slate-800 text-slate-300 — the genuinely-live .IsDark=true branch */
.sf-of__add-to-cart-icon { width: 1.25rem; height: 1.25rem; } /* w-5 h-5 */
.sf-of__add-to-cart-icon--added { color: #10b981; } /* text-emerald-500 */
.sf-of__add-to-cart-badge { position: absolute; inset-block-start: -0.25rem; inset-inline-end: -0.25rem; min-width: 1.25rem; height: 1.25rem; padding-inline: 0.25rem; border-radius: 9999px; background-color: #ef4444; color: #ffffff; font-size: 0.75rem; line-height: 1rem; font-weight: 700; display: flex; align-items: center; justify-content: center; } /* absolute -top-1 -end-1 min-w-[1.25rem] h-5 px-1 rounded-full bg-red-500 text-white text-xs font-bold flex items-center justify-center */

.sf-of__submit { flex: 1 1 0%; padding-block: 0.75rem; font-weight: 700; font-size: 0.875rem; line-height: 1.25rem; transition: box-shadow 150ms ease, transform 150ms ease; display: flex; align-items: center; justify-content: center; gap: 0.5rem; } /* flex-1 py-3 font-bold text-sm transition-all flex items-center justify-center gap-2 */
.sf-of__submit:disabled { opacity: 0.75; cursor: not-allowed; } /* disabled:opacity-75 disabled:cursor-not-allowed */
.sf-of__submit:hover { transform: translateY(-0.125rem); } /* transform hover:-translate-y-0.5 */
.sf-of__submit-spinner { width: 1.25rem; height: 1.25rem; animation: sf-spin 1s linear infinite; } /* animate-spin w-5 h-5 */
.sf-of__submit-spinner-track { opacity: 0.25; } /* opacity-25 */
.sf-of__submit-spinner-fill { opacity: 0.75; } /* opacity-75 */
@keyframes sf-spin { to { transform: rotate(360deg); } } /* Tailwind's animate-spin keyframe, namespaced to avoid colliding with a future theme's own @keyframes spin */

/* ── order_lookup.html (Task 0.13 fix round, GET/POST /track) ────────────────
   Unlike most files in this task, EVERY {{ if .IsDark }}...{{ else }}...{{
   end }} here (no "dark:" prefix inside) is genuinely LIVE — implemented as
   real --dark modifier classes below, not dropped. No pixel harness exists
   for this route; verified via go test + a structural curl diff instead. */
.sf-lookup { min-height: 100vh; transition: background-color 150ms ease; background-color: #f8fafc; } /* min-h-screen transition-colors bg-slate-50 */
.sf-lookup--dark { background-color: #020617; } /* bg-slate-950 */
.sf-lookup__header { border-bottom: 1px solid #e2e8f0; transition: background-color 150ms ease, border-color 150ms ease; background-color: #ffffff; } /* border-b transition-colors bg-white border-slate-200 */
.sf-lookup__header--dark { background-color: #0f172a; border-bottom-color: #1e293b; } /* bg-slate-900 border-slate-800 */
.sf-lookup__header-inner { max-width: 42rem; margin-inline: auto; padding-inline: 1rem; padding-block: 1rem; } /* max-w-2xl mx-auto px-4 py-4 */
.sf-lookup__logo { display: flex; align-items: center; gap: 0.5rem; } /* flex items-center gap-2 */
.sf-lookup__logo-img { height: 2.5rem; width: auto; object-fit: contain; } /* h-10 w-auto object-contain */
.sf-lookup__logo-fallback { width: 2.5rem; height: 2.5rem; border-radius: 0.5rem; display: flex; align-items: center; justify-content: center; color: #ffffff; font-weight: 700; } /* w-10 h-10 rounded-lg flex items-center justify-center text-white font-bold */
.sf-lookup__logo-name { font-size: 1.125rem; line-height: 1.75rem; font-weight: 700; color: #0f172a; } /* text-lg font-bold text-slate-900 */
.sf-lookup__logo-name--dark { color: #ffffff; } /* text-white */

.sf-lookup__main { max-width: 42rem; margin-inline: auto; padding-inline: 1rem; padding-block: 1.5rem; } /* max-w-2xl mx-auto px-4 py-6 */
@media (min-width: 640px) { .sf-lookup__main { padding-block: 2.5rem; } } /* sm:py-10 */
.sf-lookup__heading { font-size: 1.5rem; line-height: 2rem; font-weight: 700; margin-bottom: 0.5rem; color: #0f172a; } /* text-2xl font-bold mb-2 text-slate-900 */
@media (min-width: 640px) { .sf-lookup__heading { font-size: 1.875rem; line-height: 2.25rem; } } /* sm:text-3xl */
.sf-lookup__heading--dark { color: #ffffff; } /* text-white */
.sf-lookup__intro { margin-bottom: 1.5rem; font-size: 0.875rem; line-height: 1.25rem; color: #64748b; } /* mb-6 text-sm text-slate-500 */
.sf-lookup__intro--dark { color: #94a3b8; } /* text-slate-400 */
.sf-lookup__dead-link { margin-bottom: 1rem; font-size: 0.875rem; line-height: 1.25rem; font-weight: 500; color: #334155; } /* mb-4 text-sm font-medium text-slate-700 */
.sf-lookup__dead-link--dark { color: #cbd5e1; } /* text-slate-300 */

.sf-lookup__error { margin-bottom: 1rem; border-radius: 0.75rem; border: 1px solid #fecdd3; padding-inline: 1rem; padding-block: 0.75rem; font-size: 0.875rem; line-height: 1.25rem; background-color: #fff1f2; color: #be123c; } /* mb-4 rounded-xl border px-4 py-3 text-sm bg-rose-50 border-rose-200 text-rose-700 */
.sf-lookup__error--dark { background-color: rgba(76, 5, 25, 0.4); border-color: #881337; color: #fecdd3; } /* bg-rose-950/40 border-rose-900 text-rose-200 */
.sf-lookup__error-title { font-weight: 600; } /* font-semibold */
.sf-lookup__error-hint { margin-top: 0.25rem; color: #be123c; } /* mt-1 text-rose-700 */
.sf-lookup__error-hint--dark { color: #fda4af; } /* text-rose-300 */

.sf-lookup__form { border-radius: 1rem; border: 1px solid #e2e8f0; padding: 1rem; transition: background-color 150ms ease, border-color 150ms ease; background-color: #ffffff; } /* rounded-2xl border p-4 space-y-4 transition-colors bg-white border-slate-200 */
@media (min-width: 640px) { .sf-lookup__form { padding: 1.25rem; } } /* sm:p-5 */
.sf-lookup__form > * + * { margin-top: 1rem; } /* space-y-4 */
.sf-lookup__form--dark { background-color: #0f172a; border-color: #1e293b; } /* bg-slate-900 border-slate-800 */
.sf-lookup__field > * + * { margin-top: 0.25rem; } /* space-y-1 */
.sf-lookup__label { font-size: 0.75rem; line-height: 1rem; font-weight: 700; color: #334155; } /* text-xs font-bold text-slate-700 */
.sf-lookup__label--dark { color: #cbd5e1; } /* text-slate-300 */
.sf-lookup__input {
  width: 100%;
  text-align: start; /* text-right/text-left per dir — both wanted the START edge */
  padding-inline: 1rem; /* px-4 */
  padding-block: 0.625rem; /* py-2.5 */
  border-radius: 0.75rem; /* rounded-xl */
  border: 1px solid #e2e8f0; /* border-slate-200 */
  background-color: #f8fafc; /* bg-slate-50 */
  outline: none;
  transition: border-color 150ms ease, box-shadow 150ms ease; /* transition-all */
}
.sf-lookup__input:focus { border-color: var(--brand); box-shadow: 0 0 0 1px var(--brand); } /* focus:border-brand-500 focus:ring-1 focus:ring-brand-500 */
.sf-lookup__hint { font-size: 0.75rem; line-height: 1rem; color: #64748b; } /* text-xs text-slate-500 */
.sf-lookup__hint--dark { color: #94a3b8; } /* text-slate-400 */

.sf-lookup__submit { width: 100%; border-radius: 0.75rem; padding-inline: 1rem; padding-block: 0.875rem; color: #ffffff; font-weight: 600; transition: background-color 150ms ease; background-color: var(--brand); } /* w-full rounded-xl px-4 py-3.5 text-white font-semibold bg-brand-600 transition-colors */
.sf-lookup__submit:hover { background-color: color-mix(in srgb, var(--brand) 82%, black); } /* hover:bg-brand-700 */

.sf-lookup__back { margin-top: 1rem; display: block; text-align: center; font-size: 0.875rem; line-height: 1.25rem; font-weight: 500; color: #64748b; transition: color 150ms ease; } /* mt-4 block text-center text-sm font-medium text-slate-500 */
.sf-lookup__back:hover { color: #334155; } /* hover:text-slate-700 */
.sf-lookup__back--dark { color: #94a3b8; } /* text-slate-400 */
.sf-lookup__back--dark:hover { color: #e2e8f0; } /* hover:text-slate-200 */

/* ── layouts/base.html: <body> (Task 0.13 fix round) — reaches EVERY page.
   dark:bg-slate-900 dark:text-white were confirmed dead (see the template's
   own comment). */
.sf-body { background-color: #f9fafb; color: #0f172a; } /* bg-gray-50 text-slate-900 */
