/* ==========================================================================
   Bike Plates Direct - brand chrome
   --------------------------------------------------------------------------
   Replicates the legacy www.bikeplatesdirect.com design (WordPress
   "showplatescustom" theme) on the headless stack, so the platform move does
   not read as a redesign.

   Loaded AFTER assets/bikeplatesdirect/css/style.css (the CPD-derived base).
   Everything here is namespaced .bpd-* and used by headers/bikeplatesdirect.php
   and footers/bikeplatesdirect.php, so it does not fight the base stylesheet's
   .header / .footer rules still used by unconverted content pages.
   ========================================================================== */

/* ---------- Fonts (pulled from the legacy theme) ---------- */
@font-face {
    font-family: 'BloomsHeadline';
    src: url('/assets/bikeplatesdirect/fonts/BloomsHeadline-Regular.woff2') format('woff2'),
         url('/assets/bikeplatesdirect/fonts/BloomsHeadline-Regular.woff') format('woff'),
         url('/assets/bikeplatesdirect/fonts/BloomsHeadline-Regular.ttf') format('truetype');
    font-weight: normal;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Proxima Nova Rg';
    src: url('/assets/bikeplatesdirect/fonts/ProximaNova-Regular.woff2') format('woff2'),
         url('/assets/bikeplatesdirect/fonts/ProximaNova-Regular.woff') format('woff'),
         url('/assets/bikeplatesdirect/fonts/ProximaNova-Regular.ttf') format('truetype');
    font-weight: normal;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Franklin Gothic Book';
    src: url('/assets/bikeplatesdirect/fonts/FranklinGothic-Book.woff2') format('woff2'),
         url('/assets/bikeplatesdirect/fonts/FranklinGothic-Book.woff') format('woff'),
         url('/assets/bikeplatesdirect/fonts/FranklinGothic-Book.ttf') format('truetype');
    font-weight: normal;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'charleswright';
    src: url('/assets/bikeplatesdirect/fonts/laser_charles_wright-webfont.woff') format('woff');
    font-weight: normal;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'bikefont';
    src: url('/assets/bikeplatesdirect/fonts/3D.woff') format('woff');
    font-weight: normal;
    font-style: normal;
    font-display: swap;
}

/* ---------- Tokens ---------- */
:root {
    --bpd-orange:      #fa4c06;
    --bpd-orange-dark: #d63f04;
    --bpd-black:       #131313;
    --bpd-nav:         #333333;
    /* Matches the background baked into biketypes.gif so the band does not seam. */
    --bpd-grey-band:   #f2f2f5;
    --bpd-text:        #333333;
    --bpd-white:       #ffffff;

    --bpd-font-head: 'BloomsHeadline', 'Arial Narrow', Arial, sans-serif;
    --bpd-font-body: 'Proxima Nova Rg', 'Franklin Gothic Book', Arial, sans-serif;

    --bpd-wrap: 1200px;
}

.bpd-wrap {
    max-width: var(--bpd-wrap);
    margin: 0 auto;
    padding: 0 20px;
}

/* Screen-reader-only label helper (used by the hero reg fields). */
.visually-hidden {
    position: absolute !important;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* ==========================================================================
   Header - black bar, basket left, centred logo, contact right
   ========================================================================== */
.bpd-header {
    background: var(--bpd-black);
    color: var(--bpd-white);
}
.bpd-header-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: 66px;
    gap: 16px;
}
.bpd-header a { color: var(--bpd-white); text-decoration: none; }

.bpd-header-link {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    font-family: var(--bpd-font-head);
    font-size: 19px;
    letter-spacing: .5px;
    text-transform: uppercase;
    white-space: nowrap;
}
.bpd-header-link img { display: block; }
.bpd-header-link:hover { color: var(--bpd-orange); }

.bpd-logo-link { display: inline-block; line-height: 0; }
.bpd-logo-link img { display: block; height: 44px; width: auto; }

/* Basket count badge - visibility (not display) so it cannot shift layout */
.bpd-basket-wrap { position: relative; display: inline-block; }
.bpd-basket-badge {
    position: absolute;
    top: -6px;
    right: -8px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: 8px;
    background: var(--bpd-orange);
    color: #fff;
    font-family: var(--bpd-font-body);
    font-size: 11px;
    font-weight: 700;
    line-height: 16px;
    text-align: center;
    visibility: hidden;
    pointer-events: none;
}
.bpd-basket-badge.is-visible { visibility: visible; }

/* ==========================================================================
   Primary nav - dark grey bar, uppercase, evenly spread
   ========================================================================== */
.bpd-nav { background: var(--bpd-nav); }
.bpd-nav ul {
    display: flex;
    justify-content: space-between;
    align-items: center;
    list-style: none;
    margin: 0;
    padding: 0;
}
.bpd-nav li { margin: 0; }
.bpd-nav a {
    display: block;
    padding: 13px 10px;
    color: var(--bpd-white);
    font-family: var(--bpd-font-body);
    font-size: 14px;
    font-weight: 600;
    letter-spacing: .4px;
    text-transform: uppercase;
    text-decoration: none;
}
.bpd-nav a:hover,
.bpd-nav a[aria-current="page"] { color: var(--bpd-orange); }

/* Mobile nav toggle - hidden on desktop */
.bpd-nav-toggle {
    display: none;
    width: 100%;
    padding: 12px 20px;
    background: var(--bpd-nav);
    border: 0;
    color: var(--bpd-white);
    font-family: var(--bpd-font-body);
    font-size: 15px;
    font-weight: 700;
    letter-spacing: .5px;
    text-transform: uppercase;
    text-align: left;
    cursor: pointer;
}

/* ==========================================================================
   Hero
   --------------------------------------------------------------------------
   Mirrors legacy .subbar / .subbarinner. Two backgrounds, which is easy to get
   wrong: the OUTER band is #fd5c02 + bannerbackmain.gif stretched to 100%, and
   the INNER fixed 1170x410 container carries bannermain.jpg (the actual banner
   artwork, which is exactly 1170x411). Putting the artwork on the outer band
   instead produces a visible two-tone split.

   Note #fd5c02 is the band colour and is NOT the same as the --bpd-orange
   accent (#fa4c06) used for headings and buttons.
   ========================================================================== */
.bpd-hero {
    width: 100%;
    min-height: 411px;
    background-color: #fd5c02;
    background-image: url('/assets/bikeplatesdirect/images/bannerbackmain.gif');
    background-size: 100%;
    color: var(--bpd-white);
}
.bpd-hero-inner {
    width: 1170px;
    max-width: 100%;
    height: 410px;
    margin: 0 auto;
    background-image: url('/assets/bikeplatesdirect/images/bannermain.jpg');
    background-size: cover;
    background-position: center top;
    display: flex;
    flex-wrap: wrap;
    align-content: flex-start;
    font-size: 18px;
    font-weight: 600;
    color: var(--bpd-white);
}

/* h1 spans the full container; the copy block and bike share the row below. */
.bpd-hero h1 {
    width: 100%;
    margin: 0;
    font-family: var(--bpd-font-head);
    font-size: 54px;
    line-height: 1.15;
    text-transform: uppercase;
    color: var(--bpd-white);
}
.bpd-hero-main { flex: 0 1 auto; }
.bpd-hero-sub {
    margin: 0 0 10px;
    font-family: var(--bpd-font-body);
    font-size: 35px;
    font-weight: normal;
    line-height: 60px;
    text-transform: uppercase;
    color: #333333;
}

.bpd-hero-cols { display: flex; align-items: flex-start; }

.bpd-usps {
    width: 400px;
    margin: 40px 0 0;
    padding: 0;
    list-style: none;
    font-family: var(--bpd-font-head);
    font-size: 25px;
    line-height: 64px;
    text-transform: uppercase;
    color: var(--bpd-white);
}
/* Hanging indent at every width, not just on mobile. From 1200px down the
   column is 340px at 22px and "* Same Day Dispatch & Speedy Delivery" wraps,
   and without this the second line started level with the asterisk and read as
   a fourth bullet - the exact defect Matt reported on his phone on 10 Sept,
   which was only fixed inside the <=900px block at the time.

   The wrap itself cannot be designed out here. 340px is already the widest the
   column can be: at 941px, the narrowest width that still shows the bike, the
   hero has 901px of usable width and the entry (320) plus its margin (16) plus
   the bike (220) take 556 of it, leaving 345.

   On a line that does not wrap the padding and the negative indent cancel out,
   so this is a no-op at 1440px and above. text-wrap: balance evens the split
   and is ignored where unsupported. */
.bpd-usps li {
    margin: 0;
    padding-left: 0.75em;
    text-indent: -0.75em;
    text-wrap: balance;
}

/* "Start here" annotation + the two reg inputs */
.bpd-hero-entry {
    width: 370px;
    margin-left: 25px;
    font-family: 'charleswright', Arial, sans-serif;
    font-weight: 400;
}
.bpd-starthere { display: block; margin-left: 30px; max-width: 307px; height: auto; }

