:root {
  --color-sage: #71BC78;
  --color-forest: #008000;
  --color-lime: #00FF00;
  --color-teal: #009D71;
  --color-mint: #77DD77;
  --color-olive: #568203;
  --color-hunter: #06500C;
  --color-grass: #6BB323;
  --color-spring: #0BDA51;
  /* 237-public-menu-grass-outline: the grass green the owner
     sampled from a pitch photo (2026-10-30) and approved for
     the public catalog menu's pill outline. It enters the
     palette by his explicit decision, scoped to that outline
     — not a general licence to spread it (same discipline as
     --color-logo). It is NOT --color-grass: that name already
     belongs to the apple green above (#6BB323, sellers
     landing step badges), and changing its value would
     recolor live surfaces. "Pitch" is the football word for
     the grass surface the photo shows. */
  --color-pitch: #24850E;
  /* 238-search-focus-ring: the light blue of Safari's
     native focus glow around the home search field,
     sampled from the owner's own screenshot. He liked
     the «azulito» and approved making it
     deliberate (2026-10-30), so the ring shows in every
     browser, not only Safari's. Scoped to the home
     search field's focus ring — it is not a general
     form-field or link colour. "Sky" keeps the token
     block's single-word nature naming (sage, forest,
     pine, hunter, spring, pitch). */
  --color-sky: #79BBEE;
  --color-orange: #ff9800;
  --color-orange-dark: #e28000;
  /* 208-filters-toggle-footer-green: the footer's deep green,
     promoted to a token so the footer and the home Filters
     toggle share one source (owner: «el mismo verde del
     Footer»). The value is the footer's long-standing literal —
     unchanged, only named. */
  --color-pine: #102014;
  /* 213-forum-logo-green: the app icon's bright green, measured
     from the icon master. Fan-zone use ONLY (the Comunidad) —
     never the header, never a money action, never a status
     tint: the store stays orange + pine (owner, 2026-10-29). */
  --color-logo: #01B70A;
  /* 068-tracking-page-seller-ratings (constitution v1.5.0): a single
     status-only exception, NOT part of the brand palette above. Valid
     only for the "🔵 Enviados" shipment-status indicator — never on a
     button, link, or any other element. */
  --color-status-shipped: #1E88E5;
  --bg: #f4f7f5;
  --card: #fff;
  --text: #1a1a1a;
  --muted: #5e5e5e;
  --err: #b42318;
  font-family: "Segoe UI", system-ui, sans-serif;
}
/* 244-force-light-scheme: the site is light-only by
   design, and now it says so. Until tonight nothing
   anywhere declared a colour scheme, so phones whose
   browser forces dark mode (Android Chrome's Auto
   Dark Theme, MIUI and kin) algorithmically inverted
   every page — a visitor showed the owner the home
   page with a black background and inverted colours
   on 2026-10-30, and the owner approved making the
   light design binding: «Haz el arreglo: sitio
   siempre en claro». `only light` on :root is the
   documented opt-out: a browser honouring the
   declaration never force-darkens the page. The
   companion signal, <meta name="color-scheme"
   content="only light">, sits in every page's head
   (this spec) so the scheme is known before the
   stylesheet even loads. No token, no rule and no
   colour changes — the light rendering is byte-for-
   byte the design already shipped. */
:root { color-scheme: only light; }
/* 240-tap-highlight: no system tap flash. The site
   never defined a tap highlight, so Android's
   WebView painted its default blue one over every
   tap (owner, testing the published Android app:
   «cuando toco cualquier botón hace como un flash
   azul», approved «Quita el flash azul de los
   toques» on 2026-10-30). Transparent, site-wide:
   buttons and links keep their own :active
   feedback, which is the designed pressed state.
   iOS Safari barely showed the default; the
   Android wrapper showed it on every tap. */
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
header.app {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: nowrap;
  position: relative;
  z-index: 3;
  padding: 0.75rem 1.25rem; background: var(--color-hunter); color: #fff;
}
header.app a { color: #fff; text-decoration: none; margin-left: 0.75rem; }
header.app #logout {
  background: transparent; color: #fff; border: 1px solid rgba(255,255,255,0.5);
  border-radius: 999px; padding: 0.2rem 0.65rem; cursor: pointer; margin-left: 0;
}
/* 097-header-sell-button: visible Sell entry in the Home header, between the
   account status and the menu toggle; palette orange per Principle VII. */
header.app .sell-btn {
  background: var(--color-orange); color: #fff; font-weight: 700;
  /* 101-rounded-home (FR-003): pill, like the menu buttons (100).
     Padding unchanged — the 097 mobile header fit is preserved. */
  border-radius: 999px; padding: 0.4rem 0.8rem; margin-left: 0.75rem;
  white-space: nowrap; text-decoration: none;
}
header.app .sell-btn:hover, header.app .sell-btn:active { background: var(--color-orange-dark); }
/* 097 fix: with the Sell button added, the signed-in header (brand +
   lang + cart + greeting + Sell + menu toggle) needs 480px at
   min-content and overflows small phones, pushing the menu toggle
   off-screen. Compact mobile spacing (<=480px) makes every element
   fit at 360px; verified by headless render at 360/375/390/430px.
   Desktop is untouched. */
@media (max-width: 480px) {
  header.app { padding: 0.75rem 0.5rem; }
  header.app .header-actions { gap: 0.35rem; min-width: 0; }
  header.app a { margin-left: 0.25rem; }
  header.app a.brand { font-size: 0.9rem; letter-spacing: 0; }
  header.app .lang { gap: 0.25rem; }
  header.app .lang button { padding: 0.15rem 0.4rem; font-size: 0.78rem; }
  header.app #account-status { font-size: 0.82rem; line-height: 1.1; min-width: 0; }
  header.app .sell-btn { padding: 0.35rem 0.55rem; margin-left: 0.25rem; font-size: 0.88rem; }
  header.app [data-catalog-menu-toggle] { margin-left: 0.25rem; padding: 0.2rem 0.45rem; font-size: 1.15rem; }
  header.app .cart-icon { padding: 0; }
}
/* 098-seller-profiles: public seller storefront (/seller/<username>).
   Palette tokens only (Principle VII); the avatar is the seller's
   initials on --color-teal, the platform's accent for identity. */
.seller-main { width: 100%; max-width: 1100px; margin: 0 auto; padding: 1rem; }
.seller-profile { text-align: center; padding: 1.5rem 1rem 0.5rem; }
.seller-avatar {
  width: 72px; height: 72px; margin: 0 auto 0.75rem; border-radius: 50%;
  background: var(--color-teal); color: #fff; font-size: 1.6rem; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
  /* 099-seller-photo-bio: a seller photo (background image) fills the circle. */
  background-size: cover; background-position: center;
}
.seller-profile h1 { margin: 0 0 0.25rem; font-size: 1.5rem; }
.seller-username { margin: 0; color: var(--color-olive); font-weight: 600; }
.seller-bio { margin: 0.5rem auto 0; max-width: 34rem; }
.seller-since { margin: 0.25rem 0 0; }
.seller-stats { margin: 0.5rem 0 0; font-weight: 600; }
/* 225-follow-stores: the follow toggle sits under the share
   button; following trades the primary orange for a quiet pine
   outline. Palette tokens only; the transparent border on the
   base rule keeps the button from shifting when it changes. */
#seller-follow { margin-top: 0.5rem; border: 2px solid transparent; }
#seller-follow.is-following { background: transparent; color: var(--color-pine); border-color: var(--color-pine); }
.product-seller { margin: 0.25rem 0 0.75rem; }
.product-seller a { color: var(--color-teal); font-weight: 600; }
.brand { font-weight: 700; letter-spacing: 0.02em; }
header.app a.brand { margin-left: 0; }
/* 207-header-wordmark-orange: the header wordmark wears the palette
   orange (owner's pick over white, mockup approved 2026-10-29). Scoped
   to the brand link only — every other header link stays white. */
header.app a.brand { color: var(--color-orange); }
.lang { display: flex; flex-direction: row; gap: 0.35rem; }
header.app .lang:has(+ [data-catalog-menu-toggle]) { margin-left: auto; }
[data-catalog-menu-toggle] {
  display: inline-flex;
  align-items: center;
  position: relative;
  z-index: 4;
  margin-left: 0.75rem;
  background: transparent;
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.5);
  border-radius: 8px;
  padding: 0.25rem 0.55rem;
  cursor: pointer;
  font-size: 1.35rem;
  line-height: 1;
}
header.app [data-catalog-menu] {
  display: none;
  flex-direction: column;
  align-items: flex-end;
  text-align: right;
  /* 133-floating-menu (FR-004): 8px between the floating pills. */
  gap: 0.5rem;
}
header.app[data-catalog-open] [data-catalog-menu] {
  display: flex;
  position: fixed;
  top: 3.5rem;
  right: 0;
  z-index: 2;
  margin: 0;
  width: max-content;
  max-width: min(90vw, 16rem);
  padding: 0;
  box-sizing: border-box;
  /* 133-floating-menu (FR-001): no card behind the options — the
     container carries no background, border or shadow, so the
     page shows through; each pill below is its own surface. */
  color: var(--text);
}
/* 237-public-menu-grass-outline: one outline colour for both
   pill kinds — the links and the #logout button. */
header.app[data-catalog-open] [data-catalog-menu] a,
header.app[data-catalog-open] [data-catalog-menu] #logout {
  margin-left: 0;
  color: var(--text);
  border-color: var(--color-pitch);
}
header.app[data-catalog-open] [data-catalog-menu] hr {
  /* 100-pill-menu-buttons (FR-003): the bordered pills and the menu
     gap replace the separator rules. */
  display: none;
  width: 100%;
  border: none;
  border-top: 1px solid var(--muted);
  margin: 0;
}
/* 100-pill-menu-buttons (FR-001/FR-002): every entry of the open menu
   is a full-width pill, matching the Sign out button's existing shape
   (header.app #logout, border-radius: 999px). */
header.app[data-catalog-open] [data-catalog-menu] a {
  align-self: stretch;
  /* 133-floating-menu (FR-002): the pill carries its own surface —
     the white the removed card used to lend it, plus the soft
     shadow of .home-section .product:hover.
     237-public-menu-grass-outline: the outline is now 2px in
     var(--color-pitch) — "only the line, like the search field",
     in the grass green, with the black letters the pills already
     had (var(--text), shared rule above). Everything else about
     the pill — white surface, radius, shadow, padding — is
     133's and stays. */
  background: #fff;
  border: 2px solid var(--color-pitch);
  border-radius: 999px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
  padding: 0.35rem 1rem;
  text-decoration: none;
}
header.app[data-catalog-open] [data-catalog-menu] #logout {
  align-self: stretch;
  /* 133-floating-menu (FR-002/FR-003): same floating surface as
     the link pills, and their padding — at base Sign out kept the
     header button's compact padding and rendered shorter. The
     font shorthand is set for the same reason: no rule typeset
     the button, so it rendered in the UA's control font
     (13.33px, tighter line box) against the links' inherited
     page font — the probe measured 23.4px tall at base, 31.2px
     after padding + size alone, 35.2px (the links' height)
     with the inherited font. `font: inherit` is the file's own
     idiom for this ([data-bill-option]). */
  background: #fff;
  /* 237-public-menu-grass-outline: the same 2px pitch outline
     as the link pills, declared here — at base this button's
     border came from the header rule (1px, translucent white)
     with only its colour unified by the shared rule above, so
     without this line Sign out would keep a 1px outline. */
  border: 2px solid var(--color-pitch);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
  padding: 0.35rem 1rem;
  font: inherit;
}
/* 177-admin-order-detail-view: admin-only equivalent of the clients
   hamburger menu above — same icon/shape (FR-016), its own attributes
   (data-admin-menu-toggle/data-admin-menu/data-admin-open) so it never
   collides with the clients catalog menu (no page carries both). */
[data-admin-menu-toggle] {
  display: inline-flex;
  align-items: center;
  position: relative;
  z-index: 4;
  margin-left: 0.75rem;
  background: transparent;
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.5);
  border-radius: 8px;
  padding: 0.25rem 0.55rem;
  cursor: pointer;
  font-size: 1.35rem;
  line-height: 1;
}
header.app [data-admin-menu] {
  display: none;
  flex-direction: column;
  align-items: stretch;
  text-align: left;
  gap: 0;
}
/* 236-admin-menu-pine-panel: while the admin menu is open, dim the
   page below the header. The generated backdrop is keyed only to
   the admin open state; header.app already sits at z-index 3, so
   the header and its panel stay above this z-index 2 layer. A tap
   on the backdrop reaches the existing outside-click handler as a
   body click and closes the menu — no new DOM or JS is needed. */
body:has(> header.app[data-admin-open])::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 2;
  background: rgba(0, 0, 0, 0.45);
}
header.app[data-admin-open] [data-admin-menu] {
  display: flex;
  position: fixed;
  top: 3.5rem;
  right: 0;
  bottom: 0;
  z-index: 2;
  margin: 0;
  width: min(78vw, 24rem);
  max-width: 24rem;
  padding: 0.875rem 0;
  box-sizing: border-box;
  background: var(--color-pine);
  box-shadow: -0.75rem 0 1.75rem rgba(0, 0, 0, 0.28);
  color: #fff;
  overflow-y: auto;
  overscroll-behavior: contain;
}
/* 236-admin-menu-pine-panel: the panel is the only surface. Every
   entry — links and Sign out alike — is one transparent full-width
   row with white text and a hairline separator, replacing the
   floating white pills this block inherited from spec 133. */
header.app[data-admin-open] [data-admin-menu] a,
header.app[data-admin-open] [data-admin-menu] #logout {
  align-self: stretch;
  flex: 0 0 auto;
  background: transparent;
  border: 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 0;
  box-shadow: none;
  padding: 0.8125rem 1.375rem;
  margin-left: 0;
  color: #fff;
  font-size: 1.0625rem;
  line-height: 1.35;
  text-align: left;
  overflow-wrap: break-word;
}
header.app[data-admin-open] [data-admin-menu] a {
  text-decoration: none;
}
header.app[data-admin-open] [data-admin-menu] a:hover,
header.app[data-admin-open] [data-admin-menu] a:focus-visible,
header.app[data-admin-open] [data-admin-menu] #logout:hover,
header.app[data-admin-open] [data-admin-menu] #logout:focus-visible {
  background: rgba(255, 255, 255, 0.08);
}
/* The approved mockup's lead-row accent. There is no active-page
   marker in the admin markup or admin-nav-menu.js, so this is the
   first row's palette accent, not a current-page state. */
header.app[data-admin-open] [data-admin-menu] a:first-child {
  color: var(--color-orange);
  font-weight: 700;
}
header.app[data-admin-open] [data-admin-menu] #logout {
  font: inherit;
  font-size: 1.0625rem;
  cursor: pointer;
}
header.app #profile-bell { display: none !important; }
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.lang button, .bell {
  background: transparent; color: #fff; border: 1px solid rgba(255,255,255,0.5);
  border-radius: 999px; padding: 0.2rem 0.65rem; cursor: pointer;
}
.lang button[aria-pressed="true"] {
  /* 210-lang-active-pill-pine: the active language wears the
     footer's pine with white text (owner's pick over white and
     over the spring green it replaces — the spring clashed
     with the header's oranges, 2026-10-29). */
  background: var(--color-pine); color: #fff; border-color: var(--color-pine);
}
.bell[hidden] { display: none; }
footer.app {
  flex-shrink: 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1.5rem 2rem;
  margin-top: 2rem;
  padding: 2rem 1.5rem 1.5rem;
  background: var(--color-pine);
  color: #fff;
  border-top: 1px solid rgba(255, 255, 255, 0.15);
  width: 100%;
  box-sizing: border-box;
}
.footer-col-header {
  margin: 0 0 0.6rem;
  font-size: 0.8rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #fff;
}
footer.app a {
  display: block;
  color: #fff;
  text-decoration: none;
  font-size: 0.85rem;
  padding: 0.25rem 0;
}
footer.app a:hover { text-decoration: underline; }
footer.app a[hidden] { display: none; }
.footer-social {
  display: flex;
  gap: 0.75rem;
}
.footer-social a {
  display: inline-flex;
  padding: 0;
}
.footer-copyright {
  grid-column: 1 / -1;
  margin: 1rem 0 0;
  padding-top: 1rem;
  border-top: 1px solid rgba(255, 255, 255, 0.15);
  font-size: 0.75rem;
  color: #fff;
  text-align: center;
}
footer.app.footer-simple {
  display: flex;
  justify-content: center;
}
.footer-simple .footer-copyright {
  margin: 0;
  padding-top: 0;
  border-top: none;
}
@media (max-width: 40rem) {
  footer.app {
    grid-template-columns: 1fr;
    gap: 1.25rem;
    padding: 1.5rem 1rem 1rem;
  }
  footer.app a { padding: 0.35rem 0; }
}
main { flex: 1 0 auto; width: 100%; max-width: 720px; margin: 1.5rem auto; padding: 0 1rem 3rem; }
.card { background: var(--card); border-radius: 12px; padding: 1.25rem 1.5rem; box-shadow: 0 8px 24px rgba(0,0,0,0.06); }
/* 184-admin-password-toggle-recaptcha: narrows the admin sign-in card on
   large screens only; below 1024px main.admin-login keeps the plain
   main + .card width/look used before this feature. */
