/* ============================================
   PDF Maker — UI styles for the /pdf/ page.
   Étape A scope: page chrome + artwork list + bundle controls + stub buttons.
   Reuses global tokens from style.css; does NOT style the generated PDF
   (that's the jsPDF engine's job in Étape C).
   ============================================ */

.pdf-maker {
  max-width: var(--content-max);
  margin: 0 auto;
  padding: 2rem 1.5rem 4rem;
}

.pdf-maker h1 {
  font-family: var(--font-serif);
  font-weight: 700;
  font-size: 2.1rem;
  margin: 0 0 .35rem;
  color: var(--color-text);
}

.pdf-maker .subtitle {
  margin: 0 0 1.5rem;
  color: var(--color-text-muted);
  font-size: 1rem;
  line-height: 1.5;
}

/* ─────────────── Section headings inside the workspace ─────────────── */
.pdf-maker__h2 {
  font-family: var(--font-serif);
  font-weight: 700;
  font-size: 1.25rem;
  margin: 1.5rem 0 .65rem;
  color: var(--color-text);
}

/* ─────────────── Over-cap state ───────────────
   V3.5 — the empty-state section was removed; only over-cap keeps its
   own dead-end screen (cap 10 means the seller can't act on it in-page
   anyway). The inline empty-list placeholder lives in #artwork-list and
   has its own styles further down. */
.pdf-maker__overcap {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: 2rem;
  text-align: center;
  margin-top: 1.5rem;
}
.pdf-maker__overcap p { margin: 0 0 .5rem; }
.pdf-maker__overcap {
  border-color: var(--color-warning-border);
  background: var(--color-warning-bg);
}

/* ─────────────── Source banner (came from Resize/Mockup) ─────────────── */
.pdf-maker__source-banner {
  margin: 0 0 1.25rem;
  padding: .65rem .85rem;
  background: var(--color-success-bg);
  border-left: 3px solid var(--color-success-border);
  border-radius: 4px;
  font-size: .9rem;
  color: var(--color-text);
}

/* ─────────────── Artwork list — one card per artwork ─────────────── */
.pdf-maker__artworks {
  display: flex;
  flex-direction: column;
  gap: .65rem;
  margin-bottom: 1.5rem;
}

/* V3.5 — inline placeholder for an empty artworks list.
   Surfaces when artworks.length === 0 (seller arrived without a hand-off
   OR did a Reset form). Soft surface chrome that visually matches the
   card row so the workspace feels alive even when there's nothing in it.
   The "+ Add artwork manually" button sits right below — the message
   points at it. */
.pdf-maker__artwork-list-empty {
  background: var(--color-surface);
  border: 1px dashed var(--color-border);
  border-radius: var(--radius);
  padding: 1.75rem 1.25rem;
  text-align: center;
}
.pdf-maker__artwork-list-empty-title {
  margin: 0 0 .35rem;
  font-weight: 600;
  color: var(--color-text);
}
.pdf-maker__artwork-list-empty-sub {
  margin: 0;
  color: var(--color-text-muted);
  font-size: .9rem;
  line-height: 1.5;
}
.pdf-maker__artwork-list-empty-sub a {
  color: var(--color-primary);
  text-decoration: underline;
}

.pdf-maker__artwork {
  display: grid;
  grid-template-columns: 36px 1fr auto;
  gap: .85rem;
  align-items: center;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-left-width: 4px;
  border-radius: var(--radius);
  padding: .85rem 1rem;
  transition: opacity 0.12s;
}
/* When the seller unchecks "Include", the card stays in place (preserves
   order + lets them re-include in one click) but visually fades back so the
   included set is unmistakable. */
.pdf-maker__artwork--excluded {
  opacity: 0.45;
}
.pdf-maker__artwork--excluded .pdf-maker__artwork-title-input {
  text-decoration: line-through;
}
.pdf-maker__artwork--portrait  { border-left-color: var(--color-orientation-portrait); }
.pdf-maker__artwork--landscape { border-left-color: var(--color-orientation-landscape); }
.pdf-maker__artwork--square    { border-left-color: var(--color-orientation-square); }