.bpd-reg-fields input {
    width: 100%;
    /* min-width was 175px, which is wider than the entry column gets on a 320px
       screen (160px). The input could not shrink, so it overflowed its own
       column by 15px and ran under the USP text alongside it - the USP list
       starts 10px to the right, so the last 5px collided. It only showed at
       about 350px and below; from 360px up the column is already wider than
       175, which is why a normal phone looked fine.
       width:100% plus the column's own width governs at every breakpoint, and
       max-width still caps it, so the floor was doing nothing except break the
       narrowest screens. Measured after: inputs 160/171/183/200px at
       320/340/360/390, with a consistent 10px clearance, and 370px on desktop
       exactly as before. */
    min-width: 0;
    max-width: 400px;
    height: 60px;
    margin-bottom: 10px;
    padding: 2px 10px;
    border: 5px solid #000;
    background: #fff;
    color: #000;
    font-family: 'charleswright', Arial, sans-serif;
    font-size: 31px;
    font-weight: bold;
    text-align: center;
    text-transform: uppercase;
}
.bpd-reg-fields input::placeholder { color: #000; opacity: 1; }
.bpd-reg-fields input:focus { outline: 3px solid #000; outline-offset: 2px; }

.bpd-hero-bike {
    width: 270px;
    height: auto;
    margin: 30px 0 0 auto;
    align-self: flex-start;
}

/* ==========================================================================
   Section headings + bands
   ========================================================================== */
.bpd-section { padding: 46px 0; }
.bpd-section--grey { background: var(--bpd-grey-band); }

.bpd-section-title {
    margin: 0 0 34px;
    font-family: var(--bpd-font-head);
    font-size: 40px;
    line-height: 1.1;
    text-align: center;
    text-transform: uppercase;
    color: var(--bpd-orange);
}
.bpd-section-title--dark { color: var(--bpd-black); }

.bpd-strapline {
    margin: 26px 0 0;
    font-family: var(--bpd-font-head);
    font-size: 32px;
    text-align: center;
    text-transform: uppercase;
    color: var(--bpd-black);
}

.bpd-notice {
    margin: 0 0 22px;
    font-family: var(--bpd-font-body);
    font-size: 15px;
    color: var(--bpd-text);
}
.bpd-notice strong { font-weight: 700; }

/* Centred responsive image used by the bike-logo and bike-type strips */
.bpd-strip-img { display: block; max-width: 100%; height: auto; margin: 0 auto; }
.bpd-strip-img--mobile { display: none; }

/* ==========================================================================
   Prose pages (about us, plate fitting, blog)
   ========================================================================== */
.bpd-page-title {
    margin: 0 0 22px;
    font-family: var(--bpd-font-head);
    font-size: 40px;
    line-height: 1.1;
    text-transform: uppercase;
    color: var(--bpd-orange);
}
.bpd-prose { max-width: 820px; }
.bpd-prose h2 {
    margin: 34px 0 14px;
    font-family: var(--bpd-font-body);
    font-size: 25px;
    font-weight: 700;
    color: var(--bpd-text);
}
.bpd-prose h3 {
    margin: 24px 0 10px;
    font-family: var(--bpd-font-body);
    font-size: 18px;
    font-weight: 700;
    color: var(--bpd-text);
}
.bpd-prose p,
.bpd-prose li {
    font-family: var(--bpd-font-body);
    font-size: 17px;
    line-height: 1.65;
    color: var(--bpd-text);
}
.bpd-prose p { margin: 0 0 16px; }
.bpd-prose ul,
.bpd-prose ol { margin: 0 0 18px; padding-left: 22px; }
.bpd-prose li { margin: 0 0 9px; }
/* Exclude buttons: `.bpd-prose a` (0,1,1) outranks `.bpd-btn` (0,1,0), so a
   button inside prose lost its white label and rendered orange-on-orange -
   invisible until :hover, which outranks both, brought it back. */
.bpd-prose a:not(.bpd-btn) { color: var(--bpd-orange); }
.bpd-prose a.bpd-btn,
.bpd-prose a.bpd-btn:hover { color: #fff; }
.bpd-prose-cta { margin-top: 30px; }

.bpd-post {
    padding: 0 0 22px;
    margin-bottom: 22px;
    border-bottom: 1px solid #e3e3e3;
}
.bpd-post h2 { margin-top: 0; }
.bpd-post-meta {
    margin: 0 0 10px !important;
    font-size: 14px !important;
    color: #6f6e6e !important;
}

@media (max-width: 720px) {
    .bpd-page-title { font-size: 29px; }
    .bpd-prose h2 { font-size: 21px; }
    .bpd-prose p, .bpd-prose li { font-size: 16px; }
}

/* ==========================================================================
   Buttons
   ========================================================================== */
.bpd-btn {
    display: inline-block;
    padding: 15px 34px;
    background: var(--bpd-orange);
    border: 0;
    color: #fff;
    font-family: var(--bpd-font-body);
    font-size: 19px;
    font-weight: 700;
    letter-spacing: .4px;
    text-align: center;
    text-decoration: none;
    text-transform: uppercase;
    cursor: pointer;
}
.bpd-btn:hover { background: var(--bpd-orange-dark); color: #fff; }
.bpd-btn--block { display: block; width: 100%; }

/* ==========================================================================
   PlateChat widget
   --------------------------------------------------------------------------
   The shared widget (bluedigital.studio/platechat-widget.php) has BPD's brand
   primary set to #f5c518 - a copy of N1P's yellow, not a BPD colour. That is
   the canonical value and should be corrected there, since it themes the chat
   everywhere it is embedded. Until then, theme it here to BPD's black and
   orange-red.

   The widget injects its own <style> at runtime, so it lands after this file;
   these need !important to win regardless of order. They are all classes, so
   no inline-style conflict.
   ========================================================================== */
.pc-header { background: var(--bpd-black) !important; }
.pc-header-name,
.pc-header-sub,
.pc-close-btn { color: #fff !important; }
.pc-header-sub { color: rgba(255, 255, 255, .8) !important; }

/* The header avatar is an inline SVG whose rect carries fill="<brand colour>". */
.pc-header svg rect { fill: var(--bpd-orange) !important; }
.pc-header svg text { fill: #fff !important; }

.pc-send-btn {
    background: var(--bpd-orange) !important;
    color: #fff !important;
}
.pc-user .pc-bubble {
    background: var(--bpd-orange) !important;
    color: #fff !important;
}
.pc-input:focus { border-color: var(--bpd-orange) !important; }
.pc-qr-btn {
    border-color: var(--bpd-orange) !important;
    color: var(--bpd-black) !important;
}

/* ==========================================================================
   Footer - black, logo left, Navigate column right
   ========================================================================== */
.bpd-footer {
    background: var(--bpd-black);
    color: var(--bpd-white);
    padding: 42px 0 30px;
}
.bpd-footer-inner {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: start;
    gap: 30px;
}
.bpd-footer a { color: var(--bpd-white); text-decoration: none; }
.bpd-footer a:hover { color: var(--bpd-orange); }
.bpd-footer-logo { display: block; max-width: 270px; height: auto; }

.bpd-footer-nav h3 {
    margin: 0 0 14px;
    font-family: var(--bpd-font-body);
    font-size: 17px;
    font-weight: 700;
    color: var(--bpd-white);
}
.bpd-footer-nav ul { margin: 0; padding: 0; list-style: none; }
.bpd-footer-nav li { margin: 0 0 9px; }
.bpd-footer-nav a { font-family: var(--bpd-font-body); font-size: 15px; }

.bpd-footer-legal {
    margin: 34px 0 0;
    padding-top: 18px;
    border-top: 1px solid #2b2b2b;
    font-family: var(--bpd-font-body);
    font-size: 13px;
    color: #9a9a9a;
}

/* ==========================================================================
   Reviews
   --------------------------------------------------------------------------
   Follows legacy .revwid-* values: white card, 1px #e3e3e3 border, the name
   above a #ccc divider carrying the stars and date, then a bold title and the
   body copy. Arial, #6f6e6e, as the legacy widget renders. No product imagery -
   legacy carries the small stars graphic and nothing else.
   ========================================================================== */
.bpd-reviews-section { font-family: Arial, Helvetica, sans-serif; color: #6f6e6e; }

.bpd-rev-headline {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    flex-wrap: wrap;
    margin-bottom: 20px;
    padding: 14px 30px;
    background: #fff;
    border: 1px solid #e3e3e3;
    border-radius: 4px;
}
.bpd-rev-headline h2 {
    margin: 0;
    font-family: var(--bpd-font-body);
    font-size: 28px;
    font-weight: 700;
    color: #404040;
}
.bpd-rev-headline img { display: block; height: auto; max-width: 200px; }

.bpd-rev { width: 100%; padding-bottom: 30px; box-sizing: border-box; }
.bpd-rev-box {
    background: #fff;
    border: 1px solid #e3e3e3;
    border-radius: 4px;
    padding: 15px 30px 10px;
    line-height: 1.7;
}
.bpd-rev-header { margin-bottom: 16px; }
.bpd-rev-name { font-size: 15px; font-weight: bold; color: #404040; }
.bpd-rev-stars {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    margin-top: 10px;
    padding-top: 20px;
    border-top: 1px solid #ccc;
}
.bpd-rev-stars img { display: block; }
.bpd-rev-date { font-size: 14px; color: #6f6e6e; }
.bpd-rev-title { margin: 0 0 6px; font-weight: 700; color: #404040; }
.bpd-rev-text  { margin: 0; color: #6f6e6e; }

/* Builder review block (above the price / add to basket) */
.bpd-builder-reviews { text-align: left; margin-bottom: 10px; }
.bpd-builder-reviews img { display: block; height: auto; max-width: 100%; }
.bpd-builder-reviews .bbr-excellent { max-width: 150px; margin-bottom: 4px; }
.bpd-builder-reviews .bbr-stars { max-width: 200px; margin-top: 6px; }
.bpd-builder-reviews .bbr-count {
    margin: 0;
    font-family: var(--bpd-font-body);
    font-size: 15px;
    color: var(--bpd-text);
}

.bpd-rev-more { text-align: center; margin-bottom: 20px; }
.bpd-rev-more-btn {
    display: inline-block;
    padding: 0;
    background: none;
    border: 0;
    cursor: pointer;
}
.bpd-rev-more-btn img { display: block; height: auto; }

/* ==========================================================================
   Builder
   --------------------------------------------------------------------------
   Legacy shape: a three-column top row (countdown | plate | rating, price,
   CTA) above a two-column control grid, with labels sitting to the LEFT of
   each control and right-aligned.
   ========================================================================== */

/* ---- top row ---- */
.bpd-builder-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 30px;
    max-width: 1170px;
    margin: 0 auto 30px;
    text-align: left;
}
.bpd-countdown { flex: 0 0 286px; text-align: center; }
.bpd-countdown-icon,
.bpd-countdown-labels { display: block; margin: 0 auto; max-width: 100%; height: auto; }
.bpd-countdown-clock {
    margin: 8px 0 2px;
    font-family: var(--bpd-font-body);
    font-size: 30px;
    font-weight: 400;
    line-height: 1.1;
    color: #222;
}

/* Plate preview.
   --------------------------------------------------------------------------
   np-builder.js resizeForVehicle() sets an inline `width:55%` on the plate for
   bikes, sized for CPD's wide car-plate column. In this layout that made the
   plate SHRINK the moment the first render arrived, having started at the
   placeholder's natural 322px. Both states were smaller than legacy, which
   shows the plate at roughly 450px.

   The render API returns a fixed 322x262 for a 9x7 plate and ignores width,
   scale, dpi and size params, so the display size has to come from CSS. An
   author !important beats a non-important inline style, which is what jQuery
   .css() writes, so this holds against resizeForVehicle without touching it. */
   Size is a straight tradeoff against sharpness: the source is 322px wide, so
   322px is the largest fully crisp display and anything beyond it upscales.
   450px matched legacy but read as soft. 380px (1.18x) is the compromise.
   Going bigger cleanly needs the render endpoint to emit at 2x. */
.bpd-plate-preview { flex: 0 0 380px; max-width: 100%; text-align: center; }
.bpd-plate-preview img,
#carplatesdirect-builder .bpd-plate-preview img#numberplate-mob {
    display: block;
    width: 100% !important;
    max-width: 380px !important;
    height: auto !important;
    margin: 0 auto;
}

.bpd-builder-buy { flex: 0 0 300px; }
.bpd-price {
    margin: 12px 0 14px;
    font-family: var(--bpd-font-body);
    font-size: 21px;
    color: var(--bpd-text);
}
.bpd-price .true-price { font-size: 27px; font-weight: 700; color: #111; }

/* Orange CTA. custom_cpd.css styles this at `#builder-actions #add-to-basket`
   and loads from the body AFTER this file, so matching or beating its
   specificity matters more than !important alone. */
#carplatesdirect-builder .nameplate-main-container #builder-actions #add-to-basket,
#carplatesdirect-builder #builder-actions #add-to-basket,
#carplatesdirect-builder button#add-to-basket.bpd-add-basket,
#add-to-basket.bpd-add-basket,
.bpd-add-basket {
    display: block;
    width: 100% !important;
    margin-top: 0 !important;
    padding: 15px 20px !important;
    background: var(--bpd-orange) !important;
    background-color: var(--bpd-orange) !important;
    background-image: none !important;
    border: 0 !important;
    border-radius: 0 !important;
    color: #fff !important;
    font-family: var(--bpd-font-body) !important;
    font-size: 21px !important;
    font-weight: 700;
    letter-spacing: .3px;
    text-transform: uppercase;
    cursor: pointer;
}
#carplatesdirect-builder #builder-actions #add-to-basket:hover,
#add-to-basket.bpd-add-basket:hover,
.bpd-add-basket:hover {
    background: var(--bpd-orange-dark) !important;
    background-color: var(--bpd-orange-dark) !important;
}

/* ---- controls legacy does not show for a bike plate ---- */
.bpd-hide-control { display: none !important; }

/* The hero already collects the registration, so the builder's own field is
   redundant on pages that carry the hero. Scoped to the homepage wrapper so
   pages without a hero keep their own reg input. */
#bpd-builder #form_register_context_box { display: none !important; }

/* Empty CPD price stub above the controls. */
#builder-actions1 { display: none !important; }

/* --------------------------------------------------------------------------
   Break out of the CPD two-column shell.

   All of CPD's builder CSS is scoped to #carplatesdirect-builder, and it puts
   the controls in a fixed 755px-tall blue Foundation column with the preview
   beside it. Legacy is full-width: top row first, then a two-column control
   grid. So the overrides below must be scoped to the same id to outrank it,
   which also means they apply on every page carrying the builder.
   -------------------------------------------------------------------------- */
#carplatesdirect-builder #parent-container {
    display: flex;
    flex-direction: column;
}
/* #builder-actions holds the top row but sits after the form in the DOM. */
#carplatesdirect-builder #parent-container > #builder-actions { order: 1; }
#carplatesdirect-builder #parent-container > #builder-form   { order: 2; }

#carplatesdirect-builder #builder-menu,
#carplatesdirect-builder #builder-menu > .row,
#carplatesdirect-builder #maincontent #builder-menu #builder-menu-internal,
#carplatesdirect-builder #builder-menu-internal,
#carplatesdirect-builder #builder-actions > .row,
#carplatesdirect-builder .price-checkout,
#carplatesdirect-builder #builder-plate-mobile {
    width: 100% !important;
    max-width: none !important;
    float: none !important;
    height: auto !important;
    min-height: 0 !important;
    background: transparent !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
}

/* ---- two-column control grid ---- */
@media (min-width: 901px) {
    #carplatesdirect-builder #builder-menu-drilldown {
        display: grid !important;
        /* minmax(0,1fr), not 1fr: a plain fr track is floored at min-content,
           and the slogan-font preview strip's min-content was pushing column 2
           to 564px against column 1's 516px, so the two columns' controls no
           longer lined up on the right. minmax(0,...) lets both stay at 540. */
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        /* Legacy runs a consistent ~52px pitch. Rows are 42px tall, so a 12px
           gap lands on that; the Text Style row is naturally taller, as on
           legacy. 90px column gutter matches legacy's ~98px. */
        gap: 12px 90px;
        /* Rows 1-4 take their own content height; row 5 is flexible and soaks up
           whatever the slogan block needs beyond them.
           This is what keeps the gaps even. The slogan block is one element
           holding three controls and it spans to the end of the grid, so it is
           taller than the left column's remaining rows. Grid distributes a
           spanning item's excess across every spanned track that is
           intrinsically sized - so with all-intrinsic rows the excess landed
           between column 1's rows as 57px and 58px holes. A flexible track
           takes the whole distribution instead, which parks the slack at the
           bottom of the grid where nothing follows it.
           Measured after this change: 12px between every row, in all three
           states (Show+Printed, Show+4D, Legal). */
        grid-template-rows: max-content max-content max-content max-content 1fr;
        align-items: start;
        max-width: 1170px;
        margin: 0 auto;
        list-style: none;
        padding: 0;
    }
    /* Rows must be assigned explicitly, not just columns. With column-only
       placement the items still flow in DOM order, so the right-hand controls
       were pushed to rows 5-7, below the four left-hand ones - which is why
       Border and Badge sat out of line and the slogan ended up far down the
       page. Legacy pairs them row for row. */
    #carplatesdirect-builder #builder-menu-drilldown > .four-text-style { grid-column: 1; grid-row: 1; }
    #carplatesdirect-builder #builder-menu-drilldown > .one-your-reg    { grid-column: 1; grid-row: 2; }
    #carplatesdirect-builder #builder-menu-drilldown > .two-plate-size  { grid-column: 1; grid-row: 3; }
    /* Premium Style sits directly under Size, and Choose Plate Material goes
       last. That keeps the three plate-style choices (Text Style, Plate Style,
       Premium Style) together, and puts the one visually heavy block - Material
       carries the MOST POPULAR flag and is 80px against everything else's 42 -
       at the foot of the column rather than in the middle of the rhythm.
       It was also added later and left unplaced, so it auto-flowed; pinned now,
       because anything inserted above it would otherwise displace it. */
    #carplatesdirect-builder #builder-menu-drilldown > #bpd-premium-font-row { grid-column: 1; grid-row: 4; }
    #carplatesdirect-builder #builder-menu-drilldown > .bpd-grid-left        { grid-column: 1; grid-row: 5; }

    /* Premium Style hides on Legal Plate, and on any raised Text Style. Row 4
       is then empty, and its gap above plus its gap below collapse into one
       24px hole over Material - so Material moves up into the vacated row.
       Keyed off the class rather than the computed display because that is what
       the builder toggles (a stylesheet !important on .plate-row beats an inline
       display, so it has to be a class). */
    #carplatesdirect-builder #builder-menu-drilldown:has(> #bpd-premium-font-row.bpd-row-hidden) > .bpd-grid-left {
        grid-row: 4;
    }

    /* Row 1 is 46px because the Text Style buttons opposite are taller than a
       select. With align-items:start the Border control sat at the top of that
       row and left 4px under it, so the gap to Badge measured 16 against 12
       everywhere else. Stretching just this one item fills the row; its label
       is already a centred flex line, so the select stays 42px and simply
       centres against the taller row. */
    #carplatesdirect-builder #builder-menu-drilldown > .six-borders       { grid-column: 2; grid-row: 1; align-self: stretch; }
    #carplatesdirect-builder #builder-menu-drilldown > #badge-hide        { grid-column: 2; grid-row: 2; }

    /* The slogan block is a single element holding THREE rows (Slogan, Slogan
       Colour, Slogan Font + its preview). Left in one grid row it made that row
       tall enough to push Material ~105px down the left column. Spanning to the
       end of the grid lets both columns keep the same ~52px rhythm legacy runs.
       `3 / -1` rather than a fixed span: the block's height changes with what is
       shown (the preview only exists when Magento returns slogan fonts), so a
       hard span number goes stale. -1 resolves to the last line of
       grid-template-rows above. */
    #carplatesdirect-builder #builder-menu-drilldown > #builder-slogan12 {
        grid-column: 2;
        grid-row: 3 / -1;
    }
    /* Its two inner rows need their own even spacing. */
    #carplatesdirect-builder #builder-slogan12 > li {
        display: flex !important;
        flex-direction: column;
        gap: 14px;
    }

    /* The mobile preview/price li must not take a grid cell. */
    #carplatesdirect-builder #builder-menu-drilldown > #builder-reg { display: none !important; }
}

/* ---- Builder container: drop CPD's 80vw cap below 1025px ----
   headless/assets/css/breakpoints/small-monitor.css carries

       @media (max-width: 1024px)
       #carplatesdirect-builder #parent-container { max-width: 80vw }

   twice, once plain and once as "only screen", and breakpoints/mobile.css
   only restores 100vw further down. So every width from 1024 down to about
   640 threw away a fifth of the viewport in the builder area while the
   sibling sections used about 96%: measured 819 at 1024, 800 at 1000, 768 at
   960, 720 at 900, 640 at 800.

   It also produced a cliff at CPD's own breakpoint - 1025px wide at a 1025px
   viewport, 819px wide at 1024px, a 206px jump for one pixel - and it was the
   real reason the top row wrapped in the band below. The 1200px cap that
   applies from 1025px up is CPD's and is deliberately kept.

   !important because the inherited rule has identical specificity, so which
   one wins would otherwise depend on stylesheet order. */
@media (max-width: 1024px) {
    #carplatesdirect-builder #parent-container { max-width: 100% !important; }
}

/* ---- 901px to 1024px: the gap between our desktop grid and CPD's tablet bar ----
   combined.min.css carries

       @media only screen and (max-width: 1024px)
       #carplatesdirect-builder .price-checkout .row { position: fixed; display: flex }

   and #builder-plate-mobile is <div id="builder-plate-mobile" class="row
   row-cpd-builder-plate-mobile"> inside .price-checkout - so it matches that
   selector by class, not by its id. That is why grepping the id does not find
   the rule.

   On CPD that fixed bar is the mobile checkout bar. Our desktop grid starts at
   901px, so between 901 and 1024 the page got the desktop layout AND the fixed
   bar: the plate, countdown, Trustpilot block, price and Add to basket detached
   from the flow and floated over the hero. Below 901 the mobile block already
   neutralises it; above 1024 CPD's rule stops applying. Only this band was
   uncovered.

   Measured: #builder-plate-mobile is block/static at 899px and at 1026px, but
   flex/fixed with z-index 2147483647 at 901-1024. Restoring static/block here
   makes the band behave exactly as 1025px+ does.

   Targets CPD's own selector as well as the id, because the same rule also
   matches an empty sibling .row inside .price-checkout. */
@media (min-width: 901px) and (max-width: 1024px) {
    #carplatesdirect-builder .price-checkout .row,
    #carplatesdirect-builder #builder-plate-mobile {
        position: static !important;
        display: block !important;
    }

    /* Second symptom of the same gap: the plate preview vanished here.
       combined.min.css hides the desktop plate at <=1024

           #carplatesdirect-builder #numberplate-mob { display: none !important }

       and hides CPD's mobile substitute only from 1025 up

           @media (min-width: 1025px) #carplatesdirect-builder .mob-preview { display: none }

       so CPD swaps one for the other at 1025. We hide .mob-preview from 900
       down and show our own preview instead, which left 901-1024 with the
       desktop plate hidden and the substitute empty - no plate at all, and the
       top row collapsing to a stack because its middle column had zero height.
       Match what 1025px+ does. */
    #carplatesdirect-builder #numberplate-mob {
        display: block !important;
    }
    #carplatesdirect-builder .mob-preview,
    #carplatesdirect-builder .mob-price {
        display: none !important;
    }

    /* The three top-row columns - countdown (286), plate (320) and buy block
       (300) - sum to 906px, and with two 30px gaps the row needs 966px. It used
       to wrap onto two lines here, and the comment that stood here blamed
       "about 760px of usable width". That 760 was CPD's 80vw cap, not a real
       constraint: at a 960px viewport 80vw is 768. Removing the cap above took
       484px off the page height at 1000px.

       That still left a wrap below 966px, which cost 241px of page height for a
       6px shortfall at 960. .bpd-builder-top is flex-wrap: wrap, and a flex
       item wraps before it shrinks, so the plate never gave up width it could
       spare. nowrap makes it shrink instead: the plate goes 320 -> 255 as the
       viewport goes 966 -> 901, its image tracks it, and the row holds one line
       all the way down to 901 where the mobile layout takes over. Builder
       height is then flat at about 1030-1070 across this band instead of
       stepping to 1313.

       The flex rule below is what allows that shrink, and it must stay
       0 1 320px: .bpd-plate-preview is flex:1 1 320px under 1200px, so with
       free space in the row the plate would grow past its natural size (it
       reached 503px when the row was cramped). Shrink but never grow. */
    #carplatesdirect-builder .bpd-builder-top {
        flex-wrap: nowrap;
    }
    #carplatesdirect-builder .bpd-plate-preview {
        flex: 0 1 320px !important;
    }
}