@media (min-width: 1024px) {
  main.admin-login { max-width: 480px; }
}
h1 { margin-top: 0; font-size: 1.45rem; }
[data-catalog-subtitle] {
  margin-top: 0.2rem;
  font-size: 1rem;
  font-weight: 400;
  color: var(--color-hunter);
}
label { display: block; margin: 0.65rem 0 0.2rem; font-size: 0.9rem; }
input, select, textarea {
  width: 100%; padding: 0.5rem 0.6rem; border: 1px solid #c5c5c5; border-radius: 8px;
}
.stripe-element {
  width: 100%; padding: 0.6rem; border: 1px solid #c5c5c5; border-radius: 8px; background: #fff; box-sizing: border-box;
}
.stripe-element--invalid { border-color: var(--err); }
.link-btn {
  display: inline-block; margin-top: 0.5rem; background: none; border: 0;
  /* 154-button-text-scale: the official text button keeps its look
     (hunter, underlined) and gains the scale's >=44px tap area plus
     the page font (it rendered in the UA's control font before). */
  padding: 0.78rem 0.25rem; min-height: 2.75rem; font: inherit;
  color: var(--color-hunter); text-decoration: underline; cursor: pointer; font-size: 0.9rem;
}
.link-btn[hidden] { display: none; }
.saved-card-label { font-weight: 600; margin: 0.65rem 0 0.2rem; }
button.primary, a.button {
  display: inline-flex; align-items: center; justify-content: center;
  margin-top: 1rem; background: var(--color-orange); color: #fff;
  /* 104-pill-action-buttons: every action button on the platform is
     a pill — this one shared rule is what keeps them uniform. */
  border: 0; border-radius: 999px; padding: 0.55rem 1rem; cursor: pointer; text-decoration: none;
  /* 154-button-text-scale: Principal level of the button scale —
     >=48px tall, and font: inherit so the label renders in the
     page's font (the buy button measured 32.6px in the UA's
     13.33px control font before this). */
  font: inherit; min-height: 3rem;
}
button.primary:hover, button.primary:active,
a.button:hover, a.button:active { background: var(--color-orange-dark); }
button.primary:disabled { opacity: 0.7; cursor: not-allowed; }
.err { color: var(--err); min-height: 1.2rem; }
.ok { color: var(--color-forest); min-height: 1.2rem; }
.payment-groups { list-style: none; margin: 0.75rem 0; padding: 0; display: flex; flex-direction: column; gap: 0.35rem; }
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 1rem; }
/* 163-two-column-phone-grid: on phones the product grids
   always deal two cards per row (owner's Depop decision),
   where the auto-fill above collapses to one column under
   ~412px. Scoped to .product-grid so the admin surfaces
   that share .grid keep their auto-fill. minmax(0, 1fr)
   lets columns shrink below min-content — a long name can
   never widen the page. Above 480px (the existing
   compact-mobile breakpoint) the base auto-fill already
   yields >= 2 columns, so nothing changes there. */
@media (max-width: 480px) {
  .grid.product-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.product, .widget {
  background: var(--card); border-radius: 10px; padding: 1rem; border: 1px solid #ddd;
}
/* 224-admin-stat-card-links: stat cards that are anchors keep
   the card look (no link blue, no underline). */
a.widget { color: inherit; text-decoration: none; display: block; }
.section { margin-top: 1.25rem; padding-top: 0.5rem; border-top: 1px solid #ddd; }
.row { display: flex; gap: 0.75rem; flex-wrap: wrap; align-items: center; }
.row[hidden] { display: none; }
.muted { color: var(--muted); font-size: 0.9rem; }
.required-mark { color: var(--muted); margin-left: 0.2rem; }
.price { color: var(--text); font-weight: 800; white-space: nowrap; }
.google-host { margin-top: 1rem; min-height: 2.5rem; }
/* 177-apple-login: Apple's HIG treatment for its sign-in button —
   neutral black/white only (the documented Principle VII exception);
   no brand palette token is used or introduced here. */
.apple-host { margin-top: 0.75rem; }
.apple-host[hidden] { display: none; }
.apple-btn {
  width: 100%; display: flex; align-items: center; justify-content: center; gap: 0.55rem;
  background: #000; color: #fff; border: 0; border-radius: 8px;
  padding: 0.75rem 1rem; font-size: 1rem; cursor: pointer;
}
.apple-btn svg { width: 1.15rem; height: 1.15rem; flex: none; }
/* 243-google-signin-native: the house Google button the native
   bridge renders in-wrapper — .apple-btn geometry, neutral
   outline treatment, and a monochrome G glyph in currentColor,
   so no Google brand colour and no palette token is introduced
   (Principle VII). */
.google-btn {
  width: 100%; display: flex; align-items: center; justify-content: center; gap: 0.55rem;
  background: #fff; color: var(--text); border: 1px solid #ddd; border-radius: 8px;
  padding: 0.75rem 1rem; font-size: 1rem; cursor: pointer;
}
.google-btn svg { width: 1.15rem; height: 1.15rem; flex: none; }
.google-btn[disabled] { opacity: 0.6; cursor: default; }
/* FR-011: the update note that replaces the button in app
   builds without the native plugin — the login card's own
   plain paragraph styling, nothing new. */
#google-app-note { margin: 0; color: var(--muted); font-size: 0.95rem; }
[data-loader],
[data-media-loader],
[data-variant-loader] {
  display: none;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.75rem;
  font-size: 0.9rem;
  color: var(--text);
}
form[aria-busy="true"] [data-loader] { display: flex; }
#media-section[aria-busy="true"] [data-media-loader] { display: flex; }
#variants-section[aria-busy="true"] [data-variant-loader] { display: flex; }
.loader-spin {
  width: 1.1rem; height: 1.1rem;
  border: 2px solid var(--color-spring);
  border-right-color: transparent;
  border-radius: 50%;
  animation: daidar-spin 0.7s linear infinite;
}
@keyframes daidar-spin { to { transform: rotate(360deg); } }
body.is-submitting .lang button,
body.is-submitting a,
body.is-submitting #google-btn {
  pointer-events: none;
  opacity: 0.6;
}

.auth-shell {
  max-width: 28rem;
  margin: 2.5rem auto;
  padding: 0 1rem 3rem;
}
.auth-shell--wide { max-width: 46rem; }
.auth-card {
  background: var(--card);
  border-radius: 16px;
  padding: 1.75rem 1.5rem 2rem;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.08);
  border: 1px solid #e5e5e5;
}
[data-auth-tabs] {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.35rem;
  margin-bottom: 1.5rem;
  background: #f0f0f0;
  border-radius: 10px;
  padding: 0.25rem;
}
[data-auth-tabs] a {
  text-align: center;
  text-decoration: none;
  color: var(--text);
  font-weight: 600;
  padding: 0.65rem 0.5rem;
  border-radius: 8px;
}
[data-auth-tabs] a[aria-current="page"] {
  background: var(--muted);
  color: #fff;
}
.auth-badge {
  width: 4rem;
  height: 4rem;
  margin: 0 auto 1rem;
  border-radius: 12px;
  overflow: hidden;
  background: #111;
  display: flex;
  align-items: center;
  justify-content: center;
}
.auth-badge img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}
.auth-card h1 { text-align: center; font-size: 1.75rem; }
.auth-sub { text-align: center; color: var(--muted); margin: 0 0 1.25rem; }
.auth-card button.primary { width: 100%; padding: 0.75rem 1rem; font-size: 1rem; }
.field-icon { position: relative; }
.field-icon > svg {
  position: absolute;
  left: 0.7rem;
  top: 50%;
  transform: translateY(-50%);
  width: 1.15rem;
  height: 1.15rem;
  color: var(--muted);
  pointer-events: none;
}
.field-icon input { padding-left: 2.35rem; }
.field-icon:has(button[data-password-toggle]) input { padding-right: 2.5rem; }
button[data-password-toggle] {
  position: absolute;
  right: 0.35rem;
  top: 50%;
  z-index: 1;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  width: 1.75rem;
  height: 1.75rem;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  line-height: 0;
  appearance: none;
  -webkit-appearance: none;
}
button[data-password-toggle] svg {
  position: static;
  left: auto;
  top: auto;
  right: auto;
  transform: none;
  width: 1.15rem;
  height: 1.15rem;
  color: var(--muted);
  pointer-events: none;
  display: block;
}
button[data-password-toggle][aria-pressed="true"] [data-eye-off] { display: none; }
button[data-password-toggle][aria-pressed="false"] [data-eye-on],
button[data-password-toggle]:not([aria-pressed]) [data-eye-on] { display: none; }
.remember-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0.75rem 0 1.1rem;
}
.checkbox-row {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.9rem;
  cursor: pointer;
}
.checkbox-row[hidden] { display: none; }
.checkbox-row--wrap {
  align-items: flex-start;
}
.checkbox-row--wrap input[type="checkbox"] {
  margin-top: 0.15rem;
}
.checkbox-row input[type="checkbox"],
.checkbox-row input[type="radio"] {
  accent-color: var(--color-hunter);
  width: 1.05rem;
  height: 1.05rem;
  margin: 0;
}
.remember-row a { font-size: 0.9rem; white-space: nowrap; }
/* 239-auth-fit: on phones the sign-in card stacked
   ~813px before its submit — the orange «Ingresar»
   sat below the fold and the owner had to scroll
   inside what should be a one-screen form (his
   Android-app photo, 2026-10-30; the wrapper adds
   0px, the page itself is simply too tall —
   research in specs/239-auth-fit). Everything
   below lives inside the 480px compact breakpoint
   and is scoped to the auth shell/card, so the
   desktop and every other page render exactly as
   before. The register side of the card shares
   these classes and inherits the same tightening;
   its form is taller and keeps scrolling, just
   with less air. Layer 1 — the form fits: shell
   air, card air, a smaller badge, a one-step-
   smaller h1, the empty error line reserving
   nothing (a real message re-opens its space at
   the tighter margin), tighter field labels, the
   remember row held on ONE line (its link and
   label drop one font step and the row's gaps
   and link padding tighten — the measured items
   were wider than the research estimate; the
   link keeps its 154 min-height, so the tap
   target does not shrink), and the submit's
   top margin. */
@media (max-width: 480px) {
  .auth-shell { margin-top: 0.75rem; }
  .auth-card { padding-top: 1rem; }
  [data-auth-tabs] { margin-bottom: 0.75rem; }
  .auth-badge { width: 3rem; height: 3rem; margin-bottom: 0.625rem; }
  .auth-card h1 { font-size: 1.45rem; }
  .auth-sub { margin-bottom: 0.625rem; }
  .auth-card #msg { margin: 0.35rem 0; }
  .auth-card #msg:empty { min-height: 0; margin: 0; }
  .auth-card form > label { margin-top: 0.4rem; }
  .remember-row { margin: 0.625rem 0 0.75rem; gap: 0.25rem; }
  .remember-row .link-action { font-size: 0.85rem; padding-left: 0; padding-right: 0; }
  .remember-row .checkbox-row { font-size: 0.85rem; gap: 0.25rem; }
  .auth-card button.primary { margin-top: 0.75rem; }
  /* Layer 2 — the card's tail: with these four
     whitespace trims the whole card, Google/Apple
     buttons included, fits the tall phones
     (390x844, 412x915) without scrolling. */
  .auth-card .google-host { margin-top: 0.625rem; }
  .auth-card .apple-host { margin-top: 0.625rem; }
  .auth-card > p:last-of-type { margin: 0.5rem 0 0; }
  .auth-card { padding-bottom: 1.25rem; }
}
.form-grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 1rem;
}
@media (max-width: 40rem) {
  .form-grid-2 { grid-template-columns: 1fr; }
}
.form-section-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.75rem;
  color: var(--color-hunter);
}
.form-section-header svg { width: 1.15rem; height: 1.15rem; flex-shrink: 0; }
.form-section-header h2 { margin: 0; font-size: 1.05rem; }
[data-section] { margin-top: 1.5rem; padding-top: 1.25rem; border-top: 1px solid #ddd; }
[data-bill-options] {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
  margin-bottom: 1rem;
}
@media (max-width: 40rem) {
  [data-bill-options] { grid-template-columns: 1fr; }
}
[data-bill-option] {
  text-align: left;
  border: 2px solid #ddd;
  background: var(--card);
  border-radius: 12px;
  padding: 0.9rem;
  cursor: pointer;
  color: inherit;
  font: inherit;
}
[data-bill-option][aria-pressed="true"] {
  border-color: var(--color-forest);
  background: color-mix(in srgb, var(--color-sage) 18%, #fff);
}
[data-bill-option] strong { display: block; margin-bottom: 0.25rem; }
[data-bill-option] span { display: block; font-size: 0.8rem; color: var(--muted); }
[data-bill-summary] {
  border: 1px solid #ddd;
  border-radius: 12px;
  padding: 0.9rem 1rem;
  font-size: 0.9rem;
}
[data-bill-summary] .sum-title { font-weight: 600; margin: 0 0 0.5rem; color: var(--color-forest); }
[data-leave-dialog] {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.35);
}
[data-leave-dialog][hidden] { display: none; }
[data-leave-dialog] .leave-box {
  background: var(--card);
  border-radius: 12px;
  padding: 1.25rem 1.35rem;
  max-width: 22rem;
  width: calc(100% - 2rem);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.18);
}
[data-leave-dialog] .leave-actions {
  display: flex;
  gap: 0.75rem;
  justify-content: flex-end;
  margin-top: 1rem;
}
[data-leave-dialog] .leave-actions button {
  border-radius: 8px;
  padding: 0.45rem 0.85rem;
  cursor: pointer;
  font: inherit;
}
[data-leave-cancel] { background: #fff; border: 1px solid #c5c5c5; }
[data-leave-confirm] {
  background: var(--color-forest);
  color: #fff;
  border: 0;
}

.status-badge {
  display: inline-block;
  padding: 0.15rem 0.6rem;
  border-radius: 999px;
  font-size: 0.8rem;
  background: #eee;
  color: var(--text);
  margin: 0.15rem 0.35rem 0.15rem 0;
}
.status-active { background: var(--color-mint); color: var(--color-hunter); }
.status-draft { background: #eee; color: var(--muted); }
.status-inactive { background: #ddd; color: var(--color-orange-dark); }
/* 180-admin-product-approval: same "needs attention" orange already used
   by .order-status-badge--pending/--processing — no new hex (Principle VII). */
.status-pending_approval { background: var(--color-orange); color: var(--color-hunter); }

/* 180-admin-product-approval: thumbnail grid for the admin detail's
   read-only image gallery. */
.admin-product-gallery { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0.5rem 0; }
.admin-product-gallery img { width: 96px; height: 96px; object-fit: cover; border-radius: 6px; }

.variant-list { display: flex; flex-direction: column; gap: 0.4rem; margin: 0.5rem 0; }
.variant-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.4rem 0.6rem;
  border: 1px solid #ddd;
  border-radius: 8px;
}
.variant-row.out-of-stock { color: var(--muted); }
.variant-photo-thumb-sm {
  width: 2.2rem;
  height: 2.2rem;
  object-fit: cover;
  border-radius: 6px;
  flex-shrink: 0;
}
.variant-row-actions { display: flex; gap: 0.4rem; }
.variant-row-actions button {
  border: 0;
  background: #333;
  color: #fff;
  border-radius: 50%;
  width: 1.4rem;
  height: 1.4rem;
  line-height: 1;
  cursor: pointer;
}

.variant-photo-thumb {
  position: relative;
  display: inline-flex;
  width: 3.2rem;
  height: 3.2rem;
}
.variant-photo-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 8px;
  aspect-ratio: 1 / 1;
}
.variant-photo-thumb button {
  position: absolute;
  top: -0.4rem;
  right: -0.4rem;
  width: 1.4rem;
  height: 1.4rem;
  border-radius: 50%;
  border: 0;
  background: #333;
  color: #fff;
  cursor: pointer;
  line-height: 1;
}

.media-list { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0.5rem 0; }
.media-thumb {
  position: relative;
  width: 5.5rem;
  height: 5.5rem;
}
.media-thumb img, .media-thumb video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 8px;
  aspect-ratio: 1 / 1;
}
.media-thumb button {
  position: absolute;
  top: -0.4rem;
  right: -0.4rem;
  width: 1.4rem;
  height: 1.4rem;
  border-radius: 50%;
  border: 0;
  background: #333;
  color: #fff;
  cursor: pointer;
  line-height: 1;
}

.gallery { position: relative; max-width: 32rem; margin: 0 auto 1rem; }
.gallery-frame {
  aspect-ratio: 1 / 1;
  background: #fff;
  border-radius: 12px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
.gallery-frame img, .gallery-frame video {
  width: 100%;
  height: 100%;
  object-fit: contain;
  cursor: zoom-in;
}
.gallery-swipe .gallery-frame { touch-action: pan-y; cursor: grab; }
#gallery-prev, #gallery-next {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  background: rgba(255, 255, 255, 0.85);
  border: 0;
  border-radius: 50%;
  width: 2.25rem;
  height: 2.25rem;
  cursor: pointer;
  font-size: 1.1rem;
}
#gallery-prev { left: 0.5rem; }
#gallery-next { right: 0.5rem; }
#gallery-prev[hidden], #gallery-next[hidden] { display: none; }
#gallery-dots {
  position: absolute;
  bottom: 0.6rem;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 0.4rem;
  padding: 0.3rem 0.5rem;
  background: rgba(0, 0, 0, 0.45);
  border-radius: 999px;
  max-width: calc(100% - 1rem);
  overflow-x: auto;
}
#gallery-dots[hidden] { display: none; }
.gallery-dot {
  flex-shrink: 0;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  border: 0;
  background: rgba(255, 255, 255, 0.6);
  padding: 0;
  cursor: pointer;
}
.gallery-dot.active { background: #fff; }

#zoom-overlay {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: rgba(0, 0, 0, 0.85);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: zoom-out;
}
#zoom-overlay[hidden] { display: none; }
#zoom-overlay img { max-width: 95vw; max-height: 95vh; object-fit: contain; }

.media-thumb .media-edit-btn {
  position: absolute;
  bottom: -0.4rem;
  right: -0.4rem;
  top: auto;
  width: 1.4rem;
  height: 1.4rem;
  border-radius: 50%;
  border: 0;
  background: #333;
  color: #fff;
  cursor: pointer;
  line-height: 1;
  font-size: 0.75rem;
}

#photo-editor:not([hidden]) { margin-top: 0.75rem; display: flex; flex-direction: column; gap: 0.5rem; align-items: flex-start; }
#photo-editor-canvas-wrap { max-width: 100%; }
#photo-editor-canvas { max-width: 100%; height: auto; touch-action: none; cursor: move; border-radius: 8px; }