.pdf-maker__artwork-ord {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 1.2rem;
  color: var(--color-text-muted);
  text-align: center;
}

.pdf-maker__artwork-main {
  display: flex;
  flex-direction: column;
  gap: .25rem;
  min-width: 0;
}

.pdf-maker__artwork-row1,
.pdf-maker__artwork-row2 {
  display: flex;
  align-items: center;
  gap: .75rem;
  flex-wrap: wrap;
}

.pdf-maker__artwork-orient {
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  padding: .12rem .5rem;
  border-radius: 999px;
  color: #fff;
  white-space: nowrap;
}
.pdf-maker__artwork-orient--portrait  { background: var(--color-orientation-portrait); }
.pdf-maker__artwork-orient--landscape { background: var(--color-orientation-landscape); }
.pdf-maker__artwork-orient--square    { background: var(--color-orientation-square); }

/* Per-artwork editable title input.
   Visual language mirrors the Resize Tool's "Design name" input
   (.design-name-input in css/wall-cropper.css): permanent 1px border so
   the field reads as a text input at first glance, focus flips the border
   to primary. The seller already knows this pattern from Resize — keeping
   it cross-tool reinforces "you can edit this" without extra UI affordance.

   Padding is tighter than the Resize equivalent (.3rem vs .45rem vertical)
   to keep a 10-row bundle list readable — at full Resize padding, ten
   stacked cards would read as a form wall. The border itself is the
   subtlest token in the palette (--color-border) for the same reason. */
.pdf-maker__artwork-title-input {
  flex: 1 1 auto;
  min-width: 0;
  font: inherit;
  font-weight: 600;
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: .3rem .55rem;
  outline: none;
  cursor: text;
  transition: border-color 0.15s;
}
.pdf-maker__artwork-title-input:hover {
  border-color: var(--color-text-muted);
}
.pdf-maker__artwork-title-input:focus {
  border-color: var(--color-primary);
}
.pdf-maker__artwork-title-input--error,
.pdf-maker__artwork-title-input--error:focus {
  border-color: var(--color-error-border);
  background: var(--color-error-bg);
}

/* Per-row title error — sits on its own line directly below the title
   input (post-Étape C1 correction: cleaner separation than mixing with
   the size + Drive-status chips in row2). Shown as the live "Max 30
   characters." alert by applyTitleLengthValidation, or as the
   forbidden-chars error by the Generate-click pre-pass. */
.pdf-maker__artwork-title-error {
  margin: .1rem 0 .25rem;
  font-size: .8rem;
  color: var(--color-error-border);
  font-weight: 500;
  line-height: 1.4;
}
.pdf-maker__artwork-title-error[hidden] { display: none; }

/* Per-row Drive-link error — same visual family as the title error
   (red, small, same spacing). Stacks directly below the title-error
   element so two alerts can coexist on the same row when both
   conditions fire. <strong> inside renders the "Resize" tool name bold. */
.pdf-maker__artwork-drive-error {
  margin: .1rem 0 .25rem;
  font-size: .8rem;
  color: var(--color-error-border);
  font-weight: 500;
  line-height: 1.4;
}
.pdf-maker__artwork-drive-error[hidden] { display: none; }
.pdf-maker__artwork-drive-error strong {
  color: var(--color-error-border);
  font-weight: 700;
}

/* Per-row missing-sizes error (Étape E2). Same visual family as the
   title and drive-link errors. Stacks below them so up to three alerts
   can coexist on the same row when all conditions fire. <strong> inside
   renders the "Resize" tool name bold to match the drive-link error. */
.pdf-maker__artwork-sizes-error {
  margin: .1rem 0 .25rem;
  font-size: .8rem;
  color: var(--color-error-border);
  font-weight: 500;
  line-height: 1.4;
}
.pdf-maker__artwork-sizes-error[hidden] { display: none; }
.pdf-maker__artwork-sizes-error strong {
  color: var(--color-error-border);
  font-weight: 700;
}