/* ---- label left of control, right-aligned, sentence case ---- */
#carplatesdirect-builder .v2-plate-layout-container > label,
#carplatesdirect-builder .one-your-reg.plate-row label {
    display: flex !important;
    align-items: center;
    gap: 12px;
    width: 100%;
}
#carplatesdirect-builder .v2-plate-layout-container label strong,
#carplatesdirect-builder #builder-font > strong.text-style-title-strong,
#carplatesdirect-builder #builder-material > strong,
#carplatesdirect-builder .builder-menu-content > strong,
/* The slogan preview's label is in this list, not styled next to the preview
   itself, so it tracks the same basis and typography as every other label
   through all three breakpoints below. */
#carplatesdirect-builder #slogan-font-preview > .sfp-label {
    flex: 0 0 120px !important;
    font-family: var(--bpd-font-body) !important;
    font-size: 15px !important;
    /* Bold, Matt 10 Sept. Every one of the 13 control labels is inside a
       <strong> already but CPD's stylesheet had flattened them all to 400, so
       this single declaration is what carries the weight - measured 400 on all
       13 before, including Slogan Preview via .sfp-label.

       ⚠️ 700 is as heavy as this can go, and the number above it is inert.
       Proxima Nova ships as a SINGLE regular face here (there is no bold file
       anywhere in the tree), so every bold on the site is browser-synthesised,
       and Chrome synthesises exactly one bold regardless of the value: 600,
       700, 800 and 900 all measured identical glyph widths and identical ink.
       So do not "fix" a too-light label by raising this to 800 or 900 - it
       does nothing. The two levers that do work are the colour below and the
       stroke. */
    font-weight: 700 !important;
    text-align: right !important;
    text-transform: none !important;
    /* Pure black rather than the site's --bpd-text #333, and a hair of stroke
       on top (Matt, 10 Sept: "a bit bolder / black"). Legacy reaches the same
       presence differently - its labels are weight 400 but #000 at 19px - so
       black is the legacy-faithful half of this.
       -webkit-text-stroke thickens the glyph outline without touching advance
       widths, so it adds weight with zero layout effect (verified: label text
       measures the same to 0.01px). 0.3px is deliberately restrained; 0.55px
       was tried and reads as heavy rather than bold. Degrades to plain black
       wherever the property is unsupported. */
    color: #000 !important;
    -webkit-text-stroke: 0.3px currentColor;
    padding-bottom: 0 !important;
}