.header-actions { margin-left: auto; display: flex; align-items: center; gap: 0.75rem; }
.header-pill, .cart-icon {
  background: transparent; color: #fff; border: 1px solid rgba(255,255,255,0.5);
  border-radius: 999px; padding: 0.2rem 0.65rem; cursor: pointer; text-decoration: none;
  display: inline-flex; align-items: center; gap: 0.35rem;
}
.cart-icon { position: relative; }
/* 209-header-cart-orange-outline: the cart wears the palette
   orange in outline (owner's pick over a filled disc and over
   the username teal, mockups approved 2026-10-29). The glyph's
   SVG fills with currentColor, so colour alone turns it; the
   ring takes the same orange. Background stays transparent —
   that is the approved «en línea». The count badge already
   wears this orange and does not change. */
header.app .cart-icon {
  color: var(--color-orange);
  border-color: var(--color-orange);
}
.cart-badge {
  position: absolute; top: -0.4rem; right: -0.4rem;
  background: var(--color-orange); color: #fff; border-radius: 999px;
  font-size: 0.7rem; line-height: 1; min-width: 1.1rem; height: 1.1rem;
  display: flex; align-items: center; justify-content: center; padding: 0 0.2rem;
}
.cart-badge[hidden] { display: none; }

/* 063-order-messages-notifications: the "Messages"/"Mensajes" nav item's
   unread count — a small green circle with the number centered inside,
   inline with the label so both sit on one line. */
.messages-unread-count {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--color-forest); color: #fff; border-radius: 999px;
  font-size: 0.7rem; line-height: 1; min-width: 1.1rem; height: 1.1rem;
  padding: 0 0.3rem; margin-left: 0.4rem; vertical-align: middle;
}
.messages-unread-count[hidden] { display: none; }

/* 067-support-help-form: the "Soporte" pill distinguishing a support-request
   row from an order message in the merged /messages list (FR-008), and
   minimal spacing for the thread/follow-up panel rendered on open.
   212-support-badge-pine: the pill's background moves from --color-teal
   to --color-pine (spec 208's footer token) — the owner rejected the
   teal on his own /messages screenshot («Ese verde sí no me convence»,
   the same teal dropped for the header cart in 209) and picked pine
   over orange on mockups; the badge joins the pine tool family
   (208 Filtros, 210 language pill, 211 Buscar). The --color-teal token
   itself and its other uses (avatars, links, reward badge) stay. */
.support-badge {
  display: inline-block; padding: 0.15rem 0.6rem; border-radius: 999px;
  color: #fff; font-weight: 700; font-size: 0.8rem; background: var(--color-pine);
}
.support-thread-message { margin: 0.4rem 0; }
.support-followup-form { display: flex; flex-direction: column; gap: 0.5rem; margin-top: 0.75rem; }

.home-main { max-width: 72rem; margin: 1.5rem auto; padding: 0 1rem 3rem; }
.home-section { margin-top: 1.5rem; }
.home-section[hidden] { display: none; }
.home-section h2 { margin: 0 0 0.75rem; }
/* 160-infinite-scroll-home: the «Ver más» button is gone —
   batches load as the section's sentinel nears the viewport.
   What remains per section is the batch status line (the
   reused "please wait" text, only while a batch is in
   flight), the load error, and its discreet text retry
   (.link-action, spec 154), which exists only in the
   failure state. */
.home-section [data-infinite-sentinel] { height: 1px; }
.home-section p[data-loading-more] { text-align: center; }
.home-section p[data-loading-more][hidden] { display: none; }
.home-section p[data-load-error] { text-align: center; }
.home-section p[data-load-error][hidden] { display: none; }
.home-section [data-load-retry] { display: block; width: fit-content; margin: 0.5rem auto 0; }
.home-section [data-load-retry][hidden] { display: none; }
/* 161-big-product-cards: catalog card photos go portrait
   (4/5 — the owner-approved Depop-style «grandes»). This
   rule is shared, so the home grid, category landings,
   search results, the seller storefront and favorites
   all pick it up at once. The fixed-size thumbnails that
   reuse the placeholder class are NOT cards and are not
   affected: cart items pin 3.5rem × 3.5rem and order
   items pin 3rem × 3rem (both dimensions set, so this
   aspect-ratio is inert there). The product page gallery
   uses none of these classes and keeps full photos. */
.product-photo, .product-photo-placeholder {
  width: 100%; aspect-ratio: 4 / 5; object-fit: cover; border-radius: 8px; display: block;
}
.product-photo-placeholder {
  background: #eee; color: var(--muted); display: flex; align-items: center; justify-content: center;
}
/* 161-big-product-cards: the name gets two lines before
   it truncates (was one nowrap line). The grey size line
   that used to sit under it left the card in that spec —
   and returns verbatim in 165, in its original position
   between the name and the price (owner reversal of
   2026-10-25).
   170-card-name-one-line: the name now gets ONE line
   before it truncates (owner decision of 2026-10-25,
   mockup option B after the big-marketplace comparison:
   photo and price speak, the name takes one clean line
   and the row stays even). The 4/5 photo above and the
   165 size line below are untouched — only the clamp
   count changes, here in the one shared rule. */
.product-name {
  font-weight: 600; margin-top: 0.6rem; overflow: hidden;
  display: -webkit-box; -webkit-line-clamp: 1; line-clamp: 1; -webkit-box-orient: vertical;
}
.product-size-line { color: var(--muted); font-size: 0.85rem; margin-top: 0.2rem; }
.product .price { margin-top: 0.2rem; font-size: 1.05rem; }

/* 095-product-favorites: heart toggle floating over the card photo
   (top-right). The filled state uses the brand accent token
   (--color-orange): Principle VII reserves non-palette red for
   error text only. */
.product { position: relative; }
.favorite-btn {
  position: absolute; top: 1.5rem; right: 1.5rem; z-index: 1;
  width: 2.25rem; height: 2.25rem; padding: 0;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, 0.92); color: #444;
  border: 1px solid #ddd; border-radius: 50%; cursor: pointer;
}
.favorite-btn svg { width: 1.15rem; height: 1.15rem; fill: none; stroke: currentColor; stroke-width: 2; }
.favorite-btn.is-favorite { color: var(--color-orange); }
.favorite-btn.is-favorite svg { fill: var(--color-orange); stroke: var(--color-orange); }
.favorite-status {
  display: inline-block; margin-top: 0.35rem; padding: 0.1rem 0.5rem;
  font-size: 0.8rem; font-weight: 600; color: var(--muted);
  border: 1px solid #ddd; border-radius: 999px;
}

/* Trust banner: transparent strip (letters only) at the top of the
   storefront; its messages rotate (see rotateTrustBanner in home.js). */
.trust-banner {
  color: var(--text);
  text-align: center;
  font-weight: 700;
  font-size: 1rem;
  letter-spacing: 0.01em;
  padding: 0.25rem 1rem;
  margin-bottom: 0.75rem;
  transition: opacity 0.45s ease;
}
.trust-banner.tb-fade { opacity: 0; }

.category-landing { text-align: center; margin: 0.25rem auto 1rem; }
.category-landing h1 { margin-bottom: 0.35rem; }
.category-landing p { color: var(--muted); margin: 0 auto; max-width: 42rem; }

/* Category circles: horizontal shortcut row into the catalog filters. */
.category-circles {
  display: flex;
  gap: 1rem;
  overflow-x: auto;
  padding: 0.25rem 0.1rem 0.75rem;
  scrollbar-width: none;
}
.category-circles::-webkit-scrollbar { display: none; }
.category-circle {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  background: none;
  border: none;
  cursor: pointer;
  min-width: 4.3rem;
  padding: 0;
  color: var(--text);
  font: inherit;
}
.category-circle .cc-icon {
  width: 3.6rem;
  height: 3.6rem;
  border-radius: 50%;
  background: var(--card);
  border: 1.5px solid #ddd;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.7rem;
  overflow: hidden;
}
/* 162-category-circles-no-flash: the photo is inserted only
   once loaded (162 in home.js) and fades in with the trust
   banner's transition; until then the circle shows its own
   empty surface — never the emoji. */
.category-circle .cc-photo { width: 100%; height: 100%; object-fit: cover; display: block; opacity: 0; transition: opacity 0.45s ease; }
.category-circle .cc-photo.cc-in { opacity: 1; }
.category-circle .cc-name { font-size: 0.82rem; color: var(--muted); text-align: center; }
.category-circle.active .cc-icon { border-color: var(--color-hunter); box-shadow: 0 0 0 2px var(--color-hunter); }
.category-circle.active .cc-name { color: var(--text); font-weight: 700; }

/* 045-cart-page-redesign: cart-item, cart-subtotal, and cart-empty-btn
   below are reused by the /cart page's own layout (see the cart-page
   rules further down); the popup dialog chrome (cart-panel) that used
   to wrap them is gone. */
.cart-item { display: flex; gap: 0.75rem; padding: 0.6rem 0; border-bottom: 1px solid #eee; }
.cart-item-photo, .cart-item .product-photo-placeholder { width: 3.5rem; height: 3.5rem; flex-shrink: 0; }
.cart-item-info p { margin: 0.1rem 0; }
.cart-subtotal { font-weight: 600; }
.cart-empty-btn {
  width: 100%; margin-top: 0.5rem; padding: 0.55rem 1rem; border-radius: 8px; cursor: pointer;
  background: #fff; border: 1px solid #c5c5c5; color: var(--text);
}

.cart-page-main { max-width: 60rem; margin: 1.5rem auto; padding: 0 1rem 3rem; }
.cart-page-grid { display: grid; grid-template-columns: 2fr 1fr; gap: 1.5rem; align-items: start; margin-top: 1rem; }
.cart-page-grid[hidden] { display: none; }
/* 061-stripe-tax-calculation (FR-010): the cart/checkout-view-failed
   retry state, built dynamically by cart-page.js when a Stripe Tax
   outage means the view itself cannot render a verified total. */
#cart-view-error { margin-top: 1rem; }
#cart-view-error button.primary { margin-top: 0.5rem; }
@media (max-width: 640px) {
  .cart-page-grid { grid-template-columns: 1fr; }
}
.cart-page-items .cart-item:last-child { border-bottom: 0; }
.cart-page-list-actions { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 1rem; }
.cart-page-secondary-btn {
  width: auto; margin-top: 0; padding: 0.55rem 1rem; border-radius: 8px; cursor: pointer;
  background: #fff; border: 1px solid #c5c5c5; color: var(--text); text-decoration: none;
  display: inline-flex; align-items: center;
  /* 154-button-text-scale: Normal level — >=44px tall. */
  min-height: 2.75rem;
}
.cart-page-totals-box { margin-bottom: 1rem; }
.cart-page-totals-row { display: flex; justify-content: space-between; margin: 0.35rem 0; }
.cart-page-total-row { font-weight: 700; border-top: 1px solid #ddd; padding-top: 0.5rem; margin-top: 0.5rem; }
.cart-page-totals #cart-checkout-btn { width: 100%; margin-top: 0; text-align: center; }
.cart-item-unavailable { opacity: 0.6; }
.cart-item-unavailable-badge { color: var(--err); font-size: 0.85rem; font-weight: 600; }
.cart-item-qty { display: flex; align-items: center; gap: 0.4rem; margin: 0.35rem 0; }
.cart-qty-dec, .cart-qty-inc {
  width: 1.8rem; height: 1.8rem; border-radius: 6px; border: 1px solid #c5c5c5;
  background: #fff; cursor: pointer; line-height: 1; padding: 0;
}
.cart-qty-input { width: 3.2rem; text-align: center; padding: 0.3rem; }
.cart-item-capped-msg { font-size: 0.8rem; }
.cart-item-remove {
  background: transparent; border: 0; padding: 0; color: var(--color-hunter);
  text-decoration: underline; cursor: pointer; font-size: 0.85rem;
}

.search-bar { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 0.75rem; }
.search-bar input[type="search"] { flex: 1 1 14rem; min-width: 0; }
.search-bar button.primary { margin-top: 0; white-space: nowrap; }
.search-bar #filters-toggle, .search-bar #search-clear {
  background: transparent; border: 1px solid #c5c5c5; border-radius: 8px;
  padding: 0.5rem 0.9rem; cursor: pointer; color: var(--text); white-space: nowrap;
}
.filters-panel {
  display: flex; flex-wrap: wrap; gap: 1.25rem; background: var(--card);
  /* 101-rounded-home (FR-004): radius matches the product photos. */
  border: 1px solid #ddd; border-radius: 18px; padding: 0.9rem 1rem; margin-bottom: 1rem;
}
/* 101-rounded-home: the big-platform rounded language Carlos approved
   (Depop/Shein/Amazon) — generously rounded photos and pill controls
   on the home. Scoped so the cart, checkout and favorites keep their
   current radii: the photo rule is ancestor-scoped because
   .product-photo is shared with the cart thumbnails. */
.home-main .product-photo, .home-main .product-photo-placeholder,
.seller-main .product-photo, .seller-main .product-photo-placeholder {
  border-radius: 18px;
}
.search-bar input[type="search"] { border-radius: 999px; padding: 0.6rem 1.1rem; }
.search-bar button { border-radius: 999px; }
/* 105-category-circles-navigate: circles for the landing categories
   are anchors now (they read as the buttons did — the base rule sets
   color/layout); only the default underline needs removing. */
a.category-circle { text-decoration: none; }
/* 102-greeting-profile-link: the signed-in greeting's name links to
   the user's own public seller profile (098) when they have one.
   Quiet treatment — inherited color, bold, underlined. */
#account-status .profile-name-link {
  color: inherit; font-weight: 700; text-decoration: underline; text-underline-offset: 3px;
}
/* Filters/Clear carry their own ID-scoped 8px rule above; it takes
   this equally-scoped later rule to pill them too. */
.search-bar #filters-toggle, .search-bar #search-clear { border-radius: 999px; }
.filters-panel[hidden] { display: none; }
.filter-group { display: flex; flex-direction: column; gap: 0.35rem; min-width: 8rem; }
.filter-label { font-size: 0.85rem; font-weight: 600; color: var(--color-hunter); }
.filter-group .row { gap: 0.5rem; }
#filter-price-min, #filter-price-max { width: 6rem; }
#search-empty { margin-top: 1rem; }
.home-section .product { cursor: pointer; }
.home-section .product:hover { box-shadow: 0 4px 14px rgba(0,0,0,0.12); }

.product-main { max-width: 60rem; margin: 1.5rem auto; padding: 0 1rem 3rem; }
.product-detail .product-top {
  display: flex; flex-wrap: wrap; gap: 1.75rem; align-items: flex-start;
}
.product-detail .gallery { flex: 1 1 22rem; width: 100%; margin: 0; }
.product-info { flex: 1 1 18rem; min-width: 0; }
.product-info h1 { margin-top: 0; }
.product-description { color: var(--text); white-space: pre-line; }
.product-buy-row { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; margin-top: 1rem; }
.qty-field { display: flex; flex-direction: column; gap: 0.2rem; }
.qty-field[hidden] { display: none; }
.qty-field label { margin: 0; }
.qty-field input { width: 5rem; }
#variant-swatches, #saved-cards-list { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.variant-swatch {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 0.6rem;
  border: 1px solid #ccc;
  border-radius: 999px;
  background: #fff;
  cursor: pointer;
  margin-bottom: 0.6rem;
  font-size: 0.9rem;
}
.variant-swatch img {
  width: 1.6rem;
  height: 1.6rem;
  object-fit: cover;
  border-radius: 50%;
}
.variant-swatch.active { border-color: var(--color-orange); border-width: 2px; }
.variant-swatch:disabled { color: var(--muted); cursor: not-allowed; opacity: 0.6; }
.product-buy-row button.primary { margin-top: 0; }
.product-price { font-size: 1.35rem; font-weight: 700; color: var(--text); }
.product-details-section h2 { margin-top: 0; }
.detail-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr)); gap: 0.75rem 1.5rem; margin: 0 0 0.75rem; }
.detail-list dt { font-size: 0.8rem; color: var(--muted); margin: 0; }
.detail-list dd { margin: 0.1rem 0 0; font-weight: 600; }
@media (max-width: 40rem) {
  .product-detail .product-top { flex-direction: column; }
}

/* 056-locker-room-panel */
.locker-room-view { max-width: 48rem; margin: 0 auto; padding: 1rem; display: flex; flex-direction: column; gap: 1.25rem; }
.locker-room-hero { display: flex; align-items: center; gap: 1rem; }
.locker-room-avatar {
  width: 4rem; height: 4rem; border-radius: 50%; flex-shrink: 0;
  background: var(--color-orange); color: #fff; background-size: cover; background-position: center;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.5rem; font-weight: 700;
}
.locker-room-hero-text h1 { margin: 0 0 0.2rem; }
.locker-room-full-name { margin: 0; color: var(--muted); }
.locker-room-group-label { margin: 0 0 0.5rem; font-size: 1.1rem; }
.locker-room-entries { display: flex; flex-direction: column; gap: 0.4rem; }
/* 058-my-account-rename: "Detalles de la cuenta" is a visual sub-heading
   only (Clarification Q3) — same entries list styling, smaller/muted
   label so it reads as a sub-group of "Mi Perfil", not a sibling group. */
.locker-room-subgroup { display: flex; flex-direction: column; gap: 0.4rem; }
.locker-room-subgroup-label { margin: 0; font-size: 0.9rem; font-weight: 600; color: var(--muted); }
.locker-room-entry {
  /* 100-pill-menu-buttons (FR-004): pill shape, like the menu's Sign out. */
  display: block; text-align: left; padding: 0.6rem 1.1rem; border-radius: 999px;
  border: 2px solid var(--color-pitch); background: var(--card); color: var(--text); /* 260-account-menu-pitch-border */
  cursor: pointer; text-decoration: none; font: inherit;
  /* 154-button-text-scale: Normal level — >=44px tall. */
  min-height: 2.75rem;
}
.locker-room-entry:hover, .locker-room-entry:focus-visible { border-color: var(--color-orange); }
/* 261-account-back-button: round back button at the top of the account-area inner screens. */
.back-btn { display: flex; align-items: center; justify-content: center; width: 2.75rem; height: 2.75rem; border-radius: 50%; border: 2px solid var(--color-pitch); background: var(--card); color: var(--color-pitch); font-size: 1.9rem; font-weight: 700; line-height: 1; cursor: pointer; margin: 0 0 0.75rem; }
.back-btn:hover, .back-btn:focus-visible { border-color: var(--color-orange); color: var(--color-orange); }
/* 058-my-account-rename (FR-015/FR-016): replaces the 057-era `hidden`
   attribute toggle — `display: none` cannot be transitioned, so a
   collapsed panel now sits at `max-height: 0`/`opacity: 0` and an
   `.is-open` class expands it over 0.5s. `visibility` flips on a delay
   when closing (immediately when opening) so the panel's form fields
   stay out of the tab order and accessibility tree while collapsed,
   the same guarantee `[hidden]` used to provide. */