/* Per-row missing-orientation error (V3.3 T1). Same visual family as
   the other three per-row alerts. Lives inside the editable card variant
   only (locked cards always carry an orientation from the hand-off, so
   the alert never fires there). */
.pdf-maker__artwork-orient-error {
  margin: .1rem 0 .25rem;
  font-size: .8rem;
  color: var(--color-error-border);
  font-weight: 500;
  line-height: 1.4;
}
.pdf-maker__artwork-orient-error[hidden] { display: none; }
.pdf-maker__artwork-orient-error strong {
  color: var(--color-error-border);
  font-weight: 700;
}

.pdf-maker__artwork-sizes {
  font-size: .85rem;
  color: var(--color-text-muted);
}

.pdf-maker__artwork-drive {
  font-size: .8rem;
  font-weight: 500;
  padding: .15rem .55rem;
  border-radius: 999px;
  white-space: nowrap;
}
.pdf-maker__artwork-drive--ok {
  color: var(--color-success-dark);
  background: var(--color-success-bg);
}
.pdf-maker__artwork-drive--missing {
  color: #8a5a00;
  background: var(--color-warning-bg);
}

/* ─────────────── V1-b Voie 3 — source badge ───────────────
   Small chip distinguishing where the artwork came from.
   • "From Resize" / "From Mockup" → hand-off artwork.
   • "Manual" → seller-added card.
   Visual: muted, low contrast — informational, not an alert. Sits next
   to the title input in row1, alongside the orientation chip when
   present. */
.pdf-maker__artwork-source-badge {
  font-size: .68rem;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  padding: .1rem .45rem;
  border-radius: 999px;
  color: var(--color-text-muted);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  white-space: nowrap;
}

/* ─────────────── V1-b Voie 3 — "Add artwork manually" row ───────────────
   Sits between the artwork list and the bundle controls. Self-contained
   so its visibility never depends on artwork count. Help text muted,
   one-line. */
.pdf-maker__add-artwork-row {
  display: flex;
  align-items: center;
  gap: .85rem;
  flex-wrap: wrap;
  margin: .25rem 0 1.5rem;
}
.pdf-maker__add-artwork-help {
  margin: 0;
  font-size: .85rem;
  color: var(--color-text-muted);
}

/* ─────────────── V1-b Voie 3 — editable card variant ───────────────
   The same .pdf-maker__artwork grid wraps both read-only (Resize with
   Drive folder) and editable (manual / no Drive folder) cards. The
   .pdf-maker__artwork--editable modifier lays the inner main column
   as a stacked form: title row, orientation row, sizes section, link
   row, remove button. Each row keeps the visual rhythm of the read-
   only card (same font sizes, same padding) so a mixed list reads as
   one coherent column. */
.pdf-maker__artwork--editable .pdf-maker__artwork-main {
  gap: .55rem;
}
.pdf-maker__artwork-row-orient,
.pdf-maker__artwork-row-link {
  display: flex;
  align-items: center;
  gap: .55rem;
  flex-wrap: wrap;
}
.pdf-maker__artwork-row-orient label,
.pdf-maker__artwork-row-link label {
  font-size: .8rem;
  font-weight: 600;
  color: var(--color-text-muted);
  min-width: 5.5rem;
}
.pdf-maker__artwork-orient-select {
  font: inherit;
  font-size: .9rem;
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: .25rem .5rem;
  outline: none;
  cursor: pointer;
}
.pdf-maker__artwork-orient-select:hover  { border-color: var(--color-text-muted); }
.pdf-maker__artwork-orient-select:focus  { border-color: var(--color-primary); }
.pdf-maker__artwork-link-input {
  flex: 1 1 240px;
  min-width: 0;
  font: inherit;
  font-size: .9rem;
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: .3rem .55rem;
  outline: none;
  transition: border-color 0.15s;
}
.pdf-maker__artwork-link-input:hover { border-color: var(--color-text-muted); }
.pdf-maker__artwork-link-input:focus { border-color: var(--color-primary); }