/* Undo CPD's width caps on the vehicle row's dropdowns, and let every control
   fill the space left by its label.

   CPD pins these because it shows THREE dropdowns side by side there (Vehicle,
   Plate Style, Front/Rear). On a bike site the first and third are
   display:none - it is always a bike, and front/rear is chosen elsewhere - so
   every cap lands on the one control still visible and starves it.

   ⚠️ There are THREE caps, and they sit at breakpoints nobody would think to
   test. Plain-class copies live in custom_cpd.css and custom-v3-new.css, and
   ID-PREFIXED copies live in combined.min.css:

     @media (max-width: 375px)  ...:first-of-type  { max-width: 70px  !important }
     @media (max-width: 333px)  ...:nth-of-type(2) { max-width: 105px !important }
     @media (max-width: 333px)  ...:first-of-type  { max-width: 67px  !important }

   Only :first-of-type was undone here, so at 320px the Plate Style select
   rendered about 18px wide - its container pinned to 105px inside a 268px row -
   while every other control was full width. Found 10 Sept.

   ⚠️ Specificity is the whole game here, and it is easy to get wrong. The
   combined.min.css copies are `#id .class > .class:pseudo` = (1,3,0). A
   sensible-looking override of
     #carplatesdirect-builder .one-your-reg > .v2-plate-layout-container
   is only (1,2,0) and LOSES, !important or not - dropping the pseudo-class
   costs a whole specificity slot. The second id below makes it (2,2,0), which
   wins outright rather than depending on source order.

   Matching every child instead of a specific nth-of-type, so a future
   show/hide change in that row cannot resurrect this.

   These caps are invisible to a CSSOM walk over document.styleSheets, which is
   what made this hard to find - and the walk also silently reported the
   override above as absent. Use CDP CSS.getMatchedStylesForNode, which lists
   what actually matched, in precedence order (~/scratch/matched.mjs). */