.locker-room-detail {
  display: flex; flex-direction: column; gap: 0.5rem;
  max-height: 0; opacity: 0; overflow: hidden; visibility: hidden;
  transition: max-height 0.5s ease-in-out, opacity 0.5s ease-in-out, visibility 0s 0.5s;
}
.locker-room-detail.is-open {
  max-height: 40rem; opacity: 1; visibility: visible;
  transition: max-height 0.5s ease-in-out, opacity 0.5s ease-in-out;
}
.locker-room-detail form { display: flex; flex-direction: column; gap: 0.5rem; }
/* 069-nickname-change-request: #name-form toggles via the `hidden`
   attribute (read-only vs. editable, FR-007) independently of the
   section's own open/closed state above — needs its own override since
   the blanket `.locker-room-detail form` rule otherwise always wins. */
.locker-room-detail form[hidden] { display: none; }
.locker-room-readonly { font-size: 1.1rem; font-weight: 600; }
#photo-preview-canvas { border-radius: 50%; width: 8rem; height: 8rem; object-fit: cover; }
.locker-room-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; }
/* 057-locker-room-refinements: a row now stacks its clickable summary
   (.locker-room-row) above an optional detail panel instead of laying two
   inline children side by side — the old `display: flex` on the `<li>`
   itself moved onto `.locker-room-row` below. */