/* Placeholder for the sizes section before V3.2 wires presets. Sits
   where the size-count chip would on a read-only card. */
.pdf-maker__artwork-sizes-placeholder {
  margin: 0;
  font-size: .85rem;
  color: var(--color-text-muted);
  font-style: italic;
}

/* Remove button for a manual card. Subtle by default so it doesn't
   compete with the primary actions — destructive language only on hover. */
.pdf-maker__artwork-remove {
  align-self: flex-start;
  background: transparent;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: .2rem .55rem;
  font-size: .8rem;
  color: var(--color-text-muted);
  cursor: pointer;
  transition: border-color 0.12s, color 0.12s, background 0.12s;
}
.pdf-maker__artwork-remove:hover {
  border-color: var(--color-error-border);
  color: var(--color-error-border);
  background: var(--color-error-bg);
}

/* Editable card without an orientation yet — neutral left border so the
   card doesn't claim a portrait/landscape/square identity prematurely. */
.pdf-maker__artwork--undefined { border-left-color: var(--color-border); }

/* ─────────────── V3.2 — preset grid for editable cards ───────────────
   Replaces the V3.1 placeholder text once an orientation is picked.
   Layout: flex-wrap row of cocheable pills (label + system badge).
   Each pill is a <label> wrapping a checkbox + label span — clicking
   anywhere on the pill toggles the checkbox (native <label> behaviour).
   The --checked modifier is toggled in JS for visual feedback (border
   primary + tinted background). */
.pdf-maker__preset-grid {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  margin: .1rem 0 .15rem;
}
.pdf-maker__preset {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .22rem .55rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-surface);
  font-size: .85rem;
  cursor: pointer;
  user-select: none;
  transition: border-color 0.12s, background 0.12s;
}
.pdf-maker__preset:hover {
  border-color: var(--color-text-muted);
}
.pdf-maker__preset input[type="checkbox"] {
  margin: 0;
  cursor: pointer;
}
.pdf-maker__preset--checked {
  border-color: var(--color-primary);
  background: var(--color-success-bg);
}
.pdf-maker__preset-label {
  font-weight: 600;
  color: var(--color-text);
}
.pdf-maker__preset-system {
  font-size: .62rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  padding: .05rem .35rem;
  border-radius: 999px;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
}

/* Per-artwork Include checkbox — third column of the artwork card. Always
   stays at full opacity even when its parent card is dimmed (so the seller
   can re-include without hunting for the control). */
.pdf-maker__include-toggle {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  cursor: pointer;
  user-select: none;
  font-size: .85rem;
  color: var(--color-text-muted);
  /* Cancel the parent's --excluded opacity so the control stays clickable. */
  opacity: 1;
}
.pdf-maker__artwork--excluded .pdf-maker__include-toggle {
  opacity: 1;
}
.pdf-maker__include-toggle input[type="checkbox"] {
  width: 16px; height: 16px;
  accent-color: var(--color-primary);
  cursor: pointer;
}
.pdf-maker__include-label {
  font-weight: 500;
}

/* ─────────────── Bundle controls ─────────────── */
.pdf-maker__bundle {
  margin-bottom: 1.5rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: 1rem 1.15rem;
}

.pdf-maker__bundle-toggle {
  display: flex;
  align-items: center;
  gap: .6rem;
  cursor: pointer;
}
.pdf-maker__bundle-toggle input[type="checkbox"] {
  width: 18px; height: 18px;
  accent-color: var(--color-primary);
  cursor: pointer;
}
.pdf-maker__bundle-toggle span { color: var(--color-text); }

.pdf-maker__bundle-help {
  margin: .5rem 0 0 1.85rem;
  font-size: .85rem;
  color: var(--color-text-muted);
  line-height: 1.5;
}