#carplatesdirect-builder #builder-menu-drilldown .one-your-reg > .v2-plate-layout-container { max-width: none !important; }
#carplatesdirect-builder .v2-plate-layout-container { flex: 1 1 auto !important; min-width: 0; }
#carplatesdirect-builder .v2-plate-layout-container select,
#carplatesdirect-builder .v2-plate-layout-container input[type="text"],
#carplatesdirect-builder #builder-size {
    width: 100% !important;
    max-width: none !important;
    min-width: 0 !important;
    flex: 1 1 auto;
    font-size: 15px !important;
}

/* Text Style: segmented control fills its column, orange when selected. */
#carplatesdirect-builder #builder-font .segmented {
    display: flex !important;
    grid-template-columns: none !important;
    gap: 10px;
    width: 100%;
}
#carplatesdirect-builder #builder-font .segmented__option {
    flex: 1 1 auto;
    width: auto !important;
    min-width: 0;
    padding: 13px 10px;
    white-space: nowrap;
    font-size: 15px !important;
    text-align: center;
}
/* The class is the same highlight as :checked, for one case where the radio is
   deliberately unchecked but a Text Style is still in force: selecting a
   Premium Style clears the radios so the premium font id wins in
   serializeArray (see the POC block in builder.php). The premium fonts are
   printed variants, so Printed is still the base style and has to keep looking
   selected - otherwise the control shows nothing selected at all. */
#carplatesdirect-builder #builder-font .segmented__input:checked + .segmented__option,
#carplatesdirect-builder #builder-font .segmented__option.bpd-seg-active {
    background: var(--bpd-orange) !important;
    border-color: var(--bpd-orange) !important;
    color: #fff !important;
}
/* Text Style label sits left of the buttons like the dropdowns. */
#carplatesdirect-builder #builder-font {
    display: flex !important;
    align-items: center;
    gap: 12px;
}
#carplatesdirect-builder #builder-font .ak-style,
#carplatesdirect-builder #builder-font .text-style-pp-wrapper,
#carplatesdirect-builder #builder-font .text-style-option { flex: 1 1 auto; min-width: 0; width: 100%; }

/* Plate material: orange when selected, not CPD blue. */
#carplatesdirect-builder .three-material .selectable.selected.current,
#carplatesdirect-builder .three-material .selectable.selected,
#carplatesdirect-builder #builder-material article.selected {
    background-color: var(--bpd-orange) !important;
    color: #fff !important;
}
#carplatesdirect-builder #builder-material {
    display: flex !important;
    align-items: center;
    gap: 12px;
}
#carplatesdirect-builder #builder-material .scroll-pane { flex: 1 1 auto; min-width: 0; display: flex; gap: 10px; }
#carplatesdirect-builder #builder-material article { flex: 1 1 auto; text-align: center; }

/* MOST POPULAR flag UNDER Premium Acrylic with the arrow pointing up at it
   (Matt, 10 Sept; CPD has it above, we do not).
   The label sits left of the control, so the badge and the buttons stack
   inside .bpd-material-stack. The buttons are two equal flex items with a 10px
   gap, so calc(50% - 5px) is exactly the right-hand button's width - that
   centres the badge under Premium Acrylic rather than approximating it.
   Row height is unchanged by the move: same flag, other side of the buttons. */
#carplatesdirect-builder #builder-material .bpd-material-stack {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
}
#carplatesdirect-builder .material-popular-hint {
    display: flex;
    justify-content: flex-end;
    margin-top: 3px;
    pointer-events: none;
}
#carplatesdirect-builder .bpd-popular-inner {
    width: calc(50% - 5px);
    display: flex;
    flex-direction: column;
    align-items: center;
}
#carplatesdirect-builder .bpd-popular-badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 3px;
    background: var(--bpd-orange);
    color: #fff;
    font-family: var(--bpd-font-body);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .5px;
    line-height: 1.5;
    white-space: nowrap;
}
/* border-BOTTOM makes the triangle point UP - the coloured edge is opposite
   the apex. It was border-top while the badge sat above the buttons. */
#carplatesdirect-builder .bpd-popular-arrow {
    width: 0;
    height: 0;
    border-left: 6px solid transparent;
    border-right: 6px solid transparent;
    border-bottom: 6px solid var(--bpd-orange);
}

/* A Text Style button for a finish that cannot be made at the selected size
   (4D and 3D Gel on the 9x3 plate). !important because CPD's JS writes inline
   display on these same labels and is inconsistent about it - see the note in
   builder.php. An author !important declaration outranks a non-important
   inline style, so this holds either way. */
#carplatesdirect-builder #builder-font .segmented__option.bpd-seg-unavailable {
    display: none !important;
}

/* ---- slogan block visibility: ours wins, deterministically ----
   custom-v2.js's on_slogan_change() unconditionally hides #builder-slogan12
   and then keys it off a #yes-no checkbox BPD does not have. It re-runs on a
   size change, so it and builder.php's sync() both wrote inline display within
   ~20ms and the last one won - which is why the slogan section vanished on some
   size changes and not others (Matt, 10 Sept).

   An author !important declaration outranks a non-important INLINE style, and
   jQuery .hide()/.show() write exactly that, so these two rules settle it
   whatever order the two writers run in. Keyed off classes because the class is
   the thing our own code controls. */
#carplatesdirect-builder #builder-slogan12.bpd-slogan-on  { display: block !important; }
#carplatesdirect-builder #builder-slogan12.bpd-slogan-off { display: none  !important; }

/* ---- font sample photo, under the control grid ----
   Sibling of #builder-menu-drilldown, not a child - see the note in
   builder.php. Capped at 520px because the photos are 1200x800 masters served
   for retina; letting them run full width made the panel dominate the builder.
   The caption uses the body font at label weight so it reads as part of the
   controls rather than as a new section heading. */
#carplatesdirect-builder .bpd-font-sample {
    margin: 22px 0 0;
    text-align: center;
}
#carplatesdirect-builder .bpd-font-sample[hidden] { display: none; }
#carplatesdirect-builder .bpd-font-sample__caption {
    margin: 0 0 10px;
    font-family: var(--bpd-font-body);
    font-size: 18px;
    font-weight: 700;
    color: #000;
    -webkit-text-stroke: 0.3px currentColor;
}
#carplatesdirect-builder .bpd-font-sample img {
    display: block;
    width: 100%;
    /* 420, not 520: Matt asked for it smaller on 17 Sept. The masters are
       1200x800, so this is still well inside retina. */
    max-width: 420px;
    height: auto;
    margin: 0 auto;
    border-radius: 6px;
}

/* The panel's mobile home, between Font and Border. Above 900px it must be
   display:none rather than hidden-but-present: a display:none grid child takes
   no cell, so it cannot auto-flow into one of the hand-pinned controls. */
/* Block, and NOT given .plate-row: that class is display:flex !important for
   the control rows, which made the panel a shrink-to-fit flex item sitting at
   the left edge of the slot instead of filling it, so the photo looked
   left-justified even though it is centred inside the panel (Matt, 17 Sept). */
.bpd-font-sample-slot {
    list-style: none;
    display: block;
}
#carplatesdirect-builder .bpd-font-sample-slot .bpd-font-sample { width: 100%; }

/* ⚠️ combined.min.css carries
       #carplatesdirect-builder ul.vertical.menu li p { display: none }
   i.e. CPD hides every <p> inside a menu li. Moving the panel into a slot li
   therefore hid its "You have selected ..." caption, which legacy shows and
   desktop still showed - the photo appeared with no heading. Beaten on
   specificity rather than !important: (1,4,2) against their (1,2,3), so it wins
   whatever order the two files load in. */