.locker-room-list li { padding: 0.6rem 0.9rem; border-radius: 8px; border: 1px solid #ddd; }
.locker-room-row {
  display: flex; justify-content: space-between; gap: 1rem; width: 100%;
  background: none; border: none; padding: 0; font: inherit; color: inherit;
  text-align: left; cursor: pointer;
}
/* 058-my-account-rename: status swatch + label sit together on the left of
   the row; the chevron is pushed to the far right by the row's own
   `justify-content: space-between` (FR-006). A rounded *square*, not a
   circle — `border-radius: 4px`, never `50%` (spec's own "cuadrado ... con
   border-radius" wording; see specs/058-my-account-rename/research.md §5). */
.locker-room-row-main { display: flex; align-items: center; gap: 0.5rem; }
.status-swatch { width: 0.6rem; height: 0.6rem; border-radius: 4px; display: inline-block; flex-shrink: 0; }
.status-swatch--completed { background: var(--color-mint); }
.status-swatch--failed { background: var(--err); }
.status-swatch--pending { background: var(--color-orange); }
/* 068-tracking-page-seller-ratings: tracking.js's own three bucket names
   ("processing"/"shipped"/"delivered") are distinct from the pre-existing
   "pending"/"completed" buckets above (057/058's order/sale status, a
   different concept) — each needs its own modifier rule here, not a reuse
   of those. "🔵 Enviados" is the one status-only use of
   --color-status-shipped (constitution v1.5.0). */
.status-swatch--processing { background: var(--color-orange); }
.status-swatch--shipped { background: var(--color-status-shipped); }
.status-swatch--delivered { background: var(--color-mint); }
/* 176-referidos-admin-medias: a 4th, neutral bucket for a socks reward
   won but not yet redeemed — Principle VII's neutral-gray allowance
   (text/backgrounds/borders), deliberately not a brand or status token. */
.status-swatch--pending-redemption { background: var(--muted); }
/* 059-account-details-status-colors: solid, pill-shaped status badge —
   `border-radius: 999px` for the fully-rounded pill the sketch draws,
   deliberately different from `.status-swatch`'s small rounded-*square*
   (`4px`) dot (058-my-account-rename's own research.md already flagged
   that exact shape distinction). Groups with `.chevron` inside
   `.locker-room-row-end` so both sit together on the row's right side.
   Named `.order-status-badge`, not `.status-badge` — that name is
   already taken (line ~396 above) by products.js/product-page.js's own
   active/draft/inactive product-status badge, with a different color
   scheme; reusing it here would have silently overridden that badge's
   text color. */
.locker-room-row-end { display: flex; align-items: center; gap: 0.5rem; }
.order-status-badge { display: inline-block; padding: 0.15rem 0.6rem; border-radius: 999px; color: #fff; font-weight: 700; font-size: 0.8rem; }
.order-status-badge--completed { background: var(--color-mint); }
.order-status-badge--failed { background: var(--err); }
.order-status-badge--pending { background: var(--color-orange); }
.order-status-badge--processing { background: var(--color-orange); }
.order-status-badge--shipped { background: var(--color-status-shipped); }
.order-status-badge--delivered { background: var(--color-mint); }
.order-status-badge--pending-redemption { background: var(--muted); }
/* 177-admin-order-detail-view (FR-005): the admin order detail keeps
   TrackingStatus::bucketFor()'s "problem" bucket distinct (no 096-style
   folding into "processing" needed here) — same --err background
   already used above by --failed, not a new token. */
.order-status-badge--problem { background: var(--err); }
/* 177-admin-order-detail-view: reward indicator, per-seller delivery
   toggle, and incidence badges — neutral/--color-teal only (Principle
   VII), no new token. */
.order-reward-badge {
  display: inline-block; background: var(--color-teal); color: #fff;
  padding: 0.2rem 0.6rem; border-radius: 999px; font-weight: 700;
  font-size: 0.85rem; margin: 0.25rem 0;
}
.order-detail-reward-marker { color: var(--color-teal); font-weight: 700; font-size: 0.8rem; margin-left: 0.4rem; }
.order-detail-seller { margin-top: 1rem; }
.order-detail-incidence-badge {
  display: inline-block; color: #fff; padding: 0.1rem 0.5rem;
  border-radius: 999px; font-size: 0.75rem; font-weight: 700;
}
.order-detail-incidence-badge--active { background: var(--color-orange); }
.order-detail-incidence-badge--resolved { background: var(--muted); }
.order-detail-delivery-toggle {
  background: none; border: 1px solid var(--muted); border-radius: 999px;
  padding: 0.25rem 0.75rem; cursor: pointer;
}
.order-detail-delivery-body[hidden] { display: none; }
.order-detail-incidence-text { white-space: pre-wrap; }
.order-detail-incidence-toggle {
  background: none; border: none; color: var(--color-teal); cursor: pointer;
  padding: 0; font: inherit; text-decoration: underline;
}
/* 187-stripe-connect-partial-refund: refund status pill — same solid
   pill shape as .order-status-badge/.return-request-status/
   .dispute-request-status, own class so a future change to one never
   silently affects the others (same convention those already use). */
.order-detail-refund-status { display: inline-block; padding: 0.15rem 0.6rem; border-radius: 999px; color: #fff; font-weight: 700; font-size: 0.8rem; margin-right: 0.4rem; }
.order-detail-refund-status--partially_refunded { background: var(--color-orange); }
.order-detail-refund-status--fully_refunded { background: var(--color-mint); }
.order-detail-refund-panel { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; margin-top: 0.4rem; }
.order-detail-refund-panel[hidden] { display: none; }
.order-detail-refund-panel input[type="number"] { max-width: 6rem; }
.order-detail-manual-refund-form { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: flex-start; margin-top: 0.5rem; }
.order-detail-manual-refund-form input[type="number"] { max-width: 8rem; }
.order-detail-manual-refund-form textarea { flex: 1 1 200px; min-width: 160px; }
/* 119-order-confirmation-reward-badge: a soft success-tint callout
   confirming the redeemed free-socks reward on this order — the same
   `--color-mint` "success tint" role Principle VII already assigns it,
   mixed light per the `.locker-room-list li.status-completed` convention
   above, never a solid fill (this is a confirmation note, not a badge). */
.order-confirmation-reward-badge { background: color-mix(in srgb, var(--color-mint) 15%, transparent); border-radius: 8px; padding: 0.6rem 0.9rem; font-weight: 700; }
.chevron { display: inline-block; transition: transform 0.2s ease; }
.locker-room-row[aria-expanded="true"] .chevron { transform: rotate(90deg); }
/* 073-buyer-order-returns: same solid pill shape as .order-status-badge,
   under its own class name so a future change to one never silently
   affects the other. */
.return-request-status { display: inline-block; padding: 0.15rem 0.6rem; border-radius: 999px; color: #fff; font-weight: 700; font-size: 0.8rem; }
.return-request-status--pending { background: var(--color-orange); }
.return-request-status--approved { background: var(--color-mint); }
.return-request-status--denied { background: var(--err); }
.return-request-status--label_failed { background: var(--err); }
.return-review-row { display: flex; flex-direction: column; gap: 0.35rem; padding: 0.75rem; }
.return-review-photo { width: 80px; height: 80px; object-fit: cover; border-radius: 6px; margin: 0.25rem; }
.return-review-controls { display: flex; flex-direction: column; align-items: stretch; gap: 0.65rem; }
.return-review-approve-form { display: flex; flex-direction: column; align-items: flex-start; gap: 0.55rem; }
.return-review-payer-layout { display: flex; align-items: flex-start; gap: 0.75rem; }
.return-review-payer-choices { display: block; flex-direction: column; align-items: flex-start; gap: 0.35rem; }
.return-review-payer-prompt { margin: 0; }
.return-label-payer-input { width: 20%; }
.return-review-payer { display: flex; align-items: flex-start; gap: 0.4rem; margin: 0; cursor: pointer; }
.return-review-payer input { margin-top: 0.2rem; flex: none; }
.return-review-deny { display: flex; gap: 0.5rem; align-items: center; width: 100%; }
.return-review-deny-reason { flex: 1 1 auto; min-width: 0; }
/* 181-item-not-received-disputes: the claim row on /my-orders, its
   status chip (same pill shape as .return-request-status), the
   evidence block and the three-way decision controls on
   /return-review. Palette tokens only (Principle VII). */
.dispute-request-row { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
.dispute-request-status { display: inline-block; padding: 0.15rem 0.6rem; border-radius: 999px; color: #fff; font-weight: 700; font-size: 0.8rem; }
.dispute-request-status--open { background: var(--color-orange); }
.dispute-request-status--seller_protected { background: var(--color-mint); }
.dispute-request-status--refund_buyer { background: var(--color-teal); }
.dispute-request-status--courtesy_refund { background: var(--color-teal); }
.dispute-request-status--withdrawn_received { background: var(--muted); }
.dispute-withdraw-btn { display: inline-flex; align-items: center; justify-content: center; min-height: 2.5rem; background: var(--card); color: var(--text); border: 1px solid var(--color-sage); border-radius: 999px; padding: 0.5rem 0.95rem; font: inherit; font-size: 0.9rem; font-weight: 600; cursor: pointer; }
.dispute-withdraw-btn:hover, .dispute-withdraw-btn:focus-visible { border-color: var(--color-orange); }

/* 206-refund-request-case: same pill shape as .return-request-status/
   .dispute-request-status, own class so a future change to one never
   silently reshapes the other. */
.refund-request-status { display: inline-block; padding: 0.15rem 0.6rem; border-radius: 999px; color: #fff; font-weight: 700; font-size: 0.8rem; }
.refund-request-status--pending { background: var(--color-orange); }
.refund-request-status--open { background: var(--color-orange); }
.refund-request-status--awaiting_refund_execution { background: var(--color-teal); }
.refund-request-status--resolved_with_refund { background: var(--color-mint); }
.refund-request-status--resolved_no_refund { background: var(--color-mint); }
.refund-request-status--denied { background: var(--err); }
.refund-request-status--withdrawn_by_buyer { background: var(--muted); }
.refund-request-withdraw-btn { display: inline-flex; align-items: center; justify-content: center; min-height: 2.5rem; background: var(--card); color: var(--text); border: 1px solid var(--color-sage); border-radius: 999px; padding: 0.5rem 0.95rem; font: inherit; font-size: 0.9rem; font-weight: 600; cursor: pointer; }
.refund-request-withdraw-btn:hover, .refund-request-withdraw-btn:focus-visible { border-color: var(--color-orange); }
.refund-request-item-row { display: flex; align-items: center; gap: 0.5rem; margin: 0.4rem 0; }
.refund-request-item-qty { width: 4rem; }
.refund-request-review-row { display: flex; flex-direction: column; gap: 0.35rem; padding: 0.75rem; }
.refund-request-flagged-badge { display: inline-block; padding: 0.15rem 0.6rem; border-radius: 999px; background: var(--err); color: #fff; font-weight: 700; font-size: 0.8rem; }
.refund-request-flagged-badge[hidden] { display: none; }
.refund-request-threads { display: flex; flex-wrap: wrap; gap: 1rem; margin-top: 1rem; }
.refund-request-thread { flex: 1 1 280px; border: 1px solid var(--color-sage); border-radius: 8px; padding: 0.75rem; }
.refund-request-thread-list { list-style: none; margin: 0 0 0.5rem; padding: 0; max-height: 260px; overflow-y: auto; }
.refund-request-thread-list li { padding: 0.35rem 0; border-bottom: 1px solid #eee; }
.refund-request-resolution { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; margin: 0.5rem 0; }
.refund-request-shipment-form { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; margin: 0.35rem 0; width: 100%; }
.dispute-review-row { display: flex; flex-direction: column; gap: 0.35rem; padding: 0.75rem; }
.dispute-evidence { border-top: 1px solid #eee; padding-top: 0.4rem; }
.dispute-review-controls { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
.dispute-decision-btn { display: inline-flex; align-items: center; justify-content: center; min-height: 2.5rem; background: var(--card); color: var(--text); border: 1px solid var(--color-sage); border-radius: 999px; padding: 0.5rem 0.95rem; font: inherit; font-size: 0.9rem; font-weight: 600; cursor: pointer; }
.dispute-decision-btn.is-active { background: var(--color-orange); border-color: var(--color-orange); color: #fff; }
.dispute-review-reason { flex: 1 1 200px; min-width: 160px; }
/* 195-order-cancellation: the cancel row + «Cancelado» chip on
   /my-orders and /my-sales — same row/pill shapes as the 181 dispute
   row above, grey via the existing --muted token so a cancellation
   never reads as a failure (red) or an in-progress state (orange).
   Palette tokens only (Principle VII). */
.order-cancel-row { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
.order-cancel-status { display: inline-block; padding: 0.15rem 0.6rem; border-radius: 999px; color: #fff; font-weight: 700; font-size: 0.8rem; background: var(--muted); }
.order-cancel-btn { display: inline-flex; align-items: center; justify-content: center; min-height: 2.5rem; background: var(--card); color: var(--text); border: 1px solid var(--color-sage); border-radius: 999px; padding: 0.5rem 0.95rem; font: inherit; font-size: 0.9rem; font-weight: 600; cursor: pointer; }
.order-cancel-btn:hover, .order-cancel-btn:focus-visible { border-color: var(--color-orange); }
.order-cancel-confirm { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
.order-cancel-reason { flex: 1 1 200px; min-width: 160px; }
.status-swatch--cancelled { background: var(--muted); }
.order-status-badge--cancelled { background: var(--muted); }
.tabs { display: flex; gap: 0.5rem; margin-bottom: 1rem; border-bottom: 1px solid #e0e0e0; }
.tab-btn { background: none; border: none; padding: 0.6rem 1rem; cursor: pointer; font-weight: 700; color: var(--muted); border-bottom: 2px solid transparent; }
.tab-btn[aria-selected="true"] { color: var(--color-forest); border-bottom-color: var(--color-orange); }
.return-tracking-row { display: flex; flex-direction: column; gap: 0.35rem; padding: 0.75rem; }
.return-tracking-history { margin: 0; padding-left: 1.1rem; font-size: 0.85rem; color: var(--muted); }
.locker-room-list li.status-completed { background: color-mix(in srgb, var(--color-mint) 15%, transparent); }
.locker-room-list li.status-cancelled { background: color-mix(in srgb, var(--muted) 12%, transparent); }
.locker-room-list li.status-failed { background: color-mix(in srgb, var(--err) 12%, transparent); }
.locker-room-list li.status-pending { background: color-mix(in srgb, var(--color-orange) 12%, transparent); }
.locker-room-list li.status-processing { background: color-mix(in srgb, var(--color-orange) 12%, transparent); }
.locker-room-list li.status-shipped { background: color-mix(in srgb, var(--color-status-shipped) 12%, transparent); }
.locker-room-list li.status-delivered { background: color-mix(in srgb, var(--color-mint) 15%, transparent); }
.order-detail-panel { margin-top: 0.75rem; padding-top: 0.75rem; border-top: 1px solid #eee; display: flex; flex-direction: column; gap: 0.4rem; }
.order-detail-panel h4 { margin: 0.4rem 0 0.1rem; font-size: 0.95rem; }
.order-detail-item { display: flex; gap: 0.6rem; align-items: center; }
.order-detail-item p { margin: 0.1rem 0; }
.order-item-photo { width: 3rem; height: 3rem; flex-shrink: 0; border-radius: 6px; object-fit: cover; }
.order-seller-card {
  border: 2px solid var(--text); border-radius: 10px; padding: 0.85rem 1rem; margin: 0.75rem 0;
}
.order-seller-card-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem; margin-bottom: 0.75rem;
}
.order-seller-card-head h4 { margin: 0.15rem 0 0; }
.order-seller-card-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; justify-content: flex-end; }
.order-seller-card-actions .return-request-row,
.order-seller-card-actions .dispute-request-row { margin: 0; }
.order-seller-card-products { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; }
.order-seller-card-items { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 0.45rem; }
.return-request-claimed-amount { margin: 0; font-weight: 700; text-align: right; white-space: nowrap; }
.return-request-items { border: 0; margin: 0 0 1rem; padding: 0; width: 100%; min-width: 0; }
.return-request-items legend { font-weight: 700; margin-bottom: 0.4rem; }
.return-request-items-layout { display: flex; align-items: center; gap: 0.75rem; width: 100%; }
#items-list { list-style: none; margin: 0; padding: 0; flex: 1 1 auto; min-width: 0; }
.return-request-item-row {
  display: flex; align-items: center; gap: 0.75rem; margin: 0.55rem 0; width: 100%;
}
.return-request-item-check-cell { flex: 0 0 auto; max-width: 100px; }
.return-request-item-body {
  flex: 1 1 auto; min-width: 0; width: 100%;
  display: flex; align-items: center; gap: 0.75rem;
}
.return-request-item-info { flex: 1 1 auto; min-width: 0; }
.return-request-item-info p { margin: 0.1rem 0; }
.return-request-item-qty { width: 4.5rem; flex: 0 0 auto; margin-left: auto; }
.return-request-refund-total { font-weight: 700; margin: 0; text-align: right; white-space: nowrap; }
.locker-room-pagination { display: flex; gap: 0.5rem; align-items: center; }
/* 068-tracking-page-seller-ratings: the row(s) a deep link (?order_id= /
   &seller_id=) points at — a ring, not a background swap, so it never
   fights the status tint above. --color-teal is an existing Principle VII
   token (cool accent), not a new hue. */
.locker-room-list li.highlighted { outline: 2px solid var(--color-teal); outline-offset: 2px; }
.tracking-rating { margin-top: 0.5rem; padding-top: 0.5rem; border-top: 1px solid #eee; display: flex; flex-direction: column; gap: 0.4rem; }
.tracking-rating label { display: flex; flex-direction: column; gap: 0.2rem; font-size: 0.9rem; }
.tracking-rating textarea { min-height: 3rem; }
.locker-room-earnings-total { font-size: 1.75rem; font-weight: 700; }
/* 226-seller-stats: summary cards + per-product table on
   /seller-stats. Palette tokens only; layout, no new colors
   (#ddd is the standing field-border gray). */
.stats-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 0.75rem; margin: 1rem 0; }
.stats-card { border: 1px solid #ddd; border-radius: 12px; padding: 0.75rem; text-align: center; }
.stats-card-value { display: block; font-size: 1.4rem; font-weight: 700; }
.stats-card-label { color: var(--color-olive); font-weight: 600; }
.stats-table { width: 100%; border-collapse: collapse; }
.stats-table th, .stats-table td { text-align: left; padding: 0.5rem; border-bottom: 1px solid #ddd; }

/* 057-locker-room-refinements: /saved-cards's first styled table in this
   app (research.md §6) — scoped narrowly, not a shared `.data-table`. */
.saved-cards-table { width: 100%; border-collapse: collapse; }
.saved-cards-table th, .saved-cards-table td { padding: 0.6rem 0.9rem; text-align: left; border-bottom: 1px solid #eee; }
.saved-cards-table thead th { color: var(--muted); font-weight: 600; font-size: 0.85rem; border-bottom: 1px solid #ddd; }

/* 077-i18n-seo-architecture: the localized 404 page's main content. */
.not-found-main { max-width: 32rem; margin: 3rem auto; padding: 0 1.25rem; text-align: center; flex: 1; }
.not-found-main h1 { margin-bottom: 0.5rem; }
.not-found-main p { color: var(--muted); margin-bottom: 1.25rem; }

/* 077-i18n-seo-architecture: the cookie-consent message (FR-006a) and the
   Accept-Language suggestion banner (FR-006) — both fixed to the bottom,
   both using only Principle VII tokens, no new hex values. */
.cookie-consent-banner, .lang-suggestion-banner {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 10;
  background: var(--color-hunter); color: #fff;
  padding: 0.85rem 1.25rem;
  display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center; justify-content: space-between;
}
.lang-suggestion-banner { background: var(--card); color: var(--text); border-top: 1px solid #ddd; }
.cookie-consent-banner__text, .lang-suggestion-banner__text { margin: 0; flex: 1 1 16rem; }
.cookie-consent-banner__actions, .lang-suggestion-banner__actions { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.cookie-consent-banner__accept, .lang-suggestion-banner__switch {
  background: var(--color-orange); color: #fff; border: 0; border-radius: 8px;
  padding: 0.5rem 0.9rem; cursor: pointer;
}
.cookie-consent-banner__accept:hover, .cookie-consent-banner__accept:active,
.lang-suggestion-banner__switch:hover, .lang-suggestion-banner__switch:active { background: var(--color-orange-dark); }
.cookie-consent-banner__decline, .lang-suggestion-banner__dismiss {
  background: transparent; color: inherit; border: 1px solid currentColor; border-radius: 8px;
  padding: 0.5rem 0.9rem; cursor: pointer; opacity: 0.85;
}
.saved-cards-table tbody tr:last-child td { border-bottom: none; }

/* 118-web-push-notifications: Mi Cuenta → Notificaciones. Palette
   tokens only; switches are native checkboxes with an orange
   accent so no new component enters the design system. */
.push-settings-body { background: var(--card); border-radius: 18px; padding: 1rem; }
.push-hint { margin: 0 0 0.75rem; }
.push-device-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.push-device-row[hidden] { display: none; }
.push-device-state { font-weight: 600; }
.push-categories { margin-top: 0.5rem; }
.push-cat-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 0.65rem 0; border-top: 1px solid var(--bg); cursor: pointer; }
.push-cat-name { flex: 1; }
.push-switch { width: 1.35rem; height: 1.35rem; accent-color: var(--color-orange); flex-shrink: 0; }

/* 094-viral-referral-growth: banner, two progress bars, floating toast.
   Brand greens/oranges below use only the Principle VII tokens declared
   at the top of this file.
   128-referral-buttons: the banner CTA and the WhatsApp share button are
   now a matched pair of oval (pill) buttons — the CTA in the primary
   orange, the share button in the brand greens — with soft token-tinted
   shadows (the file's color-mix idiom) and >=48px touch heights.
   Styling only: ids, handlers, hrefs and share text are unchanged. */
.referral-section { margin: 1.25rem 0; }
.referral-banner {
  display: flex; align-items: center; justify-content: center; gap: 0.6rem;
  width: 100%; border: none; border-radius: 999px;
  background: linear-gradient(180deg, var(--color-orange), var(--color-orange-dark));
  color: #fff; font-weight: 800; font-size: 1.1rem; line-height: 1.25;
  min-height: 3.25rem; padding: 0.85rem 1.5rem; cursor: pointer; text-align: center;
  box-shadow: 0 6px 16px color-mix(in srgb, var(--color-orange-dark) 40%, transparent);
  transition: background 0.15s ease, box-shadow 0.15s ease, transform 0.1s ease;
}
.referral-banner:hover {
  box-shadow: 0 8px 20px color-mix(in srgb, var(--color-orange-dark) 50%, transparent);
}
.referral-banner:active {
  background: var(--color-orange-dark); transform: translateY(1px);
  box-shadow: 0 3px 10px color-mix(in srgb, var(--color-orange-dark) 40%, transparent);
}
.referral-details:not([hidden]) { margin-top: 0.75rem; display: flex; flex-direction: column; gap: 0.75rem; }
.referral-whatsapp-btn {
  display: flex; align-items: center; justify-content: center; gap: 0.6rem;
  align-self: stretch; border-radius: 999px;
  background: linear-gradient(180deg, var(--color-forest), var(--color-hunter));
  color: #fff; font-weight: 700; font-size: 1rem; line-height: 1.25;
  min-height: 3rem; padding: 0.8rem 1.4rem; text-decoration: none; text-align: center;
  box-shadow: 0 4px 12px color-mix(in srgb, var(--color-hunter) 35%, transparent);
  transition: background 0.15s ease, box-shadow 0.15s ease, transform 0.1s ease;
}
.referral-whatsapp-btn:hover {
  box-shadow: 0 6px 16px color-mix(in srgb, var(--color-hunter) 45%, transparent);
}
.referral-whatsapp-btn:active {
  background: var(--color-hunter); transform: translateY(1px);
  box-shadow: 0 2px 8px color-mix(in srgb, var(--color-hunter) 35%, transparent);
}
.referral-btn-glyph { font-size: 1.25em; line-height: 1; }
.referral-progress-bar-track {
  width: 100%; height: 0.6rem; border-radius: 999px; background: #e5e7eb; overflow: hidden;
}
.referral-progress-bar-fill {
  height: 100%; background: var(--color-spring); width: 0%; transition: width 0.3s ease;
}
.referral-progress-bar-label { margin: 0.35rem 0 0; font-size: 0.9rem; color: var(--text); }
.referral-sale-bar-label {
  margin: 0; font-size: 0.9rem; color: var(--text); padding-left: 1.4rem; position: relative;
}
.referral-sale-bar-label::before {
  content: ''; position: absolute; left: 0; top: 0.1rem; width: 1rem; height: 1rem;
  border-radius: 50%; border: 2px solid var(--color-grass);
}
.referral-sale-bar[data-done="true"] .referral-sale-bar-label::before {
  background: var(--color-spring); border-color: var(--color-spring);
}
.referral-toast {
  position: fixed; right: 1rem; bottom: 1rem; max-width: 20rem; z-index: 50;
  background: var(--color-hunter); color: #fff; border-radius: 10px;
  padding: 0.85rem 1rem; box-shadow: 0 6px 18px rgba(0, 0, 0, 0.25);
  font-size: 0.9rem; animation: daidar-referral-toast-in 0.25s ease;
}
@keyframes daidar-referral-toast-in { from { opacity: 0; transform: translateY(0.5rem); } to { opacity: 1; transform: translateY(0); } }






/* 118 fix (owner request, 2026-10-23): the Notificaciones header is a
   collapse toggle; the section body starts folded. */
.push-toggle { display: flex; align-items: center; justify-content: space-between; gap: 1rem; width: 100%; padding: 0; border: 0; background: none; font: inherit; color: inherit; text-align: left; cursor: pointer; }
.push-chevron { transition: transform 0.2s ease; }
.push-toggle[aria-expanded="true"] .push-chevron { transform: rotate(180deg); }

/* RESTORE (2026-10-23): the forum sections of specs 107/108/109/116/113/117
   and the seller-chat section of spec 114 were lost from this file in the
   Feat-94 merge (a88b1b75) — production rendered the Comunidad page and the
   chat unstyled. The blocks below are restored verbatim from the last known
   good revision (21bd4e60, spec-117 closure), in their original order.
   Not restored here, pending a decision: the 110-product-share block
   (.product-title-row / .product-share-btn), lost in the same merge. */

/* 107-community-forum: the Comunidad page — Carlos's design: a big
   composer pill, clean stacked post blocks with in-block replies, a
   gray Responder pill and like/share actions on every message. */
.forum-main { max-width: 44rem; margin: 0 auto; padding: 1rem; }
.forum-composer-open { width: 100%; text-align: left; background: var(--surface, #fff); border: 1px solid var(--color-logo); border-radius: 999px; padding: 0.9rem 1.2rem; font-size: 1rem; color: var(--muted); cursor: pointer; }
.forum-composer, .forum-reply-form { margin-top: 0.8rem; }
.forum-composer textarea, .forum-reply-form textarea { width: 100%; box-sizing: border-box; border: 1px solid #ddd; border-radius: 18px; padding: 0.8rem 1rem; font: inherit; resize: vertical; }
.forum-form-actions { display: flex; justify-content: flex-end; gap: 0.5rem; margin-top: 0.5rem; }
/* 213-forum-logo-green: the composer's «Publicar» wears the logo
   green with dark text — fan-zone publishing, not a money action.
   Scoped to .forum-composer: reply forms and every other
   button.primary keep the global orange. */
.forum-composer button.primary { background: var(--color-logo); color: var(--text); }
.forum-error { color: #b00020; margin: 0.4rem 0 0; }
.forum-post { background: var(--surface, #fff); border: 1px solid #e3e3e3; border-radius: 18px; padding: 0.9rem 1rem; margin-top: 1rem; }
.forum-head { display: flex; align-items: center; gap: 0.6rem; }
.forum-avatar { width: 2.4rem; height: 2.4rem; border-radius: 50%; background-size: cover; background-position: center; color: #fff; display: flex; align-items: center; justify-content: center; font-weight: 700; flex: none; }
.forum-avatar.sm { width: 1.8rem; height: 1.8rem; font-size: 0.85rem; }
.forum-who { font-weight: 700; }
.forum-when { color: var(--muted); font-size: 0.85rem; }
.forum-text { margin: 0.6rem 0; white-space: pre-wrap; overflow-wrap: break-word; }
.forum-actions { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.forum-action { background: none; border: 0; color: var(--muted); padding: 0.3rem 0.6rem; font-size: 0.9rem; cursor: pointer; display: inline-flex; gap: 0.3rem; align-items: center; }
.forum-like.liked { color: var(--color-orange); font-weight: 700; }
.forum-reply-btn { background: #eee; color: #333; border: 0; border-radius: 999px; padding: 0.35rem 0.95rem; font-size: 0.9rem; cursor: pointer; }
.forum-replies { margin: 0.6rem 0 0 1.1rem; border-left: 3px solid #eee; padding-left: 0.9rem; }
.forum-reply { padding: 0.55rem 0; }
.forum-reply .forum-text { margin: 0.35rem 0; }
#forum-more { display: block; margin: 2rem auto 0; }
#forum-more[hidden] { display: none; }
.forum-highlight { box-shadow: 0 0 0 3px var(--color-orange); }

/* 108-forum-pack: pinned post, product cards, reports + moderation */
/* 213-forum-logo-green: the pinned ring and its label wear the
   logo green — the community's own marker, not the store's orange. */
.forum-pinned { border-color: var(--color-logo); box-shadow: 0 0 0 2px var(--color-logo); }
.forum-pin-label { display: inline-block; margin: 0 0 0.4rem; font-weight: 700; color: var(--text); background: var(--color-logo); padding: 0.15rem 0.6rem; border-radius: 999px; }
.forum-product-card { display: flex; gap: 0.8rem; align-items: center; border: 1px solid #e3e3e3; border-radius: 18px; padding: 0.6rem; margin: 0.4rem 0 0.6rem; text-decoration: none; color: inherit; }
.forum-product-card img { width: 4rem; height: 4rem; object-fit: cover; border-radius: 12px; flex: none; }
.forum-product-info { display: flex; flex-direction: column; gap: 0.2rem; }
.forum-product-name { font-weight: 700; }
.forum-product-price { font-weight: 700; color: var(--color-hunter); }
.forum-product-wrap { display: block; margin-top: 0.6rem; }
.forum-product-wrap select { display: block; width: 100%; margin-top: 0.3rem; padding: 0.55rem; border: 1px solid #ddd; border-radius: 12px; font: inherit; }
.forum-mod { border: 1px solid var(--color-orange); border-radius: 18px; padding: 0.8rem 1rem; margin-bottom: 1rem; }
.forum-mod h2 { margin: 0 0 0.5rem; font-size: 1.05rem; }
.forum-mod-row { display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; padding: 0.4rem 0; border-top: 1px solid #eee; }
.forum-mod-info { flex: 1 1 12rem; overflow-wrap: break-word; }

/* 109-forum-icons: message actions are social icons, not words.
   The SVGs inherit currentColor; state fills key off the classes
   the JS already toggles. */
.forum-icon { display: inline-flex; }
.forum-icon svg { width: 1.15rem; height: 1.15rem; display: block; }
.forum-actions .forum-action { padding: 0.35rem 0.45rem; }
.forum-like.liked svg { fill: var(--color-orange); }
.forum-report.reported { color: var(--color-orange-dark); }
.forum-report.reported svg { fill: var(--color-orange); color: var(--color-orange); }
.forum-reply-btn .forum-icon svg { width: 1.05rem; height: 1.05rem; }
.forum-reply-btn { padding: 0.35rem 0.6rem; }
.forum-pin { font-size: 1.05rem; line-height: 1; }
.forum-pin-on { opacity: 0.4; }
.forum-action.copied { color: var(--color-forest); }
.forum-mod-row .forum-action { padding: 0.3rem 0.4rem; }
.forum-topbar { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.forum-topbar h1 { margin: 0; }
.forum-share-community { padding: 0.45rem 0.55rem; }
.forum-share-community .forum-icon svg { width: 1.3rem; height: 1.3rem; }
.forum-share-community.copied { color: var(--color-forest); }

/* 116-forum-action-labels: the bar reads like Facebook's — the
   three primary actions carry their full word next to the icon
   and share the row evenly over a thin divider; the contextual
   actions (report, delete, pin) stay icon-only. */
.forum-actions { border-top: 1px solid #eee; padding-top: 0.4rem; }
.forum-actions .forum-action-main { flex: 1 1 0; justify-content: center; font-weight: 600; border-radius: 999px; padding: 0.45rem 0.3rem; }
.forum-actions .forum-action-main:hover { background: #eee; }
.forum-actions .forum-reply-btn { background: none; }
.forum-action-label { white-space: nowrap; }
.forum-actions-side { margin-left: auto; display: inline-flex; align-items: center; gap: 0.25rem; flex: none; }
.forum-actions-side .forum-action { padding: 0.3rem 0.4rem; }

/* 113-forum-thread: a conversation's own page — the back link
   and the server-rendered copy crawlers read. */
.forum-back { display: inline-block; margin: 0 0 1rem; color: var(--color-forest); font-weight: 600; text-decoration: none; }
.forum-ssr-author { margin: 0 0 0.25rem; font-weight: 700; color: var(--color-forest); }
.forum-ssr-product { margin: 0.5rem 0 0; font-weight: 600; }

/* 114-seller-chat */
.chat-bubble { position: fixed; right: 1rem; bottom: 1rem; z-index: 60; width: 56px; height: 56px; border-radius: 999px; border: none; background: var(--color-orange); color: #fff; display: flex; align-items: center; justify-content: center; box-shadow: 0 4px 14px rgba(0,0,0,0.25); cursor: pointer; }
.chat-panel { position: fixed; right: 1rem; bottom: 5.25rem; z-index: 60; width: min(92vw, 350px); max-height: 70vh; display: flex; flex-direction: column; background: #fff; border: 1px solid var(--color-sage); border-radius: 18px; box-shadow: 0 10px 30px rgba(0,0,0,0.22); overflow: hidden; }
.chat-panel[hidden] { display: none; }
.chat-head { display: flex; align-items: center; gap: 0.5rem; padding: 0.6rem 0.75rem; background: var(--color-mint); }
.chat-avatar { width: 34px; height: 34px; border-radius: 999px; background: var(--color-forest); color: #fff; display: inline-flex; align-items: center; justify-content: center; font-weight: 700; font-size: 0.85rem; overflow: hidden; flex: none; }
.chat-avatar img { width: 100%; height: 100%; object-fit: cover; }
.chat-head-text { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.chat-head-name { font-weight: 700; color: var(--color-forest); }
.chat-head-product { font-size: 0.8rem; color: var(--color-olive); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chat-close { background: transparent; border: none; color: var(--color-forest); cursor: pointer; padding: 0.25rem; }
.chat-msgs { padding: 0.75rem; overflow-y: auto; display: flex; flex-direction: column; gap: 0.4rem; min-height: 180px; }
.chat-row { display: flex; }
.chat-row.mine { justify-content: flex-end; }
.chat-bubble-msg { max-width: 80%; padding: 0.45rem 0.7rem; border-radius: 16px; background: var(--color-mint); overflow-wrap: break-word; white-space: pre-wrap; }
.chat-row.mine .chat-bubble-msg { background: var(--color-orange); color: #fff; }
.chat-empty { color: var(--color-olive); text-align: center; margin: 1rem 0; }
.chat-error { color: #b00020; padding: 0 0.75rem; margin: 0.25rem 0; font-size: 0.85rem; }
.chat-seen { text-align: right; font-size: 0.75rem; color: var(--color-olive); margin: 0.1rem 0 0.35rem; }
.chat-form { display: flex; gap: 0.4rem; padding: 0.6rem; border-top: 1px solid var(--color-sage); }
.chat-form input { flex: 1; border: 1px solid var(--color-sage); border-radius: 999px; padding: 0.5rem 0.8rem; min-width: 0; }
.chat-send { width: 38px; height: 38px; border-radius: 999px; border: none; background: var(--color-orange); color: #fff; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; flex: none; }
.chat-list { list-style: none; margin: 0; padding: 0; }
.chat-item-btn { display: flex; align-items: center; gap: 0.6rem; width: 100%; text-align: left; background: transparent; border: none; border-bottom: 1px solid var(--color-sage); padding: 0.6rem 0.25rem; cursor: pointer; }
.chat-item-texts { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.chat-item-name { font-weight: 700; color: var(--color-forest); }
.chat-item-preview { color: var(--color-olive); font-size: 0.85rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chat-item-meta { display: flex; flex-direction: column; align-items: flex-end; gap: 0.25rem; flex: none; }
.chat-item-time { color: var(--color-olive); font-size: 0.75rem; }
.chat-unread { background: var(--color-orange); color: #fff; border-radius: 999px; min-width: 20px; height: 20px; display: inline-flex; align-items: center; justify-content: center; font-size: 0.75rem; font-weight: 700; padding: 0 5px; }
/* 159-message-chat-cleanup: a conversation row is the open button
   plus its own delete control (FR-002), so the <li> carries the
   flex and the divider — the divider moved off .chat-item-btn so
   it spans the delete button too, and the button flexes so the
   preview ellipsis keeps working beside it. The inbox rows' and
   detail panel's delete row (FR-001) sits right-aligned under the
   content. Both controls are the 154 secondary pill (44px)
   itself; these rules only place them. */
.chat-item { display: flex; align-items: center; gap: 0.5rem; border-bottom: 1px solid var(--color-sage); }
.chat-item .chat-item-btn { flex: 1 1 auto; min-width: 0; width: auto; border-bottom: none; }
.message-actions { display: flex; justify-content: flex-end; margin-top: 0.5rem; }
/* 256-messages-row-affordance: on /messages the row chevron sits at
   the far right, and while a message or support thread is open its
   list preview (and, for messages, the row-level delete) steps
   aside: the open panel carries the full body and its own delete,
   so the same text and the same action never show twice. */
#messages-list .chevron { margin-left: auto; flex-shrink: 0; color: var(--color-pitch); font-size: 1.5rem; font-weight: 700; line-height: 1; }
#messages-list li.message-open > .message-preview,
#messages-list li.message-open > .message-actions { display: none; }
.chat-thread-head { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.5rem; }
.chat-back { background: transparent; border: 1px solid var(--color-sage); border-radius: 999px; width: 34px; height: 34px; display: inline-flex; align-items: center; justify-content: center; color: var(--color-forest); cursor: pointer; flex: none; }
.chat-thread-msgs { border: 1px solid var(--color-sage); border-radius: 18px; min-height: 220px; max-height: 50vh; }
#chat-thread .chat-form { border-top: none; padding-left: 0; padding-right: 0; }

/* 117-forum-reply-to: the addressee line above a reply that
   answers another reply ("En respuesta a @…") — muted like the
   forum's timestamps; the thread stays flat (Facebook model).
   Comentar now lives on every message; no other restyle. */
.forum-reply-to { margin: 0.35rem 0 0; color: var(--muted); font-size: 0.85rem; }

/* 136-forum-polls: one poll per top-level post — tappable
   option rows while open, a result bar behind each label
   once results show (voted / closed / guest). Brand color
   is palette-only: the mint fill, orange for my own choice
   (the liked-heart accent); tracks and borders are the
   forum's own neutrals. The composer editor mirrors the
   reply form's pill inputs. */
.forum-poll { margin: 0.6rem 0; display: flex; flex-direction: column; gap: 0.4rem; }
.forum-poll-option { position: relative; display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; width: 100%; box-sizing: border-box; border: 1px solid #ddd; border-radius: 12px; padding: 0.55rem 0.8rem; background: #fff; color: inherit; font: inherit; text-align: left; overflow: hidden; }
button.forum-poll-option { cursor: pointer; }
.forum-poll-option.mine { border-color: var(--color-orange); }
.forum-poll-bar { position: absolute; top: 0; bottom: 0; left: 0; background: var(--color-mint); opacity: 0.45; }
.forum-poll-option.mine .forum-poll-bar { background: var(--color-orange); opacity: 0.35; }
.forum-poll-label { position: relative; font-weight: 600; overflow-wrap: break-word; }
.forum-poll-count { position: relative; color: var(--muted); font-size: 0.9rem; white-space: nowrap; }
.forum-poll-closed { align-self: flex-start; margin: 0; background: #eee; color: var(--muted); border-radius: 999px; padding: 0.15rem 0.6rem; font-size: 0.85rem; font-weight: 600; }
.forum-poll-foot { display: flex; align-items: center; gap: 0.8rem; }
.forum-poll-total { color: var(--muted); font-size: 0.9rem; }
.forum-poll-editor { margin-top: 0.6rem; display: flex; flex-direction: column; gap: 0.4rem; align-items: flex-start; }
.forum-poll-editor[hidden] { display: none; }
#forum-poll-options { display: flex; flex-direction: column; gap: 0.4rem; width: 100%; }
.forum-poll-row { display: flex; gap: 0.4rem; width: 100%; }
.forum-poll-row input { flex: 1; min-width: 0; border: 1px solid #ddd; border-radius: 12px; padding: 0.55rem 0.8rem; font: inherit; }
.forum-poll-remove { background: #eee; color: #333; border: 0; border-radius: 999px; padding: 0.35rem 0.7rem; font-size: 0.9rem; cursor: pointer; }

/* RESTORE addendum (2026-10-23): the 110-product-share block flagged as
   pending in the RESTORE note above is restored here too, verbatim from
   the same revision (21bd4e60), after the owner approved it after all.
   Its rules are unique to the product page, so appending at the end is safe. */
/* 110-product-share: the article's share icon at the title's
   right edge (109's pattern, commerce edition). */
.product-title-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem; }
.product-share-btn { background: none; border: none; color: var(--muted); cursor: pointer; padding: 0.45rem 0.55rem; margin-top: 0.35rem; flex: none; }
.product-share-btn svg { width: 1.3rem; height: 1.3rem; display: block; }
.product-share-btn.copied { color: var(--color-forest); }

/* 197-product-report-button: the Report action beside Share, its
   dialog (the [data-leave-dialog] overlay pattern, palette vars
   only), the /ip-report form bits and the admin view's Reports
   block. */
.product-report-btn { background: none; border: none; color: var(--muted); cursor: pointer; padding: 0.45rem 0.55rem; margin-top: 0.35rem; flex: none; display: inline-flex; align-items: center; gap: 0.3rem; font: inherit; font-size: 0.85rem; }
.product-report-btn svg { width: 1.05rem; height: 1.05rem; display: block; }
.product-report-btn.reported { color: var(--color-forest); }
.report-dialog { position: fixed; inset: 0; z-index: 40; display: flex; align-items: center; justify-content: center; background: rgba(0, 0, 0, 0.35); }
.report-dialog[hidden] { display: none; }
.report-box { background: var(--card); border-radius: 12px; padding: 1.25rem 1.35rem; max-width: 24rem; width: calc(100% - 2rem); max-height: 90vh; overflow-y: auto; box-shadow: 0 12px 32px rgba(0, 0, 0, 0.18); }
.report-box h2 { margin-top: 0; font-size: 1.1rem; }
.report-reasons { border: 0; padding: 0; margin: 0 0 0.75rem; display: flex; flex-direction: column; gap: 0.35rem; }
.report-reasons legend { font-weight: 600; margin-bottom: 0.4rem; padding: 0; }
.report-reasons label { display: flex; gap: 0.45rem; align-items: center; cursor: pointer; }
.report-box textarea { width: 100%; box-sizing: border-box; font: inherit; }
.report-actions { display: flex; justify-content: space-between; align-items: center; gap: 0.75rem; margin-top: 1rem; flex-wrap: wrap; }
.report-actions-buttons { display: inline-flex; gap: 0.5rem; }
.ip-report-form .good-faith { display: flex; gap: 0.5rem; align-items: flex-start; margin: 0.75rem 0; cursor: pointer; }
.ip-report-honeypot { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.admin-reports { margin-top: 1.5rem; }
.admin-report { border: 1px solid #e3e3e3; border-radius: 12px; padding: 0.75rem 1rem; margin-top: 0.75rem; }
.admin-report-head { display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; }
.admin-report-badge { background: var(--color-hunter); color: #fff; border-radius: 999px; padding: 0.1rem 0.55rem; font-size: 0.78rem; font-weight: 600; }
.admin-report-badge--brand { background: var(--color-orange-dark); }
.admin-report-status { color: var(--muted); font-size: 0.85rem; }
.admin-report-note { margin: 0.4rem 0 0; }
.admin-report-product { margin: 0.4rem 0 0; font-weight: 600; }
.admin-report-meta { color: var(--muted); font-size: 0.85rem; margin: 0.4rem 0 0; }
.admin-report-actions { display: flex; gap: 0.5rem; margin-top: 0.6rem; }

/* 124-buyer-offers: the offer box on the product page, the sent-offers
   list in My Account and the received-offers block in My Sales.
   Palette tokens only; the primary action (send / accept) is a
   .primary button, --color-orange like every primary on the site. */
.offer-box { margin-top: 1rem; }
.offer-box > button { border: 1px solid var(--color-orange); background: var(--card); color: var(--color-orange-dark); border-radius: 999px; padding: 0.55rem 1.1rem; font-weight: 700; cursor: pointer; /* 154: Normal level */ min-height: 2.75rem; }
.offer-form { margin-top: 0.75rem; }
.offer-form label { display: block; font-weight: 600; margin-bottom: 0.35rem; color: var(--color-forest); }
.offer-form-row { display: flex; gap: 0.5rem; align-items: center; }
.offer-form-row input { flex: 1; min-width: 0; padding: 0.55rem 0.7rem; border: 1px solid var(--color-sage); border-radius: 10px; }
.offer-active { margin-top: 0.75rem; padding: 0.6rem 0.8rem; border: 1px solid var(--color-sage); border-radius: 10px; color: var(--color-hunter); background: var(--bg); font-weight: 600; }
.offer-entry { display: flex; flex-direction: column; gap: 0.5rem; }
.offer-entry-product { font-weight: 700; color: var(--color-forest); }
.offer-entry-meta { margin: 0.15rem 0 0; color: var(--muted); }
.offer-code-box { display: flex; flex-direction: column; gap: 0.25rem; }
.offer-code { align-self: flex-start; font-weight: 800; letter-spacing: 0.04em; border: 1px dashed var(--color-orange); border-radius: 8px; padding: 0.3rem 0.6rem; color: var(--color-orange-dark); }
.offer-code-hint { margin: 0; color: var(--muted); font-size: 0.85rem; }
#offers-received-section { border: 1px solid var(--color-sage); border-radius: 14px; padding: 0.9rem 1rem; margin-bottom: 1.25rem; }
#offers-received-section h2 { margin-top: 0; color: var(--color-forest); }
.offer-received-item { padding: 0.6rem 0; border-bottom: 1px solid var(--color-sage); }
.offer-received-item:last-child { border-bottom: none; }
.offer-received-title { margin: 0; font-weight: 700; }
.offer-received-title a { color: var(--color-forest); }
.offer-received-amount { color: var(--color-orange-dark); }
.offer-received-meta { margin: 0.2rem 0 0; color: var(--muted); font-size: 0.9rem; }
.offer-received-actions { display: flex; gap: 0.5rem; margin-top: 0.55rem; }
.offer-received-actions button:not(.primary) { border: 1px solid var(--color-sage); background: var(--card); border-radius: 999px; padding: 0.45rem 1rem; font-weight: 700; cursor: pointer; /* 154: Normal level */ min-height: 2.75rem; }
#coupons-assigned-section { border: 1px solid var(--color-sage); border-radius: 14px; padding: 0.9rem 1rem; margin-bottom: 1.25rem; }
#coupons-assigned-section h2 { margin-top: 0; color: var(--color-forest); }
.coupon-assigned-item { padding: 0.6rem 0; border-bottom: 1px solid var(--color-sage); }
.coupon-assigned-item:last-child { border-bottom: none; }
.coupon-assigned-title { margin: 0; font-weight: 700; }
.coupon-assigned-code { font-weight: 800; letter-spacing: 0.04em; color: var(--color-orange-dark); }
.coupon-assigned-meta { margin: 0.2rem 0 0; color: var(--muted); font-size: 0.9rem; }
.coupon-assigned-actions { display: flex; gap: 0.5rem; margin-top: 0.55rem; }
.coupon-assigned-actions button { border: 1px solid var(--color-sage); background: var(--card); border-radius: 999px; padding: 0.45rem 1rem; font-weight: 700; cursor: pointer; /* 154: Normal level */ min-height: 2.75rem; }

/* 129-featured-products: the featured badge. On buyer cards
   (home.js, inside .product which is position:relative) it overlays
   the photo's top-left — the favorite heart owns the top-right. On
   the product page the --static variant sits inline above the title.
   The seller-side chip and tier picker live on the inventory cards
   (products.js). Palette tokens only; the badge is a label, never a
   control.
   204-featured-star-badge: the pill is now a star-only circle —
   the owner's call after seeing the mockup on his own catalog
   («Estrella sola en todas partes»). Diameter = the pill's height;
   the word survives only as the element's aria-label / title
   (the featured_badge key), never as visible text. */
.featured-badge { position: absolute; top: 1.5rem; left: 1.5rem; z-index: 1; background: var(--color-orange); color: #fff; border-radius: 50%; width: 1.8rem; height: 1.8rem; padding: 0; display: flex; align-items: center; justify-content: center; font-size: 1rem; line-height: 1; }
.featured-badge--static { position: static; display: inline-flex; margin-bottom: 0.4rem; }
.featured-badge[hidden] { display: none; }
.featured-chip { margin: 0.35rem 0 0; font-weight: 700; color: var(--color-orange-dark); }
.promo-picker { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; margin-top: 0.55rem; }
.promo-picker[hidden] { display: none; }
.promo-picker-title { flex-basis: 100%; margin: 0; font-weight: 700; color: var(--color-forest); }
.promo-picker button { border: 1px solid var(--color-sage); background: var(--card); border-radius: 999px; padding: 0.45rem 1rem; font-weight: 700; cursor: pointer; /* 154: Normal level */ min-height: 2.75rem; }
.promo-picker button.primary { background: var(--color-orange); border-color: var(--color-orange); color: #fff; }

/* 137-forum-photos: attached photos under a forum message's
   text, and the photo row in the composer / reply forms. The
   staging tray reuses .media-list / .media-thumb above.
   Layout only — no color values. */
.forum-media { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0.4rem 0 0.6rem; }
.forum-media a { flex: 1 1 10rem; max-width: 100%; }
.forum-media img { display: block; width: 100%; height: 100%; max-height: 24rem; object-fit: cover; border-radius: 12px; }
.forum-photo-row { display: flex; align-items: center; gap: 0.6rem; margin-top: 0.6rem; }

/* 138-poll-share-vote: the public poll page — a voting
   landing, not a thread clone. The poll block itself reuses
   the 136 classes; this block is the page frame: the back
   link, the question at reading size, the author line and
   the registration invitation card. Palette tokens only. */
.poll-main { max-width: 44rem; margin: 0 auto; padding: 1rem; }
.poll-back { display: inline-block; margin-bottom: 0.8rem; color: var(--color-forest); font-weight: 700; text-decoration: none; }
.poll-card { background: var(--card); border-radius: 12px; padding: 1rem; }
.poll-author { margin: 0 0 0.4rem; font-weight: 700; color: var(--color-hunter); }
.poll-dot { color: var(--muted); }
.poll-question { margin: 0 0 0.6rem; font-size: 1.45rem; line-height: 1.3; overflow-wrap: break-word; }
.poll-cta { margin-top: 1rem; background: var(--card); border: 1px solid var(--color-sage); border-radius: 12px; padding: 1rem; text-align: center; }
.poll-cta p { margin: 0 0 0.7rem; font-weight: 600; }
.poll-cta-btn { display: inline-flex; align-items: center; justify-content: center; min-height: 3rem; /* 154: Principal level */ background: var(--color-orange); color: #fff; font-weight: 700; text-decoration: none; border-radius: 999px; padding: 0.6rem 1.4rem; }
.poll-cta-btn:hover, .poll-cta-btn:active { background: var(--color-orange-dark); }
.poll-thread-wrap { margin-top: 1rem; text-align: center; }
.poll-thread-wrap a { color: var(--color-forest); font-weight: 700; }

/* 140-sellers-landing: the campaign-only sellers landing —
   a marketing page, not a marketplace screen: a dark hero
   with the campaign video, three steps, a trust strip and
   the slogan close. Palette tokens only; the CTAs are
   primary anchors (--color-orange / --color-orange-dark,
   Principle VII). */
.sellers-main { max-width: 64rem; margin: 0 auto; padding: 1rem; width: 100%; }
.sellers-hero { display: flex; flex-wrap: wrap; gap: 1.5rem; align-items: center; background: var(--color-hunter); border-radius: 16px; padding: 1.5rem; }
.sellers-hero-text { flex: 1 1 18rem; }
.sellers-title { color: #fff; font-size: 1.8rem; line-height: 1.25; margin: 0 0 0.8rem; }
.sellers-sub { color: var(--color-mint); font-size: 1.05rem; margin: 0 0 1.2rem; }
.sellers-cta { display: inline-flex; align-items: center; justify-content: center; min-height: 3rem; /* 154: Principal level */ background: var(--color-orange); color: #fff; font-weight: 700; text-decoration: none; border-radius: 999px; padding: 0.7rem 1.6rem; }
.sellers-cta:hover, .sellers-cta:active { background: var(--color-orange-dark); }
.sellers-hero-media { flex: 0 1 16rem; margin: 0 auto; width: 100%; }
.sellers-video { display: block; width: 100%; max-height: 30rem; border-radius: 12px; background: var(--text); object-fit: cover; }
.sellers-steps { margin-top: 2rem; }
.sellers-steps h2 { color: var(--color-hunter); text-align: center; margin: 0 0 1rem; }
.sellers-step-list { display: flex; flex-wrap: wrap; gap: 1rem; list-style: none; margin: 0; padding: 0; }
.sellers-step { flex: 1 1 14rem; background: var(--card); border-radius: 12px; padding: 1rem; }
.sellers-step-num { display: inline-flex; align-items: center; justify-content: center; width: 2rem; height: 2rem; border-radius: 50%; background: var(--color-grass); color: #fff; font-weight: 700; }
.sellers-step h3 { margin: 0.6rem 0 0.4rem; color: var(--color-hunter); }
.sellers-step p { margin: 0; color: var(--muted); }
.sellers-trust { display: flex; flex-wrap: wrap; gap: 0.6rem; justify-content: center; margin-top: 1.5rem; }
.sellers-trust p { margin: 0; background: var(--color-mint); color: var(--color-hunter); font-weight: 700; border-radius: 999px; padding: 0.45rem 1rem; }
.sellers-close { margin-top: 2rem; text-align: center; background: var(--card); border: 1px solid var(--color-sage); border-radius: 12px; padding: 1.5rem 1rem; }
.sellers-close h2 { color: var(--color-forest); margin: 0 0 0.6rem; }
.sellers-close p { color: var(--muted); margin: 0 0 1.1rem; }

/* 145-protected-purchase: the «Compra Protegida» badge. One static
   component reused on the product page, the cart totals aside and
   the payment form: a shield seal, the protection's name, a
   one-line explanation and a native <details> expander linking to
   the standing legal pages. Token-only colors (Principle VII);
   the check is stroked in neutral white, the one allowed neutral. */
.protected-badge { display: flex; gap: 0.6rem; align-items: flex-start; margin-top: 0.9rem; padding: 0.7rem 0.85rem; border: 1px solid var(--color-sage); border-radius: 12px; background: color-mix(in srgb, var(--color-sage) 14%, #fff); text-align: left; }
.protected-badge-icon { flex: 0 0 auto; margin-top: 0.1rem; }
.protected-badge-shield { fill: var(--color-forest); }
.protected-badge-body { min-width: 0; }
.protected-badge-line { margin: 0; font-size: 0.92rem; }
.protected-badge-line strong { color: var(--color-hunter); }
.protected-badge-details { margin-top: 0.3rem; font-size: 0.88rem; }
.protected-badge-details summary { color: var(--color-teal); font-weight: 600; cursor: pointer; }
.protected-badge-details p { margin: 0.45rem 0 0; }
.protected-badge-links a { color: var(--color-teal); font-weight: 600; }

/* 148-sellers-numbers: the landing answers «how much do I
   earn, and when do I get paid?» — a net-earnings calculator
   (its math ports CartChargeController's charge split), the
   five-step payout timeline and the objection FAQ. Only the
   landing's existing tokens; the timeline reuses .sellers-step
   and .sellers-step-num for its cards. */
.sellers-calc { margin-top: 2rem; }
.sellers-calc h2 { color: var(--color-hunter); text-align: center; margin: 0 0 1rem; }
.sellers-calc-card { background: var(--card); border: 1px solid var(--color-sage); border-radius: 12px; padding: 1rem; max-width: 34rem; margin: 0 auto; }
.sellers-calc-label { display: block; font-weight: 700; color: var(--color-hunter); margin-bottom: 0.4rem; }
.sellers-calc-input { width: 100%; box-sizing: border-box; font-size: 1.15rem; font-weight: 700; color: var(--text); padding: 0.55rem 0.7rem; border: 1px solid var(--color-sage); border-radius: 8px; margin-bottom: 0.9rem; }
.sellers-calc-rows { margin: 0; }
.sellers-calc-row { display: flex; justify-content: space-between; gap: 1rem; padding: 0.35rem 0; }
.sellers-calc-row dt { color: var(--muted); }
.sellers-calc-row dd { margin: 0; font-weight: 600; color: var(--text); white-space: nowrap; }
.sellers-calc-net { border-top: 2px solid var(--color-sage); margin-top: 0.4rem; padding-top: 0.6rem; }
.sellers-calc-net dt { color: var(--color-hunter); font-weight: 700; }
.sellers-calc-net dd { color: var(--color-forest); font-size: 1.2rem; font-weight: 800; }
.sellers-calc-note { margin: 0.8rem 0 0; font-size: 0.88rem; color: var(--muted); }
.sellers-proof { text-align: center; color: var(--color-hunter); font-weight: 600; margin: 1rem auto 0; max-width: 34rem; }
.sellers-timeline { margin-top: 2rem; }
.sellers-timeline h2 { color: var(--color-hunter); text-align: center; margin: 0 0 1rem; }
.sellers-timeline-list { display: flex; flex-wrap: wrap; gap: 1rem; list-style: none; margin: 0; padding: 0; }
.sellers-timeline-list .sellers-step { flex: 1 1 10rem; }
.sellers-faq { margin-top: 2rem; max-width: 44rem; margin-left: auto; margin-right: auto; }
.sellers-faq h2 { color: var(--color-hunter); text-align: center; margin: 0 0 1rem; }
.sellers-faq-item { background: var(--card); border: 1px solid var(--color-sage); border-radius: 12px; padding: 0.8rem 1rem; margin-bottom: 0.6rem; }
.sellers-faq-item summary { color: var(--color-hunter); font-weight: 700; cursor: pointer; }
.sellers-faq-item p { margin: 0.5rem 0 0; color: var(--muted); }

/* 150-express-checkout: the Express Checkout Element's
   section above the card form on the payment page. The
   section stays hidden until Stripe reports an available
   wallet, so these rules only ever style a section the
   buyer can actually use. Palette/neutral tokens only —
   the wallet buttons inside are rendered by Stripe and
   the wallets with their own mandated branding. */
.express-checkout { margin-top: 1rem; }
.express-checkout[hidden] { display: none; }
.express-checkout-heading { margin: 0 0 0.6rem; text-align: center; font-weight: 700; color: var(--color-hunter); }
.express-checkout-or { display: flex; align-items: center; gap: 0.75rem; margin: 0.9rem 0 0; color: var(--muted); font-size: 0.9rem; }
.express-checkout-or::before,
.express-checkout-or::after { content: ''; flex: 1; border-top: 1px solid var(--color-sage); }
.express-checkout-or span { white-space: nowrap; }

/* 151-interest-into-sales: the «avísame si entra» box under a
   zero-result search (home) and the guest note on the
   favorites page. Palette tokens only (constitution: the
   closed --color-* set + the legacy layout vars the file
   already uses). */
.search-alert { background: var(--card); border: 1px solid var(--color-sage); border-radius: 12px; padding: 0.9rem 1rem; margin: 0.8rem 0; max-width: 34rem; }
.search-alert-prompt { margin: 0 0 0.6rem; color: var(--text); }
.search-alert-email-row { margin: 0 0 0.6rem; }
.search-alert-email-row input { width: 100%; box-sizing: border-box; padding: 0.5rem 0.6rem; border: 1px solid var(--color-sage); border-radius: 8px; color: var(--text); }
.search-alert-done { margin: 0; color: var(--color-hunter); font-weight: 600; }

/* 152-categories-about-polish: the /categories index cards
   and the /about sections. Both pages are static content in
   the sellers page's shape; the step cards themselves are
   the standing .sellers-step rules above. Palette and
   neutral tokens only (Principle VII). */
.categories-main, .about-main { max-width: 64rem; margin: 0 auto; padding: 1rem; width: 100%; }
.categories-intro, .about-intro { color: var(--muted); max-width: 44rem; }
.categories-grid { display: flex; flex-wrap: wrap; gap: 1rem; list-style: none; margin: 1.5rem 0 0; padding: 0; }
.categories-grid > li { flex: 1 1 14rem; display: flex; }
.categories-card { flex: 1; display: block; background: var(--card); border: 1px solid var(--color-sage); border-radius: 12px; padding: 1rem; text-decoration: none; color: inherit; }
.categories-card h2 { margin: 0 0 0.4rem; color: var(--color-hunter); font-size: 1.1rem; }
.categories-card p { margin: 0; color: var(--muted); }
.categories-about { margin-top: 1.5rem; text-align: center; }
.about-slogan { text-align: center; color: var(--color-forest); font-size: 1.3rem; font-weight: 700; margin: 1.5rem 0 0; }
.about-section { margin-top: 2rem; }
.about-section h2 { color: var(--color-hunter); text-align: center; margin: 0 0 1rem; }
.about-sell-text { color: var(--muted); max-width: 44rem; margin: 0 auto; text-align: center; }
.about-links { display: flex; flex-wrap: wrap; gap: 0.75rem; justify-content: center; margin-top: 1.5rem; }
.about-cta { display: inline-flex; align-items: center; justify-content: center; min-height: 3rem; /* 154: Principal level */ background: var(--color-orange); color: #fff; font-weight: 700; text-decoration: none; border-radius: 999px; padding: 0.7rem 1.6rem; }
.about-cta:hover, .about-cta:active { background: var(--color-orange-dark); }
.about-main .protected-badge { max-width: 44rem; margin: 0 auto; }

/* 154-button-text-scale: the button & text-action scale. Root
   cause (audit, specs/154-button-text-scale): this stylesheet
   never had a global rule for content links or a base rule for
   <button>, so every action created without a component class
   fell back to the browser — rgb(0,0,238) underlined links and
   #EFEFEF buttons 21px tall. This block names the missing
   components once, gives real rules to the classes that never
   had any, and is applied (via class assignments in JS/HTML)
   to the 24 inventoried blue actions and their grey-button
   family. Levels: Principal >=48px (button.primary, raised
   above), Normal >=44px, Compacto >=40px (dense rows only),
   text actions in hunter green with a >=44px tap area (the
   .link-btn treatment). Palette tokens only; the file's single
   status-only blue token stays reserved for its shipment-status
   dot and is never used here. */

/* Normal — a card's main action: the primary pill at 44px. */
.btn-main {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 2.75rem; background: var(--color-orange); color: #fff;
  border: 0; border-radius: 999px; padding: 0.65rem 1.15rem;
  font-size: 0.95rem; font-weight: 600; cursor: pointer; text-decoration: none;
}
.btn-main:hover, .btn-main:active { background: var(--color-orange-dark); }

/* Normal — the secondary pill (the .offer-received-actions /
   .promo-picker pattern, named once): white, --color-sage
   border, 44px. The order detail's two actions carried the
   phantom classes .return-request-link / .track-shipment-link
   with no rules at all; they are this pill now. */
.btn-secondary,
.return-request-link,
.dispute-request-link,
.refund-request-link,
.track-shipment-link {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 2.75rem; background: var(--card); color: var(--text);
  border: 1px solid var(--color-sage); border-radius: 999px;
  padding: 0.65rem 1.05rem; font: inherit; font-size: 0.95rem; font-weight: 600;
  cursor: pointer; text-decoration: none;
}
.btn-secondary:hover, .btn-secondary:focus-visible,
.return-request-link:hover, .return-request-link:focus-visible,
.dispute-request-link:hover, .dispute-request-link:focus-visible,
.refund-request-link:hover, .refund-request-link:focus-visible,
.track-shipment-link:hover, .track-shipment-link:focus-visible {
  border-color: var(--color-orange);
}

/* Normal — «Cambiar dirección» in the cart's shipping summary,
   drawn like its sibling .cart-page-secondary-btn (the «Añadir
   dirección» button), which it never matched before. */
#cart-change-address-link {
  display: inline-flex; align-items: center; min-height: 2.75rem;
  padding: 0.55rem 1rem; border-radius: 8px; cursor: pointer;
  background: #fff; border: 1px solid #c5c5c5; color: var(--text);
  text-decoration: none; font-weight: 600;
}

/* Compacto — dense rows and tables (admin lists, saved cards,
   support): the same secondary pill at 40px, plus its orange
   main variant. The saved-cards classes (.delete-btn,
   .confirm-delete-btn, .cancel-delete-btn) and the support
   .grant-full-name-btn were phantom classes with no rules;
   they are this pill now. */
.btn-compact,
.delete-btn,
.confirm-delete-btn,
.cancel-delete-btn,
.grant-full-name-btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 2.5rem; background: var(--card); color: var(--text);
  border: 1px solid var(--color-sage); border-radius: 999px;
  padding: 0.5rem 0.95rem; font: inherit; font-size: 0.9rem; font-weight: 600;
  cursor: pointer; text-decoration: none;
}
.btn-compact:hover, .btn-compact:focus-visible,
.delete-btn:hover, .delete-btn:focus-visible,
.confirm-delete-btn:hover, .confirm-delete-btn:focus-visible,
.cancel-delete-btn:hover, .cancel-delete-btn:focus-visible,
.grant-full-name-btn:hover, .grant-full-name-btn:focus-visible {
  border-color: var(--color-orange);
}
.btn-compact-main {
  background: var(--color-orange); border-color: var(--color-orange); color: #fff;
}
.btn-compact-main:hover, .btn-compact-main:focus-visible {
  background: var(--color-orange-dark); border-color: var(--color-orange-dark);
}

/* Text action — secondary actions that stay text: the .link-btn
   treatment (hunter green, underlined) with vertical padding
   up to a >=44px tap area. The «ver fallidos» toggles carried
   the phantom ids #orders-view-toggle / #sales-view-toggle
   with no rules; they are this action now. */
.link-action,
#orders-view-toggle,
#sales-view-toggle {
  display: inline-block; padding: 0.78rem 0.25rem; min-height: 2.75rem;
  color: var(--color-hunter); text-decoration: underline;
  font-weight: 600; font-size: 0.95rem; cursor: pointer;
}

/* The product form's round icon buttons (photo × and ✎ on the
   media thumbs, the variant rows' ✎/×, the variant photo's ×)
   are drawn at 1.4rem by design — they overlay the photos.
   Their tap area grows to 44px invisibly instead. */
.media-thumb button,
.variant-photo-thumb button { position: absolute; }
.variant-row-actions button { position: relative; }
.media-thumb button::after,
.variant-photo-thumb button::after,
.variant-row-actions button::after {
  content: ''; position: absolute; left: 50%; top: 50%;
  width: 2.75rem; height: 2.75rem; transform: translate(-50%, -50%);
}

/* 171-search-bar-compact: the Home search row leaves the
   Principal tier. Spec 154 raised every button.primary to
   >=48px, and this flex row inherited that height: the
   input and the two side buttons stretch to the submit's
   48px, so the row read as three main CTAs competing with
   the products below it. The owner's decision (2026-10-25,
   A/B mockup built from the real home, option B): the
   whole row drops to the scale's own Normal tier — exactly
   44px (2.75rem), the .btn-main / .btn-secondary height —
   «Buscar» keeps the primary orange, and «Filtros» goes
   quiet: white fill, its existing neutral border, and a
   small sliders icon before its label. Scoped to
   .search-bar (the row exists only on the home):
   button.primary everywhere else keeps the Principal
   48px, and the header's «Vender» (.sell-btn) is
   untouched. The icon is a ::before alpha mask filled
   with currentColor — no raw hex (Principle VII) and no
   markup, because i18n.js replaces the textContent of
   [data-i18n] elements and would delete an inline SVG
   child of #filters-toggle the moment a language pack
   applies. */
.search-bar input[type="search"],
.search-bar button.primary,
.search-bar #filters-toggle,
.search-bar #search-clear {
  height: 2.75rem; min-height: 2.75rem;
}
.search-bar #filters-toggle {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.45rem;
  background: var(--card);
}
/* 208-filters-toggle-footer-green: the Filters toggle wears the
   footer's green (the owner's pick over black and over the
   header's hunter). Filled --color-pine with white text; the
   ::before icon is a currentColor mask, so it turns white with
   the text — no markup or icon change. The border takes the
   same green so no grey rim survives. Scoped to #filters-toggle:
   #search-clear keeps its quiet outline. */
.search-bar #filters-toggle {
  background: var(--color-pine);
  border-color: var(--color-pine);
  color: #fff;
}
.search-bar #filters-toggle::before {
  content: ''; flex: 0 0 auto; width: 1rem; height: 1rem;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M3 6h18M3 12h18M3 18h18'/%3E%3Ccircle cx='9' cy='6' r='2.4'/%3E%3Ccircle cx='15' cy='12' r='2.4'/%3E%3Ccircle cx='7' cy='18' r='2.4'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M3 6h18M3 12h18M3 18h18'/%3E%3Ccircle cx='9' cy='6' r='2.4'/%3E%3Ccircle cx='15' cy='12' r='2.4'/%3E%3Ccircle cx='7' cy='18' r='2.4'/%3E%3C/svg%3E") center / contain no-repeat;
}
/* 211-search-button-pine: the home «Buscar» submit joins
   «Filtros» in --color-pine (spec 208's footer token), so the
   whole search zone wears the serious green-black of the
   logo and the palette orange concentrates in the header
   (207 wordmark, 209 cart, «Vender»). The owner's call after
   reviewing mockups on his own screenshot: «Hagámoslo así, le
   viene mejor al logo» — and the same evening he kept
   «Vender» orange on purpose. Scoped to .search-bar:
   button.primary everywhere else (auth, checkout, product)
   keeps the primary orange; #search-clear keeps its quiet
   outline. Supersedes spec 171's «Buscar keeps the primary
   orange» for this row only. The white label already comes
   from the base button.primary rule. */
.search-bar button.primary {
  background: var(--color-pine);
  border-color: var(--color-pine);
}

/* 214-search-border-logo-green: the home search field's frame
   wears the logo green (owner, on his own annotated screenshot:
   «¿Y si lo ponemos en el borde de buscar?» — mockup approved
   «Hazlo»). A frame, not a fill: no text sits on it, and it
   pairs with 211's pine «Buscar» beside it. The field's border
   comes from the global input rule; this scoped rule recolours
   and weights it to match the approved mockup. --color-logo
   (213) gains its second home: the two places you write —
   search, and publish in the Comunidad.
   215-search-border-1px: hours later the owner, after an
   A/B mockup on his own screenshot, thinned the frame to
   1px («Hazlo: deja el marco en 1px») — the connection to
   the logo stays; the frame stops competing with the
   product cards. */
.search-bar input[type="search"] {
  border: 1px solid var(--color-logo);
}

/* 238-search-focus-ring: on focus, the home search
   field gains the soft light-blue halo the owner saw
   — and liked — in Safari's native focus glow on his
   own screenshot («Me gusta ese azulito del
   buscador», approved «Hazlo» on 2026-10-30), made
   deliberate so every browser paints the same ring.
   The 214/215 logo-green 1px frame stays exactly as
   it is; the halo sits OUTSIDE it as a box-shadow, so
   nothing moves — a shadow paints beyond the border
   without touching the box geometry, and the border
   width never changes on focus. The browser's own
   outline is suppressed so the field wears one clean
   ring, and the ring IS the focus indicator. The
   unfocused field is untouched. Scoped to .search-bar,
   which exists only on the home (171), so no other
   form field gains the ring. */
.search-bar input[type="search"]:focus,
.search-bar input[type="search"]:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--color-sky);
}

/* 173-referidos-visibilidad: the referral share card at the
   key moments (welcome after registration, first product,
   first sale) and Mi Cuenta's at-a-glance layer — the banner
   summary line inside the 094/128 pill, the what-remains
   line and the visible invite-link row in the details. The
   card reuses .referral-whatsapp-btn as-is; every color is
   a Principle VII token or an existing neutral. */
.referral-share-mount { margin: 1rem 0; }
.referral-share-card {
  position: relative; display: flex; flex-direction: column; gap: 0.6rem;
  border: 2px solid var(--color-mint); border-radius: 1rem;
  background: var(--card); padding: 1rem;
}
.referral-share-title { margin: 0; font-weight: 800; font-size: 1.05rem; color: var(--color-hunter); }
.referral-share-progress { margin: 0; font-size: 0.95rem; color: var(--text); }
.referral-share-close {
  position: absolute; top: 0.3rem; right: 0.55rem; border: none; background: none;
  font-size: 1.4rem; line-height: 1; padding: 0.35rem; cursor: pointer; color: var(--text);
}
.push-invite-mount { margin: 1rem 0; }
.push-invite-card {
  position: relative; display: flex; flex-direction: column; gap: 0.6rem;
  border: 2px solid var(--color-sage); border-radius: 1rem;
  background: var(--card); padding: 1rem;
}
.push-invite-title { margin: 0; font-weight: 800; font-size: 1.05rem; color: var(--color-hunter); }
.push-invite-text { margin: 0; font-size: 0.95rem; color: var(--text); }
.push-invite-close {
  position: absolute; top: 0.3rem; right: 0.55rem; border: none; background: none;
  font-size: 1.4rem; line-height: 1; padding: 0.35rem; cursor: pointer; color: var(--text);
}
.push-invite-cta { align-self: flex-start; }
.referral-share-linkrow { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.referral-share-link { flex: 1 1 12rem; font-size: 0.85rem; color: var(--color-teal); word-break: break-all; }
.referral-share-copy {
  border: 1px solid #c5c5c5; background: var(--card); color: var(--text);
  border-radius: 999px; padding: 0.5rem 1rem; min-height: 2.75rem;
  cursor: pointer; font-size: 0.9rem;
}
.referral-banner { flex-wrap: wrap; }
.referral-banner-summary { flex-basis: 100%; font-size: 0.85rem; font-weight: 600; }
.referral-remaining { margin: 0; font-weight: 700; color: var(--color-hunter); }

/* 194-seller-origin-address (FR-002): the publish-flow step's
   consequence line, shown once when the seller skips — plain and
   prominent, not an error. Palette tokens only (Principle VII). */
.origin-address-consequence { font-weight: 600; }

/* 194-seller-origin-address (FR-003): the persistent banner on the
   seller's own products page — the soft-tint callout family of
   .order-confirmation-reward-badge (119) with a sage edge, so it
   reads as a standing notice rather than a toast. Palette tokens
   only (Principle VII). */
.origin-address-banner { background: color-mix(in srgb, var(--color-mint) 15%, transparent); border: 1px solid var(--color-sage); border-radius: 12px; padding: 1rem 1.25rem; margin: 1rem 0; }
.origin-address-banner p { margin: 0.35rem 0; }

/* 216-app-install-prompt: the «Instala la app» bottom banner
   (view/js/install-app.js, injected by server.mjs on public
   pages). Closed palette only: pine bar, orange CTA. */
.install-app-banner {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
  background: var(--color-pine); color: #fff;
  box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.25);
}
.install-app-banner-text { flex: 1; font-weight: 600; }
.install-app-banner-cta {
  background: var(--color-orange); color: #fff; border: 0;
  font-weight: 700; padding: 8px 16px; border-radius: 999px;
  cursor: pointer; white-space: nowrap;
}
.install-app-banner-close {
  background: transparent; color: #fff; border: 0; font-size: 20px;
  line-height: 1; padding: 4px 6px; cursor: pointer;
}

/* 227-seller-coupon-creation: the create/edit forms inside
   «Mis cupones» and the origin chip. Layout only — colors
   stay on the existing coupon/form tokens.
   229-coupon-button-visibility: the submit/save buttons
   wear the shared .primary style instead (their outline
   label rendered invisibly on the owner's phone); this
   rule now covers only the remaining outline button and
   pins its label color and font explicitly. */
.coupon-origin { margin-left: 0.5rem; padding: 0.1rem 0.55rem; border: 1px solid var(--color-sage); border-radius: 999px; font-size: 0.78rem; font-weight: 700; vertical-align: middle; }
.coupon-create-form, .coupon-edit-form { display: grid; gap: 0.6rem; margin-top: 1rem; max-width: 26rem; }
.coupon-create-form label, .coupon-edit-form label { display: grid; gap: 0.25rem; font-weight: 700; }
.coupon-create-form input, .coupon-create-form select, .coupon-edit-form input, .coupon-edit-form select { padding: 0.5rem 0.6rem; border: 1px solid var(--color-sage); border-radius: 0.5rem; font: inherit; }
.coupon-create-form button:not(.primary), .coupon-edit-form button:not(.primary) { justify-self: start; border: 1px solid var(--color-sage); background: var(--card); color: var(--color-hunter); font: inherit; border-radius: 999px; padding: 0.45rem 1rem; font-weight: 700; cursor: pointer; min-height: 2.75rem; }

/* 266-saved-cards-table-scroll: wide tables scroll inside their card
   instead of pushing the whole page sideways on phones. */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.saved-cards-table th, .saved-cards-table td { white-space: nowrap; }

/* 271-home-search-pill: the home search zone becomes ONE pill,
   the layout the owner approved on his own screenshot
   (2026-11-01, mockup A-final2 — «Ok hazlo así»), following
   the big-marketplace pattern: the trust banner stays exactly
   as it is (white, rotating), and below it a single bar
   carries the field, the Filters toggle as its sliders icon,
   and the pine «Buscar» fused at the right end. The separate
   Filters row disappears, so «Más vendidos» starts higher.
   What survives from the earlier calls: 171's 44px tier for
   the children, 208's sliders mask icon (still a ::before
   currentColor mask — i18n replaces the toggle's textContent,
   so no markup icon), 211's pine «Buscar», and 214/215's
   logo-green frame at 1px — the frame moves from the field
   to the whole bar. 238's sky halo moves with it: the field
   no longer paints its own ring; the bar gains it on
   :focus-within. The toggle's label stays in the DOM
   (font-size: 0 hides it visually) so the button keeps its
   accessible name. Scoped to .search-bar, home only. */
.search-bar {
  flex-wrap: nowrap;
  align-items: center;
  background: var(--card);
  border: 1px solid var(--color-logo);
  border-radius: 999px;
  padding: 0.3rem;
  gap: 0.35rem;
}
.search-bar input[type="search"] {
  border: 0;
  background: transparent;
  box-shadow: none;
  padding-left: 0.9rem;
}
.search-bar input[type="search"]:focus,
.search-bar input[type="search"]:focus-visible {
  box-shadow: none;
}
.search-bar:focus-within {
  box-shadow: 0 0 0 3px var(--color-sky);
}
.search-bar #filters-toggle {
  flex: 0 0 auto;
  width: 2.75rem;
  padding: 0;
  background: transparent;
  border: 0;
  color: var(--color-pine);
  font-size: 0;
}
.search-bar #filters-toggle::before {
  width: 1.2rem;
  height: 1.2rem;
}
.search-bar button.primary {
  flex: 0 0 auto;
  padding-left: 1.3rem;
  padding-right: 1.3rem;
}
.search-bar #search-clear {
  background: transparent;
  border: 0;
  color: var(--muted);
  padding: 0 0.6rem;
}

/* 272-category-circles-centered: the home category row
   (Jerseys, Calzado, Vintage, Accesorios) hugged the left
   and left a dead gap on the right; the owner approved it
   centered on a mockup over his own screenshot (2026-11-01:
   «Ok ponme esto al centro y las categorías déjalas así» —
   the four categories themselves do not change). `safe
   center` keeps the row scrollable without clipping the
   first circle if the items ever stop fitting; browsers
   without it fall back to plain center. Nothing else moves. */
.category-circles {
  justify-content: center;
  justify-content: safe center;
}

/* 273-search-submit-magnifier: the home search submit stops
   wearing the word «Buscar» as a chunky pine segment and
   becomes a quiet pine circle with a white magnifier — the
   owner's pick among four mockups on his own screenshot
   (2026-11-01: «El de la lupa sola el 3 se ve bien y no le
   roba protagonismo a los productos»). Same technique as
   208/271: the icon is a ::before currentColor mask (the
   white comes from button.primary's base colour), because
   i18n replaces the textContent of [data-i18n] elements and
   would delete an inline SVG; the label stays in the DOM
   with font-size: 0, so the button keeps its accessible
   name and its submit behaviour is untouched. Scoped to
   .search-bar, home only. */
.search-bar button.primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 2.75rem;
  padding: 0;
  font-size: 0;
}
.search-bar button.primary::before {
  content: '';
  flex: 0 0 auto;
  width: 1.3rem;
  height: 1.3rem;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='10.5' cy='10.5' r='6.5'/%3E%3Cpath d='M15.5 15.5 L21 21'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='10.5' cy='10.5' r='6.5'/%3E%3Cpath d='M15.5 15.5 L21 21'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* 274-app-update-prompt: the in-app «update available»
   bottom banner (view/js/app-update.js, injected by
   server.mjs on public pages; renders only inside the
   store wrapper on an outdated build). Mirror of the 216
   install banner — closed palette only: pine bar, orange
   CTA. */
.app-update-banner {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
  background: var(--color-pine); color: #fff;
  box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.25);
}
.app-update-banner-text { flex: 1; font-weight: 600; }
.app-update-banner-cta {
  background: var(--color-orange); color: #fff; border: 0;
  font-weight: 700; padding: 8px 16px; border-radius: 999px;
  cursor: pointer; white-space: nowrap;
}
.app-update-banner-close {
  background: transparent; color: #fff; border: 0; font-size: 20px;
  line-height: 1; padding: 4px 6px; cursor: pointer;
}

/* 275-offer-button-footer-green: the product page's
   «Hacer una oferta» toggle wears the footer's green
   solid — background and border in --color-pine (spec
   208's footer token) with white text — the owner's
   pick on his product-39 screenshot, mockup approved
   2026-11-01, over the orange outline it had. It now
   matches the Filtros toggle (208) and the search
   submit (273). Only the toggle changes: the offer
   form, its submit and the active-offer box keep
   their styling. */
.offer-box > button {
  background: var(--color-pine);
  border-color: var(--color-pine);
  color: #fff;
}

/* 277-ship-by-date: the dispatch deadline line in the sale
   detail (Mis ventas). Normal state in hunter; once the
   deadline passes without a label it turns orange-dark. */
.sale-ship-by { font-weight: 600; color: var(--color-hunter); }
.sale-ship-by--overdue { color: var(--color-orange-dark); }

/* 278-guides-section: the public guides index cards and the
   guide article typography. Palette variables only; article
   pages reuse .about-main / .about-section layout. */
.guide-main h2 { color: var(--color-hunter); margin: 1.8rem 0 0.6rem; }
.guide-main p, .guide-main li { line-height: 1.55; }
.guide-main ul, .guide-main ol { padding-left: 1.4rem; margin: 0.4rem 0 1rem; }
.guide-main li { margin: 0.3rem 0; }
.guide-cards { display: grid; gap: 1rem; margin-top: 1.2rem; }
@media (min-width: 640px) { .guide-cards { grid-template-columns: 1fr 1fr; } }
.guide-card { display: block; border: 1px solid #ddd; border-radius: 12px; padding: 1rem 1.1rem; text-decoration: none; color: inherit; }
.guide-card:hover, .guide-card:focus { border-color: var(--color-pine); }
.guide-card h3 { margin: 0 0 0.4rem; color: var(--color-hunter); }
.guide-card p { margin: 0; color: var(--muted); }
.about-find-list { padding-left: 1.4rem; line-height: 1.55; }
.about-find-list li { margin: 0.3rem 0; }

/* 283-empty-cart-confirm: in-page confirmation for emptying the cart */
.cart-empty-confirm { display: inline-flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.cart-empty-confirm[hidden] { display: none; }

/* 285-checkout-success-hero: the order-confirmation page opens with
   the success moment (pitch check, «¡Pago exitoso!», summary card,
   orange CTA) above the detail sections it already carried; the
   payment page's submit button reuses .loader-spin for its
   connecting state. Palette vars only — no new colors. */
.payment-success-hero {
  text-align: center;
}
.payment-success-check {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 88px;
  height: 88px;
  border-radius: 50%;
  background: var(--color-pitch);
  margin: 8px auto 12px;
}
.payment-success-subtitle {
  color: #374151;
  margin: 4px 0 16px;
}
.payment-success-card {
  background: #f7f7f8;
  border-radius: 12px;
  padding: 12px 16px;
  text-align: left;
  margin-bottom: 16px;
}
.payment-success-cta {
  display: block;
  background: var(--color-orange);
  color: #fff;
  font-weight: 700;
  text-align: center;
  padding: 14px;
  border-radius: 999px;
  text-decoration: none;
  margin-bottom: 10px;
}
.payment-success-secondary {
  display: block;
  text-align: center;
  color: var(--color-pine);
  padding: 8px;
}
.btn-spin {
  margin-right: 8px;
  vertical-align: -2px;
}

/* 289-store-promote-button: the owner's «Promocionar productos»
   entry on the store page, the renamed solid-pine promote button
   in Mis productos, and the 2×2 card-actions layout.
   The [hidden] rules follow the house pattern (.row[hidden],
   .bell[hidden]): button.primary sets display, so the attribute
   needs an explicit rule to win — the follow one also closes
   225's intent (the owner never sees «Seguir» on his own store;
   it showed in his 2026-11-02 screenshot next to the views
   total, which only the owner payload carries). */
#seller-promote[hidden] { display: none; }
#seller-follow[hidden] { display: none; }
#seller-promote { margin-top: 0.5rem; background: var(--color-pine); }
#seller-promote:hover, #seller-promote:active { background: var(--color-pine); filter: brightness(1.35); }
.seller-promote-label::before { content: "★"; margin-right: 0.35em; }
/* .btn-promote mirrors .btn-secondary's geometry (154 scale),
   filled with the footer green the owner asked for by name. */
.btn-promote {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 2.75rem; background: var(--color-pine); color: #fff;
  border: 1px solid var(--color-pine); border-radius: 999px;
  padding: 0.65rem 1.05rem; font: inherit; font-size: 0.95rem; font-weight: 600;
  cursor: pointer; text-decoration: none;
}
.btn-promote:hover, .btn-promote:focus-visible { filter: brightness(1.35); }
/* The 2×2 — CORRECTED after the first live render (the owner's
   screenshot, 2026-11-02): the original flex rule
   (flex: 1 1 calc(50% - 0.375rem)) summed EXACTLY the container
   width — two halves plus the .row gap — so the slightest
   rounding pushed every action onto its own line, where
   flex-grow stretched it full-width: the buttons rendered
   stacked, not 2×2. A grid cannot drift: two minmax(0, 1fr)
   columns always halve the row, and min-width: 0 lets a cell
   hold its half. 0.7rem with tight inline padding is the
   measured fit for «Promocionar» at the owner's 440pt width
   (verified in a real headless render of this stylesheet:
   paired rows, no clipping); under 400pt the word fits no
   half column at a readable size, so the actions stack
   full-width there instead of clipping. */
.product-actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.5rem;
}
.product-actions > * {
  min-width: 0;
  font-size: 0.7rem;
  padding-left: 0.15rem;
  padding-right: 0.15rem;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
@media (max-width: 400px) {
  .product-actions { grid-template-columns: 1fr; }
}
