/*
 * Monex Products Section — frontend styles.
 *
 * Two authorable rendering modes: Product Cards and Standard Prices Table
 * (author-selected in Breakdance, never both in the DOM). Ported from the
 * Next.js app's .product-card* and .standard-prices* rules — but every
 * layout breakpoint is a container query on the Element's own width, so
 * dropping the section into a narrow Breakdance column collapses without
 * needing a smaller viewport.
 *
 * Non-typography design values consume CSS custom properties written by
 * css.twig at %%SELECTOR%%; fallbacks reproduce the app defaults.
 */

.monex-products,
.monex-products * { box-sizing: border-box; }

/* Screen-reader-only utility. Used to expose meaningful text to
 * assistive tech without visually rendering it — powers the "Loading"
 * announcement on skeleton cells, the table's <caption>, and other
 * a11y-only labels. Modern sr-only pattern: absolute + clip-path +
 * inset(50%) with margin -1px belt-and-suspenders. */
.monex-products__sr-only {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  clip-path: inset(50%) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

/* Shell contract — outer self-caps at 1280 and centers. Padding
 * matches the app's .products-section defaults. */
.monex-bd-products-section {
  width: 100%;
  max-width: 1280px;
  margin-inline: auto;
  box-sizing: border-box;
}

.monex-products {
  width: 100%;
  padding:
    var(--monex-pr-pad-top, 96px)
    var(--monex-pr-pad-x, 32px)
    var(--monex-pr-pad-bottom, 96px);
  background: var(--monex-pr-bg, #ecf2f5);
  color: #294560;
  font-family: "Open Sans", Arial, sans-serif;
  container-type: inline-size;
  container-name: monex-products;
}

/* Inner fills the padded outer — outer now owns width capping. */
.monex-products__inner {
  width: 100%;
}

.monex-products__intro { margin-bottom: 32px; max-width: 940px; }

/* Wrapper-scoped so specificity beats bare `h2` normalize + theme
 * `.entry-content h2 {}`. Author's Breakdance typography preset still
 * wins via %%SELECTOR%% at higher specificity. */
.monex-bd-products-section .monex-products__heading {
  margin: 0 0 18px;
  color: var(--monex-pr-heading-color, #102f49);
  font-family: var(--monex-pr-heading-font-family, inherit);
  font-size: var(--monex-pr-heading-font-size, clamp(2.4rem, 4vw, 3.4rem));
  font-weight: var(--monex-pr-heading-font-weight, 600);
  letter-spacing: -0.04em;
}

.monex-products__description {
  margin: 0;
  color: var(--monex-pr-desc-color, #294560);
  font-family: var(--monex-pr-desc-font-family, inherit);
  font-size: var(--monex-pr-desc-font-size, 1.05rem);
  font-weight: var(--monex-pr-desc-font-weight, 400);
  line-height: 1.55;
}

/* -----------------------------------------------------------
 * Live-quote state machine
 *
 *   data-monex-state on the section root, data-card-state on each
 *   card/row, both progress through: loading → fresh → stale → error.
 *
 *   loading — SSR seed, before the first /quotes reply arrives.
 *             Skeletons animate; no "Unavailable" copy shown.
 *   fresh   — most recent /quotes reply was source:"fresh".
 *   stale   — most recent /quotes reply was source:"stale"; last
 *             known-good values retained, subtle desaturation.
 *   error   — first reply completed AND this symbol had no data
 *             AND the manager holds no cached value for it. Only
 *             now do we surface "Unavailable" copy.
 * ---------------------------------------------------------- */

/* --- Skeleton shimmer for loading state ---------------------------------- */
.monex-products__skeleton {
  display: inline-block;
  min-width: 68px;
  height: 1.1em;
  border-radius: 3px;
  background: linear-gradient(90deg, rgba(150,167,183,0.20) 0%, rgba(150,167,183,0.42) 50%, rgba(150,167,183,0.20) 100%);
  background-size: 200% 100%;
  animation: monex-products-shimmer 1.2s ease-in-out infinite;
  vertical-align: baseline;
}
.monex-products__skeleton--sm { min-width: 44px; height: 0.85em; }

@keyframes monex-products-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* Standard Prices cells: skeleton fits inside the cell */
.standard-prices td .monex-products__skeleton {
  width: 80%;
  min-width: 60px;
  height: 0.95em;
}

/* Reduced-motion fallback: static block, no shimmer. */
@media (prefers-reduced-motion: reduce) {
  .monex-products__skeleton { animation: none; }
}

/* Once a card/row leaves loading state, any residual skeleton spans lose
   all visuals and become plain inline text containers. Table cells rely
   on this because their skeleton is the same element that carries the
   data-field target — JS setting textContent on it doesn't remove the
   class, only the text. Cards are already correct because their skeleton
   is a child of the data-field element (destroyed by textContent). */
.monex-products [data-card-state]:not([data-card-state="loading"]) .monex-products__skeleton {
  background: none;
  animation: none;
  min-width: 0;
  height: auto;
  border-radius: 0;
}

/* --- fresh: nothing special (default appearance) ------------------------- */

/* --- stale: subtle dim on quotes area + timestamp gets a stale marker --- */
.monex-products[data-monex-state="stale"] .product-quote__value,
.monex-products[data-monex-state="stale"] .standard-prices__frame {
  filter: saturate(0.85);
}
.product-card[data-card-state="stale"] .product-card__updated::before,
.monex-products[data-monex-state="stale"] .standard-prices__note::before {
  content: '● ';
  color: #c94e46;
  font-weight: 700;
}

/* --- error: real "Unavailable" copy replaces the skeleton --------------- */
.product-card[data-card-state="error"] [data-field="ask"],
.product-card[data-card-state="error"] [data-field="bid"] {
  color: rgba(255,255,255,0.65);
}
/* JS writes the strings; CSS below just hides the residual skeleton block. */
.product-card[data-card-state="error"] .monex-products__skeleton,
.standard-prices tr[data-card-state="error"] .monex-products__skeleton { display: none; }

/* Loading skeletons already imply the manager hasn't answered, so hide
   the "updated" line entirely until we have a real timestamp. */
.product-card[data-card-state="loading"] .product-card__updated { visibility: hidden; }

/* Legacy attribute compatibility with any external CSS: mirror the state.
   (Pre-refactor CSS may still target data-monex-stale.) */
.monex-products[data-monex-state="stale"] { --monex-pr-state-stale: 1; }


/* ==================== PRODUCT CARDS ==================== */

.product-grid {
  display: grid;
  grid-template-columns: repeat(var(--monex-pr-cards-cols, 4), minmax(0, 1fr));
  gap: var(--monex-pr-cards-gap, 18px);
}

.product-card {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--monex-pr-card-border, rgba(41, 69, 96, 0.24));
  border-radius: var(--monex-pr-card-radius, 0);
  background: var(--monex-pr-card-bg, #294560);
  box-shadow: var(--monex-pr-card-shadow, 0 16px 36px rgba(20, 43, 63, 0.12));
  transition: box-shadow 180ms ease, transform 180ms ease;
}

.product-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 22px 44px rgba(20, 43, 63, 0.2);
}

/* Focus-visible ring on the CTA anchor (the actual focus target
 * inside each card) covers keyboard users. Card-hover translate is
 * decorative; suppress it under prefers-reduced-motion. */
@media (prefers-reduced-motion: reduce) {
  .product-card {
    transition: none;
  }
  .product-card:hover {
    transform: none;
  }
  .product-call-button,
  .product-call-button:hover,
  .product-call-button:focus-visible,
  .product-call-button:active {
    transition: none;
    transform: none;
    filter: none;
  }
}

.product-card__media {
  display: grid;
  place-items: center;
  min-height: var(--monex-pr-image-height, 220px);
  padding: 20px;
  background: var(--monex-pr-image-bg, radial-gradient(circle at 50% 42%, #ffffff 0%, #f8f7f3 50%, #e9edf1 100%));
}

.product-card__media img {
  width: min(100%, 220px);
  height: var(--monex-pr-image-inner, 180px);
  object-fit: var(--monex-pr-image-fit, contain);
  filter: drop-shadow(0 14px 14px rgba(16, 47, 73, 0.16));
}

.product-card__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  padding: var(--monex-pr-card-padding, 20px 18px);
  background: var(--monex-pr-card-body-bg, linear-gradient(160deg, #315573 0%, #294560 54%, #20384e 100%));
}

/* Card tones — configurable defaults per repeater item */
.product-card--navy  .product-card__body { background: #2d4f6b; }
.product-card--teal  .product-card__body { background: #4b898f; }
.product-card--blue  .product-card__body { background: #3f809d; }
.product-card--slate .product-card__body { background: #7c8193; }

.product-card__heading {
  min-height: 78px;
  margin-bottom: 16px;
  text-align: center;
}

.product-card__heading > span {
  display: block;
  margin-bottom: 5px;
  color: var(--monex-pr-metal-color, #ffffff);
  font-family: var(--monex-pr-metal-font-family, inherit);
  font-size: var(--monex-pr-metal-font-size, clamp(1.7rem, 2.5vw, 2.1rem));
  font-weight: var(--monex-pr-metal-font-weight, 800);
  letter-spacing: -0.035em;
  line-height: 150%;
}

.monex-bd-products-section .product-card__heading h4 {
  margin: 0;
  color: var(--monex-pr-title-color, rgba(255, 255, 255, 0.9));
  font-family: var(--monex-pr-title-font-family, inherit);
  font-size: var(--monex-pr-title-font-size, 1.05rem);
  font-weight: var(--monex-pr-title-font-weight, 500);
  line-height: 1.3;
  min-height: 44px;
}

.product-quotes {
  display: grid;
  gap: var(--monex-pr-quote-gap, 12px);
}

.product-quote__label {
  display: block;
  margin-bottom: 5px;
  color: #ffffff;
  font-size: 0.92rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.product-quote__value {
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  min-height: 58px;
  padding: 10px 14px;
  background: #ffffff;
  box-shadow: 0 10px 22px rgba(9, 26, 41, 0.14);
}

.product-quote__value strong {
  min-width: 0;
  color: var(--monex-pr-price-color, #102f49);
  font-family: var(--monex-pr-price-font-family, inherit);
  font-size: var(--monex-pr-price-font-size, clamp(1rem, 1.5vw, 1.22rem));
  font-weight: var(--monex-pr-price-font-weight, 600);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.product-quote__direction {
  width: 0;
  height: 0;
  border-right: 9px solid transparent;
  border-bottom: 11px solid var(--monex-pr-neutral-color, #85909a);
  border-left: 9px solid transparent;
}

.product-quote__direction--positive { border-bottom-color: var(--monex-pr-positive-color, #32a866); }
.product-quote__direction--negative { border-top: 11px solid var(--monex-pr-negative-color, #c94e46); border-bottom: 0; }
.product-quote__direction--neutral  { border-bottom-color: var(--monex-pr-neutral-color, #85909a); }

.product-quote__change {
  font-family: var(--monex-pr-change-font-family, inherit);
  font-size: var(--monex-pr-change-font-size, 0.92rem);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.product-quote__change--positive { color: var(--monex-pr-positive-color, #32a866); }
.product-quote__change--negative { color: var(--monex-pr-negative-color, #c94e46); }
.product-quote__change--neutral  { color: var(--monex-pr-neutral-color,  #6d7781); }

.product-card__updated {
  margin: 12px 0 16px;
  color: var(--monex-pr-updated-color, rgba(255, 255, 255, 0.67));
  font-family: var(--monex-pr-updated-font-family, inherit);
  font-size: var(--monex-pr-updated-font-size, 0.76rem);
  line-height: 1.4;
  text-align: center;
}

/* Product Card CTA — dimensions and placement stay card-specific
 * (smaller padding, smaller font, card-friendly min-height and top
 * margin), but the interaction language now matches the shared
 * landing-page CTA pattern used by the Hero, About, and Video CTAs:
 *
 *   - background stays #32a866 (author still overrides via var)
 *   - color !important + explicit :link/:visited/:hover normalization
 *     so theme link styles can't repaint the label
 *   - hover animates filter: brightness(1.05) + a 1px lift, not a
 *     background swap — matches Hero exactly
 *   - active state gives a small press-down (translateY(0) + slight
 *     darken) — consolidated below in the shared :active block
 *   - the chunky green drop-shadow the card CTA used to carry
 *     (`box-shadow: 0 12px 24px rgba(20,115,64,.25)`) is removed
 *     because no other landing CTA uses one
 */
.product-call-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 46px;
  margin-top: 25px;
  padding: 10px 14px;
  border-radius: var(--monex-pr-cta-radius, 9px);
  background: var(--monex-pr-cta-bg, #32a866);
  color: var(--monex-pr-cta-color, #ffffff) !important;
  font-family: var(--monex-pr-cta-font-family, inherit);
  font-size: var(--monex-pr-cta-font-size, 0.88rem);
  font-weight: 700;
  text-align: center;
  text-decoration: none;
  transition: transform 160ms ease, filter 160ms ease;
}
.product-call-button:link,
.product-call-button:visited { color: var(--monex-pr-cta-color, #ffffff); }
.product-call-button:hover,
.product-call-button:focus-visible {
  color: var(--monex-pr-cta-color, #ffffff);
  text-decoration: none;
  filter: brightness(1.05);
  transform: translateY(-1px);
}
.product-call-button:active {
  transform: translateY(0);
  filter: brightness(0.95);
}
.product-call-button svg { width: 18px; height: 18px; flex: 0 0 auto; }

/* Real focus ring for keyboard users. White ring on dark card body
 * gives ~5:1 contrast against every card tone (default navy through
 * slate). Same pattern as Hero and Video CTAs. */
.product-call-button:focus-visible {
  outline: 3px solid #ffffff;
  outline-offset: 3px;
}

/* ==================== STANDARD PRICES TABLE ==================== */

.standard-prices { width: 100%; }

.standard-prices__intro { max-width: 940px; margin-bottom: 30px; }
.monex-bd-products-section .standard-prices__intro h3 {
  margin: 0 0 18px;
  color: var(--monex-pr-tintro-color, #102f49);
  font-family: var(--monex-pr-tintro-font-family, inherit);
  font-size: var(--monex-pr-tintro-font-size, clamp(2.4rem, 4vw, 3.4rem));
  font-weight: var(--monex-pr-tintro-font-weight, 600);
  letter-spacing: -0.04em;
}
.standard-prices__intro p {
  margin: 0;
  color: var(--monex-pr-tintrodesc-color, #294560);
  font-family: var(--monex-pr-tintrodesc-font-family, inherit);
  font-size: var(--monex-pr-tintrodesc-font-size, 1.02rem);
  line-height: 1.55;
}

.standard-prices__frame {
  overflow: hidden;
  border: 1px solid rgba(41, 69, 96, 0.26);
  background: #ffffff;
  box-shadow: 0 18px 42px rgba(20, 43, 63, 0.12);
}

.standard-prices__scroll {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
}

.standard-prices table {
  width: 100%;
  min-width: 1080px;
  border-spacing: 0;
  color: #294560;
  font-variant-numeric: tabular-nums;
}

.standard-prices th,
.standard-prices td {
  padding: 17px 18px;
  text-align: right;
  white-space: nowrap;
  font-family: var(--monex-pr-cell-font-family, inherit);
  font-size: var(--monex-pr-cell-font-size, 0.94rem);
}

.standard-prices thead th {
  border-right: 1px solid rgba(255, 255, 255, 0.1);
  background: var(--monex-pr-thead-bg, #294560);
  color: var(--monex-pr-thead-color, #ffffff);
  font-size: 0.96rem;
  font-weight: 700;
  letter-spacing: 0.01em;
}
/* Sticky first column — Product header stays pinned to the left edge while
   the horizontally-scrolling frame pans Bid/Ask/etc under it. Matches the
   Next.js app's globals.css treatment. z-index 2 sits above the tbody
   sticky column (z-index 1) so the header always renders on top. Reset in
   the mobile card blocks below (@container / @media). */
.standard-prices thead th:first-child {
  position: sticky;
  left: 0;
  z-index: 2;
  width: 20%;
  min-width: 280px;
  text-align: left;
}
.standard-prices thead th:last-child  { border-right: 0; }

.standard-prices tbody tr { background: #ffffff; }
.standard-prices tbody tr:nth-child(even) { background: #ecf2f5; }
.standard-prices tbody tr:hover { background: #bed2db; box-shadow: inset 4px 0 0 var(--monex-pr-positive-color, #32a866); }

.standard-prices tbody th,
.standard-prices tbody td { border-bottom: 1px solid #bed2db; font-size: 0.94rem; }
.standard-prices tbody tr:last-child th{ border-bottom: 0; }

/* Sticky product-name column in body rows. background: inherit picks up the
   row's alternating stripe (white / #ecf2f5) and hover colour so nothing
   scrolls "through" the pinned cell. The right-side shadow softly hints
   that content continues under the sticky column. */
.standard-prices tbody th {
  position: sticky;
  left: 0;
  z-index: 1;
  min-width: 280px;
  background: inherit;
  color: #294560;
  font-size: 0.98rem;
  font-weight: 600;
  text-align: left;
  box-shadow: 10px 0 18px -18px rgba(16, 47, 73, 0.7);
}

.standard-prices__live {
  display: inline-block;
  width: 8px; height: 8px;
  margin-right: 10px;
  border-radius: 50%;
  background: #44d080;
  box-shadow: 0 0 0 4px rgba(68, 208, 128, 0.14);
  vertical-align: middle;
}

.standard-prices__change {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  gap: 7px;
  min-width: 90px;
  font-weight: 700;
}
.standard-prices__change--positive { color: var(--monex-pr-positive-color, #32a866); }
.standard-prices__change--negative { color: var(--monex-pr-negative-color, #c94e46); }
.standard-prices__change--neutral  { color: var(--monex-pr-neutral-color,  #7e8790); }

.standard-prices__direction {
  width: 0; height: 0;
  border-right: 6px solid transparent;
  border-bottom: 8px solid var(--monex-pr-neutral-color, #7e8790);
  border-left: 6px solid transparent;
}
.standard-prices__direction--positive { border-bottom-color: var(--monex-pr-positive-color, #32a866); }
.standard-prices__direction--negative { border-top: 8px solid var(--monex-pr-negative-color, #c94e46); border-bottom: 0; }
.standard-prices__direction--neutral  { border-bottom-color: var(--monex-pr-neutral-color,  #7e8790); }

.standard-prices__note {
  display: flex;
  justify-content: flex-end;
  gap: 6px 18px;
  flex-wrap: wrap;
  margin: 13px 4px 0;
  color: var(--monex-pr-updated-color, #747d86);
  font-family: var(--monex-pr-updated-font-family, inherit);
  font-size: var(--monex-pr-updated-font-size, 0.78rem);
  text-align: right;
}

.monex-products__disclaimer {
  max-width: 100%;
  padding: 0 20px;
  margin: 20px 0 0;
  color: var(--monex-pr-disc-color, #747d86);
  font-family: var(--monex-pr-disc-font-family, inherit);
  font-size: var(--monex-pr-disc-font-size, 0.72rem);
  line-height: 1.55;
}

/* ---- Chart column (desktop, table mode) ----
 *
 * Rightmost column. Compact: icon-only link right-aligned inside the cell,
 * text label is visually hidden at desktop widths. Interaction is a real
 * link so it works with keyboard nav / middle-click / open-in-new-tab.
 * The link is intentionally rendered even when data-card-state="error" —
 * the chart destination is independent of live pricing.
 */
.standard-prices__chart-col {
  width: 92px;
  min-width: 92px;
  text-align: center;
}
.standard-prices__chart-cell {
  /* Zero cell padding — the <a> owns the click area for the whole cell. */
  padding: 0;
  text-align: center;
}
.standard-prices__chart-link {
  /* Fill the entire <td>: any pixel of the cell is a link hit-target.
     Vertical padding matches the base .standard-prices td padding
     (17px) so row heights stay consistent with the other columns.
     Horizontal padding matches the previous cell padding envelope. */
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  height: 100%;
  padding: 0px 12px;
  color: var(--monex-pr-chart-color, #294560);
  background: transparent;
  text-decoration: none;
  transition: background-color 140ms ease, color 140ms ease, transform 140ms ease;
}
.standard-prices__chart-link:hover,
.standard-prices__chart-link:focus-visible {
  color: var(--monex-pr-positive-color, #32a866);
  outline: none;
}
.standard-prices__chart-link:focus-visible {
  outline: 3px solid #32a866;
  outline-offset: 2px;
  box-shadow: 0 0 0 2px rgba(50, 168, 102, 0.55);
}

.standard-prices__chart-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  flex: 0 0 auto;
}
.standard-prices__chart-icon svg,
.standard-prices__chart-icon img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: contain;
}
.standard-prices__chart-label {
  /* Hidden at desktop widths — the icon carries the meaning here, and
     the aria-label on the parent <a> already supplies the accessible
     name for screen readers ("[Product] — view live price chart"), so
     display: none does not hurt a11y. The mobile blocks below flip this
     back to inline-block to reveal the CTA text on the card layout. */
  display: none;
}

/* ==================== CONTAINER RESPONSIVENESS ==================== */

@container monex-products (max-width: 1100px) {
  .product-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@container monex-products (max-width: 720px) {
  .monex-products { padding-left: 16px; padding-right: 16px; padding-top: 64px; padding-bottom: 64px; }
  .product-grid { grid-template-columns: 1fr; }
  .monex-bd-products-section .standard-prices__intro h3 { font-size: var(--monex-pr-tintro-font-size, clamp(2.4rem, 4vw, 3.4rem)); }
}

/* ---- Standard Prices Table — mobile card layout ----
 *
 * Below ~650px container width the semantic <table> reshapes into a stack
 * of product cards. One row = one card. Same DOM, same JS quote wiring
 * (data-symbol + data-field selectors still match), just a CSS reshape
 * driven by the pre-existing data-label attributes on every <td>.
 *
 * Card composition (per spec):
 *
 *   [ Product title spans 2 columns ]
 *   [ Bid    | Ask  ]
 *   [ Change | Open ]
 *   [ High   | Low  ]
 *   [ Chart CTA spans 2 columns ]
 *
 * The chart cell is a full-width action link — visually distinct from
 * the metric cells so it reads as an action, not another price.
 */

@container monex-products (max-width: 650px) {
  /* Frame + scroll container drop their shadow/border; each row card owns
     its own visual container instead. */
  .standard-prices__frame {
    overflow: visible;
    border: 0;
    background: transparent;
    box-shadow: none;
  }
  .standard-prices__scroll { overflow: visible; }

  .standard-prices table {
    display: block;
    width: 100%;
    min-width: 0;
  }

  /* Hide the header row (accessibly — screen readers still get the labels
     via the data-label ::before content). */
  .standard-prices thead {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }

  .standard-prices tbody {
    display: grid;
    gap: 14px;
  }

  .standard-prices tbody tr,
  .standard-prices tbody tr:nth-child(even) {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    overflow: hidden;
    border: 1px solid rgba(41, 69, 96, 0.22);
    border-radius: 6px;
    background: #ffffff;
    box-shadow: 0 10px 24px rgba(20, 43, 63, 0.08);
  }
  .standard-prices tbody tr:hover {
    background: #ffffff;
    box-shadow: 0 10px 24px rgba(20, 43, 63, 0.08);
  }

  /* Product title header — navy banner spanning both columns. Reset the
     desktop sticky positioning so the cell drops into the card grid flow. */
  .standard-prices tbody th {
    position: static;
    left: auto;
    z-index: auto;
    box-shadow: none;
    grid-column: 1 / -1;
    min-width: 0;
    padding: 14px 16px;
    border-bottom: 0;
    background: var(--monex-pr-thead-bg, #294560);
    color: #ffffff;
    font-size: 0.98rem;
    line-height: 1.35;
    font-weight: 700;
    text-align: left;
    white-space: normal;
  }

  /* Metric cells — 2 across, thin separators, label + value stacked. */
  .standard-prices tbody td {
    display: grid;
    gap: 4px;
    min-width: 0;
    padding: 12px 14px;
    border-bottom: 1px solid var(--landing-blue-300, #bed2db);
    color: #294560;
    font-size: 0.94rem;
    font-weight: 700;
    line-height: 1.25;
    text-align: left;
    white-space: normal;
  }
  .standard-prices tbody td:nth-of-type(odd) {
    border-right: 1px solid var(--landing-blue-300, #bed2db);
  }
  .standard-prices tbody td::before {
    color: #7a8490;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    content: attr(data-label);
  }

  /* The change cell's inline-flex wrapper wants left-alignment on mobile. */
  .standard-prices tbody td .standard-prices__change {
    justify-content: flex-start;
    gap: 6px;
    min-width: 0;
  }

  /* --------- Chart CTA row ---------
   * Full-width action strip below the metrics. Plain text link on the
   * white card background — reads as an action via a subtle top
   * separator and green hover state, not a bright button. The entire
   * row is clickable.
   *
   * Selectors carry `.standard-prices tbody td.standard-prices__chart-cell`
   * (two classes + descendant) so they beat the generic
   * `.standard-prices tbody td:nth-of-type(odd)` seam and the base
   * `.standard-prices tbody td::before` label emitter above.
   */
  .standard-prices tbody td.standard-prices__chart-cell {
    grid-column: 1 / -1;
    display: block;
    padding: 0;
    border-right: 0;
    border-bottom: 0;
    background: #ffffff;
    text-align: left;
  }
  .standard-prices tbody td.standard-prices__chart-cell::before {
    content: none;
  }

  .standard-prices__chart-link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    width: 100%;
    padding: 14px 16px;
    border-radius: 0;
    background: transparent;
    color: #294560;
    font-size: 0.92rem;
    font-weight: 700;
    letter-spacing: 0.01em;
    text-transform: none;
    text-decoration: none;
    border-top: 1px solid rgba(41, 69, 96, 0.14);
    box-shadow: none;
  }
  .standard-prices__chart-link:hover,
  .standard-prices__chart-link:focus-visible {
    color: #32a866;
    transform: none;
  }
  .standard-prices__chart-label {
    /* Un-hide the label at mobile — it's the CTA's actual text. */
    display: inline-block;
    text-align: left;
  }
  .standard-prices__chart-icon {
    width: 20px;
    height: 20px;
  }

  /* --------- Loading skeleton: numeric cells only ---------
   * The chart CTA row already reads correctly at loading time — no
   * skeleton class was ever put on it. Explicit rule reinforces that
   * loading/error states MUST NOT hide or destabilise the chart CTA.
   */
  .standard-prices tbody tr[data-card-state="loading"] .standard-prices__chart-cell,
  .standard-prices tbody tr[data-card-state="error"]   .standard-prices__chart-cell,
  .standard-prices tbody tr[data-card-state="stale"]   .standard-prices__chart-cell {
    opacity: 1;
    filter: none;
  }
}

/* At even narrower widths (≤ 414px), keep 2 columns per spec — the grid
   already handles it — but tighten padding so the cards don't push past
   the container edge. */
@container monex-products (max-width: 414px) {
  .standard-prices tbody td { padding: 10px 12px; }
  .standard-prices tbody th { padding: 12px 14px; font-size: 0.94rem; }
  .standard-prices__chart-link { padding: 12px 14px; }
}

/* -------------------------------------------------------------------
 * VIEWPORT-QUERY MIRROR of the mobile card layout above.
 *
 * The @container rules are the source of truth: they let the mobile
 * card layout fire whenever the Element's own inline-size is narrow,
 * even inside a wide viewport (narrow Breakdance column).
 *
 * These @media rules exist so the mobile card layout ALSO fires on any
 * narrow-viewport device regardless of Breakdance's wrapper structure,
 * plugin caching, or any environment where container-query resolution
 * against the named container may not be behaving as expected. When
 * both queries match (the common phone-viewport case), the rules are
 * identical and produce the same result — no cascade conflict.
 *
 * Keep the two blocks in lock-step. If you change one, change the other.
 * ------------------------------------------------------------------- */

@media (max-width: 650px) {
  .monex-products .standard-prices__frame {
    overflow: visible;
    border: 0;
    background: transparent;
    box-shadow: none;
  }
  .monex-products .standard-prices__scroll { overflow: visible; }

  .monex-products .standard-prices table {
    display: block;
    width: 100%;
    min-width: 0;
  }

  .monex-products .standard-prices thead {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }

  .monex-products .standard-prices tbody {
    display: grid;
    gap: 14px;
  }

  .monex-products .standard-prices tbody tr,
  .monex-products .standard-prices tbody tr:nth-child(even) {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    overflow: hidden;
    border: 1px solid rgba(41, 69, 96, 0.22);
    border-radius: 6px;
    background: #ffffff;
    box-shadow: 0 10px 24px rgba(20, 43, 63, 0.08);
  }
  .monex-products .standard-prices tbody tr:hover {
    background: #ffffff;
    box-shadow: 0 10px 24px rgba(20, 43, 63, 0.08);
  }

  .monex-products .standard-prices tbody th {
    position: static;
    left: auto;
    z-index: auto;
    box-shadow: none;
    grid-column: 1 / -1;
    min-width: 0;
    padding: 14px 16px;
    border-bottom: 0;
    background: var(--monex-pr-thead-bg, #294560);
    color: #ffffff;
    font-size: 0.98rem;
    line-height: 1.35;
    font-weight: 700;
    text-align: left;
    white-space: normal;
  }

  .monex-products .standard-prices tbody td {
    display: grid;
    gap: 4px;
    min-width: 0;
    padding: 12px 14px;
    border-bottom: 1px solid var(--landing-blue-300, #bed2db);
    color: #294560;
    font-size: 0.94rem;
    font-weight: 700;
    line-height: 1.25;
    text-align: left;
    white-space: normal;
  }
  .monex-products .standard-prices tbody td:nth-of-type(odd) {
    border-right: 1px solid var(--landing-blue-300, #bed2db);
  }
  .monex-products .standard-prices tbody td::before {
    color: #7a8490;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    content: attr(data-label);
  }

  .monex-products .standard-prices tbody td .standard-prices__change {
    justify-content: flex-start;
    gap: 6px;
    min-width: 0;
  }

  .monex-products .standard-prices tbody td.standard-prices__chart-cell {
    grid-column: 1 / -1;
    display: block;
    padding: 0;
    border-right: 0;
    border-bottom: 0;
    background: #ffffff;
    text-align: left;
  }
  .monex-products .standard-prices tbody td.standard-prices__chart-cell::before {
    content: none;
  }

  .monex-products .standard-prices__chart-link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    width: 100%;
    padding: 14px 16px;
    border-radius: 0;
    background: transparent;
    color: #294560;
    font-size: 0.92rem;
    font-weight: 700;
    letter-spacing: 0.01em;
    text-transform: none;
    text-decoration: none;
    border-top: 1px solid rgba(41, 69, 96, 0.14);
    box-shadow: none;
  }
  .monex-products .standard-prices__chart-link:hover,
  .monex-products .standard-prices__chart-link:focus-visible {
    color: #32a866;
    transform: none;
  }
  .monex-products .standard-prices__chart-label {
    display: inline-block;
    text-align: left;
  }
  .monex-products .standard-prices__chart-icon {
    width: 20px;
    height: 20px;
  }

  .monex-products .standard-prices tbody tr[data-card-state="loading"] .standard-prices__chart-cell,
  .monex-products .standard-prices tbody tr[data-card-state="error"]   .standard-prices__chart-cell,
  .monex-products .standard-prices tbody tr[data-card-state="stale"]   .standard-prices__chart-cell {
    opacity: 1;
    filter: none;
  }
}

@media (max-width: 414px) {
  .monex-products .standard-prices tbody td { padding: 10px 12px; }
  .monex-products .standard-prices tbody th { padding: 12px 14px; font-size: 0.94rem; }
  .monex-products .standard-prices__chart-link { padding: 12px 14px; }
}