/*!
 * TBD Apparel Configurator
 * Copyright (c) 2026 TshirtByDesign.com. All rights reserved.
 * Proprietary and confidential. Not licensed for redistribution or reuse.
 */
/* TBD Configurator — Product Page CSS
   Clean rewrite — no duplicate or conflicting rules
   ================================================================ */
:root {
    --tbd-navy:   #1a3a6b;
    --tbd-green:  #2e7d32;
    --tbd-green2: #1b5e20;
    --tbd-orange: #e65100;
    --tbd-gray1:  #f5f6f8;
    --tbd-gray2:  #e8eaf0;
    --tbd-gray3:  #c8cdd8;
    --tbd-gray4:  #8892a4;
    --tbd-dark:   #1e2230;
    --tbd-radius: 5px;
}

/* ── Configurator container ── */
.tbd-configurator {
    width: 100%;
    border: 1px solid #c8d8f0;
    border-radius: var(--tbd-radius);
    overflow: hidden;
    margin-bottom: 20px;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

/* ── Product header (title + price inside configurator) ── */
.tbd-product-header {
    padding: 12px 16px 8px;
    border-bottom: 1px solid var(--tbd-gray2);
}
.tbd-product-title {
    font-size: 18px;
    font-weight: 700;
    color: var(--tbd-dark);
    margin: 0 0 4px 0;
    line-height: 1.3;
}
.tbd-product-price {
    font-size: 14px;
    font-weight: 600;
    color: var(--tbd-dark);
    margin: 0;
}

/* ── Header bar ── */
.tbd-hdr {
    background: var(--tbd-navy);
    color: #fff;
    padding: 10px 16px;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 1px;
    text-transform: uppercase;
}

/* ── Fields ── */
.tbd-field {
    padding: 14px 16px;
    border-bottom: 1px solid var(--tbd-gray2);
}
.tbd-field:last-of-type { border-bottom: none; }
.tbd-field-label {
    font-size: 12px;
    font-weight: 700;
    color: var(--tbd-dark);
    margin-bottom: 10px;
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}
.tbd-size-chart-link {
    font-size: 11px;
    font-weight: 400;
    color: var(--tbd-navy);
    text-decoration: underline;
}

/* ── Decoration mode tiles ── */
.tbd-modes {
    display: flex;
    gap: 8px;
    padding: 14px 16px;
    border-bottom: 1px solid var(--tbd-gray2);
    flex-wrap: wrap;
}
/* display:flex overrides the hidden attribute, so hiding the row needs saying outright.
   Set in PHP when the product offers fewer than two decoration methods. */
.tbd-modes[hidden] { display: none; }
.tbd-mode {
    flex: 1;
    min-width: 70px;
    border: 2px solid var(--tbd-gray3);
    border-radius: var(--tbd-radius);
    background: #fff;
    cursor: pointer;
    padding: 10px 8px 8px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;
    font-size: 12px;
    font-weight: 600;
    color: var(--tbd-gray4);
    position: relative;
    transition: all .15s;
    font-family: inherit;
    min-height: 70px;
}
.tbd-mode:hover { border-color: var(--tbd-navy); color: var(--tbd-navy); }
.tbd-mode.active { border-color: var(--tbd-navy); background: #f0f4ff; color: var(--tbd-navy); }
.tbd-mode-check {
    position: absolute;
    top: -8px; left: -8px;
    width: 18px; height: 18px;
    background: var(--tbd-green);
    color: #fff;
    border-radius: 50%;
    font-size: 10px;
    font-weight: 700;
    display: none;
    align-items: center;
    justify-content: center;
    line-height: 1;
}
.tbd-mode.active .tbd-mode-check { display: flex; }
.tbd-mode-icon { width: 24px; height: 24px; }

/* ── Color swatches ── */
.tbd-swatches { display: flex; flex-wrap: wrap; gap: 7px; }
.tbd-swatch {
    width: 26px; height: 26px;
    border-radius: 50%;
    border: 2px solid transparent;
    cursor: pointer;
    flex-shrink: 0;
    transition: transform .12s, border-color .12s;
    padding: 0;
}
.tbd-swatch:hover { transform: scale(1.18); }
.tbd-swatch.active {
    border-color: var(--tbd-navy) !important;
    box-shadow: 0 0 0 2px rgba(26,58,107,.2);
    transform: scale(1.1);
}

/* ── Size qty inputs ── */
.tbd-sizes {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 6px;
}
@media(min-width:480px){ .tbd-sizes { grid-template-columns: repeat(8, 1fr); } }
.tbd-size-col { display: flex; flex-direction: column; align-items: center; gap: 3px; }
.tbd-size-qty {
    width: 100%;
    padding: 8px 2px;
    text-align: center;
    border: 1.5px solid var(--tbd-gray3);
    border-radius: var(--tbd-radius);
    font-size: 15px;
    font-family: inherit;
    color: var(--tbd-dark);
    /* Native number spinners left ON: the up/down arrows appear on hover and are
       the quickest way to nudge a quantity on desktop. They were suppressed here,
       which is why the boxes looked inert. */
    min-height: 44px;
}
/* Keep the spinners visible rather than only on hover, so it's obvious they're
   there. Touch devices show no spinner at all, so nothing is lost on mobile. */
.tbd-size-qty::-webkit-inner-spin-button,
.tbd-size-qty::-webkit-outer-spin-button { opacity: 1; }
.tbd-size-qty:focus { outline: none; border-color: var(--tbd-navy); }
.tbd-size-lbl { font-size: 11px; font-weight: 700; color: var(--tbd-gray4); }
.tbd-size-uc  { font-size: 10px; color: var(--tbd-orange); font-weight: 600; }

/* ── Live pricing summary ── */
.tbd-summary { padding: 12px 16px; border-top: 1px solid var(--tbd-gray2); background: var(--tbd-gray1); }
.tbd-sum-row { display: flex; justify-content: space-between; font-size: 12px; color: var(--tbd-gray4); padding: 2px 0; }
.tbd-sum-row span:last-child { font-weight: 700; color: var(--tbd-dark); }
.tbd-sum-divider { border-top: 1px solid var(--tbd-gray3); margin: 6px 0; }
.tbd-sum-total { font-size: 13px; }
.tbd-sum-total span { font-weight: 700 !important; }

/* ── Starting price (printed/embroidery) ── */
.tbd-starting-price {
    font-size: 18px;
    font-weight: 700;
    color: var(--tbd-dark);
    padding: 12px 16px;
    border-top: 1px solid var(--tbd-gray2);
    background: var(--tbd-gray1);
}

/* ── Action buttons ── */
.tbd-actions { padding: 14px 16px; }
.tbd-btn-primary {
    display: block;
    width: 100%;
    padding: 14px;
    background: var(--tbd-green);
    color: #fff;
    font-size: 15px;
    font-weight: 700;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    border: none;
    border-radius: var(--tbd-radius);
    cursor: pointer;
    font-family: inherit;
    transition: background .15s;
    min-height: 52px;
}
.tbd-btn-primary:hover { background: var(--tbd-green2); }
.tbd-btn-primary.blank-mode { background: var(--tbd-navy); }
.tbd-btn-primary.blank-mode:hover { background: #0f2350; }
.tbd-btn-primary:disabled { background: var(--tbd-gray3); cursor: not-allowed; }
.tbd-secondary-actions { margin-top: 10px; text-align: center; display: flex; flex-direction: column; gap: 6px; }
.tbd-sample-link { font-size: 13px; color: var(--tbd-navy); text-decoration: underline; }
.tbd-quote-link  { font-size: 11px; color: var(--tbd-gray4); }
.tbd-quote-link strong { color: var(--tbd-navy); }

/* ══ THEME LAYOUT — PrintIt4Less specific ════════════════════════
   ds_custom_field wraps both the gallery and product-info.
   We make it flex so image sits left and configurator sits right.
   TMEPO JS resets display to block after load — our setTimeout
   in PHP overrides it back to flex after 800ms.
   ================================================================ */

/* Hide duplicates created by WooCommerce/TMEPO/theme outside our panel.
   Descendant (not child) selectors on purpose: the theme wraps the title one
   level deeper in some templates, and `>` was silently missing those — that was
   the "duplicate title still showing" bug. Our own header uses .tbd-product-*
   class names, so it can never match these selectors. */
.tbd-active-product .product-info h1.product_title,
.tbd-active-product .product-info h2.product_title,
.tbd-active-product .product-info p.price,
.tbd-active-product .product-info .price,
.tbd-active-product .product-info .reg,
.tbd-active-product .ds_custom_field > h1.product_title,
.tbd-active-product .ds_custom_field > p.price,
.tbd-active-product .ds_custom_field > .price,
.tbd-active-product .ds_custom_field > .reg,
.tbd-active-product .product-area > h1.product_title,
.tbd-active-product .product-area > p.price,
.tbd-active-product .product-area > .price {
    display: none !important;
}

/* Belt and braces: nothing above may ever hide our own header. */
.tbd-active-product #tbd-configurator .tbd-product-header { display: block !important; }
.tbd-active-product #tbd-configurator .tbd-product-title  { display: block !important; }
.tbd-active-product #tbd-configurator .tbd-product-price  { display: block !important; }

/* The theme also prints a title/price in a sibling column beside our product
   area. The JS in class-tbd-frontend.php hides those by walking the DOM; these
   rules cover the same cases pre-paint so nothing flashes on load. Modern
   :not() with a descendant argument does the ancestor exclusion CSS-side. */
.tbd-active-product .product-area h1.product_title:not(#tbd-configurator *),
.tbd-active-product .product-area p.price:not(#tbd-configurator *),
.tbd-active-product .product-area .reg:not(#tbd-configurator *),
.tbd-active-product .ds_custom_field ~ * h1.product_title,
.tbd-active-product .ds_custom_field ~ * p.price,
.tbd-active-product .ds_custom_field ~ h1.product_title,
.tbd-active-product .ds_custom_field ~ p.price,
.tbd-active-product .ds_custom_field ~ .price {
    display: none !important;
}

/* Desktop & Tablet: side by side */
@media(min-width:768px){
    .tbd-active-product .ds_custom_field {
        display: flex !important;
        align-items: flex-start !important;
        gap: 20px !important;
        width: 100% !important;
        box-sizing: border-box !important;
    }
    .tbd-active-product .ds_custom_field .tbd-gallery {
        flex: 0 0 48% !important;
        max-width: 48% !important;
        min-width: 0 !important;
    }
    .tbd-active-product .ds_custom_field .tbd-gallery-main img {
        width: 100% !important;
        height: auto !important;
    }
    .tbd-active-product .ds_custom_field .tbd-gallery-thumbs img {
        width: 60px !important;
        height: 60px !important;
        object-fit: cover !important;
    }
    .tbd-active-product .ds_custom_field .product-info {
        flex: 1 1 0 !important;
        min-width: 0 !important;
        max-width: none !important;
    }
}

/* Mobile: stack vertically */
@media(max-width:767px){
    .tbd-active-product .ds_custom_field {
        display: flex !important;
        flex-direction: column !important;
        width: 100% !important;
    }
    .tbd-active-product .ds_custom_field .tbd-gallery,
    .tbd-active-product .ds_custom_field .product-info {
        flex: 0 0 100% !important;
        max-width: 100% !important;
        width: 100% !important;
    }
    .tbd-active-product .ds_custom_field .tbd-gallery-main img {
        width: 100% !important;
        max-height: 320px !important;
        object-fit: contain !important;
    }
    .tbd-active-product .ds_custom_field .tbd-gallery-thumbs img {
        width: 60px !important;
        height: 60px !important;
        object-fit: cover !important;
    }
    .tbd-mode { min-height: 60px !important; }
    .tbd-size-qty { min-height: 48px !important; font-size: 16px !important; }
    .tbd-btn-primary { min-height: 56px !important; font-size: 16px !important; }
}

/* Beside the size boxes, not in a browser alert: a native dialog covers the fields it
   is describing, and on a phone it is tapped away before it is read. */
.tbd-size-hint{
  margin:6px 0 0;
  font-size:13px;line-height:1.4;color:#b32d2e;font-weight:600;
}

/* ── GARMENT PICKER ──
   Sits above the colour swatches, because that is the order the decision happens: pick the
   shirt, then pick its colour. Hidden entirely unless the product is available on more than
   one garment — a picker with one option is a label. */
.tbd-garment-field[hidden] { display: none; }
.tbd-garments {
    display: flex;
    gap: 6px;
    /* THE ROW MUST CONTAIN ITS CHILDREN.
       On the TshirtByDesign theme the images rendered 139px inside a tile reporting 53px and
       spilled 86px over the colour swatches below. The cause was flex-basis:0 on the tiles,
       which computes their height from zero rather than from the picture inside — fixed on
       .tbd-garment below. align-items:flex-start stops one tile stretching its neighbours.
       No min-height:0 here: it tells the row it may be shorter than its contents, which is
       the opposite of what is needed. Nothing changes how big the garments are. */
    align-items: flex-start;
}
/* NO BOX. The shirts are photographed on white and read as objects on the page; putting
   each one in a bordered card added three rectangles competing with the colour swatches
   below and made the garments themselves smaller to fit. Selection is carried by the label
   instead — see .active below. */
.tbd-garment {
    /* flex-basis:auto, NOT 0. With flex:1 1 0 the tile's height is computed from a basis of
       zero and it collapses to 53px while the image inside renders at 139px and spills onto
       the colour swatches below. flex-basis:auto measures the tile from its own content,
       which is what a picture with a caption under it needs.
       min-height:0 was added here in 5.16.2 for the opposite reason and made it worse — it
       is gone. Widths are unchanged, so tiles still share the row equally. */
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding: 4px 2px;
    background: transparent;
    border: 0;
    border-radius: 6px;
    font-family: inherit;
    cursor: pointer;
}
.tbd-garment:hover { background: var(--tbd-gray1); }
/* contain, not cover: these are whole shirts on white, and cropping one to fill a box cuts
   the sleeves off — which is the detail that distinguishes a long sleeve from a tee. */
/* The garment and the design stack inside this box. Positioned, because the design is
   placed against the garment's own print zone in percentages — the same percentages the
   studio uses — and percentage offsets need a positioned ancestor to mean anything. */
.tbd-garment-img {
    position: relative;
    display: block;
    width: 100%;
    /* flex:0 0 auto — the tile is a COLUMN flex container, so without this the wrapper is
       given flex-shrink:1 and gets squashed to whatever the row feels like while the image
       inside still renders at its natural height and spills out. That is the whole bug: a
       139px image inside a 53px box, overflowing onto the colour swatches below. Nothing is
       mispositioned and nothing needs shrinking — the box simply has to be allowed to be as
       tall as its content. */
    flex: 0 0 auto;
    /* NO HEIGHT CAP HERE. height:auto is deliberate: the design overlay is positioned in
       percentages of the image, so this wrapper must take the image's own aspect ratio or
       those percentages measure the wrong rectangle.
       A 130px cap was tried and reverted — it shrank the garments on printit4less, where
       they were already rendering at 139px and looked correct. The overflow problem is the
       ROW failing to contain its children, and it is fixed on .tbd-garments below. Do not
       solve a containment bug by shrinking the content. */
}
/* height:auto, NOT a fixed box with object-fit:contain. Contain letterboxes — the rendered
   shirt can be narrower than its container — and the design is positioned in percentages of
   the print zone, which are percentages of the IMAGE. Against a letterboxed box those
   percentages measure the wrong rectangle and the design drifts off-centre. Letting the
   wrapper take the image's own aspect ratio makes the two coordinate spaces identical. */
.tbd-garment-img > img:first-child {
    width: 100%;
    height: auto;
    display: block;
}
/* The design sits over the garment. height:auto so it keeps its own aspect ratio — the
   width is what the print zone constrains, exactly as on the real shirt. */
.tbd-garment-plate {
    position: absolute;
    height: auto;
    pointer-events: none;
}
.tbd-garment-name {
    font-size: 12.5px;
    line-height: 1.2;
    text-align: center;
    color: var(--tbd-gray4);
}
/* Selection lives in the label now that the borders are gone. Colour and weight together,
   not weight alone — a single bold word among three is easy to miss at a glance. */
.tbd-garment.active .tbd-garment-name {
    color: var(--tbd-navy);
    font-weight: 700;
}

/* The short description, SKU/tags and share row, moved under the product photograph by
   configurator.js. A rule above them so they read as their own block rather than as a
   caption stuck to the image. */
.tbd-under-image {
    clear: both;
    width: 100%;
    margin-top: 18px;
    padding-top: 16px;
    border-top: 1px solid var(--tbd-gray2);
    text-align: left;
}
.tbd-under-image .product_meta { margin-top: 12px; font-size: 13px; }
/* The long description now follows the configurator panel directly, so it needs room
   between the two rather than sitting tight against the button. */
.tbd-configurator + .ds_custom_desc { margin-top: 22px; }

/* ── WIDER PANEL ON SITES WITH NO LEFT NAVIGATION ──
   printit4less has a product-category sidebar; tshirtbydesign, tagandlabel and boxprinting
   do not, so the summary column there has noticeably more room and the configurator was
   sized for the narrower case.

   SCOPED BY VIEWPORT, not by theme. A media query above 1500px cannot reach printit4less's
   layout, where the sidebar keeps the column narrow whatever the window size — so this can
   only widen the sites that have the space. A theme-class rule would have needed a different
   selector per site and would break the day a theme changes.

   max-width only. The panel still shrinks normally below this. */
@media (min-width: 1500px) {
    .tbd-configurator {
        max-width: 640px;
    }
}

/* ══════════════════════════════════════════════════════════════════════════════
   PER-SITE LAYOUT — TSHIRTBYDESIGN ONLY
   ══════════════════════════════════════════════════════════════════════════════

   EVERY rule below is scoped to body.tbd-site-tshirtbydesign, added by
   TBD_Frontend::body_class(). pi4ldev/printit4less never receives that class, so nothing
   here can reach it. This is the rule that 5.16.1 and 5.16.2 broke: they changed SHARED
   sizing to fix one theme and made the working site worse. Do not add an unscoped rule to
   this block, and do not "simplify" the selectors by removing the body class.

   ── WHY THIS IS HARDENING RATHER THAN A ROOT-CAUSE FIX ──
   The root cause on this theme is NOT known. 5.16.4's `flex: 1 1 auto` fixed the identical
   symptom on printit4less and is live on the network at 5.17.0, and the swatches still
   overlap here — so the cause is a THEME rule this plugin cannot see. Computed styles were
   not available for this session, so these values were measured off a screenshot of the real
   page instead:

       garment images render  y 390 → 520      caption sits at   y 536 → 544
       colour swatch renders  y 486 → 508      i.e. INSIDE the garment images

   The swatch field starts ~96px below the top of the garment row while the row's contents
   visually run ~155px. The row is reporting a height smaller than its children — the same
   containment failure as before, from a different cause.

   Since the cause cannot be identified from here, these rules do not target it. They assert
   the outcome the layout needs — every box in the garment stack is sized by its content —
   which holds whatever the theme is doing. `!important` is used deliberately and only here:
   it is beating a theme rule, and the scope means it can only ever apply on one site.

   NOT USED: min-height:0. It was tried in 5.16.2 and made this worse, because it grants
   permission to be shorter than the contents, which is the opposite of what is needed.
   NOT USED: any height cap. 5.16.1 capped the image at 130px and shrank the garments on
   printit4less. Nothing here changes how big anything is. */

body.tbd-site-tshirtbydesign .tbd-garment-field,
body.tbd-site-tshirtbydesign .tbd-garments,
body.tbd-site-tshirtbydesign .tbd-garment,
body.tbd-site-tshirtbydesign .tbd-garment-img {
    height: auto !important;
    max-height: none !important;
    min-height: auto !important;
}

/* The row as a GRID rather than a flex row. A grid track is sized from its contents and
   cannot be collapsed by an inherited height or flex-basis, which is the failure being
   worked around. Column widths are unchanged: minmax(0,1fr) gives each tile an equal share
   exactly as flex:1 1 auto did, and min-width:0 stays available to long garment names.
   align-items:start keeps one tall tile from stretching its neighbours. */
body.tbd-site-tshirtbydesign .tbd-garments {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    align-items: start;
    gap: 6px;
}

/* The tile keeps its own column layout — picture above caption. Restated because the theme
   may be setting display on <button>, and .tbd-garment IS a button. */
body.tbd-site-tshirtbydesign .tbd-garment {
    display: flex !important;
    flex-direction: column !important;
    align-items: center;
}

/* The image takes its natural height. height:auto (never object-fit/contain) because the
   design overlay is positioned in PERCENTAGES OF THE IMAGE — a letterboxed box makes those
   percentages measure the wrong rectangle and the design drifts off-centre.

   WIDTH IS PINNED TO THE TILE. Measured after 5.17.1: the three shirts ran from x787 to
   x1140 inside a panel whose inner width ends at x1122, so they were reaching past the
   padding to the panel border and the outer sleeves were being cut. Releasing the height cap
   let the pictures render larger, and nothing was holding their width. width AND max-width,
   both !important, because a theme rule setting `img { width: auto }` is the likeliest cause
   and would otherwise win. This constrains the box, it does not resize the artwork: the
   aspect ratio still comes from height:auto. */
body.tbd-site-tshirtbydesign .tbd-garment-img > img:first-child {
    height: auto !important;
    max-height: none !important;
    width: 100% !important;
    max-width: 100% !important;
}

/* Belt and braces: the swatch field is the block that is being painted over. Giving it its
   own stacking context means that even if some containment is still failing, the swatches
   are drawn ABOVE the garment pictures rather than behind them — visible and clickable
   instead of invisible, which is the difference between a cosmetic gap and an unusable
   control. This does not move anything. */
body.tbd-site-tshirtbydesign .tbd-swatches {
    position: relative;
    z-index: 2;
}

/* ── PANEL WIDTH — TSHIRTBYDESIGN ONLY ──
 *
 * MEASURED, not inferred. Read off the real page:
 *
 *   .product-area     1250 = .ds_custom_field 833 + .ds-tpo-block 417   (free = 0)
 *   .ds_custom_field   833 = .tbd-gallery 400 + .product-info 413 + 20 gap
 *
 * The panel IS .product-info: both measure 413. pi4ldev's panel is 531, so the target is
 * .product-info = 531, which needs .ds_custom_field = 400 + 531 + 20 = 951, which leaves
 * .ds-tpo-block = 1250 - 951 = 299. The badges inside that block occupy about 244, so 299
 * holds them without clipping.
 *
 * WHY THIS AND NOT THE OTHER FIVE ATTEMPTS. There is no free space in this row and no slack
 * in the badge block — that is why every "find the spare width" approach returned zero and
 * did nothing. The 118px the panel needs can only come from .ds-tpo-block, so it is taken
 * explicitly. Nothing is detected at runtime and nothing is measured in the browser.
 *
 * THE 531 IS THE ONE NUMBER TO TUNE. It came from measuring pi4ldev's panel in a screenshot
 * and converting at the same zoom as the tshirtbydesign shot. If pi4ldev's window was at a
 * different zoom the true figure moves, and the two derived numbers move with it:
 *     .ds-tpo-block = 1250 - (400 + TARGET + 20)
 * The panel's own max-width is 640, so anything up to 640 is available without further edits.
 *
 * Scoped to body.tbd-site-tshirtbydesign — pi4ldev never has that class, so these rules
 * cannot match there. Held above 1100px so the theme's own stacked mobile layout is
 * untouched; below that the fixed widths would be wrong. */

/* ── BADGES ABOVE THE ROW, PHOTO AND PANEL TAKE THE WIDTH THEY FREE ──
 *
 * The two trust badges used to sit in a 299px column to the RIGHT of the photo and panel.
 * They are about 60px tall, so that column was empty for most of its height — the unused
 * white space down the right-hand side of the product block.
 *
 * They now sit on their own full-width row above, right-aligned, and the 299px goes to the
 * content. MEASURED on the live page, not estimated:
 *
 *   .product-area   280 → 1530   (1250)
 *   .tbd-gallery    280 →  880   ( 600)
 *   .tbd-configurator 900 → 1530 ( 630)      600 + 20 gap + 630 = 1250
 *
 * so the badge row and the panel now share a right edge at 1530.
 *
 * TWO THINGS THAT COST SEVERAL WRONG ATTEMPTS, BOTH WORTH KNOWING BEFORE EDITING THIS:
 *
 * 1. THE WRAPPERS MUST STAY BLOCKS. The chain is
 *       .ds-tpo-block > .ds-product-title > .price-review > .sa-plugin > (a > img) + img
 *    Making .ds-tpo-block a flex container turns .ds-product-title into a flex item, which
 *    shrinks to its content — measured at 617px inside a 1250px parent. The badges then
 *    right-align neatly to the wrong box. Only .price-review is a flex row here; everything
 *    above it is left as a block so it fills naturally.
 *
 * 2. SPECIFICITY. The rules this replaces were written as
 *       body.tbd-site-tshirtbydesign .product-area > .ds-tpo-block   (0,3,1)
 *    so an override needs at least that. `.ds-tpo-block.ds-tpo-block` repeats the class to
 *    get there without depending on source order.
 *
 * Scoped to body.tbd-site-tshirtbydesign and held above 1100px, so pi4ldev and the phone and
 * tablet layouts are untouched. Verified against the live page before shipping. */
@media (min-width: 1100px) {

    body.tbd-site-tshirtbydesign .product-area {
        flex-wrap: wrap !important;
    }

    body.tbd-site-tshirtbydesign .product-area > .ds-tpo-block.ds-tpo-block {
        order: -1 !important;
        flex: 0 0 100% !important;
        max-width: 100% !important;
        width: 100% !important;
        margin: 0 0 10px !important;
        display: block !important;
    }

    /* Block, not a flex item — see note 1 above. */
    body.tbd-site-tshirtbydesign .ds-tpo-block > .ds-product-title {
        display: block !important;
        width: 100% !important;
        max-width: 100% !important;
    }

    /* The only flex row in the chain: this is what pushes the badges right. */
    body.tbd-site-tshirtbydesign .ds-tpo-block .price-review {
        display: flex !important;
        justify-content: flex-end !important;
        align-items: center !important;
        width: 100% !important;
        max-width: 100% !important;
    }

    /* nowrap keeps the seal and the flag on one line; without it they stack. */
    body.tbd-site-tshirtbydesign .ds-tpo-block .sa-plugin {
        display: flex !important;
        align-items: center !important;
        gap: 14px !important;
        flex: 0 0 auto !important;
        margin-left: auto !important;
        white-space: nowrap !important;
    }
    body.tbd-site-tshirtbydesign .ds-tpo-block .sa-plugin img {
        max-width: none !important;
    }

    /* The content row now spans the whole 1250 the badge column used to share. */
    body.tbd-site-tshirtbydesign .product-area > .ds_custom_field {
        flex: 0 0 100% !important;
        max-width: 100% !important;
    }

    /* 600 + 20 + 630 = 1250. Changing either number means changing the other, or the panel
       and the badge row stop sharing a right edge. */
    body.tbd-site-tshirtbydesign .ds_custom_field > .tbd-gallery {
        flex: 0 0 600px !important;
        max-width: 600px !important;
    }
    body.tbd-site-tshirtbydesign .tbd-configurator {
        max-width: 630px !important;
    }
}

/* ── PRODUCT NAME ON THE BADGE ROW ─────────────────────────────
 *
 * The name is moved into .price-review by tbdMoveTitleToBadgeRow() in configurator.js, which
 * also sets body.tbd-title-moved once the move has actually happened. Everything that would
 * look wrong without the move is scoped to that class, so a JS failure leaves the original
 * layout intact rather than a page with no product name on it.
 *
 * THE 620 IS NOT INDEPENDENT. It is the photo's 600 plus the 20px column gap, which is what
 * puts the name exactly on the left edge of the Customization box. Change the photo width and
 * this moves with it — the three numbers (600 / 630 / 620) only work as a set.
 *
 * THE ROW GAP. .product-area wraps, so its `gap` applies between the badge row and the content
 * row as well as between the photo and the panel. That row gap was the visible band of white
 * under the badges; the column gap still has to stay 20, hence `gap: 0 20px` rather than 0. */
@media (min-width: 1100px) {

    body.tbd-site-tshirtbydesign .product-area {
        gap: 0 20px !important;
        row-gap: 0 !important;
    }

    body.tbd-site-tshirtbydesign .ds-tpo-block .price-review {
        justify-content: space-between !important;
        align-items: flex-end !important;
        line-height: 1 !important;
    }

    body.tbd-site-tshirtbydesign .ds-tpo-block .tbd-product-title {
        margin: 0 0 0 620px !important;
        padding: 0 !important;
        font-size: 24px !important;
        line-height: 1.2 !important;
        text-align: left !important;
        flex: 0 1 auto !important;
        white-space: nowrap !important;
    }

    /* Inline images carry a few px of baseline descender under them, which read as extra
       space beneath the seal and the flag. */
    body.tbd-site-tshirtbydesign .ds-tpo-block .sa-plugin img {
        display: block !important;
    }

    /* The spacing dial: raise this if the name ever sits too close to the box. */
    body.tbd-site-tshirtbydesign .product-area > .ds-tpo-block.ds-tpo-block {
        margin: 0 0 2px !important;
        padding-bottom: 0 !important;
    }

    body.tbd-site-tshirtbydesign .ds-tpo-block > .ds-product-title,
    body.tbd-site-tshirtbydesign .ds-tpo-block .price-review,
    body.tbd-site-tshirtbydesign .ds-tpo-block .sa-plugin {
        margin-top: 0 !important;
        margin-bottom: 0 !important;
        padding-bottom: 0 !important;
    }

    body.tbd-site-tshirtbydesign .product-area > .ds_custom_field {
        margin-top: 0 !important;
        padding-top: 0 !important;
    }

    /* ONLY once the title has actually left it. Without the body class this would hide the
       product name outright whenever the script did not run. */
    body.tbd-title-moved.tbd-site-tshirtbydesign #tbd-configurator .tbd-product-header {
        display: none !important;
    }
}

/* ── BENEFIT LINE, BETWEEN THE PRICE AND THE BUTTON ────────────
 * Quiet by design. It sits directly above the primary action, so it only has to be read once
 * on the way to the click — making it loud would compete with the green button it is there to
 * support. Small caps-ish tracking and a muted colour keep it as a caption rather than a
 * second headline. */
.tbd-benefit-line{
  margin: 8px 16px 12px;
  /* 13.5, not 11.5. At caption size this sat under the price as something to skip rather
     than read, which defeats the point of putting it above the button. Still smaller than
     the body text so it does not compete with the price or the button it sits between. */
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: .2px;
  line-height: 1.5;
  color: var(--tbd-gray6, #333);
  text-align: center;
}
.tbd-benefit-line span[aria-hidden]{
  color: var(--tbd-gray3, #bbb);
  margin: 0 3px;
}
/* Phones: a touch smaller and no extra tracking, which is what keeps the line from
   wrapping. If a very narrow device still wraps it, lower this rather than rewording the
   markup — the sentence is the client's. */
@media (max-width: 600px){
  .tbd-benefit-line{ font-size: 13px; letter-spacing: 0; margin-left: 8px; margin-right: 8px; }
}

/* ── TWO GARMENTS ─────────────────────────────────────────────────────────────
   The row is a four-up grid on this site, which stretches two tiles across the
   whole panel and leaves them looking like a mistake. Side by side at a sane
   width instead, centred, and side by side on a phone too — two tees stacked
   vertically is not a comparison.

   ONE garment is handled in configurator.js, which simply never reveals the
   field, so there is no single-tile case to style here. The .is-single rules
   from 5.36.1 are gone with it. */
.tbd-garments.is-pair,
body.tbd-site-tshirtbydesign .tbd-garments.is-pair {
    display: flex !important;
    justify-content: center !important;
    align-items: flex-start !important;
    gap: 14px !important;
}
.tbd-garments.is-pair .tbd-garment,
body.tbd-site-tshirtbydesign .tbd-garments.is-pair .tbd-garment {
    flex: 0 1 180px !important;
    min-width: 0 !important;
}
@media (max-width: 600px) {
    .tbd-garments.is-pair,
    body.tbd-site-tshirtbydesign .tbd-garments.is-pair {
        gap: 10px !important;
    }
    .tbd-garments.is-pair .tbd-garment,
    body.tbd-site-tshirtbydesign .tbd-garments.is-pair .tbd-garment {
        flex: 1 1 0 !important;
    }
}

/* ── STARTING PRICE ───────────────────────────────────────────────────────────
   Rendered by PHP now and visible from the first paint, so it is in the HTML a
   crawler is served rather than appearing only after the script runs. The theme's
   own price is hidden by this stylesheet, so without this the page had no price
   in its markup at all. configurator.js still rewrites it when the mode changes. */
.tbd-starting-price[hidden] { display: none; }