#carplatesdirect-builder ul.vertical.menu li.bpd-font-sample-slot p.bpd-font-sample__caption {
    display: block;
}
.bpd-font-sample-slot[hidden] { display: none !important; }
@media (min-width: 901px) {
    #carplatesdirect-builder #builder-menu-drilldown > .bpd-font-sample-slot {
        display: none !important;
    }
}

/* Size row: plate-size.php puts the label, a tooltip and the select as loose
   siblings in the li, so it needs the same flex treatment as the others or the
   label floats above the control instead of sitting beside it. */
#carplatesdirect-builder .two-plate-size .builder-menu-content {
    display: flex !important;
    align-items: center;
    gap: 12px;
}
#carplatesdirect-builder .two-plate-size .builder-menu-content > .ooltip { flex: 0 0 auto; order: 3; }
#carplatesdirect-builder .two-plate-size .builder-menu-content > select { order: 2; }

/* "Choose Plate Material:" is longer than the other labels; give the column a
   little more room and tighten the wrap so it stays legible. */
#carplatesdirect-builder #builder-material > strong {
    flex: 0 0 130px !important;
    line-height: 1.2;
}

/* Legacy groups the badge dropdowns under a single "Badge:" label. Suppress the
   second label's text while keeping it in the accessibility tree. */
#carplatesdirect-builder #builder-badge1 .v2-plate-layout-container:nth-of-type(2) label > strong {
    flex: 0 0 0 !important;
    width: 0 !important;
    overflow: hidden;
    white-space: nowrap;
    text-indent: -9999px;
}

/* --------------------------------------------------------------------------
   Builder control rhythm.

   Legacy runs a tight ~52px row pitch with a ~95px right-aligned label column
   and ~435px controls, and the two columns line up row for row. The CPD build
   is much airier, so the rows drift apart and the columns stop corresponding.

   builder.php re-links this stylesheet after combined.min.css and
   custom_cpd.css, so plain declarations here win on cascade order.
   -------------------------------------------------------------------------- */

/* Strip the inherited vertical padding and margins that widen the pitch. */
#carplatesdirect-builder #builder-menu-drilldown > li,
#carplatesdirect-builder #builder-menu-drilldown > div,
#carplatesdirect-builder #builder-menu-drilldown .plate-row,
#carplatesdirect-builder #builder-menu-drilldown .builder-menu-content,
#carplatesdirect-builder #builder-menu-drilldown .size_background,
#carplatesdirect-builder #builder-menu-drilldown ul.vertical.menu,
#carplatesdirect-builder .two-plate-size,
#carplatesdirect-builder .three-material,
#carplatesdirect-builder .six-borders,
#carplatesdirect-builder #builder-badge1 {
    margin-top: 0 !important;
    margin-bottom: 0 !important;
    padding-top: 0 !important;
    padding-bottom: 0 !important;
}
#carplatesdirect-builder #builder-menu-drilldown .plate-row { gap: 12px; }

/* Controls: legacy proportions. */
#carplatesdirect-builder .plate-row select,
#carplatesdirect-builder #builder-size,
#carplatesdirect-builder .v2-plate-layout-container select,
#carplatesdirect-builder .v2-plate-layout-container input[type="text"] {
    height: 42px !important;
    padding: 8px 12px !important;
    border-radius: 6px !important;
    font-size: 14px !important;
}

/* Text Style buttons: sentence case, legacy size. CPD forces 17px !important
   and uppercases the labels; the markup itself is already sentence case. */
#carplatesdirect-builder #builder-font .segmented { gap: 12px; margin-bottom: 0; }
#carplatesdirect-builder #builder-font .segmented__option,
#carplatesdirect-builder label.segmented__option {
    height: 46px;
    padding: 0 10px !important;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 6px;
    font-size: 15px !important;
    font-weight: 600;
    text-transform: none !important;
    letter-spacing: 0;
}

/* Plate material: orange when selected. The article carries only .selectable
   server-side; the selected/current classes are added by JS at runtime, so
   cover each combination. */
#carplatesdirect-builder .three-material .selectable.selected.current,
#carplatesdirect-builder .three-material .selectable.selected,
#carplatesdirect-builder .three-material .selectable.current,
#carplatesdirect-builder #builder-material article.selected {
    background: var(--bpd-orange) !important;
    background-color: var(--bpd-orange) !important;
    color: #fff !important;
}
#carplatesdirect-builder #builder-material article {
    height: 42px !important;
    max-height: 42px !important;
    display: flex !important;
    align-items: center;
    justify-content: center;
    border-radius: 6px;
    font-size: 14px !important;
    text-transform: none !important;
}

/* ==========================================================================
   Responsive
   ========================================================================== */
/* Legacy drops to a 900px then 600px container, shrinks the headings, swaps the
   text USP list for the uspsinbanner.jpg image, and narrows then hides the bike. */
@media (max-width: 1200px) {
    .bpd-hero, .bpd-hero-inner { height: auto; min-height: 0; }
    /*
     * ⚠️ NO fixed width here. This used to pin .bpd-hero-inner to 900px, and
     * that is what made the hero look unresponsive between 941 and 1200px
     * (Matt, 11 Sept: "staging at 1000px has the motorbike image below,
     * wasting lots of space compared to live").
     *
     * The row under the h1 holds .bpd-hero-main and the bike side by side, and
     * .bpd-hero-inner is flex-wrap: wrap, so it is really a width budget:
     *
     *     usps 340 + entry margin 16 + entry 320 + bike 220 = 896
     *
     * A 900px container less 40px padding leaves 860, so the bike could not
     * fit and wrapped onto its own line. And because the container was FIXED,
     * a wider viewport did not help - at 1000px it still sat at 900 and simply
     * left 100px unused. The hero went 411px -> 665px, over half the viewport.
     *
     * The base rule is already fluid (width: 1170px; max-width: 100%), so not
     * overriding it here is the entire fix. Measured after: 379px at 941, 960,
     * 1000, 1024, 1100 and 1200, bike on the row at every one, no overflow,
     * and nothing changed above 1200 (411px) or below 940 (bike hidden).
     * Legacy holds 411px across this band, so this is no taller than live.
     */
    .bpd-hero-inner { padding: 20px; background-size: cover; }
    .bpd-hero h1 { font-size: 44px; }
    .bpd-hero-sub { font-size: 27px; line-height: 44px; }
    .bpd-usps { width: 340px; font-size: 22px; line-height: 48px; }
    /* 25px base margin trimmed to 16. The budget above comes to 896 against
       the 901 available at 941px - the narrowest width the bike still shows
       at. At 25px it overflowed by 4px and wrapped in a 941-944 sliver. */
    .bpd-hero-entry { width: 320px; margin-left: 16px; }
    .bpd-hero-bike { width: 220px; }
}

@media (max-width: 1200px) {
    /* Let the plate give ground before the countdown and buy columns do.
       flex-grow must be 0: the intent here is only that the plate SHRINKS
       first, but `1 1 320px` also let it grow into whatever the row had spare,
       so it ballooned to 524px at 1200 against 322px at 1280 - a 200px jump
       across the breakpoint, and the widest plate on the site appearing on a
       narrower screen. With grow off it holds 320 and the spare width goes to
       the row's space-between, which is what 1280px and up already do. */
    .bpd-plate-preview { flex: 0 1 320px; }
}

@media (max-width: 940px) {
    .bpd-hero-inner { width: 100%; }
    .bpd-hero h1 { font-size: 34px; }
    .bpd-hero-sub { font-size: 24px; line-height: 34px; }
    .bpd-hero-bike { display: none; }
    .bpd-section-title { font-size: 29px; }
    .bpd-strapline { font-size: 23px; }
}

/* ==========================================================================
   Mobile
   --------------------------------------------------------------------------
   Legacy's mobile layout is not simply the desktop one stacked, so collapsing
   everything to full width diverged badly from it:

   - Legacy keeps the USPs in a NARROW COLUMN beside the reg entry
     (.uspsinbannersm, 240px, float right) rather than stacking them full
     width, which is what keeps the hero short enough to see the inputs.
   - Legacy HIDES the dispatch countdown on mobile and puts the plate and the
     rating/price/CTA side by side.
   - Legacy's controls stay label-left and fit inside the viewport.

   Stacking full width also broke the builder outright: the buy column held a
   300px basis and the Text Style buttons were nowrap, so the row exceeded the
   viewport and the CTA overlapped the buttons.
   ========================================================================== */
