/**
 * Easy Order v2 -- grid-based bulk ordering styles.
 *
 * Version 12 -- repainted onto the walker token layer.
 *
 * WHAT CHANGED AND WHY
 *
 * This sheet carried two dead palettes simultaneously: OpenCart's #00a0dc
 * blue (14 literals) and the OLD gold, rgba(156,125,63,a), in 28 literals
 * across 19 different alpha values. The walker moved to aqua a generation
 * ago -- walked-shell.css sets --accent:#3695ab and keeps gold scoped to
 * weddings -- and this page never got the memo. A customer designing in the
 * walker and landing here crossed a visible seam.
 *
 * Every colour now reads a token from walker_tokens.css, so the next accent
 * retune reaches this page for free instead of requiring 45 hand edits.
 *
 * THE THREE ACCENT ROLES ARE NOT INTERCHANGEABLE
 *   --accent       surfaces only -- backgrounds, borders, rules, rings
 *   --accent-deep  text -- anything a person reads
 *   --accent-rgb   bare channels, for rgba() alpha work
 * Using --accent as a `color:` is the contrast bug walked-shell.css line 34
 * records. Text that was blue is now --accent-deep; backgrounds and borders
 * that were blue are --accent. They are NOT the same substitution.
 *
 * DELETED IN THIS PASS
 *   .style-images-row / .style-image-item   the three decorative tiles
 *   .easyorder-image                        their wrapper + caption
 *   .ez-style-preview                       the mini thumbnail under Style
 * All three presented a style choice the customer now makes for real, in
 * the row, via ez-stylecards-v2. Roughly 485px of dead chrome above the
 * fold went with them.
 *
 * REQUIRES walker_tokens.css, loaded first.
 */
 
/* Container */
.easyorder-container {
    max-width: 1400px;
    margin: 0 auto;
    padding: 20px;
    /* The sheet never declared a family; it inherited the WP theme's
       Quicksand. The mu-plugin dequeues that on this route, so the walker
       face is declared here explicitly rather than left to a fallback. */
    font-family: var(--sans);
    color: var(--ink);
}


.btn-copy-row {
    background-color: #5bc0de;  /* Light blue to differentiate from Add Another Design */
    color: #fff;
    margin-left: 10px;
}

.btn-copy-row:hover {
    background-color: #46b8da;
}


/* Instructions — a <details> element. The summary carries the heading and a
   chevron; the default disclosure triangle is suppressed so it reads as a
   designed header rather than an OS widget. */
.easyorder-instructions {
    background: #f8f9fa;
    border: 1px solid #e0e0e0;
    border-radius: 8px;
    padding: 20px;
    margin-bottom: 20px;
}

.easyorder-instructions > summary {
    display: flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    list-style: none;
}
.easyorder-instructions > summary::-webkit-details-marker { display: none; }
.easyorder-instructions > summary::after {
    content: "\25B8";              /* chevron, rotates when open */
    margin-left: auto;
    font-size: 14px;
    color: var(--accent-deep);
    transition: transform 0.18s ease;
}
.easyorder-instructions[open] > summary::after { transform: rotate(90deg); }

.easyorder-instructions h3 {
    margin-top: 0;
    margin-bottom: 0;
    display: inline;
    color: var(--accent-deep);
}
.easyorder-instructions[open] > summary { margin-bottom: 12px; }

.easyorder-instructions ol {
    margin-bottom: 15px;
    padding-left: 20px;
}

.easyorder-instructions li {
    margin-bottom: 8px;
}

/* One of the two step lists is always hidden. Said out loud because the ol
   rule above selects the same elements, and a display declaration landing
   there later would silently show both. */
.easyorder-instructions ol[hidden] { display: none; }

.easyorder-instructions code {
    background: #e8e8e8;
    padding: 2px 6px;
    border-radius: 3px;
    font-family: monospace;
}

/* Symbol Charts - Collapsible Section */
.easyorder-symbols {
    margin-bottom: 30px;
    border: 1px solid #ddd;
    border-radius: 8px;
    background: #fff;
    overflow: hidden;
}

.symbols-toggle {
    width: 100%;
    padding: 15px 20px;
    background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
    border: none;
    cursor: pointer;
    font-size: 24px;
    font-weight: 600;
    color: #333;
    text-align: left;
    display: flex;
    align-items: center;
    gap: 10px;
    transition: background 0.2s;
}

