/*
 * Color/type scheme aligned to the live styercustoms.com site (2026-08-31,
 * from Styer: "can we make the overall color scheme meet the Styercustoms.com
 * webiste more?"). Pulled the real values straight from the site's own CSS
 * custom properties and computed styles rather than eyeballing a screenshot:
 * navy (#0d2137) is its header/hero brand-dark, #e8431a/#f05c33 is its
 * orange-red accent (buttons, the "Custom" highlight word, the "Customs"
 * half of the logotype), Montserrat is its headline font and Inter its body
 * font. The generic blue accent (#2454ff) this app started with had no
 * connection to the actual brand — swapped throughout for the real one.
 * Semantic pass/fail/flag colors (green/red) are left as plain green/red —
 * those are functional status signals, not brand decoration, so they stay
 * legible/conventional rather than being forced into the brand palette.
 */
:root {
  --ink: #1a1a2e;
  --muted: #64748b;
  --border: #e2e8f0;
  --bg: #f4f7fb;
  --panel: #ffffff;
  --pass: #1a7f37;
  --pass-bg: #eaf7ee;
  --fail: #b42318;
  --fail-bg: #fdecea;
  --flag: #ffffff;
  --flag-bg: #b42318;
  --accent: #e8431a;
  --accent-hover: #f05c33;
  --accent-bg: #fdece4;
  --navy: #0d2137;
  --navy-light: #1e4976;
  --font-heading: "Montserrat", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  /* Checkerboard used behind every transparent-PNG preview (thumbnails, the
     check-highlight detail image, gang sheet preview tiles) — added
     2026-09-11, from Styer: "if there is a lot of white in the image it is
     hard to see [against the background]". The three spots that used this
     pattern before were each their own near-white-on-white pairing
     (#eee/#fff, ~7% lightness gap) — enough contrast for a mid-tone or dark
     design, but a white or very light design's own opaque pixels barely
     stood out from the lighter checker square, which is exactly the "hard
     to see" Styer reported. One shared, more contrasting pairing (a light
     slate-gray against white, ~25% lightness gap — the same kind of
     contrast most design tools' transparency checkerboard uses) fixes it
     everywhere transparency is shown, automatically, with no per-image
     color choice needed. */
  --checker-a: #ffffff;
  --checker-b: #c3cad3;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Sticky page header (added 2026-09-02, from Styer: "I'd like to see the
   header (because of the checkout button and information) no matter how far
   I scroll") — `position: sticky; top: 0` keeps it pinned to the top of the
   viewport instead of scrolling away with the page content below it. z-index
   50 keeps it above ordinary page content but still under the zoom lightbox
   (z-index 1000), which should cover everything including the header while
   it's open. public/app.js measures this header's own real height (it can
   wrap onto two lines on some narrower desktop widths, since its contents
   use flex-wrap) into the --header-height custom property below, so the
   live-preview panel's sticky offset/height-cap (see .preview-panel) always
   clears it instead of the two overlapping. */
.page-header {
  padding: 22px 32px;
  margin-bottom: 8px;
  background: linear-gradient(135deg, var(--navy) 0%, var(--navy-light) 100%);
  color: #ffffff;
  display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  box-shadow: 0 4px 20px rgba(13, 33, 55, 0.2);
  position: sticky;
  top: 0;
  z-index: 50;
}
.header-brand { display: flex; align-items: center; gap: 14px; }
.cart-summary {
  display: flex; align-items: center; gap: 10px;
  background: rgba(255, 255, 255, 0.14); border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: 22px; padding: 8px 8px 8px 18px; font-size: 13px; font-weight: 600;
}
.cart-summary[hidden] { display: none; }
.cart-summary .cart-icon { font-size: 16px; }
.btn-checkout {
  padding: 7px 16px; font-size: 13px; border-radius: 18px;
  background: #ffffff; color: var(--navy); border: none; font-weight: 700;
  box-shadow: 0 2px 6px rgba(13, 33, 55, 0.18);
}
.btn-checkout:hover:not(:disabled) { background: #f0f4ff; transform: none; box-shadow: 0 2px 6px rgba(13, 33, 55, 0.18); }
.checkout-status { padding: 0 32px; color: var(--muted); }
.brand-logo {
  width: 48px; height: 48px; border-radius: 50%; object-fit: cover; flex-shrink: 0;
  border: 2px solid rgba(255, 255, 255, 0.35);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.22);
}
.page-header h1 { margin: 0 0 4px; font-size: 24px; font-family: var(--font-heading); font-weight: 700; color: #ffffff; letter-spacing: 0.01em; }
.subtitle { margin: 0; color: rgba(255, 255, 255, 0.75); }

/* Rate badge (added 2026-09-04, from Styer: "I need to have the 'per inch
   price' clearly visible on every page. Customers will want an easy way to
   ensure that the coupon codes are working.") — a small pill in the sticky
   header, rendered by public/rate-badge.js. Empty (no visible pill) until
   that script's fetch resolves, and stays empty on a failed fetch rather
   than showing a broken/stale number. The plain state matches the header's
   existing translucent-white treatment (.cart-summary); the discounted
   state switches to a solid pass-green so a valid coupon is unmistakable at
   a glance, not just implied by a slightly different dollar amount. */
.rate-badge {
  display: inline-flex; align-items: center; gap: 6px;
  background: rgba(255, 255, 255, 0.14); border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: 22px; padding: 6px 14px; font-size: 13px; font-weight: 600;
  color: #ffffff; margin-top: 6px;
}
.rate-badge:empty { display: none; }
.rate-badge-price { font-family: var(--font-heading); }
.rate-badge-discounted {
  background: var(--pass); border-color: var(--pass);
}
.rate-badge-discounted .rate-badge-check { font-weight: 700; }
.rate-badge-discounted .rate-badge-code { font-weight: 500; opacity: 0.92; }

main {
  display: grid;
  grid-template-columns: 1fr 340px;
  grid-template-areas:
    "upload  upload"
    "designs preview"
    "build   preview";
  gap: 24px;
  padding: 4px 32px 40px;
  max-width: 1600px;
  align-items: start;
}

.upload-panel { grid-area: upload; }
.designs-panel { grid-area: designs; }
/* The preview column spans both the "designs" and "build" rows (see
   grid-template-areas above), so its own height never dictates how far
   down the Build Gang Sheet section sits — a tall live preview (lots of
   designs/quantities) used to make the whole "designs / preview" grid row
   as tall as the preview itself, leaving the build section visually
   stranded next to the still-scrolling preview column instead of sitting
   cleanly below the (usually much shorter) designs list. Capped to the
   viewport height with its own scroll so it also never grows taller than
   the screen. */
/* --header-height (set by public/app.js from the real page header's own
   offsetHeight, since it can wrap onto two lines at some widths) offsets
   this panel's own sticky position and height cap below the now-sticky page
   header (added 2026-09-02) instead of underneath/overlapping it. The
   92px fallback matches the header's typical single-line height, used only
   for the very first paint before app.js's measurement runs. */
.preview-panel {
  grid-area: preview;
  position: sticky;
  top: calc(var(--header-height, 92px) + 20px);
  max-height: calc(100vh - var(--header-height, 92px) - 40px);
  overflow-y: auto;
}
.build-panel { grid-area: build; }

section, aside {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 20px 22px;
  box-shadow: 0 2px 6px rgba(13, 33, 55, 0.04), 0 10px 28px rgba(13, 33, 55, 0.07);
}

h2 {
  font-family: var(--font-heading); font-weight: 700; font-size: 14px; margin: 0 0 16px;
  text-transform: uppercase; letter-spacing: 0.06em; color: var(--navy);
  display: flex; align-items: center; gap: 8px;
}
h2::before { content: ""; width: 4px; height: 14px; background: var(--accent); border-radius: 2px; flex-shrink: 0; }
h3 { font-family: var(--font-heading); font-weight: 600; font-size: 14px; margin: 18px 0 10px; color: var(--navy); }

/* --- Add designs / drop zone --- */
#drop-zone {
  border: 2px dashed var(--border);
  border-radius: 12px;
  padding: 36px 16px;
  text-align: center;
  cursor: pointer;
  color: var(--muted);
  background: linear-gradient(180deg, #fbfcfe 0%, #f2f5fa 100%);
  transition: border-color 0.15s, background 0.15s, transform 0.15s;
}
#drop-zone:hover, #drop-zone:focus-visible { border-color: var(--accent); background: var(--accent-bg); transform: translateY(-1px); }
#drop-zone.dragover { border-color: var(--accent); background: var(--accent-bg); transform: scale(1.008); }
#drop-zone .drop-icon { font-size: 32px; color: var(--accent); margin-bottom: 6px; }
#drop-zone p { margin: 2px 0; }

.field { display: flex; flex-direction: column; gap: 4px; margin-top: 14px; }
label { font-size: 13px; color: var(--muted); }

/* Coupon code field (added 2026-09-03) — input plus Apply/Remove buttons on
   one row, rather than the buttons stacking full-width like a normal .field
   button would (see .btn-secondary's own margin-top, overridden here to 0
   since this row already has its own gap). */
.coupon-field-row { display: flex; align-items: center; gap: 8px; }
.coupon-field-row input[type="text"] { flex: 1; min-width: 0; }
.coupon-field-row .btn-secondary { margin-top: 0; padding: 8px 14px; font-size: 13px; flex-shrink: 0; }
#coupon-status.applied { color: var(--pass, #1a7f37); }
#coupon-status.inactive { color: var(--fail, #b42318); }
select, input[type="number"], input[type="text"] {
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 14px;
}

button {
  background: var(--accent);
  color: white;
  border: none;
  padding: 11px 18px;
  border-radius: 8px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  box-shadow: 0 2px 6px rgba(232, 67, 26, 0.25);
  transition: background 0.15s, transform 0.12s, box-shadow 0.15s;
}
button:disabled { background: var(--border); color: #94a3b8; cursor: not-allowed; box-shadow: none; }
button:hover:not(:disabled) { background: var(--accent-hover); transform: translateY(-1px); box-shadow: 0 4px 12px rgba(232, 67, 26, 0.32); }
button:active:not(:disabled) { transform: translateY(0); box-shadow: 0 2px 6px rgba(232, 67, 26, 0.25); }
.btn-secondary { background: #fff; color: var(--accent); border: 1px solid var(--accent); margin-top: 10px; box-shadow: none; }
.btn-secondary:hover:not(:disabled) { background: var(--accent-bg); color: var(--accent-hover); border-color: var(--accent-hover); box-shadow: none; }

.status-line { margin-top: 10px; font-size: 13px; color: var(--muted); min-height: 18px; }
.hint { font-size: 12px; color: var(--muted); margin: 6px 0 0; }
.empty-state { color: var(--muted); font-size: 13px; }

/* --- Designs table --- */
.table-header, .design-row {
  display: grid;
  /* thumb | name | width + 0.1" stepper | height | DPI | qty | status | duplicate + remove
     (DPI column, stepper and Duplicate added 2026-09-24) */
  grid-template-columns: 48px minmax(60px, 1fr) 96px 58px 44px 54px 84px 118px;
  gap: 10px;
  align-items: center;
}
.table-header {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.03em; color: var(--muted);
  padding: 0 6px 8px; border-bottom: 1px solid var(--border); margin-bottom: 6px;
}
.designs-list { display: flex; flex-direction: column; gap: 4px; }
.design-row { padding: 6px; border-radius: 8px; transition: background 0.12s; }
.design-row:hover { background: #f6f8fb; }
.design-row .thumb {
  width: 40px; height: 40px; object-fit: contain; border: 1px solid var(--border); border-radius: 4px;
  background: repeating-conic-gradient(var(--checker-b) 0% 25%, var(--checker-a) 0% 50%) 50% / 10px 10px;
}
.design-row .fname { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.design-row .w-input, .design-row .q-input { width: 100%; padding: 5px 6px; font-size: 13px; }
.design-row .h-display { font-size: 13px; color: var(--muted); }
.status-wrap { display: flex; }
.status-badge {
  font-size: 11px; font-weight: 600; padding: 4px 8px; border-radius: 12px; border: none; cursor: pointer;
  background: #eee; color: var(--muted);
}
.status-badge.pass { background: var(--pass-bg); color: var(--pass); }
.status-badge.fail { background: var(--fail-bg); color: var(--fail); }
.status-badge.checking { background: #eee; color: var(--muted); cursor: default; }
.design-row .w-cell { display: flex; align-items: stretch; gap: 3px; min-width: 0; }
.design-row .w-cell .w-input { min-width: 0; }
.size-stepper { display: flex; flex-direction: column; gap: 2px; }
.size-stepper .step-btn {
  flex: 1; width: 22px; padding: 0; font-size: 8px; line-height: 1;
  background: #eef2f7; color: var(--ink); border: 1px solid var(--border); border-radius: 3px; cursor: pointer;
}
.size-stepper .step-btn:hover:not(:disabled) { background: var(--accent-bg); border-color: var(--accent); color: var(--accent); }
.size-stepper .step-btn:disabled { opacity: 0.4; cursor: default; }
.design-row .dpi-display { font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--muted); }
.design-row .dpi-display.dpi-good { color: var(--pass); }
.design-row .dpi-display.dpi-ok { color: #b86e00; }
.design-row .dpi-display.dpi-low { color: var(--fail); }
.row-actions { display: flex; align-items: center; justify-content: flex-end; gap: 4px; }
.design-row .dup-btn {
  font-size: 12px; padding: 4px 8px; white-space: nowrap; cursor: pointer;
  background: transparent; color: var(--navy-light); border: 1px solid var(--border); border-radius: 6px;
}
.design-row .dup-btn:hover:not(:disabled) { border-color: var(--navy-light); background: #f0f5fb; }
.design-row .dup-btn:disabled { opacity: 0.4; cursor: default; }
.design-row .remove-btn {
  background: transparent; color: var(--fail); padding: 2px 6px; font-size: 13px; line-height: 1;
}
.row-error { grid-column: 1 / -1; font-size: 12px; color: var(--fail); padding: 0 6px 6px 58px; }
.row-details {
  grid-column: 1 / -1; margin: 2px 6px 8px 58px; padding: 8px 10px;
  background: #fafafa; border: 1px solid var(--border); border-radius: 6px;
  display: flex; flex-direction: column; gap: 4px;
}

.check-list { display: flex; flex-direction: column; gap: 6px; }
.check-item { display: flex; gap: 8px; align-items: flex-start; padding: 6px 8px; border-radius: 6px; font-size: 12px; }
.check-item.pass { background: var(--pass-bg); color: var(--pass); }
.check-item.fail { background: var(--fail-bg); color: var(--fail); }
.check-item .badge { font-weight: 700; min-width: 44px; margin-right: 8px; display: inline-block; }

.detail-image-wrap {
  position: relative; width: 100%; max-width: 260px; margin: 0 0 10px;
}
.detail-image-wrap img {
  width: 100%; display: block; border: 1px solid var(--border); border-radius: 6px;
  background: repeating-conic-gradient(var(--checker-b) 0% 25%, var(--checker-a) 0% 50%) 50% / 16px 16px;
}
.detail-image-wrap .overlay-svg { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; }

/* --- Zoomable check-detail images (2026-08-31, "I'd like the ability to
   zoom in on the images with the highlights") --- */
.detail-image-wrap.zoomable { cursor: zoom-in; }
.detail-image-wrap.zoomable::after {
  content: "🔍 Click to zoom";
  position: absolute; right: 6px; bottom: 6px;
  background: rgba(13, 33, 55, 0.72); color: #fff;
  font-size: 11px; padding: 3px 7px; border-radius: 10px;
  pointer-events: none; opacity: 0; transition: opacity 0.12s;
}
.detail-image-wrap.zoomable:hover::after { opacity: 1; }

.lightbox-backdrop {
  position: fixed; inset: 0; z-index: 1000;
  background: rgba(13, 33, 55, 0.86);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 20px;
}
.lightbox-backdrop[hidden] { display: none; }
.lightbox-toolbar {
  display: flex; align-items: center; gap: 8px; margin-bottom: 10px; flex-wrap: wrap; justify-content: center;
}
.lightbox-toolbar button {
  background: rgba(255, 255, 255, 0.12); color: #fff; border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 6px; padding: 6px 12px; font-size: 15px; font-weight: 600; line-height: 1;
}
.lightbox-toolbar button:hover:not(:disabled) { background: rgba(255, 255, 255, 0.24); }
/* Class-based (not ID-based) so this applies to every lightbox instance on a
   page — added 2026-09-11 alongside the second (gang-sheet) lightbox, which
   has its own element ids. */
.lightbox-toolbar .lightbox-reset-btn { font-size: 12px; }
.lightbox-hint { color: rgba(255, 255, 255, 0.7); font-size: 12px; margin: 0 6px; }
.lightbox-close { font-size: 20px !important; padding: 4px 12px !important; }
.lightbox-stage {
  position: relative; width: 90vw; height: 78vh; max-width: 1100px;
  overflow: hidden; border-radius: 10px; background: repeating-conic-gradient(#1a3350 0% 25%, #17304f 0% 50%) 50% / 20px 20px;
  cursor: grab;
  /* Stops text/image selection from starting during a click-drag pan —
     without this, dragging over the image can select nearby text or show
     a "no drop" cursor instead of panning smoothly. */
  user-select: none; -webkit-user-select: none;
}
.lightbox-stage.dragging { cursor: grabbing; }
.lightbox-content {
  position: absolute; top: 50%; left: 50%;
  transform-origin: center center;
  transform: translate(-50%, -50%);
  transition: transform 0.05s linear;
}
/* Fixed 2026-09-02: this used to force the wrap to a fixed WIDTH
   (min(80vw, 900px)) with no matching height cap, so a tall/portrait design's
   image (auto height, following its own aspect ratio) could render taller
   than the stage's 78vh and get clipped by the stage's `overflow: hidden` —
   looking like the image opened "already zoomed in a small amount," while
   `lb.scale` was still exactly 1 (LIGHTBOX_MIN_SCALE), so the pan handler's
   `if (lb.scale <= LIGHTBOX_MIN_SCALE) return;` guard blocked panning
   entirely even though part of the image was genuinely off-stage. Now the
   WRAP hugs the image's own rendered box (`display: inline-block`, no fixed
   width) and the IMAGE itself is constrained by max-width/max-height (a
   hair inside the stage's own 90vw/1100px × 78vh) with width/height left
   auto — the browser's native "contain" sizing — so the whole image is
   always fully visible at 1x regardless of its aspect ratio, matching what
   the pan-gating logic assumes. */
.lightbox-content .detail-image-wrap { max-width: none; width: auto; display: inline-block; margin: 0; cursor: default; }
.lightbox-content .detail-image-wrap::after { content: none; }
.lightbox-content .detail-image-wrap img {
  width: auto; height: auto;
  max-width: min(86vw, 1050px); max-height: 74vh;
  border-radius: 4px; -webkit-user-drag: none;
}

/* --- Live gang sheet preview --- */
/* Houses the "Gang sheet preview" h2 and the new zoom/pan button
   (added 2026-09-11) side by side, without disturbing h2's own bottom
   margin/accent-bar styling (moved onto this row instead). */
.preview-heading-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 16px; }
.preview-heading-row h2 { margin-bottom: 0; }
.preview-zoom-button { margin-top: 0; font-size: 12px; padding: 6px 12px; flex-shrink: 0; }
.sheet-preview { max-height: 520px; overflow-y: auto; padding-top: 4px; }
.preview-section { margin-bottom: 14px; }
.preview-section-label { font-size: 11px; color: var(--muted); margin-bottom: 4px; }
.preview-roll {
  border: 1px solid var(--border); border-radius: 4px; background: #fff;
  padding: 4px; width: max-content;
}
/* True-to-scale sheet (2026-09-30, see public/sheet-render.js): every design
   block and every copy is absolutely positioned at the x/y the packer chose,
   so the preview matches the print file exactly, rotations included. */
.preview-canvas { position: relative; }
.preview-group { position: absolute; outline: 1px dashed var(--border); outline-offset: 1px; }
.preview-tile {
  position: absolute; border: 1px solid #eee; border-radius: 2px; overflow: hidden; box-sizing: border-box;
  background: repeating-conic-gradient(var(--checker-b) 0% 25%, var(--checker-a) 0% 50%) 50% / 8px 8px;
}
.preview-tile img { width: 100%; height: 100%; object-fit: contain; display: block; }
.preview-tile img.rotated { position: absolute; max-width: none; transform: rotate(90deg); transform-origin: 50% 50%; }
.preview-total { margin-top: 10px; font-size: 13px; font-weight: 600; }

/* --- Build results --- */
.build-results { margin-top: 16px; display: flex; flex-direction: column; gap: 14px; }
.review-banner { padding: 10px 12px; border-radius: 6px; background: var(--flag-bg); color: var(--flag); font-weight: 600; }

/* Customer-facing "added to cart" confirmation (2026-08-31) — replaces the
   old per-design AI-check breakdown, which now goes to the printer-side
   review log instead (see lib/artworkNotes.js) rather than the browser. */
.cart-confirmation {
  display: flex; gap: 14px; align-items: flex-start;
  background: var(--pass-bg); border: 1px solid #bfe3c9; border-radius: 10px;
  padding: 18px 20px;
  box-shadow: 0 2px 10px rgba(26, 127, 55, 0.08);
}
.cart-confirmation-icon {
  flex-shrink: 0; width: 30px; height: 30px; border-radius: 50%;
  background: var(--pass); color: #fff; display: flex; align-items: center; justify-content: center;
  font-size: 16px; font-weight: 700;
}
.cart-confirmation-title { font-family: var(--font-heading); font-weight: 700; font-size: 16px; color: var(--navy); }
.cart-confirmation-detail { font-size: 13px; color: var(--ink); margin-top: 2px; }
.cart-confirmation .hint { margin-top: 8px; }
.total-line { font-family: var(--font-heading); font-size: 20px; font-weight: 700; color: var(--navy); }
.total-line .sub { font-size: 13px; font-weight: 400; color: var(--muted); }

table.section-table { width: 100%; border-collapse: collapse; font-size: 13px; }
table.section-table th, table.section-table td { text-align: left; padding: 6px 8px; border-bottom: 1px solid var(--border); }

.design-ai-block { border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px; }
.design-ai-block h4 { margin: 0 0 6px; font-size: 13px; }

@media (max-width: 900px) {
  main {
    grid-template-columns: 1fr;
    grid-template-areas: "upload" "designs" "preview" "build";
  }
  .preview-panel { position: static; max-height: none; overflow-y: visible; }
  .table-header, .design-row { grid-template-columns: 36px minmax(40px, 1fr) 80px 46px 38px 44px 70px 56px; font-size: 12px; }
  .design-row .dup-label { display: none; }
}

/* Rights-confirmation modal (added 2026-09-03, from Styer: "a pop-up after
   they click 'build gangsheet' where they see this language and then have
   to click a checkbox and then click 'Continue'"). Same centered-backdrop
   pattern as .lightbox-backdrop above, but with a plain white card (reusing
   the same elevated-card look as section/aside) instead of an image stage. */
.modal-backdrop {
  position: fixed; inset: 0; z-index: 900;
  background: rgba(13, 33, 55, 0.55);
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
}
.modal-backdrop[hidden] { display: none; }
.modal-card {
  background: var(--panel);
  border-radius: 12px;
  box-shadow: 0 2px 6px rgba(13, 33, 55, 0.08), 0 20px 50px rgba(13, 33, 55, 0.28);
  padding: 26px 28px;
  max-width: 460px;
  width: 100%;
}
.modal-card h2 {
  margin: 0 0 10px; font-size: 18px; text-transform: none; letter-spacing: normal;
}
.modal-card h2::before { display: none; }
.modal-body { font-size: 13px; color: var(--ink); line-height: 1.5; margin: 0 0 16px; }
.modal-checkbox {
  display: flex; align-items: flex-start; gap: 8px;
  font-size: 13px; font-weight: 600; color: var(--navy);
  cursor: pointer; margin-bottom: 20px;
}
.modal-checkbox input { margin-top: 2px; accent-color: var(--accent); width: 16px; height: 16px; flex-shrink: 0; }
.modal-actions { display: flex; justify-content: flex-end; gap: 10px; }
.modal-actions .btn-secondary { margin-top: 0; }

/* Add-to-Cart confirmation pop-up (added 2026-09-11) — reuses .modal-card/
   .modal-actions above and the .cart-confirmation-icon circle style below,
   just laid out side-by-side with the modal's own h2 instead of stacked. */
.cart-confirmation-icon-row { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.cart-confirmation-icon-row h2 { margin: 0; }

/* Order history entry point in the page header (added 2026-09-13).
   .header-actions wraps the "My orders" link and the existing cart pill so
   they sit together on the right without the link being swallowed when the
   cart summary is hidden (which it is until something is in the cart). */
.header-actions { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; justify-content: flex-end; }
.header-link { color: #fff; text-decoration: none; font-weight: 600; font-size: 14px; opacity: 0.9; white-space: nowrap; border-bottom: 1px solid rgba(255, 255, 255, 0.35); padding-bottom: 1px; }
.header-link:hover { opacity: 1; }