.pdf-maker__bundle-name-row {
  display: flex;
  flex-direction: column;
  gap: .35rem;
  margin: 1rem 0 0 1.85rem;
  max-width: 480px;
}
.pdf-maker__bundle-name-label {
  font-size: .85rem;
  font-weight: 600;
  color: var(--color-text);
}
.pdf-maker__bundle-name-input {
  font: inherit;
  padding: .55rem .75rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-bg);
  color: var(--color-text);
}
.pdf-maker__bundle-name-input:focus {
  outline: 2px solid var(--color-primary);
  outline-offset: -1px;
  border-color: var(--color-primary);
}
.pdf-maker__bundle-name-error {
  margin: .2rem 0 0;
  font-size: .85rem;
  color: var(--color-error-border);
}

/* ─────────────── Branding block (Étape B) ─────────────── */
.pdf-maker__branding-stub {
  margin-bottom: 1.5rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: 1rem 1.15rem;
}
.pdf-maker__branding-status {
  margin: .25rem 0 .75rem;
  font-size: .9rem;
  line-height: 1.5;
  padding: .5rem .75rem;
  border-radius: var(--radius);
}
.pdf-maker__branding-status--warn {
  background: var(--color-warning-bg);
  color: #8a5a00;
  border-left: 3px solid var(--color-warning-border);
}
.pdf-maker__branding-status--ok {
  background: var(--color-success-bg);
  color: var(--color-success-dark);
  border-left: 3px solid var(--color-success-border);
}

/* ─────────────── Branding modal — form fields ─────────────── */
.branding-modal__body {
  /* Modal body grows tall on small screens — keep it scrollable while the
     title + actions stay pinned. */
  max-height: 70vh;
  overflow-y: auto;
  padding-right: .25rem;
}
.branding-modal__actions {
  display: flex;
  align-items: center;
  gap: .5rem;
  flex-wrap: wrap;
}
.branding-modal__actions-spacer { flex: 1 1 auto; }

.branding-field {
  margin-bottom: 1.1rem;
}
.branding-field__label {
  display: block;
  font-weight: 600;
  font-size: .9rem;
  color: var(--color-text);
  margin-bottom: .35rem;
}
.branding-field__req {
  color: var(--color-error-border);
  font-weight: 700;
  margin-left: .15rem;
}
.branding-field__input {
  width: 100%;
  font: inherit;
  padding: .5rem .7rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-surface);
  color: var(--color-text);
  outline: none;
  transition: border-color 0.15s;
}
.branding-field__input:focus { border-color: var(--color-primary); }
.branding-field__help {
  margin: .3rem 0 0;
  font-size: .8rem;
  color: var(--color-text-muted);
  line-height: 1.45;
}
.branding-field__error {
  margin: .3rem 0 0;
  font-size: .85rem;
  color: var(--color-error-border);
  font-weight: 500;
}

.branding-colors {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}
.branding-color-row {
  display: flex;
  align-items: center;
  gap: .65rem;
}
.branding-field__color {
  width: 56px; height: 36px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: transparent;
  cursor: pointer;
  padding: 0;
  flex: 0 0 auto;
}
/* Editable hex input — bidirectionally synced with the color picker
   (post-Étape B correction 1). Permanent border so it reads as a text
   field, monospace so HEX is unambiguous, --error variant for invalid input. */
.branding-color-row__hex-input {
  font: inherit;
  font-family: ui-monospace, "SF Mono", "Consolas", monospace;
  font-size: .85rem;
  font-weight: 600;
  letter-spacing: .03em;
  text-transform: uppercase;
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: .35rem .55rem;
  width: 88px;
  outline: none;
  transition: border-color 0.15s, background 0.15s;
}
.branding-color-row__hex-input:focus {
  border-color: var(--color-primary);
}
.branding-color-row__hex-input--error,
.branding-color-row__hex-input--error:focus {
  border-color: var(--color-error-border);
  background: var(--color-error-bg);
}

/* Logo block — fully driven by renderLogoBlock(logoBase64) in
   pdf-branding.js. Two render states share this wrapper:
     • no logo : placeholder square + "No logo uploaded" + Upload button.
       No <img> element exists — no broken-image icon possible.
     • has logo: 80px thumb + Replace + Remove buttons.
   The flex layout works for both: items wrap as needed on narrow screens. */
