  /* SELECTABLE CONDITION ROWS — V3 (compact, no platform line)
     Applies only to items with conditionRows:true. Every selector below
     is scoped under .cond-rows / .result-right-noprice / :has(.cond-rows),
     so no other result row, page or breakpoint is affected. */

  .cond-rows{
    display:flex;flex-direction:column;gap:6px;margin-top:0;width:100%;
    --cond-check:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4.5 12.75 10.5 18.75 19.5 5.25'/%3E%3C/svg%3E");
  }

  .cond-row{
    display:flex;align-items:center;gap:8px;width:100%;
    background:#fff;border:1px solid var(--line);border-radius:8px;
    padding:6px 10px;text-align:left;cursor:pointer;
    font-family:'Inter';color:var(--ink);
    -webkit-tap-highlight-color:transparent;
    /* Only transform and box-shadow animate. Fill and border are left out
       deliberately so the default -> active colour step stays instant and
       the row settles back smoothly when another condition is picked. */
    transition:transform 140ms ease-out, box-shadow 140ms ease-out;
  }
  @media (prefers-reduced-motion:reduce){
    .cond-row{transition:none;}
  }
  /* The negative right margin closes the mark-to-label gap by 3px WITHOUT
     touching the row's `gap`, which also governs label-to-price — pulling
     that in too would have crowded the payout. The mark itself does not
     move, so the icon's alignment with the row's left padding is
     unchanged and nothing jumps between the selected and unselected
     states; the label simply starts 3px earlier and its flex track grows
     by the same 3px, which the price never notices.
     The circle's stroke is one step lighter than --line (#E3E8DD) so the
     unselected rows recede — still clearly a target, just no longer one
     of the darker marks in the selector. It is overridden to transparent
     on the selected row, so this only affects unselected circles. */
  .cond-row-mark{
    flex-shrink:0;width:19px;height:19px;border-radius:50%;
    border:1.5px solid #E7EBE1;background:#fff;
    display:flex;align-items:center;justify-content:center;
    margin-right:-3px;
  }
  /* overflow:hidden is a hard guarantee that the label can never render
     on top of the price the way .result-price used to bleed into the Add
     button. The widths below are sized so it never actually truncates —
     this is the safety net, not the mechanism. */
  .cond-row-label{
    /* Was flex:1. The icon now sits immediately after the label text, so
       the label may no longer eat the free track — if it did, the icon
       would be pushed across the row and land against the price. The
       label takes its natural width (still shrinkable, still ellipsised)
       and .cond-row-info carries the margin-right:auto instead. */
    flex:0 1 auto;min-width:0;font-size:.88rem;font-weight:500;line-height:1.2;
    letter-spacing:.2px;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
    /* One step up from --ink-soft: easier to scan than the 400/#5C6259
       pass, still clearly behind the title and the green prices.
       500 and 600 are both real loaded Inter weights (the URL requests
       400;500;600) — the 700 this used to carry was not, so the browser
       was synthesising a faux-bold that rendered heavier and wider than
       real Inter. */
    color:#4F554D;
  }

  /* INFO ICON — deliberately the quietest mark in the row.
     Muted grey-blue against a selector whose accents are all green, so
     it reads as chrome rather than as another piece of the choice. It
     must never out-weigh the label, the price or the checkmark.

     Height is capped below the 19px mark (17px on mobile), which is the
     row's tallest child, so this cannot grow the row. margin-right:auto
     is what keeps the price pinned right now that the label no longer
     spans the free track; the negative margin-left claws back most of
     the row's 8px `gap` so the icon sits a few pixels off the label
     rather than a third of the way to the price. */
  .cond-row-info{
    position:relative;
    /* Above .cond-row::after, the row's own mobile hit-slop pseudo, which
       is the row's last child in the box tree and would otherwise paint
       over this icon and swallow its taps. */
    z-index:2;
    flex:none;margin-left:-4px;margin-right:auto;
    display:inline-flex;align-items:center;justify-content:center;
    width:13px;height:13px;
    color:#8A96A8;opacity:.78;
    cursor:pointer;-webkit-tap-highlight-color:transparent;
    transition:color 120ms ease-out, opacity 120ms ease-out;
  }
  .cond-row-info svg{width:100%;height:100%;display:block;}
  /* Understated darkening only — no fill, no circle, no size change. */
  .cond-row-info:hover,
  .cond-row-info:focus-visible,
  .cond-row-info.is-open{color:#5E6B80;opacity:1;}
  .cond-row-info:focus{outline:none;}
  .cond-row-info:focus-visible{
    outline:2px solid #8A96A8;outline-offset:3px;border-radius:50%;
  }
  /* Comfortable target around a 13px glyph. The span has no padding, so
     its padding box IS the 13px content box and these insets resolve
     against that: 13 + 8 + 8 = 29px each way. Layout-free — an absolutely
     positioned pseudo-element does not size its parent. */
  .cond-row-info::after{content:'';position:absolute;inset:-8px;}

  .cond-row-price{
    flex-shrink:0;font-size:1.02rem;font-weight:600;
    color:var(--green-dark);white-space:nowrap;
  }

  /* DEFAULT selection — "Complete" on load, which the seller has not
     touched yet. A near-white fill and a soft neutral border: enough to
     read as chosen (helped by the solid green checkmark, which is
     identical in both states) without competing with the game title.
     Colours only — the 1px border width is unchanged, so nothing moves. */
  .cond-row.is-selected{
    background:#fcfdfc;
    border-color:#d5dbd2;
  }
  /* ACTIVE selection — the seller has tapped this selector. The row goes
     pure white against its near-white default and rises: elevation, not
     colour, is the signal. The only green left on the row is the
     checkmark and the payout price, which is the point — the brand
     accent reads as accent rather than as a wash. */
  .cond-rows.is-user-chosen .cond-row.is-selected{
    background:#ffffff;
    border-color:#b9c1b5;
    /* Deliberate-choice lift. transform is composited and does not
       participate in layout, so offsetHeight/offsetWidth, the card height
       and the Add button's position are all untouched — only the painted
       row grows, by 3.3px wide and 0.6px tall at mobile size. The 4px
       inter-row gap absorbs the vertical growth with room to spare, and
       z-index keeps the lifted row's shadow above its siblings.
       Not applied to the untouched default selection. */
    transform:scale(1.02);
    transform-origin:center center;
    box-shadow:0 1px 4px rgba(25,28,25,.10);
    position:relative;
    z-index:1;
  }
  /* The mark keeps its 19px box (17px on mobile) so nothing in the row
     shifts, but on selection the filled disc and its ring both go
     transparent — a bare checkmark is left sitting in the same slot.
     Only colours change here; width, height, border-width and
     border-radius are all untouched. */
  .cond-row.is-selected .cond-row-mark{
    background:transparent;border-color:transparent;
  }
  /* Checkmark: an inline SVG path in the Heroicons/Lucide idiom, with
     round caps and joins, applied as a MASK rather than a background
     image so the colour still comes from --green-dark (the same green as
     the payout price) instead of being baked into the data URI.
     The mark is a fixed-size flex container that centres its child, so
     this pseudo-element's own dimensions cannot move anything around it
     — position and spacing stay pixel-identical to the old border-drawn
     tick. stroke-width 3 in a 24 viewBox renders ~2.25px at 18px, so it
     is no heavier than the 2px border it replaces. */
  .cond-row.is-selected .cond-row-mark::after{
    content:'';width:17px;height:17px;flex-shrink:0;
    /* Fallback for anything without mask support: the previous
       border-drawn tick, so a browser that ignores the @supports block
       below still shows a checkmark rather than a solid green square. */
    box-sizing:border-box;width:6px;height:11px;margin-top:-2px;
    border:solid var(--green-dark);border-width:0 2px 2px 0;transform:rotate(45deg);
  }
  @supports ((-webkit-mask-image:url("")) or (mask-image:url(""))){
    .cond-row.is-selected .cond-row-mark::after{
      width:17px;height:17px;margin-top:0;
      border:0;transform:none;
      background-color:var(--green-dark);
      -webkit-mask:var(--cond-check) center / contain no-repeat;
              mask:var(--cond-check) center / contain no-repeat;
    }
  }
  /* Selection is carried by the row's fill, border and checkmark, so the
     label only needs a small tone step (dE 4.3) to reinforce it. Kept at
     the same 500 weight as the unselected labels deliberately: pushing it
     to 600 costs 5px of the horizontal headroom that keeps "Missing
     Manual" from truncating next to a 3-digit price. */
  .cond-row.is-selected .cond-row-label{font-weight:500;color:#464B45;}
  .cond-row.is-selected .cond-row-price{font-weight:700;}

  /* With the duplicate large price removed, the action slot holds only
     the Add button (or the qty stepper) — keep it on the right. */
  .result-right-noprice{justify-content:flex-end;}

  /* --- Tighten the surrounding stack, conditionRows cards only --- */
  .result-info:has(.cond-rows){gap:6px;}
  /* The title carries the hierarchy now that the platform line is gone:
     bigger and much heavier than the shared 340 weight, so it reads
     before the condition rows rather than competing with them.
     The margin-bottom sits on top of .result-info's own flex gap and is
     what separates the title from the selector, so the title reads as
     the card's header instead of as the first option in the list.
     Typography itself is untouched. */
  .result-info:has(.cond-rows) h4{margin-bottom:7px;font-weight:600;font-size:1.4rem;}
  .result-info:has(.cond-rows) .result-right{margin-top:2px;}

  @media (max-width:560px){
    .result-right-noprice{display:flex;justify-content:flex-end;}

    /* The three-column row (mark + label + price) is horizontally tight
       next to the 140px thumbnail: at ≤414px "Missing Manual" needed more
       width than its flex track and rendered over the price. The image,
       the card's outer width and the card's own 14px padding are all
       untouched — the space is reclaimed from the thumbnail-to-text
       gutter and the row's internal padding/gaps. */
    .result-row:has(.cond-rows){gap:6px;}

    /* 5px vertical padding + 17px mark keeps the visible row 30px tall.
       The whole button is the tap target; see the hit-slop below.
       Horizontal padding and gap were both trimmed 1px when the info
       icon landed: the icon costs ~15px of the label's track, and at
       360px "Missing Manual" next to a 3-digit price had only ~4px of
       headroom left — the same margin that already truncated once on a
       real iPhone, where Inter renders wider than this sandbox's
       fallback face. Vertical padding is untouched, so row height is
       unchanged. */
    .cond-row{padding:5px 5px;gap:5px;position:relative;}
    /* Invisible hit-slop — same pattern as the ± buttons' ::after at
       ≤430px. NOTE: inset on an absolutely positioned pseudo-element
       resolves against the PADDING box, so -2px here clears the row's 1px
       border by only 1px. Net tap area is 32px against a 30px visible
       box, with 2px of the 4px inter-row gap left untouched so no two
       rows' targets can overlap. Nothing shifts by a pixel. */
    .cond-row::after{content:'';position:absolute;inset:-2px 0;}
    .cond-row-mark{width:16px;height:16px;}
    .cond-row.is-selected .cond-row-mark::after{width:5.5px;height:10px;}
    @supports ((-webkit-mask-image:url("")) or (mask-image:url(""))){
      .cond-row.is-selected .cond-row-mark::after{width:17px;height:17px;}
    }
    /* Sized so the longest label ("Missing Manual") still fits in full in
       its worst case — selected, so bold and wider, next to a 3-digit
       price — at 360px. The price font is deliberately untouched. */
    .cond-row-label{font-size:.80rem;}
    /* 12px at ≤560px — still under the 16px mark, so the row height is
       set by the mark exactly as before. The row's gap drops to 6px here,
       so the negative margin drops with it to keep the same few-pixel
       offset from the label. */
    .cond-row-info{width:12px;height:12px;margin-left:-2px;}
    .cond-row-price{font-size:.95rem;}

    .result-info:has(.cond-rows){gap:5px;}
    .result-info:has(.cond-rows) h4{font-size:1.18rem;margin-bottom:7px;}
    /* Most of the 7px above is paid back by tightening the selector's own
       stack and closing the gap under it, so the card grows by 4px rather
       than 7. Row heights and the Add button are untouched. */
    .cond-rows{gap:4px;}
    .result-info:has(.cond-rows) .result-right{margin-top:0;}
    /* The Add button's own padding is the last big block of vertical
       space in the card. Trimmed here only — its font-size and the
       shared .result-add rule are untouched everywhere else. */
    .result-info:has(.cond-rows) .result-add{padding:11px 22px;}

    /* Slightly firmer lift on phones. Desktop's 1.02 plus its soft shadow
       reads a touch too faint at 390px, so the mobile tier alone nudges
       the scale up and warms the shadow — enough to register on tap
       without the row detaching from the card. No translateY: the row
       grows in place rather than rising off the surface.
       Only transform and box-shadow are overridden — colours, border,
       typography, timing and transform-origin all still come from the
       shared rules, and every declaration here sits inside the mobile
       query so desktop and tablet are untouched.
       Still layout-free: transform does not affect offsetWidth/Height,
       so the card, the rows and the Add button do not move. */
    .cond-rows.is-user-chosen .cond-row.is-selected{
      transform:scale(1.025);
      box-shadow:0 3px 8px rgba(25,28,25,.13);
    }
  }

  @media (min-width:761px){
    .cond-row-label{font-size:1rem;}
    .cond-row-price{font-size:1.15rem;}
  }

  /* ============================================================
     EXPERIMENT (v86) — COMPACT MOBILE PAYOUT, "Case + Game" ONLY

     Paired with condPriceHTML() in js/condition-rows.js, which writes
     BOTH price strings into .cond-row-price for that one condition when
     the payout carries 4+ digits. Everything here only chooses which of
     the two is shown — no width, spacing, font, colour or box property
     is set, so no row moves and no other condition is affected.

     Hide-by-default first, media-query show second (cascade order).
     Desktop never sees .price-compact.

     On mobile the exact string is not deleted, it is clipped to 1px and
     taken out of flow: a screen reader still announces the real payout
     ($12.75) while the eye sees the compact one ($12.8), which carries
     aria-hidden. Absolute positioning means it contributes zero width,
     so the label gets the space back.

     TO REMOVE: delete this block and the JS function it names.
     ============================================================ */
  .price-compact{display:none;}

  @media (max-width:560px){
    .price-full{
      position:absolute;width:1px;height:1px;overflow:hidden;
      clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;
    }
    .price-compact{display:inline;}
  }