@media (max-width: 900px) {

    /* ---- hero: keep USPs beside the reg entry, as legacy does ---- */
    .bpd-hero { min-height: 0; }
    .bpd-hero-inner { height: auto; padding: 16px 14px 20px; }
    .bpd-hero h1 { font-size: 34px; line-height: 1.05; }
    .bpd-hero-sub { font-size: 13px; line-height: 1.3; margin-bottom: 14px; }

    .bpd-hero-cols {
        display: flex;
        flex-wrap: nowrap;
        align-items: flex-start;
        gap: 10px;
    }
    .bpd-hero-entry {
        order: 1;
        width: auto;
        flex: 1 1 55%;
        min-width: 0;
        margin-left: 0;
    }
    /* Legacy swaps the text USPs for uspsinbanner.jpg at this width, but that
       graphic has its own orange baked in and cannot match the hero gradient
       behind it, so we keep the text at every width and size it down here. */
    .bpd-usps--text {
        order: 2;
        display: block;
        flex: 0 1 42%;
        width: auto;
        min-width: 0;
        /* Offset past the Start here annotation (34px + 6px margin) so the
           USPs start level with the TOP REG box rather than above it. Derived
           from the pinned .bpd-starthere height, not guessed. */
        margin: 40px 0 0;
        /* 14px, not the 11.5px this started at (Matt, 10 Sept: they looked
           "really small" on a 375px iPhone). Sized against the hero sub-head
           rather than picked - the USPs now sit 1px above it (14 vs 13, and
           13 vs 12 below 380px), so the two read as a matched pair instead of
           the USPs looking like small print.

           The ceiling is vertical, not horizontal: the list has to stay
           roughly level with the two reg inputs beside it. At 14/13px it keeps
           the 2/2/1 line pattern at every width from 320 up with 20px of hero
           left underneath. 15px is the first size that pushes "Hassle Free
           Returns" onto two lines at 320, which is why it stops here. */
        font-size: 14px;
        line-height: 1.25;
    }
    /* These CANNOT be held to one line each at phone widths, and trying is
       the wrong instinct. The column is ~39% of the viewport (146px at 375),
       while "* Same Day Dispatch & Speedy Delivery" needs 166px on one line -
       so one line would mean a 9.2px font at 375 and 7.7px at 320. Unreadable.

       So they wrap, and the job is making the wrap read correctly. The real
       defect Matt reported (10 Sept) was not the wrapping itself: with no
       hanging indent the second line started level with the asterisk, so it
       looked like a separate bullet. The negative text-indent pulls the
       asterisk out into the padding, and continuation lines sit under the
       TEXT instead.

       text-wrap: balance evens the two lines rather than leaving one word
       stranded - at 375 the split goes from 125/38px to 86/77px. Ignored by
       browsers that do not support it, which is a no-op, not a fallback.

       If one line each is ever a hard requirement, the only real lever is
       shorter mobile copy (e.g. "Same Day Dispatch", "Largest Plate Range"),
       which fits at 320 up - that is a copy decision, not a CSS one. */
    .bpd-usps--text li {
        margin: 0 0 8px;
        padding-left: 0.75em;
        text-indent: -0.75em;
        text-wrap: balance;
    }

    .bpd-starthere { margin: 0 0 6px; width: 128px; height: 34px; max-width: none; }
    .bpd-reg-fields input {
        height: 44px;
        font-size: 20px;
        border-width: 3px;
        margin-bottom: 8px;
    }

    /* ---- builder top row: plate beside the buy block, countdown hidden ----
       CPD hides its whole desktop price/plate wrapper on mobile
       (#builder-plate-mobile { display:none } at <=768px, and position:fixed
       from .price-checkout .row at <=1024px - see the 901-1024px block above)
       and shows a duplicate plate and price inside #builder-reg instead. Our legacy-style
       top row lives inside that wrapper, so on mobile it was invisible and the
       CPD duplicate was what actually rendered.

       Re-enable ours and hide the duplicate, so there is one layout at every
       width - which is also what legacy does. */
    #carplatesdirect-builder #builder-plate-mobile {
        display: block !important;
        position: static !important;
    }
    #carplatesdirect-builder .mob-preview,
    #carplatesdirect-builder .mob-price { display: none !important; }

    /* ...and with both of those hidden, #builder-reg is a zero-height flex item
       that still consumes one of the list's 10px gaps, which showed up as dead
       space between the CTA and the first control (Matt, 17 Sept: the gap was
       bigger than legacy's). Desktop already hides this li so it cannot take a
       grid cell; this is the mobile half of the same thing.
       ⚠️ If the CPD mobile preview/price is ever un-hidden above, this rule has
       to go with it - it would hide them. Verified 17 Sept that all three
       children compute display:none at 360 / 500 / 700 / 899px. */
    #carplatesdirect-builder #builder-menu-drilldown > #builder-reg {
        display: none !important;
    }

    #carplatesdirect-builder .bpd-builder-top {
        display: flex;
        flex-wrap: nowrap;
        align-items: center;
        gap: 12px;
        /* 8, not 18: with the wasted gap above removed, this is the rest of the
           difference against legacy. The 48px between the CTA and Text Style
           was 20 (the builder column's own flex gap) + 18 here + 10 wasted. */
        margin-bottom: 8px;
    }
    #carplatesdirect-builder .bpd-countdown { display: none; }
    #carplatesdirect-builder .bpd-plate-preview {
        flex: 0 1 46%;
        min-width: 0;
    }
    /* CPD hides #numberplate-mob on mobile (its own mobile markup uses
       #numberplate-mob2) AND styles .numberplate-mobile-style as
       position:fixed for a sticky preview. We use one layout at all widths, so
       the plate has to be put back AND returned to normal flow - left fixed it
       escapes its 170px column and renders full width further down the page. */
    #carplatesdirect-builder .bpd-plate-preview img,
    #carplatesdirect-builder .bpd-plate-preview img#numberplate-mob {
        display: block !important;
        position: static !important;
        width: 100% !important;
        max-width: 100% !important;
        height: auto !important;
        margin: 0 auto !important;
        inset: auto !important;
    }
    #carplatesdirect-builder .bpd-builder-buy {
        flex: 1 1 52%;
        min-width: 0;
    }
    /* Both of these stay on ONE line. "Your Price:" wrapping away from its
       figure, and ADD TO BASKET going to two lines, each added a line of height
       above the controls and pushed the options further down the page (Matt,
       17 Sept, at 320px). The sizes in the 380px block below are what make the
       nowrap fit rather than overflow. */
    #carplatesdirect-builder .bpd-price { margin: 8px 0 10px; font-size: 17px; white-space: nowrap; }
    #carplatesdirect-builder .bpd-price .true-price { font-size: 21px; }
    #carplatesdirect-builder .bpd-builder-reviews .bbr-excellent { max-width: 84px; }
    #carplatesdirect-builder .bpd-builder-reviews .bbr-stars { max-width: 112px; margin-top: 4px; }
    #carplatesdirect-builder .bpd-builder-reviews .bbr-count { font-size: 10.5px; }
    #carplatesdirect-builder #builder-actions #add-to-basket,
    #carplatesdirect-builder button#add-to-basket.bpd-add-basket {
        padding: 12px 10px !important;
        font-size: 15px !important;
        white-space: nowrap;
    }

    /* ---- controls: must fit the viewport, with legacy's side gutters ----
       The shell breakout above zeroes padding-left/right on the wrapper chain
       (#builder-menu, #builder-menu-internal, .price-checkout,
       #builder-plate-mobile) to get full width on desktop. On mobile that left
       the controls and the CTA flush against both screen edges, with the label
       column squeezed off the left. Put it back here, on the two blocks that
       actually hold content.

       ⚠️ These gutters are DELIBERATELY UNEVEN, 16 left / 36 right. An earlier
       version of this comment claimed "legacy carries even padding either
       side" - that was wrong, and it is why Matt reported the mobile controls
       looking pushed right (10 Sept). Measured against legacy as a share of
       viewport width, on the same "Size:" row:

                        legacy    16/16 (before)   16/36 (now)
         label starts    18.2%        20.0%           20.0%
         control ends    90.9%        95.9%           90.8%
         control width   62.1%        66.2%           61.0%
         block centre    54.5%        58.0%           55.4%

       Even padding is what pushed it right: the label column is right-aligned,
       so the LEFT gutter already has the label's own dead space behind it,
       while the control runs to the right edge. Matching legacy needs more room
       on the right than the left. Do not "tidy" these back to a single value.

       Legacy is not responsive - it reports a 780px layout viewport on a 390px
       device - so it can only be compared in percentage terms, never in px. */
    #carplatesdirect-builder .bpd-builder-top,
    #carplatesdirect-builder #builder-menu-drilldown {
        padding-left: 16px !important;
        padding-right: 36px !important;
        box-sizing: border-box;
    }
    #carplatesdirect-builder .v2-plate-layout-container label strong,
    #carplatesdirect-builder #builder-font > strong.text-style-title-strong,
    #carplatesdirect-builder #builder-material > strong,
    #carplatesdirect-builder .builder-menu-content > strong,
    #carplatesdirect-builder #slogan-font-preview > .sfp-label {
        flex: 0 0 88px !important;
        font-size: 12.5px !important;
        line-height: 1.2;
    }
    #carplatesdirect-builder #builder-menu-drilldown .plate-row { gap: 6px; }

    /* Even spacing between rows, and Choose Plate Material moved to the end.
       The rhythm block above zeroes vertical margins for the desktop grid,
       where the row gap provides the spacing. On mobile there is no grid, so
       the rows ended up flush against one another - hence the squashed look.
       Give every row the same margin here instead.

       The material row is also taller than the rest (two-line label plus the
       MOST POPULAR flag), so sitting mid-list it broke the rhythm either side
       of it. Flex column lets us order it last without touching the markup,
       which keeps the desktop grid placement untouched. */
    #carplatesdirect-builder #builder-menu-drilldown {
        display: flex !important;
        flex-direction: column;
        /* Single source of row spacing. Per-child margin-bottom did not hold
           evenly - the rhythm block zeroes margins on several of these same
           wrappers, so some rows ended up flush (38px pitch, i.e. no gap at
           all) while only the wrapper boundaries picked up the margin.
           Measured before: 38, 38, 49, 38, 46, 48. A flex gap cannot be
           overridden by a child margin, so every row gets the same. */
        gap: 10px;
    }
    #carplatesdirect-builder #builder-menu-drilldown > li,
    #carplatesdirect-builder #builder-menu-drilldown > div {
        margin-top: 0 !important;
        margin-bottom: 0 !important;
    }
    /* The slogan block is one child holding two rows, so its internal spacing
       has to match the column gap or those two look different to the rest. */
    #carplatesdirect-builder #builder-slogan12 > li {
        gap: 10px;
        /* builder.php carries an inline style="margin-top:-3px" on this li,
           which left the slogan row 3px tighter than every other gap. An
           author !important is needed to beat an inline style. */
        margin-top: 0 !important;
    }

    #carplatesdirect-builder #builder-menu-drilldown > .bpd-grid-left {
        order: 9;
        /* Every other row boundary measures exactly the 10px column gap; this
           one came out at 30px. Traced to the order-9 boundary rather than a
           margin on this element, so it is compensated here explicitly. */
        margin-top: -20px !important;
    }
    /* The MOST POPULAR flag stays in normal flow, now below the buttons, so it
       has room to breathe - overlaying it onto the button crowded it. That means
       this row sits ~22px lower than the uniform 48px pitch, which is the
       flag's own height and is intentional: it needs the space.
       Overridden a few rules down; kept as the documented value. */
    #carplatesdirect-builder .material-popular-hint { margin-top: 4px; }
    /* Pull the material row back towards Slogan Colour. The slogan block's box
       ran 30px below its last control, so the gap measured 40px rather than the
       10px column gap. Trim that trailing space at source. */
    #carplatesdirect-builder #builder-slogan12,
    #carplatesdirect-builder #builder-slogan12 > li,
    #carplatesdirect-builder #builder-slogan12 .plate-row,
    #carplatesdirect-builder #builder-slogan12 .v2-plate-layout-container,
    #carplatesdirect-builder #builder-slogan12 label {
        margin-bottom: 0 !important;
        padding-bottom: 0 !important;
    }
    /* Wins over the 4px above - tightens the flag against the buttons on
       mobile, where the pitch is 10px rather than the desktop 12. */
    #carplatesdirect-builder .material-popular-hint { margin-top: 1px; }
    #carplatesdirect-builder .bpd-grid-left ul.vertical.menu,
    #carplatesdirect-builder .bpd-grid-left .size_background,
    #carplatesdirect-builder .bpd-grid-left > li,
    #carplatesdirect-builder #builder-material {
        margin-top: 0 !important;
        padding-top: 0 !important;
    }
    #carplatesdirect-builder .v2-plate-layout-container select,
    #carplatesdirect-builder .v2-plate-layout-container input[type="text"],
    #carplatesdirect-builder #builder-size {
        height: 38px !important;
        padding: 6px 8px !important;
        font-size: 13px !important;
    }
    #carplatesdirect-builder #builder-font .segmented { gap: 6px; }
    #carplatesdirect-builder #builder-font .segmented__option,
    #carplatesdirect-builder label.segmented__option {
        height: 38px;
        padding: 0 4px !important;
        font-size: 12px !important;
        white-space: nowrap;
    }
    #carplatesdirect-builder #builder-material .scroll-pane { gap: 6px; }
    /* "Premium Acrylic" has to stay on ONE line, and the wider right gutter
       took 20px off this row. The button inherits 10px of horizontal padding
       it does not need (the text is centred in a flex box), so buying the room
       back there rather than off the gutter: 6px padding and 11.5px type puts
       the one-line requirement at 106px against a 107px button at 360 and a
       116px one at 390. It now fits on one line from 360 up, where before the
       gutter change it only fitted from about 375 - so this is better than the
       starting point, not just a repair.
       Below 360 it still wraps into the fixed 38px box, as it always has. */
    #carplatesdirect-builder #builder-material article {
        height: 38px !important;
        max-height: 38px !important;
        font-size: 11.5px !important;
        padding-left: 6px !important;
        padding-right: 6px !important;
    }
    #carplatesdirect-builder .bpd-popular-badge { font-size: 9px; padding: 1px 6px; }
    /* The panel now sits in the controls flow between Font and Border, so it
       reads as one of the rows rather than a section under them: tighter
       margins, smaller caption, and a photo that sits with the controls instead
       of dominating them (Matt, 17 Sept).
       ⚠️ This replaces an earlier `img { max-width: 100% }` here, which is what
       let the photo run the full width of the column. A 250px rule added above
       it did nothing - same specificity, later rule won. */
    #carplatesdirect-builder .bpd-font-sample { margin: 2px 0 4px; }
    #carplatesdirect-builder .bpd-font-sample__caption { font-size: 13px; margin: 0 0 6px; }
    #carplatesdirect-builder .bpd-font-sample img { max-width: 250px; border-radius: 5px; }

    #carplatesdirect-builder,
    #carplatesdirect-builder .bpd-builder-top,
    #carplatesdirect-builder #builder-menu-drilldown { max-width: 100%; }
}

