/* Driver merch: storefront, product page, and the driver's own store screens.
   Depends on tokens.css and nav.css for the palette, reset, and responsive
   nav-link collapse -- every merch template loads both first, the same way
   dashboard.css and profile.css do. This file supplies .topbar/.brand/.search
   itself (nav.css deliberately doesn't -- see its own header comment), same
   split every other page-css file in the repo uses.

   The templates are near-classless semantic HTML, so most of this styles
   elements inside .store-page rather than inventing a class per node. That
   keeps the markup readable and means a new field in a form picks up the
   styling without anyone remembering to add a class. */

/* The same body every other page-css file in the repo declares
   (profile.css, dashboard.css, calendar.css, galeria.css): the shared
   --font-display token and the site's 15px/1.5 rhythm. It used to hard-code
   its own font stack and leave the size to the browser, which was invisible
   on the nine standalone store screens but not on the storefront: that one
   loads store.css after profile.css inside the pilot shell, so the identity
   card and the tab bar changed size between Resumen and Tienda. */
body {
  margin: 0;
  background: var(--ink);
  color: var(--text-primary);
  font-family: var(--font-display);
  -webkit-font-smoothing: antialiased;
  font-size: 15px;
  line-height: 1.5;
}

/* .topbar / .brand / .btn-ghost / .search live in nav.css now. */

.store-page {
  max-width: 900px;
  /* Bottom padding clears the fixed theme toggle base.html plants in the
     corner, which would otherwise sit on top of the last button. */
  margin: 0 auto;
  padding: 0 20px 96px;
}

/* Inside the pilot shell the centre column owns width and padding. The
   wrapper stays for the element-scoped styling below it. */
.col-center > .store-page { max-width: none; margin: 0; padding: 0; }

.store-page h1 {
  font-size: clamp(24px, 5vw, 34px);
  letter-spacing: -0.02em;
  margin-bottom: 6px;
}

/* The page title is the shared .page-head (nav.css): the store's own h1 sizing
   applies only to a bare h1 elsewhere on the page. */
.store-page .page-head h1 { font-size: 28px; letter-spacing: -0.01em; margin: 0; }

.store-page h2 {
  font-size: 15px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-secondary);
  margin: 32px 0 12px;
}

.store-page p { line-height: 1.55; margin: 8px 0; }
.store-page a { color: var(--accent); }
.store-page a:hover { color: var(--accent-strong); }

/* The product page's price used to be a plain <p>, the same weight as the
   description below it -- nothing marked it as the number the whole page
   exists to show. */
.store-product-price {
  color: var(--accent);
  font-size: 20px;
  font-weight: 800;
  margin: 4px 0 14px;
}

.store-page .hint,
.store-page .store-muted {
  color: var(--text-secondary);
  font-size: 13px;
}

.store-page .error {
  background: rgba(255, 84, 112, 0.12);
  border: 1px solid var(--critical);
  border-radius: var(--radius-md);
  color: var(--critical);
  padding: 10px 14px 18px;
  margin-bottom: 16px;
}

/* Lists carry the structure on most of these screens (orders, variants,
   withdrawals), so they get rows rather than bullets.

   This reset MUST stay above the card block below. Both selectors are one
   class plus one element, so they carry identical specificity and the later
   one wins -- with the reset last, its `padding: 0` silently stripped the
   card padding from every <ul> card in the store, which is why the balance
   page's earnings and withdrawals lists sat flush against their own border
   while the <form> card beside them was correctly inset. */
.store-page ul { list-style: none; margin: 0; padding: 0; }

/* Sections read as cards so a page of several of them has visible seams. */
.store-page > section,
.store-page > form,
.store-page > ul,
.store-page > fieldset {
  /* The site's card: the same gradient, line and 16px radius as profile.css,
     calendar.css and import.css. These used to be a flat --surface box with
     the smaller --radius-md, the one family of cards that didn't match. */
  background: linear-gradient(175deg, var(--surface) 0%, var(--card-gradient-end) 100%);
  border: 1px solid var(--line);
  border-radius: 16px;
  margin: 16px 0;
  padding: 20px 22px;
}

.store-page > section > h2:first-child { margin-top: 0; }

.store-page > ul > li,
.store-page > section > ul > li {
  border-bottom: 1px solid var(--line-soft);
  padding: 14px 0;
}

.store-page > ul > li:last-child,
.store-page > section > ul > li:last-child { border-bottom: 0; }

.store-page li ul {
  color: var(--text-secondary);
  font-size: 13px;
  margin-top: 6px;
}

.store-page li ul li { border: 0; padding: 2px 0; }

/* The storefront and the product grid. auto-fill rather than a fixed count
   so one product does not stretch across the page and six do not squeeze. */
.store-grid {
  display: grid;
  gap: 16px;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}