.branding-logo {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  background: var(--color-bg);
  border: 1px dashed var(--color-border);
  border-radius: var(--radius);
  padding: 1rem;
  min-height: 96px;
}
.branding-logo__placeholder {
  width: 64px;
  height: 64px;
  flex: 0 0 64px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 6px;
  color: var(--color-text-muted);
}
.branding-logo__empty-content {
  display: flex;
  flex-direction: column;
  gap: .5rem;
  flex: 1 1 200px;
}
.branding-logo__empty-text {
  margin: 0;
  color: var(--color-text-muted);
  font-size: .9rem;
}
.branding-logo__thumb {
  width: 80px; height: 80px;
  border-radius: 6px;
  border: 1px solid var(--color-border);
  object-fit: cover;
  background: var(--color-surface);
  flex: 0 0 80px;
}
.branding-logo__actions {
  display: flex;
  gap: .5rem;
  flex-wrap: wrap;
  flex: 1 1 auto;
}

.branding-format {
  display: flex;
  flex-direction: column;
  gap: .4rem;
}
.branding-format__option {
  display: flex;
  align-items: center;
  gap: .6rem;
  cursor: pointer;
  padding: .35rem .55rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-surface);
}
.branding-format__option:hover {
  border-color: var(--color-text-muted);
}
.branding-format__option input[type="radio"] {
  accent-color: var(--color-primary);
}

/* ─────────────── Logo cropper modal ─────────────── */
.logo-cropper {
  display: flex;
  justify-content: center;
  margin: 1rem 0;
}
.logo-cropper__stage {
  position: relative;
  user-select: none;
  touch-action: none; /* prevents scroll-while-dragging on touch */
}
.logo-cropper__image {
  display: block;
  pointer-events: none;
  user-select: none;
}
.logo-cropper__mask {
  position: absolute;
  background: rgba(0, 0, 0, 0.55);
  pointer-events: none;
}
.logo-cropper__square {
  position: absolute;
  border: 2px dashed #fff;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.4);
  cursor: move;
  background: transparent;
}
.logo-cropper__square::after {
  /* Subtle inner border for contrast against any image. */
  content: '';
  position: absolute;
  inset: 1px;
  border: 1px solid rgba(255, 255, 255, 0.55);
  pointer-events: none;
}

/* ─────────────── Buttons ─────────────── */
.pdf-maker__btn {
  font: inherit;
  font-weight: 600;
  padding: .65rem 1.15rem;
  border-radius: var(--radius);
  cursor: pointer;
  transition: background 0.12s, color 0.12s, border-color 0.12s, opacity 0.12s;
}
.pdf-maker__btn--primary {
  background: var(--color-primary);
  color: #fff;
  border: 1px solid var(--color-primary);
}
.pdf-maker__btn--primary:hover { background: var(--color-primary-dark); border-color: var(--color-primary-dark); }
.pdf-maker__btn--primary:disabled { opacity: .55; cursor: not-allowed; }

.pdf-maker__btn--secondary {
  background: var(--color-surface);
  color: var(--color-text);
  border: 1px solid var(--color-border);
}
.pdf-maker__btn--secondary:hover { border-color: var(--color-text-muted); }
.pdf-maker__btn--secondary:disabled { opacity: .55; cursor: not-allowed; }

/* Generate-button 3-state machine (Étape C1).
   Mirrors the Resize output-zone pattern (css/wall-cropper.css:467-547).
     • State 1 → .pdf-maker__btn--primary  (teal, enabled)        — default
     • State 2 → .pdf-maker__btn--ghost    (muted, DISABLED)      — fresh
     • State 3 → .pdf-maker__btn--update   (orange --color-pending, enabled) — stale
   Exactly one of the three state classes is on the button at any moment;
   the JS strips the others before applying the active one. */