.symbols-toggle:hover {
    background: linear-gradient(135deg, #e9ecef 0%, #dee2e6 100%);
}

.toggle-icon {
    font-size: 12px;
    color: var(--accent-deep);
    transition: transform 0.2s;
}

.symbols-content {
    padding: 20px;
    background: #fafafa;
    border-top: 1px solid #ddd;
}

.symbols-charts {
    display: flex;
    flex-wrap: wrap;
    gap: 30px;
    justify-content: center;
}

.symbol-chart {
    flex: 1;
    min-width: 300px;
    max-width: 600px;
    text-align: center;
}

.symbol-chart h4 {
    margin: 0 0 15px 0;
    color: var(--accent-deep);
    font-size: 18px;
}

.symbol-chart img {
    max-width: 100%;
    height: auto;
    border: 1px solid #ddd;
    border-radius: 6px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

/* Grid Wrapper */
.easyorder-grid-wrapper {
    overflow-x: auto;
    margin-bottom: 20px;
}

/* Grid Table */
.easyorder-grid {
    width: 100%;
    border-collapse: collapse;
    font-size: 14px;
}

.easyorder-grid th,
.easyorder-grid td {
    padding: 10px 8px;
    border: 1px solid #ddd;
    vertical-align: middle;
}

.easyorder-grid thead th {
    background: var(--accent);
    color: #fff;
    font-weight: 600;
    text-align: center;
    white-space: nowrap;
}

.easyorder-grid tbody tr:nth-child(even) {
    background: #f9f9f9;
}

.easyorder-grid tbody tr:hover {
    background: #eef7fb;
}

/* Column Widths */
.col-qty { width: 70px; }
.col-style { width: 340px; }   /* wide enough for the in-row style band to read as product photography rather than icons */
.col-size { width: 180px; }
.col-unit { width: 80px; text-align: right; }
.col-ext { width: 90px; text-align: right; }
.col-action { width: 40px; text-align: center; }

/* NOTE: The old col-upper / col-sole / col-strap / col-swatch rules that
   used to live here are gone — those cells no longer exist in the row
   template. All three color pickers now share col-colors (see below). */

/* Color swatches next to dropdowns */
.color-swatch {
    width: 32px;
    height: 32px;
    border: 1px solid #999;
    border-radius: 3px;
    background-color: #fff;
    display: inline-block;
    vertical-align: middle;
    position: relative;
}

/* X pattern for empty/unselected swatch */
.color-swatch.empty::before,
.color-swatch.empty::after {
    content: '';
    position: absolute;
    width: 80%;
    height: 2px;
    background-color: #ccc;
    top: 50%;
    left: 10%;
}
.color-swatch.empty::before {
    transform: rotate(45deg);
}
.color-swatch.empty::after {
    transform: rotate(-45deg);
}

.easyorder-grid thead th {
    /* thead swatch column rule removed with the column bundling */
}

/* Form Elements */
.easyorder-grid input[type="number"],
.easyorder-grid input[type="text"],
.easyorder-grid select {
    width: 100%;
    padding: 8px;
    border: 1px solid #ccc;
    border-radius: 4px;
    font-size: 13px;
    box-sizing: border-box;
}

.easyorder-grid input[type="number"] {
    text-align: center;
}

.easyorder-grid select {
    background: #fff;
    cursor: pointer;
}

.easyorder-grid select:disabled {
    background: #f0f0f0;
    color: #999;
    cursor: not-allowed;
}

.easyorder-grid input:focus,
.easyorder-grid select:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 3px rgba(0,160,220,0.3);
}

/* Disabled text inputs */
.easyorder-grid input[type="text"]:disabled {
    background: #f0f0f0;
    color: #999;
    cursor: not-allowed;
}

/* Error state */
.easyorder-grid .error {
    border-color: #dc3545 !important;
    background-color: #fff0f0 !important;
}

/* Price displays */
.unit-price,
.ext-price {
    font-weight: 600;
    color: #333;
}

.ext-price {
    color: var(--accent-deep);
}

/* Remove button */
.btn-remove-row {
    width: 28px;
    height: 28px;
    padding: 0;
    border: none;
    background: #dc3545;
    color: #fff;
    border-radius: 50%;
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    transition: background 0.2s;
}

.btn-remove-row:hover {
    background: #c82333;
}

/* ===================== ORDER FOOT =====================
   Branding options and the Order Total, order-wide. These used to be the
   grid's <tfoot>, in a <td colspan="6"> -- .totals-row, .totals-options-cell
   and their mobile un-tabling rules are gone with it. A plain block needs no
   un-tabling, so the phone layout below lost rules rather than gaining
   them. */
.ez-order-foot {
    margin: 4px 0 20px;
}

.ez-order-total {
    display: flex;
    align-items: baseline;
    justify-content: flex-end;
    gap: 10px;
    padding-top: 10px;
    border-top: 1px solid #dde;
    font-size: 16px;
}

.grand-total {
    font-size: 20px;
    font-weight: 700;
    color: var(--accent-deep);
}

.ez-volume-note {
    font-size: 12px;
    color: #666;
    text-align: right;
    margin-bottom: 4px;
}

/* ===========================================
   Print Add-ons Section Styles
   =========================================== */

.print-addons-section {
    background: #e9ecef;
    border: 1px solid #ccc;
    border-radius: 6px;
    padding: 12px 15px;
    margin-bottom: 12px;
    text-align: left;
}

.print-addon-title {
    font-weight: 600;
    font-size: 14px;
    color: #333;
    margin-bottom: 10px;
    border-bottom: 1px solid #ccc;
    padding-bottom: 6px;
}

.print-addon-option {
    margin-bottom: 10px;
    padding-bottom: 10px;
    border-bottom: 1px dashed #ccc;
}

.print-addon-option:last-of-type {
    margin-bottom: 8px;
    padding-bottom: 0;
    border-bottom: none;
}

.print-addon-label {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    font-size: 13px;
    color: #333;
}

.print-addon-label.disabled {
    color: #999;
    cursor: not-allowed;
}

.print-addon-label.disabled input[type="checkbox"] {
    cursor: not-allowed;
}

.print-addon-label input[type="checkbox"] {
    width: 16px;
    height: 16px;
    cursor: pointer;
}

/* Style checkboxes when multiple styles qualify */
.print-addon-styles {
    margin-left: 24px;
    margin-top: 8px;
    padding: 8px;
    background: #f8f9fa;
    border-radius: 4px;
}

.style-checkbox-group {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.style-checkbox-label {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    cursor: pointer;
}

.style-checkbox-label input[type="checkbox"] {
    width: 14px;
    height: 14px;
}

.style-qty {
    color: #888;
    font-size: 11px;
}

/* Cost display */
.print-addon-cost {
    margin-top: 6px;
    margin-left: 24px;
    font-size: 13px;
    font-weight: 600;
    color: var(--accent-deep);
}

.print-addon-cost .addon-amount {
    font-weight: 700;
}

/* Note about minimum */
.print-addon-note {
    font-size: 11px;
    color: #777;
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid #ccc;
}

.print-addon-note.has-eligible {
    color: #28a745;
}

/* ===========================================
   Print Details Accordion Styles
   =========================================== */

.print-details-accordion {
    margin-top: 10px;
    margin-left: 24px;
    border: 1px solid #d0d0d0;
    border-radius: 6px;
    background: #fff;
    overflow: hidden;
}

.print-details-toggle {
    width: 100%;
    padding: 10px 14px;
    background: linear-gradient(135deg, #f0f4f8 0%, #e8ecf0 100%);
    border: none;
    cursor: pointer;
    font-size: 13px;
    font-weight: 500;
    color: #444;
    text-align: left;
    display: flex;
    align-items: center;
    gap: 8px;
    transition: background 0.2s;
}

.print-details-toggle:hover {
    background: linear-gradient(135deg, #e8ecf0 0%, #dce2e8 100%);
}

.print-details-toggle .toggle-icon {
    font-size: 10px;
    color: var(--accent-deep);
    transition: transform 0.2s;
}

.print-details-toggle.expanded .toggle-icon {
    transform: rotate(90deg);
}

.print-details-content {
    padding: 15px;
    background: #fafbfc;
    border-top: 1px solid #d0d0d0;
}

.print-details-field {
    margin-bottom: 15px;
}

.print-details-field:last-child {
    margin-bottom: 0;
}

.print-details-field label {
    display: block;
    font-size: 12px;
    font-weight: 600;
    color: #444;
    margin-bottom: 6px;
}

.print-details-field textarea {
    width: 100%;
    padding: 10px;
    border: 1px solid #ccc;
    border-radius: 4px;
    font-size: 13px;
    font-family: inherit;
    resize: vertical;
    min-height: 70px;
    box-sizing: border-box;
}

.print-details-field textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 3px rgba(0,160,220,0.3);
}

.print-details-field textarea::placeholder {
    color: #999;
}

/* Artwork Upload Styles */
.artwork-upload-wrapper {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.artwork-file-input {
    display: none;
}

.artwork-upload-button {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 14px;
    background: linear-gradient(135deg, var(--accent) 0%, var(--accent-deep) 100%);
    color: #fff;
    border-radius: 4px;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    transition: background 0.2s, transform 0.1s;
}

.artwork-upload-button:hover {
    background: linear-gradient(135deg, var(--accent-deep) 0%, var(--accent-deep) 100%);
}

.artwork-upload-button:active {
    transform: scale(0.98);
}

.upload-icon {
    font-size: 14px;
}

.artwork-filename {
    font-size: 12px;
    color: #666;
    font-style: italic;
    max-width: 200px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.artwork-filename.has-file {
    color: #28a745;
    font-style: normal;
    font-weight: 500;
}

.artwork-upload-status {
    width: 100%;
    margin-top: 6px;
    font-size: 12px;
}

.artwork-upload-status.uploading {
    color: #007bff;
}

.artwork-upload-status.success {
    color: #28a745;
}

.artwork-upload-status.error {
    color: #dc3545;
}

.upload-hint {
    font-size: 11px;
    color: #888;
    margin: 6px 0 0 0;
}

/* Uploaded file preview/remove */
.artwork-uploaded {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    background: #e8f5e9;
    border: 1px solid #c8e6c9;
    border-radius: 4px;
    margin-top: 8px;
}

.artwork-uploaded-name {
    font-size: 12px;
    color: #2e7d32;
    font-weight: 500;
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.artwork-remove-btn {
    padding: 4px 8px;
    background: #dc3545;
    color: #fff;
    border: none;
    border-radius: 3px;
    font-size: 11px;
    cursor: pointer;
    transition: background 0.2s;
}

.artwork-remove-btn:hover {
    background: #c82333;
}

/* Action Buttons */
/* One button now: Add to Cart. The two row-builders live in the flip-flops
   section beside the grid they act on. */
.easyorder-actions {
    display: flex;
    gap: 15px;
    justify-content: center;
    margin: 24px 0 30px;
}

.easyorder-actions .button {
    padding: 12px 30px;
    font-size: 16px;
    font-weight: 600;
    border: none;
    border-radius: 6px;
    cursor: pointer;
    transition: all 0.2s;
    text-align: center;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.btn-add-row {
    background: #6c757d;
    color: #fff;
}

.btn-add-row:hover {
    background: #5a6268;
}

.btn-add-cart {
    background: var(--accent);
    color: #fff;
}

.btn-add-cart:hover {
    background: var(--accent-deep);
}

/* Messages */
.easyorder-messages {
    max-width: 600px;
    margin: 0 auto;
}

.message {
    padding: 15px 20px;
    border-radius: 6px;
    margin-bottom: 10px;
    animation: slideIn 0.3s ease;
}

@keyframes slideIn {
    from {
        opacity: 0;
        transform: translateY(-10px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.message-success {
    background: #d4edda;
    border: 1px solid #c3e6cb;
    color: #155724;
}

.message-error {
    background: #f8d7da;
    border: 1px solid #f5c6cb;
    color: #721c24;
}

.message-warning {
    background: #fff3cd;
    border: 1px solid #ffeeba;
    color: #856404;
}

.message-info {
    background: #d1ecf1;
    border: 1px solid #bee5eb;
    color: #0c5460;
}

/* ===========================================
   Preview Column Styles
   =========================================== */

/* Preview column - larger size */
.col-preview { 
    width: 140px; 
    min-width: 140px;
    text-align: center; 
}

/* Preview container */
.flipflop-preview {
    width: 130px;
    height: 130px;
    position: relative;
    display: inline-block;
    background: #f5f5f5;
    border: 1px solid #ddd;
    border-radius: 4px;
    overflow: hidden;
}

/* The actual preview image */
.flipflop-preview-img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}

/* Placeholder shown when no selections made */
.preview-placeholder {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #f9f9f9;
    color: #ccc;
    font-size: 36px;
    font-weight: bold;
}

/* Hide placeholder when image is loaded */
.flipflop-preview:not(.preview-empty) .preview-placeholder {
    display: none;
}

/* Loading spinner */
.preview-loader {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 24px;
    height: 24px;
    margin: -12px 0 0 -12px;
    border: 3px solid #f3f3f3;
    border-top: 3px solid var(--accent);
    border-radius: 50%;
    animation: spin 1s linear infinite;
    display: none;
}

.flipflop-preview.preview-loading .preview-loader {
    display: block;
}

.flipflop-preview.preview-loading .preview-placeholder {
    display: none;
}

.flipflop-preview.preview-loading .flipflop-preview-img {
    opacity: 0.3;
}

@keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

/* Error state */
.flipflop-preview.preview-error {
    background: #fff0f0;
    border-color: #ffcccc;
}

.flipflop-preview.preview-error .preview-placeholder {
    display: flex;
    color: #cc0000;
    font-size: 20px;
}

.flipflop-preview.preview-error .preview-placeholder span::before {
    content: '!';
}

/* Empty state - show question mark */
.flipflop-preview.preview-empty .flipflop-preview-img {
    display: none;
}

/* ===========================================
   Combined Sand Imprint Column Styles
   =========================================== */

.col-imprint {
    width: 200px;
    min-width: 180px;
}

.imprint-fields {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.imprint-row {
    display: flex;
    flex-direction: column;
    gap: 2px;
    position: relative;
}

.imprint-label {
    font-size: 11px;
    font-weight: 600;
    color: #666;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.imprint-row .input-text {
    width: 100%;
}

/* Character counter positioning for stacked layout */
.imprint-row .char-counter {
    position: absolute;
    right: 2px;
    top: 0;
    font-size: 10px;
}

/* Inspiration off-ramp, under the two imprint fields. A quiet text link and
   not a button: the shopper who needs it has stalled, they are not choosing
   between actions, and a button here would compete with the fields it sits
   beneath.

   It hides itself the moment either editor holds anything. paintChipEditor
   empties the editor outright when a field has no tokens, so :empty is exact
   rather than approximate -- and it stays exact while someone types, because
   contenteditable puts text nodes straight into the editor. A walker row is
   born hidden: hydrateWalkerRow paints both editors before the row is seen.

   :has() is Chrome 105+/Safari 15.4+. Where it is missing the link stays
   visible -- it can never hide wrongly, so the whole cost of the fallback is
   a little clutter on an old browser. */
.ez-inspire-link {
    display: inline-block;
    margin-top: 8px;
    font-size: 12px;
    color: var(--accent-deep, #8a6d3b);
    text-decoration: none;
}
.ez-inspire-link:hover {
    text-decoration: underline;
}
.col-imprint:has(.ez-chip-editor:not(:empty)) .ez-inspire-link {
    display: none;
}

/* Character counter colors */
.char-counter {
    color: #999;
}

.char-counter.near-limit {
    color: #f0ad4e;
}

.char-counter.over-limit {
    color: #dc3545;
    font-weight: bold;
}

/* ===========================================
   Responsive Styles
   =========================================== */

@media (max-width: 1200px) {
    .easyorder-grid {
        font-size: 12px;
    }
    
    .easyorder-grid th,
    .easyorder-grid td {
        padding: 8px 5px;
    }
    
    .easyorder-grid input[type="number"],
    .easyorder-grid input[type="text"],
    .easyorder-grid select {
        padding: 6px;
        /* was 12px — under iOS's 16px focus-zoom threshold, and this band
           covers landscape phones/small tablets where the card layout has
           not yet kicked in. 13px is the smallest that reads comfortably;
           the <=768px block takes it to 16px. */
        font-size: 13px;
    }
    
    .flipflop-preview {
        width: 100px;
        height: 100px;
    }
    
    .col-preview {
        width: 110px;
        min-width: 110px;
    }
    
    .print-addons-section {
        padding: 10px 12px;
    }
    
    .print-addon-label {
        font-size: 12px;
    }
    
    .print-details-accordion {
        margin-left: 0;
    }
}

/* ===========================================
   MOBILE CARD LAYOUT (<= 768px)
   The grid is a DATA-ENTRY form, not a comparison table, so it stacks into
   one card per row rather than scrolling sideways: every cell holds a control
   that takes focus, and a horizontally-panned table loses the customer's place
   the moment the keyboard opens. Cards also scale as rows accumulate, which
   they do — Copy Last Line exists for exactly that.

   NOTE: the wrapper's overflow-x:auto is switched OFF here. A stacked card
   layout and a horizontal scroller are mutually exclusive; leaving both on
   produced a phantom 1px scroll and clipped the focus rings on the outer
   edges of the cards.
   =========================================== */
@media (max-width: 768px) {
    .easyorder-container { padding: 12px; }


    /* --- instructions: collapsed by default on phones (JS drops [open]);
       six numbered steps otherwise consume the entire first screen. --- */
    .easyorder-instructions { padding: 14px 16px; }
    .easyorder-instructions ol { padding-left: 18px; font-size: 14px; }

    .easyorder-grid-wrapper { overflow-x: visible; }

    /* --- the card --- */
    .easyorder-grid thead { display: none; }
    .easyorder-grid,
    .easyorder-grid tbody { display: block; width: 100%; }

    .easyorder-grid tbody tr {
        display: block;
        margin-bottom: 16px;
        border: 1px solid #d8dde2;
        border-radius: 10px;
        padding: 14px 14px 10px;
        background: #fff;
        box-shadow: 0 2px 8px rgba(20, 30, 40, 0.06);
    }
    /* zebra + hover are desktop table affordances; on cards they read as
       "this row is selected". Cards are already visually separated. */
    .easyorder-grid tbody tr:nth-child(even),
    .easyorder-grid tbody tr:hover { background: #fff; }

    .easyorder-grid tbody td {
        display: flex;
        justify-content: space-between;
        align-items: center;
        gap: 12px;
        width: auto;
        min-width: 0;
        border: none;
        padding: 9px 0;
        border-bottom: 1px solid #f0f0f0;
    }
    .easyorder-grid tbody td:last-child { border-bottom: none; }

    .easyorder-grid tbody td::before {
        content: attr(data-label);
        flex: 0 0 88px;
        font-size: 12px;
        font-weight: 600;
        color: #667;
        text-transform: uppercase;
        letter-spacing: 0.04em;
    }
    /* cells with no data-label must not reserve the label gutter */
    .easyorder-grid tbody td:not([data-label])::before { display: none; }

    .easyorder-grid tbody td input,
    .easyorder-grid tbody td select {
        flex: 1 1 auto;
        min-width: 0;
        max-width: none;      /* the old 200px clamp stranded controls mid-card */
    }

    /* 16px kills iOS focus-zoom. The wrapper disables user scaling, so a
       zoomed-in page cannot be zoomed back out by the customer. */
    .easyorder-grid input[type="number"],
    .easyorder-grid input[type="text"],
    .easyorder-grid select,
    .ez-chip-editor,
    .print-details-field textarea {
        font-size: 16px;
        padding: 10px;
    }
    .easyorder-grid input[type="number"] { max-width: 110px; flex: 0 0 110px; }

    /* --- COLORS: three stacked pickers. The generic label gutter would
       indent all three; the cell takes the full width and labels its own
       internal rows instead. --- */
    .easyorder-grid tbody td.col-colors {
        display: block;
        padding: 12px 0 10px;
    }
    .easyorder-grid tbody td.col-colors::before {
        display: block;
        flex: none;
        margin-bottom: 8px;
    }
    .ez-color-row { gap: 10px; margin: 8px 0; }
    .ez-color-lbl { flex: 0 0 46px; font-size: 11px; text-align: left; }
    .ez-color-row .color-swatch { width: 30px; height: 30px; }

    /* --- STYLE: dropdown + mini preview thumbnail --- */
    .easyorder-grid tbody td.col-style { flex-wrap: wrap; }

    /* --- PREVIEW: full-width, centered, no label gutter --- */
    .easyorder-grid tbody td.col-preview {
        display: block;
        width: 100%;
        text-align: center;
        padding: 14px 0;
    }
    .easyorder-grid tbody td.col-preview::before { display: none; }
    .flipflop-preview { width: 150px; height: 150px; margin: 0 auto; }

    /* --- SAND IMPRINT: two chip editors + their insert buttons. Full width,
       own labels, no gutter. --- */
    .easyorder-grid tbody td.col-imprint {
        display: block;
        width: 100%;
        padding: 12px 0;
    }
    .easyorder-grid tbody td.col-imprint::before { display: none; }
    .imprint-fields { gap: 14px; width: 100%; }
    .imprint-row { flex-direction: column; gap: 4px; }
    .imprint-label { font-size: 12px; }
    .ez-chip-editor { min-height: 46px; line-height: 24px; }
    /* 32px wide was a precision target with no pinch-zoom to recover from */
    .ez-insert-btn { width: 46px; font-size: 22px; }
    /* chips are tap-to-replace controls, not decoration */
    .ez-chip { height: 30px; min-width: 30px; padding: 3px 7px; }
    .ez-chip img { height: 22px; max-width: 46px; }
    .imprint-row .char-counter { position: static; align-self: flex-end; font-size: 11px; }
    /* Same tap-target reasoning as .ez-insert-btn above: a 12px link under a
       46px field is a precision target with no pinch-zoom to recover from. */
    .ez-inspire-link { font-size: 14px; margin-top: 12px; padding: 4px 0; }

    /* --- PRICES: read-only, so they pair on one line rather than eating
       two full rows of card height --- */
    .easyorder-grid tbody td.col-unit,
    .easyorder-grid tbody td.col-ext { padding: 7px 0; }
    .unit-price, .ext-price { font-size: 15px; }
    .ext-price { font-size: 17px; }

    /* --- REMOVE: below the 44px touch floor at its desktop 28px --- */
    .easyorder-grid tbody td.col-action {
        justify-content: flex-end;
        padding-top: 10px;
    }
    .btn-remove-row {
        width: 44px;
        height: 44px;
        font-size: 20px;
        border-radius: 8px;
    }
    .btn-remove-row::after {
        content: "Remove";
        font-size: 0;        /* label for screen readers / hit area only */
    }

    /* --- DRAWSTRING SUB-ROW (walker handoff) ---
       Renders directly beneath its paired flip-flop card. Tinted and pulled
       upward so it reads as an attachment to the pair above, not a peer. Its
       colspan cell carries no data-label, so the gutter is suppressed. --- */
    .easyorder-grid tbody tr.ez-ds-subrow {
        margin-top: -10px;
        margin-bottom: 16px;
        border-color: var(--hairline);
        border-top-left-radius: 0;
        border-top-right-radius: 0;
        background: var(--panel);
        padding-top: 10px;
    }
    .easyorder-grid tbody tr.ez-ds-subrow:nth-child(even),
    .easyorder-grid tbody tr.ez-ds-subrow:hover { background: var(--panel); }
    .easyorder-grid tbody tr.ez-ds-subrow td { border-bottom-color: rgba(203, 185, 143, 0.4); }
    .easyorder-grid tbody td.ez-ds-cell {
        display: block;
        padding: 10px 0;
    }
    .easyorder-grid tbody td.ez-ds-cell::before { display: none; }
    .ez-ds-flex { gap: 14px; align-items: flex-start; }
    .ez-ds-meta { font-size: 14px; }
    .ez-ds-remove { font-size: 1.6rem; padding: 8px 12px; }
    .ez-ds-qty { font-weight: 600; }

    /* --- TOTALS --- */
    .ez-order-foot {
        border: 1px solid #d8dde2;
        border-radius: 10px;
        padding: 14px;
        background: #f8f9fa;
    }
    .grand-total { font-size: 24px; }
    .print-addons-toggle {
        width: 100%;
        justify-content: center;
        min-height: 46px;
        font-size: 14px;
    }
    .print-details-toggle,
    .print-addon-label,
    .artwork-upload-button { min-height: 44px; }
    .print-addon-label { display: flex; align-items: center; }
    .print-addon-label input[type="checkbox"] { width: 22px; height: 22px; }
    .artwork-upload-wrapper { flex-wrap: wrap; }

    /* --- ACTIONS: sticky footer bar. Add to Cart is the page's terminal
       action and sat below an arbitrarily long stack of cards; sticky keeps
       it one tap away at any scroll depth. position:sticky (not fixed) so it
       never overlaps content and needs no body padding compensation. --- */
    .easyorder-actions {
        /* ONE button now, so the wrapping-row arrangement that let Add to
           Cart claim a full line while the two row-builders shared the one
           beneath it is no longer needed -- those moved into the flip-flops
           section. The sticky bar is a single 50px button instead of the
           ~180px of chrome that used to sit permanently over the Strap
           field on a phone. */
        flex-direction: row;
        gap: 10px;
        position: sticky;
        bottom: 0;
        z-index: 20;
        margin: 20px 0 0;
        padding: 12px 0 calc(12px + env(safe-area-inset-bottom, 0px));
        background: linear-gradient(180deg, rgba(255,255,255,0) 0%, #fff 18%);
    }
    .easyorder-actions .button {
        margin-left: 0;
        min-height: 50px;
        font-size: 16px;
        width: 100%;
    }

    /* symbol charts (legacy JPG section, if present) */
    .symbols-charts { flex-direction: column; }
    .symbol-chart { max-width: 100%; }
    .btn-browse-symbols { width: 100%; min-height: 46px; }
}

/* Narrow phones: the label gutter costs more than it explains */
@media (max-width: 420px) {
    .easyorder-grid tbody td::before { flex-basis: 74px; font-size: 11px; }
    .easyorder-grid tbody tr { padding: 12px 11px 8px; }
}


/* ==================== CHIP EDITOR + SYMBOL PICKER (v2) ====================
   Text with (SymbolName) tokens is canonical; the input holding it is hidden
   and .ez-chip-editor is the visible editing surface. Chips are inline spans
   with the SVG glyph from symbols-web/. Picker modal opens for chip clicks
   (replace), + button clicks (insert), and the Browse Symbol Library button. */

/* Hide the original text input — chip editor takes over as visible surface.
   Keep it in the DOM so all existing code that reads .value / sets .disabled
   continues to work. */
.ez-hidden-source {
    position: absolute !important;
    left: -9999px !important;
    width: 1px !important;
    height: 1px !important;
    opacity: 0 !important;
    pointer-events: none !important;
}

/* ---- Browse Symbol Library button (replaces the JPG chart section) ---- */
.easyorder-symbols-toolbar {
    display: flex;
    justify-content: center;
    margin: 12px 0 20px;
}
.btn-browse-symbols {
    padding: 8px 16px;
    background: #fff;
    color: var(--accent-deep);
    border: 1px solid rgba(var(--accent-rgb), 0.45);
    border-radius: 8px;
    font-family: inherit;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.03em;
    cursor: pointer;
    transition: all 0.18s;
}
.btn-browse-symbols:hover {
    background: rgba(var(--accent-rgb), 0.10);
    border-color: rgba(var(--accent-rgb), 0.7);
    color: var(--ink);
}
.browse-icon {
    display: inline-block;
    margin-right: 4px;
    opacity: 0.75;
}

/* ---- Chip editor: the visible replacement for the L/R text input ---- */
.ez-chip-wrapper {
    display: flex;
    align-items: stretch;
    gap: 6px;
    width: 100%;
}
.ez-chip-editor {
    flex: 1 1 auto;
    min-height: 32px;
    padding: 6px 10px;
    border: 1px solid #ccc;
    border-radius: 4px;
    background: #fff;
    font-family: inherit;
    font-size: 14px;
    line-height: 20px;
    color: #333;
    outline: none;
    cursor: text;
    overflow: hidden;
    word-wrap: break-word;
    /* Text and chips flow inline together. Preserve spaces so the customer's
       cursor lands where they expect. */
    white-space: pre-wrap;
    transition: border-color 0.15s, box-shadow 0.15s;
}
.ez-chip-editor:focus {
    border-color: #b39145;
    box-shadow: 0 0 0 2px rgba(179, 145, 69, 0.15);
}
.ez-chip-editor:empty::before {
    content: attr(data-placeholder);
    color: #999;
    font-style: italic;
    pointer-events: none;
}
.ez-chip-editor-disabled,
.ez-chip-editor[contenteditable="false"] {
    background: #f5f5f5;
    color: #888;
    cursor: not-allowed;
}

/* + button next to each editor (opens picker in insert mode) */
.ez-insert-btn {
    flex: 0 0 auto;
    width: 32px;
    padding: 0;
    background: rgba(var(--accent-rgb), 0.10);
    color: var(--accent-deep);
    border: 1px solid rgba(var(--accent-rgb), 0.45);
    border-radius: 4px;
    font-family: inherit;
    font-size: 18px;
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
    transition: all 0.15s;
}
.ez-insert-btn:hover {
    background: rgba(var(--accent-rgb), 0.20);
    border-color: rgba(var(--accent-rgb), 0.7);
}
.ez-chip-editor-disabled + .ez-insert-btn,
.ez-chip-editor[contenteditable="false"] + .ez-insert-btn {
    opacity: 0.4;
    cursor: not-allowed;
    pointer-events: none;
}

/* ---- Chips: inline SVG-glyph pills ----
   Glyph-only by design. Names discoverable via title/tooltip (desktop) or
   long-press (mobile), and via the picker modal opened on tap/click. */
.ez-chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin: 0 2px;
    padding: 2px 5px;
    height: 22px;
    min-width: 22px;
    background: rgba(var(--accent-rgb), 0.10);
    border: 1px solid rgba(var(--accent-rgb), 0.40);
    border-radius: 4px;
    cursor: pointer;
    user-select: none;
    vertical-align: middle;
    transition: background 0.15s, border-color 0.15s, transform 0.1s;
}
.ez-chip:hover {
    background: rgba(var(--accent-rgb), 0.22);
    border-color: rgba(var(--accent-rgb), 0.75);
}
.ez-chip:active {
    transform: scale(0.96);
}
.ez-chip img {
    display: block;
    height: 18px;
    width: auto;
    max-width: 40px;
    object-fit: contain;
    pointer-events: none;
}
/* Fallback when SVG fails to load */
.ez-chip-missing {
    background: rgba(179, 64, 46, 0.10);
    border-color: rgba(179, 64, 46, 0.40);
    color: #a03024;
    padding: 2px 8px;
    font-size: 11px;
    font-weight: 600;
    font-family: monospace;
}
/* Non-editable state (row not ready): chips look muted */
.ez-chip-editor[contenteditable="false"] .ez-chip {
    cursor: not-allowed;
    opacity: 0.6;
}

/* ==================== PICKER MODAL ==================== */
.ez-picker-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(20, 20, 20, 0.55);
    z-index: 10000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    animation: ez-picker-fade 0.15s ease both;
}
@keyframes ez-picker-fade {
    from { opacity: 0; }
    to { opacity: 1; }
}
.ez-picker-modal {
    background: #fff;
    border-radius: 12px;
    max-width: 640px;
    width: 100%;
    max-height: 80vh;
    display: flex;
    flex-direction: column;
    box-shadow: 0 20px 50px rgba(0, 0, 0, 0.35);
    animation: ez-picker-pop 0.18s cubic-bezier(0.2, 0.8, 0.3, 1.05) both;
    overflow: hidden;
}
@keyframes ez-picker-pop {
    from { opacity: 0; transform: scale(0.96) translateY(8px); }
    to { opacity: 1; transform: none; }
}
.ez-picker-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 20px 12px;
    border-bottom: 1px solid #eee;
}
.ez-picker-head h3 {
    margin: 0;
    font-size: 18px;
    font-weight: 600;
    color: #222;
}
.ez-picker-close {
    background: none;
    border: 0;
    color: #666;
    font-size: 24px;
    line-height: 1;
    cursor: pointer;
    padding: 4px 8px;
    border-radius: 4px;
    transition: color 0.15s, background 0.15s;
}
.ez-picker-close:hover {
    color: #000;
    background: #f0f0f0;
}
.ez-picker-current {
    padding: 10px 20px;
    background: rgba(var(--accent-rgb), 0.08);
    font-size: 13px;
    color: var(--accent-deep);
    border-bottom: 1px solid rgba(var(--accent-rgb), 0.15);
    display: flex;
    align-items: center;
    gap: 10px;
}
.ez-picker-current-glyph {
    display: inline-block;
    height: 28px;
    width: auto;
    max-width: 60px;
    vertical-align: middle;
    background: #fff;
    border: 1px solid rgba(var(--accent-rgb), 0.30);
    border-radius: 4px;
    padding: 2px 4px;
}
.ez-picker-current-tok {
    color: #888;
    font-family: monospace;
    font-size: 12px;
    margin-left: 4px;
}
.ez-picker-tabs {
    display: flex;
    gap: 4px;
    padding: 12px 20px 0;
    border-bottom: 1px solid #eee;
}
.ez-picker-tab {
    padding: 8px 16px;
    background: none;
    border: 0;
    border-bottom: 2px solid transparent;
    color: #666;
    font-family: inherit;
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    margin-bottom: -1px;
    transition: color 0.15s, border-color 0.15s;
}
.ez-picker-tab:hover { color: #333; }
.ez-picker-tab.on {
    color: var(--accent-deep);
    border-bottom-color: #b39145;
    font-weight: 600;
}
.ez-picker-search {
    padding: 12px 20px;
    border-bottom: 1px solid #f0f0f0;
}
.ez-picker-search input {
    width: 100%;
    padding: 8px 12px;
    border: 1px solid #ddd;
    border-radius: 6px;
    font-family: inherit;
    font-size: 14px;
    outline: none;
    transition: border-color 0.15s;
}
.ez-picker-search input:focus {
    border-color: #b39145;
}
.ez-picker-grid {
    padding: 12px 20px 20px;
    overflow-y: auto;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(90px, 1fr));
    gap: 10px;
    flex: 1;
}
.ez-picker-cell {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 12px 8px 8px;
    background: #fff;
    border: 1px solid #e0e0e0;
    border-radius: 8px;
    cursor: pointer;
    transition: all 0.15s;
    font-family: inherit;
}
.ez-picker-cell:hover {
    border-color: #b39145;
    background: rgba(var(--accent-rgb), 0.06);
    transform: translateY(-1px);
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.06);
}
.ez-picker-cell img {
    display: block;
    height: 40px;
    width: auto;
    max-width: 60px;
    object-fit: contain;
    margin-bottom: 6px;
    pointer-events: none;
}
.ez-picker-cell-lbl {
    font-size: 11px;
    color: #444;
    text-align: center;
    line-height: 1.2;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding: 0 2px;
}
.ez-picker-cell-missing {
    border-color: rgba(179, 64, 46, 0.30);
    background: rgba(179, 64, 46, 0.05);
}
.ez-picker-empty {
    padding: 40px 20px;
    text-align: center;
    color: #999;
    font-size: 14px;
    font-style: italic;
}

/* Mobile picker: full-width, taller */
@media (max-width: 640px) {
    .ez-picker-backdrop { padding: 10px; }
    /* dvh tracks iOS Safari's collapsing toolbar; 90vh alone let the grid's
       last row sit under the browser chrome. */
    .ez-picker-modal { max-height: 90vh; max-height: calc(100dvh - 20px); }
    .ez-picker-grid { grid-template-columns: repeat(auto-fill, minmax(76px, 1fr)); gap: 8px; padding: 10px 12px 16px; }
    .ez-picker-cell { padding: 10px 4px 8px; min-height: 76px; justify-content: center; }
    .ez-picker-cell img { height: 34px; }
    /* touch floor on the modal's own chrome */
    .ez-picker-close { min-width: 44px; min-height: 44px; font-size: 28px; }
    .ez-picker-tab { min-height: 44px; font-size: 15px; }
    .ez-picker-search input { font-size: 16px; padding: 11px 12px; }
    .ez-picker-head { padding: 12px 14px 10px; }
    .ez-picker-tabs, .ez-picker-search { padding-left: 14px; padding-right: 14px; }
}

/* ==================== WALKER HELPER (v2) ====================
   Small assistant that engages only for customers arriving via walker's
   Continue-to-order. Tip box lives at the top of the table; a gold breathing
   ring pulses on the currently-actionable field. The toggle switch inside
   the tip lets the customer turn hints off; the tip stays visible (in a
   compact "off" state) so they can flip it back on. */

.ez-helper {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin: 4px 0 16px;
    padding: 10px 14px;
    background: rgba(var(--accent-rgb), 0.09);
    border: 1px solid rgba(var(--accent-rgb), 0.32);
    border-radius: 8px;
    font-family: inherit;
    font-size: 14px;
    color: var(--ink);
    transition: background 0.2s, border-color 0.2s;
}
.ez-helper[data-mode="off"] {
    background: rgba(120, 120, 120, 0.05);
    border-color: rgba(120, 120, 120, 0.20);
    color: #888;
    font-style: italic;
}
.ez-helper-body {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1 1 auto;
    min-width: 0;
}
.ez-helper-icon {
    flex: 0 0 auto;
    font-size: 18px;
    line-height: 1;
    opacity: 0.9;
}
.ez-helper[data-mode="off"] .ez-helper-icon {
    opacity: 0.35;
}
.ez-helper-text {
    flex: 1 1 auto;
    line-height: 1.35;
    /* transition text softly when the tip changes */
    animation: ez-helper-fade 0.25s ease-out;
}
@keyframes ez-helper-fade {
    from { opacity: 0.3; transform: translateY(-1px); }
    to   { opacity: 1;   transform: none; }
}

/* Toggle switch: iOS-style pill with a sliding thumb */
.ez-helper-switch {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex: 0 0 auto;
    cursor: pointer;
    user-select: none;
    font-size: 12px;
    color: var(--accent-deep);
    font-weight: 600;
    letter-spacing: 0.03em;
}
.ez-helper[data-mode="off"] .ez-helper-switch { color: #999; }
.ez-helper-switch input { position: absolute; left: -9999px; opacity: 0; }
.ez-helper-switch-track {
    display: inline-block;
    width: 34px;
    height: 18px;
    background: #ccc;
    border-radius: 999px;
    position: relative;
    transition: background 0.2s;
}
.ez-helper-switch-thumb {
    display: block;
    position: absolute;
    top: 2px;
    left: 2px;
    width: 14px;
    height: 14px;
    background: #fff;
    border-radius: 50%;
    box-shadow: 0 1px 3px rgba(0,0,0,0.25);
    transition: transform 0.2s;
}
.ez-helper-switch input:checked ~ .ez-helper-switch-track {
    background: #b39145;
}
.ez-helper-switch input:checked ~ .ez-helper-switch-track .ez-helper-switch-thumb {
    transform: translateX(16px);
}
.ez-helper-switch-label { line-height: 1; }

/* ---- The breathing ring on the actionable field ----
   Applied to any element with .ez-actionable — currently select/input, could
   be extended to buttons in the future. Uses box-shadow instead of outline
   so animation is smooth across browsers. Position:relative gives the shadow
   a stable anchor; z-index lifts the field above adjacent cells so the halo
   doesn't get clipped by table cell borders. */
.ez-actionable {
    position: relative;
    z-index: 2;
    border-radius: 4px;
    animation: ez-breathe 1.8s ease-in-out infinite;
}
@keyframes ez-breathe {
    0%, 100% {
        box-shadow: 0 0 0 2px rgba(var(--accent-rgb), 0.35),
                    0 0 0 5px rgba(var(--accent-rgb), 0.10);
    }
    50% {
        box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.85),
                    0 0 0 9px rgba(var(--accent-rgb), 0.18);
    }
}

/* Mobile: smaller tip, toggle stays visible */
@media (max-width: 640px) {
    .ez-helper {
        padding: 8px 12px;
        font-size: 13px;
        gap: 8px;
    }
    .ez-helper-icon { font-size: 16px; }
    .ez-helper-switch-label { display: none; }
    /* the toggle track is 34x18 — pad the label so the tap target clears 44px */
    .ez-helper-switch { padding: 13px 8px; margin: -13px -8px; }
}

/* Motion sensitivity: freeze the breathing but keep the ring visible */
@media (prefers-reduced-motion: reduce) {
    .ez-actionable {
        animation: none;
        box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.65),
                    0 0 0 7px rgba(var(--accent-rgb), 0.15);
    }
    .ez-helper-text { animation: none; }
}

/* ==================== BUNDLED COLORS COLUMN (v2) ====================
   The three color pickers (Upper / Sole / Strap) share a single table
   column and stack vertically. Each internal row: label + dropdown + swatch
   in a compact horizontal strip. Frees ~200px of horizontal space vs the
   old 6-column layout, while keeping each existing JS selector functional
   (nothing about the .select-upper / .swatch-upper class names moved). */
.col-colors {
    width: 150px;                /* trimmed 50px vs first-cut min-width:200px; the 50px moved to col-style for the mini preview */
    min-width: 150px;
    vertical-align: middle;
    padding: 6px 8px;
}
.ez-color-row {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 3px 0;
}
.ez-color-row:first-child { margin-top: 0; }
.ez-color-row:last-child  { margin-bottom: 0; }
.ez-color-lbl {
    flex: 0 0 42px;
    font-size: 11px;
    font-weight: 600;
    color: #666;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    text-align: right;
}
.ez-color-row .color-swatch {
    flex: 0 0 auto;
}
.ez-color-row select {
    flex: 1 1 auto;
    min-width: 0;   /* allow the select to shrink within its cell */
}

@media (max-width: 900px) {
    .ez-color-lbl { flex-basis: 38px; font-size: 10px; }
}


/* ==================== BRANDING OPTIONS ACCORDION (v2) ====================
   Collapses the Print Add-ons section by default. Toggle button acts as a
   call-to-action when closed ("See Branding Options for 50+ pairs") and a
   dismiss when open. Chevron rotates via CSS keyed off the section's
   data-open attribute so the JS just needs to flip that flag. */
.print-addons-toggle {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 14px;
    background: transparent;
    border: 1px solid rgba(var(--accent-rgb), 0.35);
    border-radius: 6px;
    font-family: inherit;
    font-size: 13px;
    font-weight: 600;
    color: var(--accent-deep);
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
}
.print-addons-toggle:hover {
    background: rgba(var(--accent-rgb), 0.10);
    border-color: rgba(var(--accent-rgb), 0.65);
}
.print-addons-toggle-chevron {
    display: inline-block;
    font-size: 10px;
    line-height: 1;
    transition: transform 0.18s ease;
    opacity: 0.7;
}
.print-addons-section[data-open="true"] .print-addons-toggle-chevron {
    transform: rotate(90deg);
    opacity: 1;
}
.print-addons-body[hidden] { display: none; }
.print-addons-body:not([hidden]) {
    margin-top: 12px;
}

/* ===================== shared symbol picker (sym-lib.js) =====================
   SymLib.grid() emits .sym-tile / .sym-tile-cap, and all three pickers — the
   walker chart, the EZOrder modal and the bp-review author modal — render
   through it. Styling it once is what stops the three drifting apart again. */
.sym-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(84px,1fr));
  gap:8px;max-height:52vh;overflow-y:auto;padding:4px}
.sym-tile{display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:4px;padding:8px 4px;background:#fff;border:1px solid #d8d2c4;border-radius:8px;
  cursor:pointer;min-height:78px;transition:border-color .12s,box-shadow .12s}
.sym-tile:hover,.sym-tile:focus-visible{border-color:#b8963e;box-shadow:0 0 0 2px rgba(184,150,62,.18)}
.sym-tile img{width:38px;height:38px;object-fit:contain;pointer-events:none}
.sym-tile-cap{font:600 10px/1.2 system-ui,-apple-system,'Segoe UI',sans-serif;
  color:#5b5347;text-align:center;overflow-wrap:anywhere}
.sym-tile-missing{border-style:dashed;opacity:.55}
.sym-search{width:100%;box-sizing:border-box;padding:8px 10px;margin-bottom:8px;
  border:1px solid #d8d2c4;border-radius:8px;font:14px/1.3 system-ui,-apple-system,sans-serif}

/* ===================== refresh recovery (ez-restore-v2.js) =====================
   The grid is rebuilt one row at a time — each row waits on its own inventory
   fetch — so for a few seconds it is visibly filling in. Lock it while that
   happens: a click on a half-populated <select> would race the cascade that is
   still writing to it, and the customer would be fighting the restore.

   Opacity rather than a spinner over the top: watching the order come back is
   the reassurance, and hiding it would defeat the point. */
.ez-sections.ez-restoring {
    opacity: 0.55;
    pointer-events: none;
    transition: opacity 0.2s ease;
}

.ez-restore-banner {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 10px;
    padding: 9px 14px;
    border: 1px solid #cbb98f;
    border-left: 3px solid #b8963e;
    border-radius: 6px;
    background: #fbf7ec;
    font-size: 13px;
    font-weight: 600;
    color: #5b5347;
}
.ez-restore-banner::before {
    content: "";
    width: 12px;
    height: 12px;
    flex: 0 0 12px;
    border: 2px solid #cbb98f;
    border-top-color: #b8963e;
    border-radius: 50%;
    animation: ez-restore-spin 0.7s linear infinite;
}
@keyframes ez-restore-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
    .ez-sections.ez-restoring { transition: none; }
    .ez-restore-banner::before { animation: none; }
}

/* ===================== ORDER SECTIONS (Phase 2) =====================
   One section per product type. Collapsed, a section is a single line: what
   is in it, what it costs, or what is wrong with it. Expanded, it is that
   product's own grid with only the columns that product needs.

   The toggle deliberately mirrors .print-addons-section -- data-open on the
   container, [hidden] on the body, chevron rotated by CSS -- so the page has
   one accordion idiom rather than two. What is added here and not there is
   the SUMMARY, because a collapsed product section has to say something
   about its contents; a branding accordion does not.

   Toggling is manual. Nothing auto-advances, and an empty-but-available
   section stays openable: it is the upsell. */

.ez-sections {
    margin-bottom: 8px;
}

.ez-section {
    border: 1px solid #d8dde2;
    border-radius: 10px;
    margin-bottom: 12px;
    background: #fff;
    overflow: hidden;
}
.ez-section[hidden] { display: none; }

/* The whole header is the hit target, full width, so a collapsed section is
   as easy to open on a phone as a chevron is to miss.

   ::before carries the product cutout. It is decorative, so it lives here
   rather than in the template -- and CSS url() resolves against THIS FILE,
   not against the <base href> abc-zurb/header.php emits from the permalink,
   so a root-relative path is right on the WP route and on walked.html alike.
   That is the same trap that once turned accordion.js's cutouts into alt
   text; a stylesheet is simply immune to it. */
.ez-section-toggle {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 13px 16px;
    background: #f7f9fa;
    border: none;
    border-bottom: 1px solid transparent;
    font-family: inherit;
    font-size: 15px;
    text-align: left;
    color: var(--accent-deep);
    cursor: pointer;
    transition: background 0.15s;
}

/* Negative block margin lets the art overhang the text line, so the row reads
   as a product rather than a heading without the bar growing to fit it. */
.ez-section-toggle::before {
    content: "";
    flex: 0 0 auto;
    width: 44px;
    height: 32px;
    margin: -5px 0;
    background: no-repeat center / contain;
    filter: drop-shadow(0 3px 6px rgba(22, 33, 44, 0.22));
    transition: transform 0.18s ease;
}
#ez-sec-flipflops  .ez-section-toggle::before { background-image: url("/accordion-cutouts/classic.png"); }
#ez-sec-drawstring .ez-section-toggle::before { background-image: url("/accordion-cutouts/drawstring.png"); }
#ez-sec-beach      .ez-section-toggle::before { background-image: url("/accordion-cutouts/tote.png"); }

/* Hover was four points of luminance under a bold title -- indistinguishable
   from nothing happening. A collapsed section has to answer "is this a
   control?" before it answers anything else, so the whole bar shifts, the
   name underlines, and the art leans in. */
.ez-section-toggle:hover { background: #e4edf2; }
.ez-section-toggle:hover::before { transform: scale(1.06); }
.ez-section-toggle:hover .ez-section-name { text-decoration: underline; }
.ez-section-toggle:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
}
.ez-section[data-open="true"] .ez-section-toggle {
    border-bottom-color: #e3e8ec;
}

/* order:-1 keeps the chevron ahead of ::before, which flow order would
   otherwise place first. Bigger and fully opaque than it was: the element
   that announces the control should not be the quietest mark on the line. */
.ez-section-chevron {
    flex: 0 0 auto;
    order: -1;
    font-size: 14px;
    line-height: 1;
    transition: transform 0.18s ease;
}
.ez-section[data-open="true"] .ez-section-chevron {
    transform: rotate(90deg);
}

.ez-section-name {
    flex: 0 0 auto;
    font-weight: 700;
}





/* Pushed right, and allowed to shrink before the name does: the product name
   is the thing that identifies the row you are about to open. */
.ez-section-summary {
    flex: 1 1 auto;
    min-width: 0;
    text-align: right;
    font-size: 13px;
    font-weight: 500;
    color: #5a6570;
}

/* An empty section reads as an offer, never as "0 - $0.00". Zero is a fact
   about an order nobody placed; an invitation is a thing to act on. */
.ez-section-summary.is-empty {
    font-style: italic;
    opacity: 0.8;
}

/* Blocking state. Loud enough to find from a collapsed section, because that
   is exactly the case it exists for: highlightError() flashes a field red for
   three seconds, and inside a collapsed panel nobody sees it. */
.ez-section-summary.is-error {
    color: #a33;
    font-weight: 700;
}
.ez-section-summary.is-error::before {
    content: "\26A0";
    margin-right: 6px;
}

.ez-section-body { padding: 14px 16px 4px; }

/* Chrome that belongs to ONE product lives inside that product's section:
   "How to Order" and the branding accordion are both flip-flop-only. Inside a
   section body they need less of their own margin than they did as top-level
   page blocks. */
.ez-section-body > .easyorder-instructions { margin-bottom: 14px; }
.ez-section-body > .easyorder-symbols-toolbar { margin: 0 0 14px; }
.ez-section-body > .print-addons-section { margin-bottom: 6px; }
.ez-section-body[hidden] { display: none; }

/* The grid already carries its own bottom margin; doubling it inside a
   section leaves a gap that reads as a broken panel. */
.ez-section-body > .easyorder-grid-wrapper { margin-bottom: 6px; }

@media (max-width: 768px) {
    .ez-section-body { padding: 12px 12px 2px; }
    .ez-section-toggle {
        padding: 14px;
        min-height: 52px;
        flex-wrap: wrap;
        font-size: 15px;
    }
    /* Wrap rather than truncate: a three-style breakdown plus a price does
       not fit a ~330px card on one line, and the price is the part that must
       not be the thing that disappears. */
    .ez-section-summary {
        flex: 1 0 100%;
        text-align: left;
        margin-left: 20px;
    }
}

/* ===================== BAG SECTION GRIDS (Phase 3) =====================
   Drawstring and beach bags share one row layout -- the same one, now that
   the drawstring's "For" column has gone with pair binding. Both inherit
   .easyorder-grid, so
   the cell padding, borders, zebra and the whole <=768px card transform come
   for free — including the data-label gutter, which is why every cell below
   carries one.

   .ez-bb-* is gone with ez-beachbag-v2.css. The beach bag was a standalone
   card because it was a standalone add-on; it is a product section now, and a
   card inside a section would be a second frame around the same thing. */

.col-bag        { width: 120px; }
.col-bagdesign  { min-width: 220px; }

/* NO width here, at any breakpoint. bagCompose pins the composed wrap to an
   exact pixel width and solves the panel matrix for it, so a width declared
   here cannot resize the picture -- it only resizes the box around it. This
   rail shrink-wraps instead, and easyorder-v2.js's bagRowW() is the single
   place the number lives. */
.ez-bag-art {
    display: inline-block;
    border: 1px solid var(--hairline, #ddd);
    border-radius: 5px;
    overflow: hidden;
    background: #eee;
    cursor: zoom-in;
    line-height: 0;
}

.ez-bag-text {
    font-size: 13px;
    opacity: 0.85;
}

.ez-bag-btns { margin-top: 6px; }

.ez-bag-edit {
    padding: 5px 12px;
    border: 1px solid var(--accent-line, #cbb98f);
    border-radius: 6px;
    background: #fff;
    font: inherit;
    font-size: 13px;
    cursor: pointer;
}
.ez-bag-edit:hover { background: var(--accent-panel, #fbf7ec); }

.ez-bag-qtyin { width: 100%; }

.ez-bag-remove {
    background: none;
    border: none;
    color: #c0392b;
    font-size: 1.3rem;
    line-height: 1;
    cursor: pointer;
    padding: 4px 8px;
}

/* Every section's own Add / Copy. The bag ones carried only the theme's bare
   .button, because every size and colour rule for the page's action buttons
   is scoped to `.easyorder-actions .button` -- so they rendered washed-out
   grey and read as DISABLED. An add control that looks unavailable in an
   empty section defeats the section: the invitation is the whole point.

   Same palette as the pair controls, one step smaller because these sit
   inside a section rather than under the whole order. */
.ez-section-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin: 4px 0 12px;
}
.ez-section-actions .button {
    padding: 10px 22px;
    font-size: 15px;
    font-weight: 600;
    border: none;
    border-radius: 6px;
    cursor: pointer;
    transition: all 0.2s;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.ez-section-actions .btn-add-bag,
.ez-section-actions .btn-add-row {
    background: var(--accent);
    color: #fff;
}
.ez-section-actions .btn-add-bag:hover,
.ez-section-actions .btn-add-row:hover { background: var(--accent-deep); }

.ez-section-actions .btn-copy-bag,
.ez-section-actions .btn-copy-row {
    background-color: #5bc0de;
    color: #fff;
    margin-left: 0;          /* the page-level rule gave it a 10px nudge */
}
.ez-section-actions .btn-copy-bag:hover,
.ez-section-actions .btn-copy-row:hover { background-color: #46b8da; }

/* Copy needs something to copy. Disabled here is HONEST, unlike the grey
   above, so it is allowed to look it. */
.ez-section-actions .btn-copy-bag[disabled] {
    background-color: #c9d3d9;
    cursor: not-allowed;
}

/* Borrow-a-design: outlined, not a third solid block. Three saturated buttons
   in one row read as three equally normal ways to use the section, and this
   one is a shortcut -- it is absent entirely until the other section has
   something in it. */
.ez-section-actions .btn-bag-from {
    background: #fff;
    color: var(--accent-deep, #8a6d3b);
    border: 1px solid var(--accent, #b99a4b);
}
.ez-section-actions .btn-bag-from:hover {
    background: var(--accent-panel, #fbf7ec);
    border-color: var(--accent-deep, #8a6d3b);
}

/* [hidden] has to be said out loud here. The UA sheet's `[hidden]{display:none}`
   is an attribute-selector rule and loses to `.ez-section-actions .button`'s
   display:inline-flex two blocks above, so a button hidden from JS would still
   render. */
.ez-section-actions .button[hidden] { display: none; }

/* An empty bag section still shows its Add button — that is the upsell, and
   an empty grid with a header and no way to fill it would read as broken. */
.ez-bag-grid tbody:empty { display: none; }
.ez-bag-grid tbody:empty + tfoot { display: none; }

@media (max-width: 768px) {
    .ez-section-actions .button { flex: 1 1 100%; min-height: 46px; font-size: 15px; }
    /* The art cell's label gutter is wasted on a picture that identifies
       itself. */
    .easyorder-grid tbody td.col-bag::before { display: none; }
    .easyorder-grid tbody td.col-bag { justify-content: center; }
}

/* ===================== EMPTY FLIP-FLOP GRID =====================
   Zero rows is a legal order: a shopper arriving on a bag link starts with
   none, and deleting the last row no longer refuses. With no rows the table is
   a header over nothing, which reads as a rendering fault rather than as an
   empty state -- so hide the grid and let the section's own action button
   ("+ Design a flip-flop", relabelled by updateAddRowButtons) carry it.

   The wrapper goes, not just <thead>: the table's borders and bottom margin
   would otherwise leave a stray rule under the instructions.

   Class is written by updateAddRowButtons() on #ez-sec-flipflops. Only that
   section ever carries it -- the bag sections render their own empty state
   inside their bodies. */
.ez-section.is-empty .easyorder-grid-wrapper { display: none; }