@media (max-width: 380px) {
    /* Narrowest common handsets: give the labels back a little more room by
       shrinking the controls rather than letting them overflow. */
    .bpd-hero h1 { font-size: 30px; }
    .bpd-hero-sub { font-size: 12px; }
    .bpd-usps--text { font-size: 13px; margin-top: 36px; }   /* keeps 1px above the 12px hero sub here */
    .bpd-starthere { width: 112px; height: 30px; }
    /* ⚠️ #builder-font's label MUST be in this list. It was missing, so at
       380px and below every label narrowed to 76px except Text Style, which
       stayed on the 88px basis from the max-width:900px block - pushing the
       Printed / 4D Plate / 3D Gel buttons 12px right of every dropdown and
       making them 12px narrower. Matt spotted it on a 375px iPhone (10 Sept);
       it is invisible from 390px up, which is why it survived.
       This is the third time a control has gone out of line by being left out
       of one of these three shared label lists. Add new controls to ALL of
       them. */
    #carplatesdirect-builder .v2-plate-layout-container label strong,
    #carplatesdirect-builder #builder-font > strong.text-style-title-strong,
    #carplatesdirect-builder #builder-material > strong,
    #carplatesdirect-builder .builder-menu-content > strong,
    #carplatesdirect-builder #slogan-font-preview > .sfp-label { flex: 0 0 76px !important; font-size: 11.5px !important; }
    #carplatesdirect-builder #builder-font .segmented__option,
    #carplatesdirect-builder label.segmented__option { font-size: 10.5px !important; }
    #carplatesdirect-builder .v2-plate-layout-container select,
    #carplatesdirect-builder #builder-size { font-size: 12px !important; }
    /* The wider right gutter narrows the material row, and at 320px the MOST
       POPULAR badge no longer fitted the half-column it is centred in
       (.bpd-popular-inner is calc(50% - 5px) = 85px; the badge wanted 90).
       It overflowed 2.5px each side rather than clipping. Tightened to fit:
       84.5px against 85. */
    #carplatesdirect-builder .bpd-popular-badge {
        padding: 1px 3px;
        letter-spacing: .2px;
    }

    /* The buy column is ~136px here, and at 17/21px "Your Price: £34.36" and at
       15px "ADD TO BASKET" both needed two lines. Sized down so each fits on
       one, which is the point of the nowrap in the 900px block: nowrap alone
       would overflow instead of wrapping. */
    #carplatesdirect-builder .bpd-price { font-size: 13px; margin: 6px 0 8px; }
    #carplatesdirect-builder .bpd-price .true-price { font-size: 15px; }
    #carplatesdirect-builder #builder-actions #add-to-basket,
    #carplatesdirect-builder button#add-to-basket.bpd-add-basket {
        padding: 11px 6px !important;
        font-size: 12.5px !important;
        letter-spacing: 0;
    }
}

@media (max-width: 720px) {
    /* Legacy ships separate mobile markup rather than media queries; we collapse
       the single markup set instead, but keep the same visual outcome. */
    .bpd-header-inner { min-height: 58px; }
    .bpd-header-link span { display: none; }   /* icons only on small screens */
    .bpd-logo-link img { height: 34px; }

    .bpd-nav-toggle { display: block; }
    .bpd-nav ul {
        display: none;
        flex-direction: column;
        align-items: stretch;
    }
    .bpd-nav ul.is-open { display: flex; }
    .bpd-nav a { padding: 13px 20px; border-top: 1px solid #454545; }

    .bpd-strip-img--desktop { display: none; }
    .bpd-strip-img--mobile  { display: block; }

    .bpd-footer-inner { grid-template-columns: 1fr; }
    .bpd-section { padding: 32px 0; }
}

/* Two-line reg entry (includes/reg-entry.php).
   In the hero, .bpd-reg-fields input already carries its own margin, so only
   the in-builder rendering - the pages with no hero - needs the gap. */
#form_register_context_box #two-line-reg-inputs .entries + .entries {
    margin-top: 6px;
}