.pdf-maker__btn--ghost {
  background: transparent;
  color: var(--color-text-muted);
  border: 1.4px solid var(--color-border);
}
.pdf-maker__btn--ghost:disabled {
  cursor: not-allowed;
  /* No opacity dim here — the muted text + transparent bg already convey
     "non-interactive but accessible", matching Resize's fresh state. */
}

.pdf-maker__btn--update {
  background: var(--color-pending);
  color: #fff;
  border: 1px solid var(--color-pending);
  box-shadow: 0 4px 14px -4px rgba(217, 110, 60, 0.4);
}
.pdf-maker__btn--update:hover:not(:disabled) {
  background: #c25f30;
  border-color: #c25f30;
}
.pdf-maker__btn--update:disabled {
  opacity: .55;
  cursor: not-allowed;
  box-shadow: none;
}

.pdf-maker__generate-row {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: .55rem;
  margin-bottom: 1.25rem;
}
.pdf-maker__generate-row .pdf-maker__btn {
  align-self: flex-start;
}
.pdf-maker__generate-status {
  margin: 0;
  font-size: .9rem;
  color: var(--color-text);
}

/* ─────────────── PDF Preview (Étape C1) ───────────────
   Real jsPDF blob URL rendered in an iframe — not a mock HTML
   reproduction. The download button sits next to the heading so the
   seller doesn't have to scroll past the iframe to grab the file. */
.pdf-maker__preview {
  margin-bottom: 1.5rem;
}
.pdf-maker__preview[hidden] { display: none; }
.pdf-maker__preview-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: .35rem;
}
.pdf-maker__preview-header .pdf-maker__h2 {
  margin: 0;
}
.pdf-maker__preview-actions {
  display: flex;
  gap: .5rem;
  /* É3 fix 4a — align-items default 'stretch' was stretching the
     Download button (flex item) to the height of the
     .pdf-maker__drive-stack wrapper (which is taller because it holds
     button + caption). flex-start keeps each flex item at its natural
     height → Download and Save end up identical, and the legend
     overflows below the wrapper without tugging any button vertically. */
  align-items: flex-start;
}
/* É3 fix 3 — Save-to-Drive button + its operator microcopy stacked.
   The <p class="drive-operated-by"> sits BELOW the Drive button so the
   FR caption "Sauvegarde sur Google Drive, opéré par ListingPrep" reads
   as the button's legend (Geoffrey-validated placement). EN-side the <p>
   is :empty → display:none (rule in css/style.css), so the stack
   degenerates to the bare button — zero phantom whitespace, layout of
   the two-button row identical to pre-fix EN. PDF-specific: Resize /
   Mockup keep their "caption ABOVE the button" pre-existing placement
   (deliberate, harmonisation deferred to É5 UI pass).

   É3 fix 4c — the caption was contributing to the wrapper height
   (flex-column normal flow) → the whole preview-actions row inflated,
   pushing the drive-microcopy below away from "Aperçu" by ~one caption-
   height. Solution: pull the <p> out of the wrapper's flow with
   position:absolute anchored on .drive-stack (position:relative). The
   wrapper's flex height is now just the button → row height = button
   height = pre-fix 3. The caption floats centered below the wrapper,
   landing at roughly the same vertical level as .drive-microcopy. It
   sits in the right column (drive-stack is the right flex item) while
   .drive-microcopy starts left-aligned → no horizontal collision in
   practice. EN-side the :empty rule still runs first → display:none →
   absolute positioning never applies. */
