/* ==========================================================================
   Meridian Assessments — design tokens & base
   Sage + cream palette with a muted gold / clay accent.
   ========================================================================== */

:root {
  --cream: #F8F5EE;
  --white: #FFFFFF;

  --sage-900: #333F2C;   /* sidebar, primary buttons, dark surfaces */
  --sage-800: #46573A;   /* icon strokes, links on light bg */
  --sage-300: #C7D3B4;
  --sage-100: #E7EBDA;   /* tinted icon circles */
  --sage-50:  #F0F2E7;

  --border: #DEE2D0;
  --ink: #23281D;
  --ink-muted: #565F4C;

  --gold: #A9843F;        /* decorative accents only (dots, stars) */
  --gold-light: #D9BE86;  /* gold on dark surfaces */
  --clay: #B97B54;        /* cart badge */

  --success: #2F7A4F;
  --success-bg: #E7F3EA;
  --danger: #B23B3B;
  --danger-bg: #FBEAEA;
  --pending: #A9843F;
  --pending-bg: #FBF3E3;

  --font-display: 'Spectral', Georgia, 'Times New Roman', serif;
  --font-body: 'Public Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  --sidebar-width: 260px;
}

* {
  box-sizing: border-box;
}

html, body {
  margin: 0;
  padding: 0;
}

body {
  font-family: var(--font-body);
  color: var(--ink);
  background: var(--cream);
  -webkit-font-smoothing: antialiased;
}

a {
  color: inherit;
  text-decoration: none;
}

a:hover {
  opacity: 0.82;
}

button {
  font-family: inherit;
  cursor: pointer;
}

svg {
  display: block;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  white-space: nowrap;
  clip: rect(0 0 0 0);
}

:focus-visible {
  outline: 2px solid var(--sage-800);
  outline-offset: 2px;
}

/* The [hidden] attribute must always win over a class's own `display`,
   regardless of selector order — several components here are toggled
   between visible and hidden purely via the `hidden` DOM property. */
[hidden] {
  display: none !important;
}

/* ==========================================================================
   Shell layout
   ========================================================================== */

.app-shell {
  display: flex;
  min-height: 100vh;
  align-items: stretch;
}

/* ==========================================================================
   Sidebar
   ========================================================================== */

.sidebar {
  flex: 0 0 var(--sidebar-width);
  width: var(--sidebar-width);
  box-sizing: border-box;
  background: var(--sage-900);
  color: var(--cream);
  padding: 32px 22px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}

.brand {
  display: flex;
  align-items: center;
  margin-bottom: 28px;
}

/* Replaces the old icon + stacked "Edufun / Evaluaciones de desarrollo"
   text with the real wordmark artwork (see public/media/README.md for
   where the source files and colorways come from). The image already
   bakes in the tagline, so there's no separate text node here — and
   since it's outlined vector paths (not live text), it needs no font
   loaded to render correctly.
   width/height mirror the asset's own viewBox (480x175) so the browser
   reserves the right aspect ratio before the image loads (no layout
   shift); the visible size is set by max-width alone. max-width matches
   the sidebar's content width exactly (260px sidebar - 22px padding each
   side = 216px) so the wordmark reads at the same scale as the nav items
   below it, flush to the same left/right edges, instead of sitting
   smaller and inset like it did with .brand's own extra padding. */
.brand__logo {
  display: block;
  max-width: 216px;
  width: 100%;
  height: auto;
}

.nav {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.nav__link {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border-radius: 10px;
  color: rgba(248, 245, 238, 0.8);
  font-size: 14.5px;
  font-weight: 500;
  background: none;
  border: none;
  width: 100%;
  text-align: left;
}

.nav__link:hover {
  opacity: 1;
  background: rgba(255, 255, 255, 0.08);
}

.nav__link--active,
.nav__link--active:hover {
  background: rgba(255, 255, 255, 0.13);
  color: var(--cream);
  font-weight: 600;
}

.nav__label {
  margin: 12px 14px 2px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(248, 245, 238, 0.45);
}

/* Holds the product links that cart.js's renderProductNav() builds from
   /api/products at runtime (see index.html/product.html/cart.html's
   [data-product-nav]). .nav itself is the flex column that gives each of
   its direct children 6px of gap — since this wrapper is one such child,
   it needs the same flex/gap rules repeated here so the product links
   stack with identical spacing to when they were hardcoded siblings. */
.nav__products {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* Hamburger toggle for the mobile nav — hidden on desktop, shown only
   below the sidebar breakpoint (see Responsive section). */
.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.08);
  color: var(--cream);
  border: none;
  flex: 0 0 auto;
}