.store-grid > li {
  background: var(--surface-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  border-bottom: 1px solid var(--line);
  overflow: hidden;
  padding: 0 0 12px;
  transition: border-color 0.15s ease, transform 0.15s ease;
}

.store-grid > li:hover { border-color: var(--accent-line); transform: translateY(-2px); }

.store-grid img {
  aspect-ratio: 1 / 1;
  display: block;
  object-fit: cover;
  width: 100%;
}

/* A product with no photo yet used to leave a blank gap where the image
   belongs -- same aspect-ratio box as a real photo, so the grid's rhythm
   holds either way. */
.store-grid-noimg {
  align-items: center;
  aspect-ratio: 1 / 1;
  background: var(--surface-2);
  color: var(--text-tertiary);
  display: flex;
  font-size: 12px;
  justify-content: center;
}

.store-grid > li > a { color: var(--text-primary); display: block; }

/* The telemetry-session fallback below (no image, no price) keeps the old
   plain-link padding; the merch card wraps image+name+price in one link
   now, so its own children carry the padding instead -- padding on the
   <a> itself would push the image in from the card's edge. */
.store-grid > li > a:not(.store-grid-link) { font-weight: 600; padding: 12px; }

.store-grid-name { display: block; font-weight: 600; padding: 12px 12px 0; }
.store-grid-price { color: var(--accent); display: block; font-size: 13px; font-weight: 700; padding: 4px 12px 0; }

.store-grid p { color: var(--text-secondary); margin: 4px 12px 0; }

/* The driver's own catalogue: a thumbnail beside each product, so a store
   with several products is scannable by sight rather than by reading names. */
.store-row { align-items: flex-start; display: flex; gap: 14px; }

.store-row-body { flex: 1; min-width: 0; }

.store-row-thumb {
  border: 1px solid var(--line);
  border-radius: 8px;
  flex: 0 0 auto;
  height: 64px;
  object-fit: cover;
  width: 64px;
}

.store-row-thumb-empty {
  align-items: center;
  background: var(--surface-raised);
  color: var(--text-tertiary);
  display: flex;
  font-size: 11px;
  justify-content: center;
  text-align: center;
}

/* Product page photos: a scroll strip, not a stack of full-width images.
   The scrollbar itself is hidden -- scroll-snap already telegraphs "more
   photos this way", and the bare system scrollbar this strip render with
   otherwise reads as a stray UI element rather than part of the page. */
.store-gallery {
  display: flex;
  gap: 12px;
  margin: 16px 0;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}
.store-gallery::-webkit-scrollbar { display: none; }

.store-gallery img {
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  flex: 0 0 auto;
  height: 320px;
  object-fit: cover;
  scroll-snap-align: start;
  width: 320px;
}

/* Forms. The checkout form is eleven address fields plus a variant picker,
   which is the shape that overflows a phone -- hence the auto-fit grid
   rather than a single column of full-width inputs. */
.store-page label {
  color: var(--text-secondary);
  display: flex;
  flex-direction: column;
  font-size: 13px;
  gap: 6px;
  margin-bottom: 12px;
}

.store-page input,
.store-page textarea {
  background: var(--ink);
  border: 1px solid var(--line);
  border-radius: 8px;
  color: var(--text-primary);
  font: inherit;
  font-size: 15px;
  /* 15px, not smaller: iOS Safari zooms the page on focus below 16px, and
     the resulting viewport shift reads as the layout breaking. */
  padding: 10px 12px;
  width: 100%;
}

/* 15px for the same iOS-zoom reason as the inputs above. */
.store-page select { width: 100%; font-size: 15px; padding: 10px 34px 10px 12px; }
.store-page textarea { min-height: 90px; resize: vertical; }

.store-page input:focus,
.store-page textarea:focus {
  border-color: var(--accent-line);
  outline: none;
}

.store-page fieldset {
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  margin: 16px 0;
  padding: 16px;
}

.store-page legend {
  color: var(--text-secondary);
  font-size: 12px;
  letter-spacing: 0.08em;
  padding: 0 6px;
  text-transform: uppercase;
}

.store-page fieldset > label { margin-bottom: 12px; }

@media (min-width: 620px) {
  .store-address {
    display: grid;
    gap: 0 14px;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  }
  .store-address legend { grid-column: 1 / -1; }
}

/* Radio and checkbox rows are horizontal; the column layout above is for
   labelled text inputs. */
.store-page .store-choice { flex-direction: row; align-items: center; gap: 8px; }
.store-page .store-choice input { width: auto; }

.store-page button[type="submit"],
.store-page .btn {
  background: var(--accent);
  border-radius: 8px;
  color: var(--ink);
  display: inline-block;
  font-size: 14px;
  font-weight: 600;
  padding: 11px 18px;
}

.store-page button[type="submit"]:hover,
.store-page .btn:hover { background: var(--accent-strong); }

.store-page button[type="submit"]:disabled {
  cursor: default;
  opacity: 0.6;
}

/* Checkout's last line used to be a bare shipping-cost <p> immediately
   above the button, easy to read as one more form field rather than the
   order's own summary. A bordered bar separates it from the address/
   payment fields above and gives shipping cost and the buy button equal
   visual weight as the two things left to decide. */
.store-checkout-bar {
  align-items: center;
  border-top: 1px solid var(--line-soft);
  display: flex;
  justify-content: space-between;
  gap: 14px;
  margin-top: 18px;
  padding-top: 18px;
}
.store-checkout-shipping { color: var(--text-secondary); font-size: 13.5px; }
.store-checkout-bar button[type="submit"] { flex-shrink: 0; }

.store-page .btn { color: var(--ink); }

/* The address snapshot on the order queue is preformatted text, and a long
   street name should wrap rather than push the page sideways. */
.store-page pre {
  background: var(--ink);
  border: 1px solid var(--line-soft);
  border-radius: 8px;
  color: var(--text-secondary);
  font-size: 13px;
  margin: 10px 0;
  overflow-x: auto;
  padding: 10px 12px;
  white-space: pre-wrap;
  word-break: break-word;
}

/* Balance page: the number is the whole point of the screen. */
.store-balance-figure {
  font-size: clamp(26px, 6vw, 34px);
  font-weight: 800;
  letter-spacing: -0.02em;
}
/* The big figure (your plan, your balance) sits in the outlined glow block the
   other pages use for their headline numbers. */
.store-page p.store-balance-figure {
  display: inline-block; margin: 4px 0 16px; padding: 10px 22px; line-height: 1.2;
  border: 1px solid var(--accent-line); border-radius: 14px;
  background: linear-gradient(160deg, var(--accent-soft), transparent 70%);
  box-shadow: 0 0 24px -10px var(--accent);
}

/* The way back: a pill button with an arrow that slides left on hover. On the
   store dashboard / product-form / orders pages it is the only way back to the
   dashboard, so it is a real tap target (40px tall), not a quiet text link. */
.store-page .store-back {
  display: inline-flex; align-items: center; gap: 10px; margin: 20px 0 16px; padding: 14px 28px 14px 22px;
  border: 1px solid var(--line); border-radius: 999px; background: var(--surface-2);
  color: var(--text-primary); font-size: 13.5px; font-weight: 700; line-height: 1.2;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.store-page .store-back svg { width: 18px; height: 18px; flex-shrink: 0; color: var(--accent); transition: transform 0.15s ease; }
.store-page .store-back:hover { border-color: var(--accent-line); background: var(--accent-soft); color: var(--accent); }
.store-page .store-back:hover svg { transform: translateX(-3px); }

/* The store dashboard is where the product forms land after their redirect,
   so it is the only page that can show the messages they queue -- a photo
   that was rejected, or stock that moved while the form sat open. Same class
   names as dashboard.css's block, restated because store.css is loaded
   without it. `warning` is the level the stock notice uses: the save did go
   through, so it must not read as a failure the way `error` does. */
.store-page .messages { display: flex; flex-direction: column; gap: 8px; margin-bottom: 16px; }
.store-page .msg { padding: 10px 14px; border-radius: 9px; font-size: 12.5px; }
.store-page .msg.error { background: rgba(255, 84, 112, 0.1); border: 1px solid rgba(255, 84, 112, 0.35); color: var(--critical); }
.store-page .msg.warning { background: rgba(255, 176, 32, 0.12); border: 1px solid rgba(255, 176, 32, 0.35); color: var(--text-primary); }
.store-page .msg.success,
.store-page .msg.info { background: var(--accent-soft); border: 1px solid var(--accent-line); color: var(--accent); }

/* ---------------------------------------------------------------------------
   Money tables and status pills — /cuenta/pagos/ and /tienda/saldo/.

   payment_history.html was the one screen in the store whose structure is a
   real table rather than a list, and the card block above only ever reached
   section/form/ul/fieldset -- so its tables inherited browser defaults:
   no padding, no rules, and columns colliding ("a la plataforma$599.00").
   Styled here rather than as a new class because it is still the only table
   under .store-page, so there is nothing else to surprise.
   --------------------------------------------------------------------------- */
.store-page table {
  border-collapse: collapse;
  width: 100%;
}

/* Same language as .store-page h2 -- uppercase, tracked, secondary -- so a
   column head and a section head read as the same level of furniture. */
.store-page thead th {
  border-bottom: 1px solid var(--line);
  color: var(--text-secondary);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.07em;
  padding: 0 12px 10px;
  text-align: left;
  text-transform: uppercase;
}

.store-page tbody td {
  border-bottom: 1px solid var(--line-soft);
  padding: 13px 12px;
  vertical-align: middle;
}

.store-page tbody tr:last-child td { border-bottom: 0; }

/* First and last cells sit flush with the card's own padding rather than
   adding a second inset on top of it. */
.store-page thead th:first-child,
.store-page tbody td:first-child { padding-left: 0; }
.store-page thead th:last-child,
.store-page tbody td:last-child { padding-right: 0; }

/* Money is right-aligned so the decimal points line up down the column;
   .tnum (tokens.css) makes the digits monospaced-width so they actually do. */
.store-page .money,
.store-page th.money { text-align: right; white-space: nowrap; }

/* A status is a state, not a sentence: a pill reads at a glance in a column
   of twenty rows where plain text does not. No --warning token exists, and a
   refund is not a failure, so REFUNDED stays deliberately neutral instead of
   borrowing the critical colour. */
.store-page .pill {
  border: 1px solid var(--line);
  border-radius: 999px;
  display: inline-block;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 3px 10px;
  white-space: nowrap;
}

.store-page .pill.is-paid { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent); }
.store-page .pill.is-failed { background: rgba(255, 84, 112, 0.12); border-color: rgba(255, 84, 112, 0.35); color: var(--critical); }
.store-page .pill.is-refunded,
.store-page .pill.is-pending { background: var(--surface-raised); color: var(--text-secondary); }

/* Two links in one cell ("Ver reciboPDF" before this) need a real gap and a
   visible separator, not whitespace collapsing between anchors. */
.store-page .receipt-links { display: inline-flex; gap: 10px; }
.store-page .receipt-links a { white-space: nowrap; }

/* Label on the left, number on the right, for rows that are a pair rather
   than a sentence -- the earnings breakdown read "Merch: $444.00 MXN" as one
   run of text, which cannot be scanned down a column. */
.store-page .kv { display: flex; align-items: baseline; gap: 12px; justify-content: space-between; }
.store-page .kv > :last-child { text-align: right; white-space: nowrap; }
.store-page .kv-label { color: var(--text-secondary); }

/* A row that is three things (amount, state, date) rather than two. */
.store-page .row-3 { display: flex; align-items: center; gap: 12px; justify-content: space-between; }
.store-page .row-3 .row-3-date { color: var(--text-secondary); font-size: 13px; white-space: nowrap; }

/* 640px matches standings.css. Below it a five-column table cannot fit, and
   Gate C (T-C2) forbids solving that with horizontal scroll, so each row
   becomes its own stacked block and the column heads are carried per-cell by
   data-label instead of a <thead> nobody can see. */
@media (max-width: 640px) {
  .store-page thead { display: none; }

  .store-page tbody tr {
    border-bottom: 1px solid var(--line-soft);
    display: block;
    padding: 12px 0;
  }

  .store-page tbody tr:last-child { border-bottom: 0; }

  .store-page tbody td {
    border: 0;
    display: flex;
    gap: 12px;
    justify-content: space-between;
    padding: 3px 0;
    text-align: right;
  }

  .store-page tbody td::before {
    color: var(--text-secondary);
    content: attr(data-label);
    font-size: 11.5px;
    letter-spacing: 0.07em;
    text-align: left;
    text-transform: uppercase;
  }

  /* Nothing to label against on a cell whose data-label is empty. */
  .store-page tbody td:not([data-label])::before { content: none; }
}

/* ---------------------------------------------------------------------------
   Planes (/planes/). Was one full-width box per plan with the price and a
   button in it -- nothing to compare side by side, which is the whole job of
   a pricing page. Now a grid of cards; the top tier and the plan you are on
   get the outlined glow the rest of the site uses for its headline block.
   --------------------------------------------------------------------------- */
.plan-banner {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  padding: 14px 18px; margin: 0 0 18px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--surface);
  font-size: 14px; color: var(--text-secondary);
}
.plan-banner strong { color: var(--text-primary); }
.store-page .plan-banner-link {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 14px; border-radius: 999px;
  border: 1px solid var(--accent-line); background: transparent;
  color: var(--accent); font-size: 13px; font-weight: 600; text-decoration: none;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.store-page .plan-banner-link::after { content: "\2192"; transition: transform 0.15s ease; }
.store-page .plan-banner-link:hover { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }
.store-page .plan-banner-link:hover::after { transform: translateX(3px); }
.plan-grid {
  display: grid; gap: 24px; margin: 0; padding: 24px 0;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}
.store-page .plan-card {
  position: relative; display: flex; flex-direction: column;
  margin: 0; padding: 36px 32px;
  background: linear-gradient(175deg, var(--surface) 0%, var(--card-gradient-end) 100%);
  border: 1px solid var(--line); border-radius: 16px;
}
.store-page .plan-card.is-featured {
  border-color: var(--accent-line);
  background: linear-gradient(175deg, rgba(0, 230, 118, 0.07) 0%, var(--card-gradient-end) 70%);
  box-shadow: 0 0 28px -12px var(--accent);
}
.store-page .plan-card h2 {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  margin: 0 0 14px; font-size: 13px; color: var(--text-secondary);
}
.plan-price { margin: 0 0 4px; line-height: 1.1; }
.plan-price-amount { font-size: 34px; font-weight: 800; letter-spacing: -0.02em; color: var(--text-primary); }
.plan-price-period { font-size: 13px; color: var(--text-secondary); margin-left: 4px; }
.store-page .plan-features { margin: 16px 0 20px; display: flex; flex-direction: column; gap: 10px; flex: 1; }
.store-page .plan-features li {
  display: flex; gap: 10px; align-items: flex-start; padding: 0; border: 0;
  font-size: 14px; color: var(--text-primary); line-height: 1.4;
}
.plan-features svg { flex-shrink: 0; width: 18px; height: 18px; color: var(--accent); margin-top: 1px; }
.plan-features-none { color: var(--text-tertiary); font-size: 13px; flex: 1; margin: 16px 0 20px; }
.store-page .plan-card form { margin-top: auto; }
.store-page .plan-card form + form { margin-top: 8px; }
.store-page .plan-move-note { margin: 10px 0 0; font-size: 12.5px; line-height: 1.45; color: var(--text-secondary); }
.store-page .plan-move-note a { color: var(--accent); }
.plan-price-alt { margin: 0 0 14px; font-size: 13px; color: var(--text-secondary); }
/* Both buttons share one shape in every card: the monthly one is the filled
   primary, the annual one the outlined secondary, so the pair reads as a
   choice rather than two unrelated controls. */
.store-page .plan-card button[type="submit"] {
  width: 100%; padding: 13px 18px; border-radius: 10px;
  font-size: 14px; font-weight: 700; letter-spacing: 0.01em; cursor: pointer;
  border: 1px solid var(--accent);
  background: var(--accent); color: var(--ink);
  transition: background 0.15s, border-color 0.15s, transform 0.1s, box-shadow 0.15s;
}
.store-page .plan-card button[type="submit"]:hover:not(:disabled) {
  background: var(--accent-strong); border-color: var(--accent-strong);
  box-shadow: 0 6px 18px -8px var(--accent);
}
.store-page .plan-card button[type="submit"]:active:not(:disabled) { transform: translateY(1px); }
.store-page .plan-card button[type="submit"]:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.store-page .plan-card button.plan-btn-alt {
  background: transparent; color: var(--accent); border-color: var(--accent-line);
}
.store-page .plan-card button.plan-btn-alt:hover:not(:disabled) {
  background: var(--accent-soft); border-color: var(--accent); box-shadow: none;
}

/* ---------------------------------------------------------------------------
   Mi tienda (/tienda/). Each product was one run of text ("Drop — $1200.00
   MXN — A la venta") over a list of "M — 18 en existencia" lines.
   --------------------------------------------------------------------------- */
.store-toolbar {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  margin: 0 0 4px;
}
.store-toolbar .store-status { display: flex; align-items: center; gap: 8px; color: var(--text-secondary); font-size: 13.5px; }
.store-row-title { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.store-page .store-row-title a { color: var(--text-primary); font-weight: 700; font-size: 15px; }
.store-page .store-row-title a:hover { color: var(--accent); }
.store-row-price { display: block; margin-top: 2px; color: var(--accent); font-weight: 700; font-size: 14px; }
.store-page .store-variants { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.store-page .store-variants li {
  padding: 3px 10px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface-raised); font-size: 12px; color: var(--text-secondary);
}
.store-variants li strong { color: var(--text-primary); font-weight: 700; }
.store-page .store-variants li.is-out { color: var(--critical); border-color: rgba(255, 84, 112, 0.35); }
/* A button, not a loose green word: the pill outline reads as pressable and the
   pencil says what it does. On a phone the label drops and it stays a 40px tap
   target (the old rule hid it, leaving the product name as the only way in). */
.store-page .store-row-edit {
  margin-left: auto; align-self: center; flex-shrink: 0;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 16px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface-2); color: var(--text-primary);
  font-size: 13px; font-weight: 600; line-height: 1.2; text-decoration: none;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.store-row-edit svg { width: 15px; height: 15px; color: var(--accent); }
.store-page .store-row-edit:hover { border-color: var(--accent-line); background: var(--accent-soft); color: var(--accent); }
.store-page .store-row-thumb { width: 72px; height: 72px; border-radius: 10px; }

/* Product form, "Fotos": one row per photo in the order the storefront shows
   them, with arrows that save the form and come back to it (no JavaScript:
   the CSP would block it, and a drag handle with no script has nothing to do). */
.photo-default-submit { position: absolute; left: -9999px; width: 1px; height: 1px; padding: 0; opacity: 0; }
.photo-list { display: grid; gap: 10px; margin: 8px 0 14px; }
.photo-item {
  display: flex; align-items: center; gap: 14px; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: 14px; background: var(--surface-raised);
}
.photo-item.is-lead {
  border-color: var(--accent-line); box-shadow: 0 0 24px -12px var(--accent);
  background: linear-gradient(160deg, var(--accent-soft), transparent 70%), var(--surface-raised);
}
/* The grip and the grab cursor only exist once product_photo_sort.js has run
   (it adds .is-sortable): without the script there is nothing to drag. */
.photo-grip { display: none; color: var(--text-tertiary, var(--text-secondary)); flex-shrink: 0; }
.photo-grip svg { width: 20px; height: 20px; display: block; }
.photo-list.is-sortable { position: relative; }
.photo-list.is-sortable .photo-item { cursor: grab; touch-action: none; user-select: none; -webkit-user-select: none; }
.photo-list.is-sortable .photo-grip { display: block; }
.photo-item.is-dragging {
  position: relative; z-index: 2; cursor: grabbing; border-color: var(--accent);
  box-shadow: 0 14px 34px -10px rgba(0, 0, 0, 0.7), 0 0 0 1px var(--accent-line); transition: none;
}
.photo-item.is-dragging .photo-thumb { pointer-events: none; }
.photo-dirty[hidden] { display: none; }
.store-page .photo-dirty { color: var(--accent); }
.photo-thumb { width: 72px; height: 72px; flex-shrink: 0; border-radius: 10px; object-fit: cover; background: var(--surface-2); }
.photo-meta { flex: 1; min-width: 0; display: grid; gap: 4px; }
.photo-pos { font-size: 13.5px; font-weight: 700; color: var(--text-primary); }
.photo-item.is-lead .photo-pos { color: var(--accent); }
.store-page .photo-remove { flex-direction: row; align-items: center; gap: 6px; margin: 0; font-size: 12.5px; cursor: pointer; }
.store-page .photo-remove input { width: auto; padding: 0; }
.photo-move { display: flex; gap: 6px; }
.store-page .photo-move button[type="submit"] {
  display: grid; place-items: center; width: 40px; height: 40px; padding: 0;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface-2); color: var(--text-primary); cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.photo-move svg { width: 18px; height: 18px; }
.store-page .photo-move button[type="submit"]:hover:not(:disabled) { border-color: var(--accent-line); background: var(--accent-soft); color: var(--accent); }
.store-page .photo-move button[type="submit"]:disabled { opacity: 0.3; cursor: default; }

/* The toolbar's actions are the site's buttons (nav.css .btn-primary / .btn-secondary),
   not links: `.store-page a` paints every anchor accent green, which is what made
   them read as loose text. Restating the colours here is the price of that rule. */
.store-actions { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.store-page a.btn-primary,
.store-page a.btn-secondary { padding: 9px 16px; text-decoration: none; }
.store-page a.btn-primary { color: #04150c; }
.store-page a.btn-primary:hover { background: var(--accent-strong); color: #04150c; }
.store-page a.btn-secondary { color: var(--text-primary); border: 1px solid var(--line); }
.store-page a.btn-secondary:hover { background: var(--surface-hover); color: var(--text-primary); }
@media (max-width: 640px) {
  .store-row-edit span { display: none; }
  .store-page .store-row-edit { width: 40px; height: 40px; padding: 0; justify-content: center; }
}

/* ---------------------------------------------------------------------------
   Mi saldo (/tienda/saldo/): the balance and the withdrawal form in one
   outlined glow card, then one tile per earning source.
   --------------------------------------------------------------------------- */
.store-page > section.balance-hero {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; flex-wrap: wrap;
  padding: 24px 26px;
  border-color: var(--accent-line);
  background: linear-gradient(160deg, rgba(0, 230, 118, 0.08) 0%, var(--card-gradient-end) 65%);
  box-shadow: 0 0 30px -14px var(--accent);
}
.balance-label { font-size: 12px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; color: var(--text-secondary); }
.store-page .balance-amount { margin: 4px 0 0; font-size: clamp(30px, 6vw, 42px); font-weight: 800; letter-spacing: -0.02em; line-height: 1.1; }
.balance-amount span { font-size: 0.45em; font-weight: 700; color: var(--text-secondary); letter-spacing: 0; }
.balance-withdraw { display: flex; align-items: flex-end; gap: 10px; flex-wrap: wrap; }
.store-page .balance-withdraw label { margin: 0; min-width: 180px; }
.store-page .balance-noaccount { color: var(--text-secondary); font-size: 13.5px; margin: 0; max-width: 34ch; }
.balance-tiles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; margin: 0 0 4px; }
.balance-tile {
  display: flex; flex-direction: column; gap: 2px; padding: 16px 18px;
  background: linear-gradient(175deg, var(--surface) 0%, var(--card-gradient-end) 100%);
  border: 1px solid var(--line); border-radius: 14px;
}
.balance-tile .kv-label { font-size: 12.5px; }
.balance-tile b { font-size: 22px; font-weight: 800; letter-spacing: -0.01em; }
.balance-tile small { font-size: 11px; color: var(--text-tertiary); }
@media (max-width: 640px) {
  .balance-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .balance-withdraw { width: 100%; }
  .store-page .balance-withdraw label { flex: 1; min-width: 0; }
}


/* ============================================================
   Tienda redesign: storefront (membership banner, product cards) and the
   product page (gallery beside the buy column).
   ============================================================ */

/* Section headings: a tick of accent in front, brighter than the old grey. */
.store-page > section > h2 {
  display: flex; align-items: center; gap: 10px; font-size: 13px; letter-spacing: 0.1em; color: var(--text-soft);
}
.store-page > section > h2::before { content: ""; width: 4px; height: 16px; border-radius: 2px; background: var(--accent); }

/* Membership: a banner, not a paragraph and a button. */
.store-page > section.store-plan {
  display: flex; align-items: center; justify-content: space-between; gap: 20px; flex-wrap: wrap;
  padding: 24px 28px; border-color: var(--accent-line);
  background: linear-gradient(160deg, var(--accent-soft), var(--surface) 70%);
  box-shadow: 0 0 34px -16px var(--accent);
}
.store-plan-info { min-width: 0; flex: 1 1 260px; }
.store-plan-info h2 { margin: 0 0 6px; }
.store-plan-info h2::before { display: none; }
.store-plan-price { margin: 0 !important; font-size: 34px; font-weight: 800; letter-spacing: -0.02em; color: var(--text-primary); }
.store-plan-price small { font-size: 14px; font-weight: 700; color: var(--text-soft); letter-spacing: 0; }
.store-plan form { margin: 0; }
.store-plan button[type="submit"] { padding: 13px 26px; font-size: 15px; font-weight: 800; border: 0; cursor: pointer; }

/* Merch cards: a taller, calmer card -- the photo leads, then name and a price pill. */
.store-products { grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 18px; }
.store-products > li { border-radius: 16px; padding: 0 0 16px; background: var(--surface-2); }
.store-products > li:hover { box-shadow: 0 14px 30px -18px rgba(0, 0, 0, 0.7); }
.store-grid-media { display: block; overflow: hidden; background: var(--surface); }
.store-products .store-grid-media img { transition: transform 0.3s ease; }
.store-products > li:hover .store-grid-media img { transform: scale(1.05); }
.store-products .store-grid-name { padding: 14px 16px 0; font-size: 15px; font-weight: 700; line-height: 1.3; }
.store-products .store-grid-price {
  display: inline-block; margin: 10px 16px 0; padding: 4px 12px; border-radius: 999px;
  background: var(--accent-soft); border: 1px solid var(--accent-line); font-size: 13.5px; font-weight: 800;
}

/* Product page. */
.store-product { display: grid; gap: 26px; align-items: start; }
@media (min-width: 900px) {
  .store-product { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .store-product-media { position: sticky; top: 76px; }
}
.store-product-info { min-width: 0; }
.store-product-info .store-product-price {
  display: inline-block; margin: 0 0 14px; padding: 6px 16px; border-radius: 999px; font-size: 22px;
  background: var(--accent-soft); border: 1px solid var(--accent-line);
}
.store-product-desc { color: var(--text-soft); font-size: 15px; line-height: 1.65; margin-bottom: 20px; }
.store-product-desc p { margin: 0 0 10px; }

/* One big photo per swipe, square, instead of a strip of 320px thumbnails. */
.store-product-media .store-gallery { margin: 0; gap: 0; border-radius: 18px; border: 1px solid var(--line); background: var(--surface-2); }
.store-product-media .store-gallery img { flex: 0 0 100%; width: 100%; height: auto; aspect-ratio: 1 / 1; border: 0; border-radius: 0; scroll-snap-align: center; }
/* Desktop controls for the strip (store_gallery.js unhides them): arrows over the photo's
   edges, dots under it, and a grab cursor for mouse drag. */
.store-gallery-wrap { position: relative; }
.store-gallery-wrap .store-gallery { cursor: grab; }
.store-gallery.is-dragging { cursor: grabbing; scroll-snap-type: none; user-select: none; }
.store-gallery:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.store-gallery-nav {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  width: 38px; height: 38px; border-radius: 50%; display: grid; place-items: center; padding: 0;
  background: rgba(0, 0, 0, 0.55); border: 1px solid rgba(255, 255, 255, 0.2); color: #fff;
  font-size: 22px; line-height: 1; cursor: pointer; backdrop-filter: blur(4px);
}
.store-gallery-nav[hidden] { display: none; }
.store-gallery-nav.prev { left: 10px; }
.store-gallery-nav.next { right: 10px; }
.store-gallery-nav:hover:not(:disabled) { background: var(--accent); border-color: var(--accent); color: #04150c; }
.store-gallery-nav:disabled { opacity: 0.35; cursor: default; }
.store-gallery-dots { display: flex; justify-content: center; gap: 7px; margin-top: 10px; }
.store-gallery-dots[hidden] { display: none; }
.store-gallery-dots button {
  width: 8px; height: 8px; padding: 0; border-radius: 50%; border: 0; cursor: pointer;
  background: var(--line); transition: background 0.15s ease, transform 0.15s ease;
}
.store-gallery-dots button.on { background: var(--accent); transform: scale(1.25); }
@media (pointer: coarse) { .store-gallery-nav { display: none !important; } }
.store-gallery-hint { margin-top: 8px; text-align: center; font-size: 12.5px; color: var(--text-soft); }
.store-gallery-empty {
  display: grid; place-items: center; aspect-ratio: 1 / 1; border-radius: 18px; border: 1px dashed var(--line);
  background: var(--surface-2); color: var(--text-tertiary); font-size: 14px;
}

/* The buy form as one card. */
.store-product-info #buy-form {
  padding: 22px; border: 1px solid var(--line); border-radius: 16px;
  background: linear-gradient(175deg, var(--surface) 0%, var(--card-gradient-end) 100%);
}
.store-product-info #buy-form .store-checkout-bar button[type="submit"] { padding: 14px 30px; font-size: 15px; font-weight: 800; border: 0; cursor: pointer; }
.store-early { padding: 14px 16px; border-radius: 12px; border: 1px solid rgba(255, 201, 74, 0.35); background: var(--gold-soft); color: var(--gold); font-weight: 600; }

/* ---------------------------------------------------------------------------
   Pedidos (/tienda/pedidos/): one card per order -- who/when and the status on
   the head row, what to pack, where to send it, then the shipping form (or the
   tracking once it has gone). Paid is amber because it is the one state that
   is waiting on the driver.
   --------------------------------------------------------------------------- */
.store-page .pill.is-todo {
  background: rgba(245, 166, 35, 0.12); border-color: rgba(245, 166, 35, 0.35); color: var(--amber);
}
.order-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.order-title { display: flex; flex-direction: column; gap: 2px; }
.order-id { font-size: 16px; font-weight: 800; letter-spacing: -0.01em; }
.order-meta { display: flex; align-items: center; gap: 12px; }
.order-total { font-size: 16px; font-weight: 800; color: var(--accent); }
.store-page .order-items {
  margin: 14px 0 0; padding-top: 12px; border-top: 1px solid var(--line-soft);
  display: flex; flex-direction: column; gap: 4px; font-size: 14px; color: var(--text-primary);
}
.store-page .order-items li { border: 0; padding: 0; }
.order-qty { color: var(--text-secondary); margin-right: 2px; }
.order-label {
  display: block; margin-bottom: 6px; color: var(--text-tertiary);
  font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
}
.order-ship-to { margin-top: 14px; }
.order-ship-to pre {
  margin: 0; padding: 12px 14px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--ink); color: var(--text-secondary); font-family: var(--font-mono);
  font-size: 12.5px; line-height: 1.55; white-space: pre-wrap;
}
.store-page .order-tracking { margin: 14px 0 0; font-size: 14px; }
.store-page .order-tracking .order-label { display: inline; margin: 0 8px 0 0; }
.store-page .order-ship {
  display: grid; gap: 0 12px; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  align-items: end; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line-soft);
}
.store-page .order-ship label { margin-bottom: 0; }
.store-page .order-ship button { height: 42px; }
@media (max-width: 640px) {
  .store-page .order-ship label { margin-bottom: 10px; }
}

/* Mi tienda's tabs (Merch / Telemetría), the pilot shell's tab look. */
.store-tabs { display: flex; gap: 2px; margin: 0 0 18px; border-bottom: 1px solid var(--line); }
.store-page .store-tab { padding: 10px 14px; font-size: 13.5px; font-weight: 700; color: var(--text-soft); border-bottom: 2px solid transparent; margin-bottom: -1px; text-decoration: none; }
.store-page .store-tab:hover { color: var(--text-primary); }
.store-page .store-tab.active { color: var(--accent); border-bottom-color: var(--accent); }

/* The Telemetría tab: the head sits in .store-page, the session cards below
   it in a box of the same width (see store_telemetry.html). */
.store-page.store-page-head-only { padding-bottom: 0; }
.store-telemetry { max-width: 900px; margin: 0 auto; padding: 0 20px 96px; }
.store-telemetry > .card { margin-bottom: 14px; }
.store-telemetry-intro { font-size: 13.5px; color: var(--text-secondary); margin: 0 0 16px; }
.store-telemetry-intro a, .store-telemetry .empty-hint a { color: var(--accent); font-weight: 600; }

/* Mi saldo's section headings in the mockups' style (bold, title case, white)
   rather than the store's small tracked caps. */
.store-page.balance-page h2 { font-size: 18px; font-weight: 800; text-transform: none; letter-spacing: -0.01em; color: var(--text-primary); }

/* The team plans' seat range ("De 2 a 5 asientos", "6 o más asientos"). */
.store-page .plan-seats { margin: 0 0 6px; font-size: 13px; font-weight: 700; color: var(--accent); }

/* The heading of the team plans section on /planes/. */
.store-page .plan-section-head { margin: 40px 0 16px; }
.store-page .plan-section-head h2 { margin: 0 0 4px; font-size: 22px; font-weight: 800; }
.store-page .plan-section-head p { margin: 0; color: var(--text-secondary); }

/* The team plans' "write us" button: same look as the subscribe buttons, but a link. `a.plan-btn-link` (not just the
   class) so it outranks `.store-page a:hover`, which would paint the text accent green on the green button. */
.store-page a.plan-btn-link {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  margin-top: auto; padding: 14px 20px; border-radius: 12px;
  font-size: 14.5px; font-weight: 700; letter-spacing: 0.01em; text-decoration: none;
  border: 1px solid var(--accent); background: var(--accent); color: var(--ink);
  transition: background 0.15s, border-color 0.15s, transform 0.1s, box-shadow 0.15s;
}
.store-page a.plan-btn-link svg { width: 18px; height: 18px; flex-shrink: 0; }
.store-page a.plan-btn-link:hover,
.store-page a.plan-btn-link:focus-visible {
  color: var(--ink); background: var(--accent-strong); border-color: var(--accent-strong); box-shadow: 0 8px 22px -8px var(--accent);
  transform: translateY(-1px);
}
.store-page a.plan-btn-link:active { transform: translateY(1px); }
.store-page a.plan-btn-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