.pdf-maker__drive-stack {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.pdf-maker__drive-stack .drive-operated-by {
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  margin-top: .25rem;
}
.pdf-maker__preview-caption {
  margin: 0 0 .65rem;
  font-size: .82rem;
  color: var(--color-text-muted);
  font-family: ui-monospace, "SF Mono", "Consolas", monospace;
}

/* Étape D — Save-to-Drive microcopy + transient status line. The
   microcopy line sits below the action row at full width and adapts to
   the preview kind (single / bundle / unlinked) — see pdf-maker.js
   refreshSaveToDriveButton. The status line replaces it during async
   Drive operations ("Connecting to Google…", "Uploading…"). */
.pdf-maker__drive-microcopy {
  margin: 0 0 .35rem;
  font-size: .82rem;
  color: var(--color-text-muted);
  line-height: 1.45;
}
.pdf-maker__drive-microcopy[hidden] { display: none; }
.pdf-maker__drive-status {
  margin: 0 0 .65rem;
  font-size: .85rem;
  color: var(--color-text);
  font-style: italic;
}
.pdf-maker__drive-status[hidden] { display: none; }

/* .drive-collision__* styles migrated to /css/style.css (Chantier α
   palier 1) — they are now shared chrome consumed by Resize + Mockup +
   PDF Maker collision modals. The PDF Maker page still renders them
   identically because /css/style.css loads before /css/pdf-maker.css. */
.pdf-maker__preview-stage {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  /* Tall enough to comfortably show a Letter portrait at the
     workspace's default width (~720px → ~930px tall at the right ratio). */
  aspect-ratio: 8.5 / 11;
  max-height: 80vh;
  position: relative;
}
.pdf-maker__preview-iframe {
  width: 100%;
  height: 100%;
  border: none;
  display: block;
  background: var(--color-surface);
}
.pdf-maker__preview-fallback {
  margin: 0;
  padding: 1.5rem;
  color: var(--color-text-muted);
  text-align: center;
}

/* iOS fallback (Étape E3) — sits in the SAME stage box as the iframe.
   Iframe is hidden via [hidden] on iOS; this block fills the box with a
   centred message + an "Open PDF in a new tab" CTA. Absolute fill so it
   takes the full stage area regardless of the iframe's display state. */
.pdf-maker__preview-fallback-ios {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  padding: 1.5rem;
  text-align: center;
  background: var(--color-surface);
}
.pdf-maker__preview-fallback-ios[hidden] { display: none; }
.pdf-maker__preview-fallback-ios-msg {
  margin: 0;
  color: var(--color-text-muted);
  font-size: 1rem;
}

/* ─────────────── Reset (form only) — matches the existing reset-btn family ─────────────── */
/* Visual style mirrored from .mockup .reset-btn (css/mockup.css:701-718) so
   the three tools share the same Reset button language. The PDF Maker has a
   single Reset, so we adopt the Mockup's single-style approach (vs. Resize's
   split between .output-zone__reset and .reset-btn). The label "Reset form"
   makes the non-destructive scope clear: it only rolls back the in-page form
   state (titles, Include checkboxes, Link toggle, bundle name) — it does NOT
   touch the hand-off in sessionStorage or the branding in localStorage. */
.pdf-maker .reset-btn {
  background: var(--color-bg);
  color: var(--color-text-muted);
  border: 1px solid var(--color-border);
  padding: .5rem 1rem;
  border-radius: var(--radius);
  font-family: inherit;
  font-size: .85rem;
  font-weight: 600;
  cursor: pointer;
  transition: color 0.12s, border-color 0.12s, background 0.12s;
  margin-top: 1rem;
}
.pdf-maker .reset-btn:hover {
  color: var(--color-text);
  border-color: var(--color-text-muted);
  background: var(--color-surface);
}

/* ─────────────── Responsive ─────────────── */
@media (max-width: 540px) {
  .pdf-maker { padding: 1.25rem 1rem 3rem; }
  .pdf-maker h1 { font-size: 1.7rem; }
  /* On narrow screens the Include checkbox drops to a third row on the right,
     keeping touch targets comfortable. */
  .pdf-maker__artwork {
    grid-template-columns: 28px 1fr auto;
    padding: .75rem .85rem;
  }
  .pdf-maker__include-label {
    /* Hide the word "Include" on tight screens — the checkbox itself + the
       tooltip carry the meaning. */
    display: none;
  }
  .pdf-maker__bundle-name-row,
  .pdf-maker__bundle-help { margin-left: 0; }
  /* Color pickers stack on small screens to keep the labels readable. */
  .branding-colors { grid-template-columns: 1fr; gap: .5rem; }
}