.nav-toggle:hover {
  background: rgba(255, 255, 255, 0.14);
}

.sidebar__spacer {
  flex-grow: 1;
}

.order-card {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  padding: 14px;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.1);
}

/* Wraps the icon + text so the whole row still links to /cart.html like
   before, while the dismiss button beside it (added below) stays its own
   clickable element rather than a button nested inside an <a> — nesting
   interactive elements is invalid HTML and gets flaky click handling in
   some browsers. */
.order-card__link {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  flex: 1;
  min-width: 0;
}

.order-card__dismiss {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  margin-top: 1px;
  padding: 0;
  border: none;
  border-radius: 7px;
  background: none;
  color: rgba(248, 245, 238, 0.45);
}

.order-card__dismiss:hover {
  background: rgba(255, 255, 255, 0.12);
  color: var(--cream);
}

.order-card__icon {
  width: 32px;
  height: 32px;
  border-radius: 9px;
  background: rgba(255, 255, 255, 0.1);
  color: var(--gold-light);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
}

.order-card__text {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.order-card__title {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--cream);
}

.order-card__meta {
  font-size: 11.5px;
  color: rgba(248, 245, 238, 0.62);
}

/* ==========================================================================
   Main column
   ========================================================================== */

.main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

/* Topbar */

/* Sticky so the cart link stays reachable no matter how far the page has
   scrolled (e.g. down into the product grid) — on both the desktop row
   layout and the mobile column layout, since this rule isn't overridden
   at any breakpoint. Needs an opaque background so scrolling content
   (product cards, etc.) doesn't show through once this is pinned in
   place, and a z-index above the page's other stacking contexts (hero
   illustration tops out at z-index: 3) so it stays on top. */
.topbar {
  display: flex;
  align-items: center;
  gap: 22px;
  padding: 28px 40px;
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--cream);
}

.topbar__spacer {
  flex-grow: 1;
}

.topbar__link {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--ink-muted);
  background: none;
  border: none;
}

.cart-icon {
  position: relative;
  display: flex;
}

.cart-icon__badge {
  position: absolute;
  top: -7px;
  right: -8px;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: var(--clay);
  color: #fff;
  font-size: 9.5px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Hero */

.hero {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 32px;
  padding: 24px 40px 56px;
}

.hero__content {
  flex: 1 1 420px;
  min-width: 340px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.eyebrow {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--sage-800);
}

.eyebrow__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--gold);
  flex: 0 0 auto;
}

.hero__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(2.2rem, 4vw, 3.4rem);
  line-height: 1.08;
  color: var(--ink);
}

.hero__title em {
  font-style: italic;
  font-weight: 500;
  color: var(--sage-900);
}

.hero__lede {
  margin: 0;
  font-size: 16.5px;
  line-height: 1.6;
  color: var(--ink-muted);
  max-width: 440px;
}

.hero__actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 8px;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-size: 15px;
  font-weight: 600;
  padding: 16px 26px;
  border-radius: 999px;
  border: 1px solid transparent;
  background: none;
}

.btn--primary {
  background: var(--sage-900);
  color: var(--cream);
}

.btn--primary:disabled {
  background: var(--sage-300);
  color: var(--white);
  cursor: not-allowed;
}

.btn--secondary {
  background: var(--white);
  color: var(--ink);
  border-color: var(--border);
}

.btn--block {
  display: flex;
  width: 100%;
}

.btn--small {
  padding: 9px 16px;
  font-size: 13.5px;
}

/* Hero illustration (decorative placeholder — swap for real product photography) */

.hero__visual {
  flex: 0 0 460px;
  width: 460px;
  max-width: 100%;
  height: 520px;
  position: relative;
  margin-inline: auto;
}

.visual__arch {
  position: absolute;
  left: 40px;
  top: 20px;
  width: 380px;
  height: 480px;
  background: var(--sage-100);
  border-radius: 220px 220px 28px 28px;
}

.visual__card {
  position: absolute;
  background: var(--white);
  border-radius: 16px;
  box-shadow: 0 22px 44px -18px rgba(35, 40, 29, 0.4);
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
}

.visual__card--manual {
  left: 90px;
  top: 110px;
  width: 168px;
  height: 210px;
  padding: 20px;
  gap: 10px;
  transform: rotate(-6deg);
  z-index: 1;
}

.visual__card--protocol {
  left: 210px;
  top: 185px;
  width: 180px;
  height: 224px;
  padding: 18px;
  gap: 13px;
  transform: rotate(5deg);
  z-index: 2;
}

.visual__tab {
  width: 38px;
  height: 7px;
  border-radius: 3px;
  background: var(--sage-900);
}

.visual__line {
  height: 7px;
  border-radius: 3px;
  background: var(--sage-100);
  display: block;
}

.visual__caption {
  margin-top: auto;
  font-size: 12px;
  font-weight: 700;
  color: var(--sage-900);
}

.visual__label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.visual__row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.visual__check {
  width: 16px;
  height: 16px;
  border-radius: 4px;
  border: 1.5px solid var(--sage-300);
  flex: 0 0 auto;
  box-sizing: border-box;
}

.visual__check--on {
  border-color: transparent;
  background: var(--sage-900);
}

.visual__kitbox {
  position: absolute;
  left: 170px;
  top: 395px;
  width: 104px;
  height: 104px;
  /* The brand icon SVG (public/media/edufun-icon-optimized.svg) bakes in
     its own dark rounded-square background, so this box no longer needs
     one of its own to show the icon correctly — background here is just
     a backdrop for the icon artwork's own ~3px inset safe-area (its
     rounded rect sits a few pixels in from the SVG's edge), and is set to
     that artwork's exact background color (not --sage-900, which is a
     close but visibly different shade) so that sliver blends in rather
     than reading as a mismatched border. border-radius is likewise a
     backstop match for the icon's own corner rounding, not load-bearing. */
  background: #3c4a30;
  border-radius: 22px;
  box-shadow: 0 18px 32px -14px rgba(35, 40, 29, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 3;
  overflow: hidden;
}

.visual__kitbox-icon {
  display: block;
  width: 100%;
  height: 100%;
}

/* Products */

.products {
  padding: 0 40px 56px;
}

.products__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 18px;
}

.products__header h2 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 22px;
  color: var(--ink);
}

.link-more {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 14px;
  font-weight: 600;
  color: var(--sage-800);
  white-space: nowrap;
  background: none;
  border: none;
}

/* Prev/next controls for the products carousel below. Hidden by default
   (see the `hidden` attribute in index.html) and only revealed by
   products.js once the catalog actually overflows one screen's width —
   with today's 4 products that may not happen on a wide desktop, but as
   more kits are added to data/products.js this appears on its own with no
   markup changes needed. */
.carousel-controls {
  display: flex;
  gap: 8px;
  flex: 0 0 auto;
}

.carousel-btn {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--white);
  border: 1px solid var(--border);
  color: var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  transition: background 0.15s ease, opacity 0.15s ease;
}

.carousel-btn:hover {
  background: var(--sage-50);
}

.carousel-btn:disabled {
  opacity: 0.35;
  cursor: default;
  pointer-events: none;
}

/* Products carousel — a horizontally-scrolling row rather than a wrapping
   grid, so adding more kits to data/products.js extends the scrollable
   width instead of growing the page vertically. scroll-snap-type keeps
   cards aligned to the viewport edge on every scroll/swipe/arrow-click,
   and the hidden native scrollbar (both here and its -webkit sibling
   below) leaves the carousel-btn pair above as the only visible affordance
   on non-touch devices, with touch/trackpad swipe working natively too. */
.products__grid {
  display: flex;
  gap: 20px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding-left: 2px;
  padding-bottom: 2px;
  -ms-overflow-style: none;
  scrollbar-width: none;
}

.products__grid::-webkit-scrollbar {
  display: none;
}

.product-card {
  margin: 0;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
  flex: 0 0 calc((100% - 60px) / 4);
  scroll-snap-align: start;
}

.product-card__link {
  display: flex;
  flex-direction: column;
  gap: 10px;
  color: inherit;
  text-decoration: none;
}

.product-card__link:hover .product-card__name {
  text-decoration: underline;
}

.product-card__image {
  height: 168px;
  background: var(--sage-50);
  color: var(--sage-800);
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.product-card__photo {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.product-card__image--alt {
  background: var(--sage-50);
}

.product-card__name {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.product-card__desc {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink-muted);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.product-card__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: auto;
}

.product-card__price-group {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.product-card__price {
  font-size: 14.5px;
  font-weight: 700;
  color: var(--ink);
}

.product-card__turnaround {
  font-size: 11px;
  color: var(--ink-muted);
}

.add-btn {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--sage-100);
  color: var(--sage-800);
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  transition: background 0.15s ease, transform 0.15s ease;
}

.add-btn:hover {
  background: var(--sage-300);
}

.add-btn--added {
  background: var(--success);
  color: var(--white);
}

/* ==========================================================================
   Product detail page
   ========================================================================== */

.product-detail {
  padding: 8px 40px 64px;
  display: flex;
  gap: 36px;
  align-items: flex-start;
  flex-wrap: wrap;
}

.product-detail__image {
  flex: 1 1 360px;
  min-width: 280px;
  height: 360px;
  background: var(--sage-50);
  color: var(--sage-800);
  border-radius: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.product-detail__image svg {
  width: 96px;
  height: 96px;
}

.product-detail__photo {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.product-detail__info {
  flex: 1 1 380px;
  min-width: 280px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.product-detail__name {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 30px;
  color: var(--ink);
}

.product-detail__desc {
  margin: 4px 0 0;
  font-size: 15px;
  line-height: 1.6;
  color: var(--ink-muted);
  max-width: 52ch;
}

.product-detail__buybox {
  margin-top: 18px;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 22px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-width: 420px;
}

.product-detail__price-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.product-detail__price {
  font-size: 24px;
  font-weight: 700;
  color: var(--ink);
}

.product-detail__turnaround {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  font-size: 13px;
  color: var(--ink-muted);
}

.product-detail__actions {
  display: flex;
  align-items: center;
  gap: 14px;
}

.product-detail__actions .btn {
  flex: 1 1 auto;
}

.product-detail__not-found {
  padding: 60px 40px;
  text-align: center;
}

.product-detail__not-found h1 {
  font-family: var(--font-display);
  font-size: 26px;
  color: var(--ink);
  margin: 0 0 8px;
}

.product-detail__not-found p {
  color: var(--ink-muted);
  margin: 0 0 20px;
}

/* ==========================================================================
   Page header (used on cart / status pages instead of the hero)
   ========================================================================== */

.page-header {
  padding: 40px 40px 8px;
}

.page-header h1 {
  margin: 0 0 6px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 30px;
  color: var(--ink);
}

.page-header p {
  margin: 0;
  color: var(--ink-muted);
  font-size: 15px;
}

.breadcrumb {
  font-size: 13px;
  color: var(--ink-muted);
  margin: 0 0 10px;
}

.breadcrumb a {
  color: var(--sage-800);
  font-weight: 600;
}

/* ==========================================================================
   Cart page
   ========================================================================== */

.cart-page {
  padding: 8px 40px 64px;
  display: flex;
  gap: 28px;
  align-items: flex-start;
  flex-wrap: wrap;
}

.cart-items {
  flex: 1 1 480px;
  min-width: 320px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.cart-item {
  display: flex;
  align-items: center;
  gap: 16px;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 16px;
}

.cart-item__image {
  width: 64px;
  height: 64px;
  border-radius: 12px;
  background: var(--sage-50);
  color: var(--sage-800);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  overflow: hidden;
}

.cart-item__photo {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.cart-item__body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.cart-item__name {
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
}

.cart-item__unit-price {
  font-size: 13px;
  color: var(--ink-muted);
}

.cart-item__turnaround {
  font-size: 12px;
  color: var(--ink-muted);
}

.cart-item__controls {
  display: flex;
  align-items: center;
  gap: 18px;
  flex: 0 0 auto;
}

.qty-stepper {
  display: flex;
  align-items: center;
  gap: 0;
  border: 1px solid var(--border);
  border-radius: 999px;
  overflow: hidden;
}

.qty-stepper button {
  width: 30px;
  height: 30px;
  border: none;
  background: var(--sage-50);
  color: var(--sage-900);
  font-size: 16px;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
}

.qty-stepper button:hover {
  background: var(--sage-100);
}

.qty-stepper__value {
  width: 34px;
  text-align: center;
  font-size: 14px;
  font-weight: 600;
}

.cart-item__line-total {
  min-width: 84px;
  text-align: right;
  font-size: 14.5px;
  font-weight: 700;
  color: var(--ink);
}

.cart-item__remove {
  background: none;
  border: none;
  color: var(--ink-muted);
  padding: 4px;
  border-radius: 8px;
  display: flex;
}

.cart-item__remove:hover {
  color: var(--danger);
  background: var(--danger-bg);
}

.cart-empty {
  background: var(--white);
  border: 1px dashed var(--border);
  border-radius: 16px;
  padding: 48px 24px;
  text-align: center;
  color: var(--ink-muted);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}

.cart-summary {
  flex: 0 0 340px;
  width: 340px;
  max-width: 100%;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 22px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  position: sticky;
  /* .topbar is now sticky too (74px tall including its padding), so this
     needs enough clearance to settle below it rather than tucking
     underneath — 74px topbar + the original 24px breathing room. */
  top: 98px;
}

.cart-summary h2 {
  margin: 0;
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 600;
}

.summary-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  color: var(--ink-muted);
}

.summary-row--total {
  font-size: 16px;
  font-weight: 700;
  color: var(--ink);
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.field label {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-muted);
}

.field input,
.field select {
  font-family: inherit;
  font-size: 14px;
  padding: 11px 13px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--cream);
  color: var(--ink);
}

.field input:focus-visible,
.field select:focus-visible {
  outline: 2px solid var(--sage-800);
  outline-offset: 1px;
}

/* Shipping — the checkout form's "how do you want this delivered" step.
   .shipping-option deliberately reuses the same visual language as
   .field (same label sizing/color) rather than introducing a new type
   scale for what's still just a form control. */
.field-label {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-muted);
  margin: 0 0 8px;
}

.shipping-method {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.shipping-option {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 12px;
  cursor: pointer;
}

/* Highlights whichever option is currently selected — plain CSS, no JS
   needed, since :has() is well-supported across all current browsers. */
.shipping-option:has(input:checked) {
  border-color: var(--sage-800);
  background: var(--sage-50);
}

.shipping-option input {
  margin-top: 3px;
  accent-color: var(--sage-800);
  flex: 0 0 auto;
}

.shipping-option strong {
  display: block;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
}

.shipping-option small {
  display: block;
  font-size: 12.5px;
  color: var(--ink-muted);
  margin-top: 2px;
}

.shipping-address {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* Acknowledgment checkbox — has to be checked before the MercadoPago
   button (data-checkout-submit) enables; see checkout.js. Visually a
   quieter, smaller sibling of .shipping-option (same bordered-row shape)
   rather than a new pattern, since it's the same "read this, then pick"
   interaction. */
.ack-checkbox {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 12px;
  cursor: pointer;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink-muted);
}

.ack-checkbox input {
  margin-top: 2px;
  accent-color: var(--sage-800);
  flex: 0 0 auto;
}

.checkout-note {
  font-size: 12px;
  line-height: 1.5;
  color: var(--ink-muted);
}

/* Shown on the cart page in place of the acknowledgment checkbox + Pay
   button while ORDERING_ENABLED=false (see checkout.js's
   applyOrderingState()). Uses the same muted gold "pending" tokens as an
   in-progress order status elsewhere in the app — this is deliberately not
   the red/danger treatment, since nothing has gone wrong, ordering just
   isn't open yet. */
.ordering-disabled {
  background: var(--pending-bg);
  border: 1px solid rgba(169, 132, 63, 0.28);
  border-radius: 12px;
  padding: 14px 16px;
}

.ordering-disabled__title {
  margin: 0 0 4px;
  font-size: 13.5px;
  font-weight: 700;
  color: var(--ink);
}

.ordering-disabled__desc {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink-muted);
}

.checkout-error {
  font-size: 13px;
  line-height: 1.5;
  color: var(--danger);
  background: var(--danger-bg);
  border-radius: 10px;
  padding: 10px 12px;
  display: none;
}

.checkout-error[data-visible="true"] {
  display: block;
}

.mp-mark {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

/* ==========================================================================
   Status pages (success / failure / pending)
   ========================================================================== */

/* .status-page fills whatever vertical space is left below the topbar
   (.main is a column flex container, so flex: 1 here claims the rest of
   the viewport) and centers .status-card within it, both horizontally and
   vertically. Previously this only capped the card's width and left it
   pinned to the top-left, which read as a half-empty page on anything
   wider/taller than the card itself — the "loading" state below gets the
   same treatment so the page doesn't jump as it settles. */
.status-page {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px;
}

[data-order-loading] {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.status-card {
  width: 100%;
  max-width: 560px;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 40px 36px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  box-sizing: border-box;
}

.status-icon {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.status-icon--success {
  background: var(--success-bg);
  color: var(--success);
}

.status-icon--failure {
  background: var(--danger-bg);
  color: var(--danger);
}

.status-icon--pending {
  background: var(--pending-bg);
  color: var(--pending);
}

.status-card h1 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 24px;
}

.status-card p {
  margin: 0;
  color: var(--ink-muted);
  font-size: 15px;
  line-height: 1.6;
}

.status-meta {
  background: var(--sage-50);
  border-radius: 12px;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 13px;
}

.status-meta__row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
}

.status-meta__row dt {
  color: var(--ink-muted);
}

.status-meta__row dd {
  margin: 0;
  font-weight: 600;
  color: var(--ink);
}

.status-actions {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}

.order-item-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  font-size: 13.5px;
  color: var(--ink);
}

.order-item-row__name {
  color: var(--ink-muted);
}

.order-item-row__total {
  font-weight: 600;
  white-space: nowrap;
}

/* ==========================================================================
   Add-to-cart modal
   ========================================================================== */

.added-modal {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.added-modal--visible {
  display: flex;
}

.added-modal__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(35, 40, 29, 0.45);
}

.added-modal__card {
  position: relative;
  width: 100%;
  max-width: 360px;
  background: var(--white);
  border-radius: 18px;
  padding: 30px 26px 26px;
  box-shadow: 0 30px 60px -18px rgba(35, 40, 29, 0.4);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  animation: added-modal-in 0.18s ease;
}

@keyframes added-modal-in {
  from {
    opacity: 0;
    transform: translateY(8px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

.added-modal__icon {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--success-bg);
  color: var(--success);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 10px;
}

.added-modal__title {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 600;
  margin: 0 0 6px;
}

.added-modal__desc {
  font-size: 14px;
  color: var(--ink-muted);
  margin: 0 0 20px;
}

.added-modal__actions {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* ==========================================================================
   Toast
   ========================================================================== */

.toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%) translateY(12px);
  background: var(--sage-900);
  color: var(--cream);
  padding: 12px 20px;
  border-radius: 999px;
  font-size: 13.5px;
  font-weight: 600;
  box-shadow: 0 16px 32px -12px rgba(35, 40, 29, 0.5);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
  z-index: 40;
}

.toast--visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* ==========================================================================
   Responsive
   ========================================================================== */

@media (max-width: 960px) {
  .product-card {
    flex-basis: calc((100% - 20px) / 2);
  }

  .cart-summary {
    position: static;
    width: 100%;
    flex: 1 1 100%;
  }
}

@media (max-width: 860px) {
  .app-shell {
    flex-direction: column;
  }

  .sidebar {
    position: static;
    /* The desktop rule sets flex: 0 0 var(--sidebar-width) (260px) to fix
       the sidebar's *width* in the desktop row layout. At this breakpoint
       .app-shell switches to a column layout, which makes that same
       flex-basis control *height* instead of width — so without this
       reset the sidebar was locked to a fixed 260px tall box regardless
       of "height: auto" below (flex-basis wins over height for main-axis
       sizing when it's a definite length), leaving a large empty gap
       whenever content was shorter than 260px and clipping it when
       content ran taller. */
    flex: 0 0 auto;
    height: auto;
    /* The desktop rule sets overflow-y: auto for the sticky 100vh
       sidebar's internal scroll — left in place here, it was clipping the
       wrapped mobile nav to a shorter box than its actual content, even
       though height is "auto" (a real, confirmed rendering bug, not just
       a screenshot artifact — verified via getBoundingClientRect showing
       the nav extending well past the sidebar's own clipped bounds). */
    overflow: visible;
    width: 100%;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: 16px;
    padding: 16px 20px;
  }

  .brand {
    margin-bottom: 0;
    flex: 1 1 auto;
    /* Without this, the flex item's default min-width:auto refuses to
       shrink below the logo's natural width, which — combined with the
       hamburger button and the row's gap — pushed the whole header wider
       than the viewport on narrow phones. */
    min-width: 0;
  }

  /* Collapsible mobile nav: hidden by default and toggled open by the
     hamburger button, as a full-width panel that stacks vertically below
     the brand row. Replaces the old horizontal strip, which forced
     sideways scrolling once there were enough links to overflow the
     screen width. */
  .nav-toggle {
    display: flex;
  }

  .nav {
    flex-basis: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.2s ease;
  }

  .nav--open {
    /* max-height is set inline by JS (public/js/cart.js) to the nav's
       actual measured content height, not a flat guess here — see the
       comment in initMobileNav() for why. */
    margin-top: 4px;
  }

  .nav__link {
    white-space: normal;
  }

  .sidebar__spacer,
  .order-card {
    display: none;
  }

  .topbar,
  .hero,
  .products,
  .page-header,
  .cart-page,
  .status-page,
  .product-detail {
    padding-left: 20px;
    padding-right: 20px;
  }

  .hero__visual {
    order: -1;
  }
}

@media (max-width: 560px) {
  .product-card {
    /* Just under full width rather than 100% so the next card peeks in
       from the edge — a visual hint that the row scrolls, for shoppers who
       might otherwise not realize there's more to see on a single card
       per screen. */
    flex-basis: 86%;
  }

  /* The hero illustration is hand-positioned with fixed pixel offsets
     (see .visual__arch / .visual__card / .visual__kitbox) sized for its
     460px design width — those offsets don't scale down, so below this
     width parts of it were pushed past the viewport edge and forced
     horizontal scrolling on the whole page. It's decorative and already
     aria-hidden, so the simplest correct fix is to not render it on
     screens this narrow rather than trying to rescale hand-tuned
     absolute positioning. */
  .hero__visual {
    display: none;
  }

  .hero__content {
    min-width: 0;
  }

  .hero__actions {
    flex-direction: column;
    align-items: stretch;
  }

  .btn {
    justify-content: center;
  }

  .cart-item {
    flex-wrap: wrap;
  }

  .cart-item__controls {
    width: 100%;
    justify-content: space-between;
  }
}
