/* =========================================================================
   Make My — basket → checkout → confirmation
   ONE stylesheet for the whole journey: the basket (and its empty state),
   the checkout, the order confirmation, and the payment failed / order
   pending states.

   Register: Schedule (Design.md §8.3) — 24px band padding, Body SM 14px. The journey picks one register and holds it across all
   four screens.

   Four sections, three prefixes:

     1. SHARED     `mmj-`  the vocabulary every screen uses — page shell,
                           opener, two-column grid, the single total, the
                           step bar, the route-map frame, the mobile
                           summary bar.
     2. BASKET     `mmj-`  the basket rows (configured parts and cut lists on
                           one grid), the cut-list table, the drawing card,
                           the order summary card (shared with checkout
                           and confirmation), the empty state.
     3. CHECKOUT   `mmc-`  step header, step panels, fields, delivery rows,
                           payment, review, the mobile foot.
     4. CONFIRM    `mmo-`  header, lede, order facts, stages, address line,
                           status notice.

   Design.md component vocabulary that is genuinely generic — `.spec-pair`,
   `.btn`, `.stepper`, `.card`, `.badge`, `.input` — lives in
   design-base.css and is used unprefixed throughout.

   Everything reads the theme's tokens. There is no literal hex in this file
   and there must never be one: contrast is decided in the token (§3), and a
   hex here is a colour nobody measured.

   Merged from checkout-journey.css / cart.css / checkout.css /
   confirmation.css on 2026-08-11. Four sheets meant four enqueues, a
   dependency chain to keep in the right order, and a prefix collision when
   two of them loaded together on the order-received page. One sheet, one
   handle, one place to look.
   ========================================================================= */


/* #############################################################################
   1. SHARED — the journey vocabulary
   ######################################################################### */

/* ── Page shell ─────────────────────────────────────────────────────────── */

.mmj {
  --mmj-rail: 420px;      /* one width on all three screens (2026-09-26) */
  --mmj-rail-top: calc(var(--mm-header-h) + var(--sp-4));   /* clears the header, plus a card's breathing room */
  --mmj-gap: var(--sp-16);
  background: var(--paper);
  padding: var(--sp-6) var(--container-pad) var(--sp-12);
}
.mmj__inner {
  max-width: var(--container-max);
  margin: 0 auto;
}

/* ── Page opener (§9.1) — the page's name, stated plainly. No accent. ───── */

.mmj-opener {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-6);
  padding-bottom: var(--sp-4);
  border-bottom: 1px solid var(--rule-strong);
}
.mmj-opener__title {
  margin: 0;
  font-size: var(--fs-36);
  font-weight: var(--fw-regular);
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-tight);
}

/* ── Two-column shell ────────────────────────────────────────────────────
   Content + sticky rail down to 1180px; below that every screen falls to
   the single-column mobile design rather than compressing (the handoff's
   `min-width:1180px`, expressed as a breakpoint so nothing ever forces a
   horizontal scrollbar). */

.mmj-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--mmj-rail);
  gap: var(--mmj-gap);
  align-items: start;
  padding-top: var(--sp-6);
}
.mmj-grid__main {
  display: flex;
  flex-direction: column;
  gap: var(--sp-8);
  min-width: 0;
}
.mmj-rail {
  position: sticky;
  top: var(--mmj-rail-top);
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  min-width: 0;
}

@media (max-width: 1179px) {
  .mmj-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--sp-8);
  }
  .mmj-rail {
    position: static;
    top: auto;
  }
}

/* ── Row controls ────────────────────────────────────────────────────────
   The section-opener square, and the basket row's remove control and its
   inline confirmation. */

/* The section-opener square (§8.4) — 8px, accent, 0 radius. */
.mmj-square {
  width: 8px;
  height: 8px;
  flex: 0 0 auto;
  background: var(--accent);
}


/* Remove control on a row — a 32px square (§5.4: a × that removes a row
   takes the row's height, and the row's other control is the 32px bare
   stepper), reaching 44×44 through an invisible hit area as the stepper's
   buttons do (§7.3). Ghost until hovered, then Error (§7.1 Danger reads the
   same way round). The glyph size is the basket drawer's too (header.css). */
.mmj-remove {
  position: relative;
  width: var(--h-btn-sm);
  height: var(--h-btn-sm);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: transparent;
  color: var(--ink-muted);
  border-radius: var(--r-sm);
  font-size: var(--fs-18);
  line-height: 1;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.mmj-remove::after {
  content: "";
  position: absolute;
  inset: -6px;
}
.mmj-remove:hover {
  background: var(--paper-soft);
  color: var(--err);
}
/* Inline remove confirmation — revealed in place of following the ×, so a
   stray tap never throws away a configured part. Pebble, like any aside that
   asks a question; Remove is Primary because it is the answer being asked. */
.mmj-confirm {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3) var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-md);
  background: var(--paper-soft);
}
.mmj-confirm[hidden] { display: none; }
.mmj-confirm__text {
  flex: 1 1 240px;
  margin: 0;
  font-size: var(--fs-14);
  line-height: var(--lh-body);
  color: var(--ink);
}
.mmj-confirm__text strong { font-weight: var(--fw-semibold); }
.mmj-confirm__actions {
  display: flex;
  gap: var(--sp-2);
}


/* ── Delivery estimate (§11.8) ──────────────────────────────────────────
   The basket's one rail entry: a postcode, answered by WooCommerce's own
   rate. It lives inside the order summary, under the Delivery row it fills
   in. Its controls do not belong to the cart form they sit inside — they are
   associated by `form=` with a form emitted after it; see
   makemy_cart_estimate_field() for the two reasons. (There is no promo-code
   field: it was deliberately removed from the basket on 2026-09-25.) */

.mmj-estimate__row {
  display: flex;
  gap: var(--sp-3);
}
/* A postcode is read back character by character, so it is upper-cased. The
   placeholder is prose and stays sentence case. Basket-only, so it is set in
   the basket's one face (Lexend) rather than the numeric one. */
.mmj-estimate__input {
  flex: 1 1 auto;
  min-width: 0;
  height: var(--h-control);
  padding: 0 var(--sp-3);
  background: var(--paper);
  /* §3.4 — the border of anything a customer operates. */
  border: 1px solid var(--rule-interactive);
  border-radius: var(--r-sm);
  font-family: var(--font-sans);
  font-size: var(--fs-14);
  letter-spacing: var(--tracking-normal);
  text-transform: uppercase;
  color: var(--ink);
  transition: border var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.mmj-estimate__input::placeholder {
  /* §3.3 — Ink Faint is placeholder and disabled glyphs, and nothing else. */
  color: var(--ink-faint);
  text-transform: none;
}
.mmj-estimate__input:focus {
  outline: 0;
  border-color: var(--ink);
  box-shadow: var(--focus-ring);
}
.mmj-estimate__go { flex: 0 0 auto; }

/* The form is empty but for its hidden fields — it exists to own the
   controls above, not to occupy space. */
.mmj-estimate-form { margin: 0; }

/* ── The one total ───────────────────────────────────────────────────────
   Exactly one per page, labelled "Total incl. VAT" (§11.8 B). Sunken card
   so it reads as the page's resting point. */

.mmj-total {
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  background: var(--paper-soft);
  padding: var(--sp-6);
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}
.mmj-total__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-4);
}
.mmj-total__label {
  /* Pebble surface — Ink Soft, not Ink Muted (§3.3). */
  color: var(--ink-soft);
}
.mmj-total__value {
  font-size: var(--fs-28);
  line-height: var(--lh-tight);
}
/* Loading / absent price (§11.10) — the placeholder sits at roughly the
   width of a real price. */
.mmj-total__value.is-placeholder { color: var(--ink-faint); }
/* ── Note card — a short factual aside in the rail ───────────────────────── */

.mmj-note {
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  background: var(--paper);
  padding: var(--sp-5) var(--sp-6);
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}
.mmj-note__body {
  margin: 0;
  font-size: var(--fs-14);
  line-height: var(--lh-body);
  color: var(--ink-soft);
}

/* ── Section opener (§8.4) ───────────────────────────────────────────────── */

.mmj-section {
  display: flex;
  flex-direction: column;
  gap: var(--sp-6);
  padding-top: var(--sp-8);
  border-top: 1px solid var(--rule);
}
.mmj-section__eyebrow {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-bottom: var(--sp-3);
}
/* The journey's text sits in the main grid column (or a flex column inside
   it), not the page container, so it reads the measure caps: a share would
   resolve against the column and compound. */
.mmj-section__heading {
  margin: 0;
  max-width: var(--container-copy-cap);
  font-size: var(--fs-28);
  font-weight: var(--fw-regular);
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-tight);
}
.mmj-section__note {
  margin: 0;
  max-width: var(--container-blurb-cap);
  font-size: var(--fs-14);
  line-height: var(--lh-body);
  color: var(--ink-muted);
}

/* ── Step bar ────────────────────────────────────────────────────────────
   The configurator's steps bar (core-stepper.css) carried onto the journey,
   emitted by makemy_journey_steps(): equal columns split by Rule Strong
   hairlines, the current label in the accent, and a 2px accent line under
   every step up to the current one — drawn INSIDE the label (bottom: 0) and
   started 1px left on every run step after the first, so it reads unbroken
   across the dividers. The checkout's three steps and the confirmation's order
   stages both use it; a stage's detail and date sit in its column below. */

.mmj-steps {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  margin: 0;
  padding: 0;
  list-style: none;
}
.mmj-steps__step {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.mmj-steps__step + .mmj-steps__step { border-left: 1px solid var(--rule-strong); }
.mmj-steps__label {
  position: relative;
  display: block;
  width: 100%;
  padding: var(--sp-3) var(--sp-2);
  border: 0;
  border-bottom: 1px solid var(--rule-strong);
  background: none;
  font: inherit;
  font-size: var(--fs-13);
  line-height: var(--lh-snug);
  text-align: center;
  color: var(--ink);
}
.mmj-steps__step.is-later .mmj-steps__label { color: var(--ink-muted); }
.mmj-steps__step.is-current .mmj-steps__label { color: var(--accent); }
.mmj-steps__step.is-run .mmj-steps__label::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  background: var(--accent);
  pointer-events: none;
}
.mmj-steps__step + .mmj-steps__step.is-run .mmj-steps__label::after { left: -1px; }
button.mmj-steps__label {
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease);
}
button.mmj-steps__label:hover { background: var(--paper-soft); }
button.mmj-steps__label:focus-visible {
  outline: 0;
  box-shadow: var(--focus-ring);
}
.mmj-steps__detail {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-2) 0;
  font-size: var(--fs-12);
  line-height: var(--lh-body);
}
.mmj-steps__note { color: var(--ink-muted); }
.mmj-steps__when { color: var(--ink); }

/* ── Route map ───────────────────────────────────────────────────────────
   Workshop → delivery address. The frame is ours; the geometry is real
   (never hand-drawn). Caption in Num: route left, lead time right. */

.mmj-map {
  max-width: var(--container-copy-cap);
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  background: var(--paper);
  overflow: hidden;
}
.mmj-map__canvas {
  display: block;
  width: 100%;
  height: 280px;
  border: 0;
}
/* Inline SVG, so the route picks up the site accent with no per-site rule.
   The map zooms by its viewBox (route-map.php frames it; route-map.js
   animates the frame in), so the coastline and the route keep their on-screen
   weight with non-scaling strokes; the pins and labels are groups scaled by
   the inverse of the zoom instead. */
.mmj-map__land {
  fill: var(--paper-soft);
  stroke: var(--rule-strong);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}
.mmj-map__route {
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.5;
  stroke-dasharray: 4 3;
  vector-effect: non-scaling-stroke;
}
/* Both pins — workshop and delivery — are accent dots with a 1px Ink
   outline, so they hold on the land fill and on the route line alike. */
.mmj-map__pin {
  fill: var(--accent);
  stroke: var(--ink);
  stroke-width: 1;
}
.mmj-map__pin-label {
  font-family: var(--font-sans);
  font-size: var(--fs-11);
  letter-spacing: var(--tracking-normal);
  fill: var(--ink-soft);
  /* A Paper halo, so a label reads over the land and the route alike. */
  paint-order: stroke;
  stroke: var(--paper);
  stroke-width: 3px;
  stroke-linejoin: round;
}
.mmj-map__caption {
  display: flex;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  border-top: 1px solid var(--rule);
  font-size: var(--fs-11);
  color: var(--ink-muted);
}

/* ── Mobile sticky summary bar (84px) ────────────────────────────────────
   Total left, the one primary action right. Hidden on the desktop shell,
   where the rail carries both. Rung 1 — a hairline seat, cast upward
   because a bottom-anchored downward shadow is clipped off-screen (§6.1's
   sanctioned bottom-sheet exception). */

.mmj-foot { display: none; }

@media (max-width: 1179px) {
  .mmj-foot {
    position: sticky;
    bottom: 0;
    z-index: var(--z-sticky);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-4);
    min-height: var(--summary-bar-h);
    margin: var(--sp-8) calc(var(--container-pad) * -1) 0;
    padding: var(--sp-4) var(--container-pad);
    border-top: 1px solid var(--rule);
    background: var(--paper);
    box-shadow: 0 -1px 0 rgb(0 0 0 / 0.04);
  }
  .mmj-foot__label {
    display: block;
    font-size: var(--fs-11);
    font-weight: var(--fw-semibold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--ink-muted);
  }
  .mmj-foot__value {
    display: block;
    font-size: var(--fs-22);
    line-height: var(--lh-snug);
  }
  .mmj-foot .btn { flex: 0 0 auto; }
}


/* ── WooCommerce's own notices ───────────────────────────────────────────
   §11.9 surface B: a server rejection is announced at the top of the page.
   The notice design itself is woocommerce.css's — one design network-wide
   (§7.11: 2px signal edge, 6% wash, Ink, square). WooCommerce emits these
   from `woocommerce_before_cart` / `woocommerce_before_checkout_form`, which
   fire OUTSIDE the `.mmj` wrapper — so all this adds, scoped to the body
   classes, is the journey's page width.

   WC already gives the error list `role="alert"`, so the live-region half is
   handled. */

body.woocommerce-cart .woocommerce-error,
body.woocommerce-cart .woocommerce-message,
body.woocommerce-cart .woocommerce-info,
body.woocommerce-checkout .woocommerce-error,
body.woocommerce-checkout .woocommerce-message,
body.woocommerce-checkout .woocommerce-info {
  max-width: var(--container-max);
  margin: 0 auto var(--sp-6);
}

/* A notice's own action ("View basket", "Undo") is a link inside the card;
   give it the underline a text button carries and a real target height. */
body.woocommerce-cart .woocommerce-error .button,
body.woocommerce-cart .woocommerce-message .button,
body.woocommerce-checkout .woocommerce-error .button,
body.woocommerce-checkout .woocommerce-message .button {
  display: inline-flex;
  align-items: center;
  min-height: var(--h-control);
  margin-left: var(--sp-3);
  text-decoration: underline;
  text-underline-offset: 3px;
}


/* #############################################################################
   2. BASKET
   ######################################################################### */


/* The basket takes the shared shell as is: the opener's full-width Rule
   Strong line (the checkout and confirmation headers draw the same one), the
   420px rail, and the Order summary card starting at the same height on all
   three screens (2026-09-26). The rows below carry a line UNDER each item,
   so the list opens with no rule of its own. */

/* ── Drawing card ────────────────────────────────────────────────────────
   Per-part 2D snapshots come from the configurator's renderer and are not
   wired up yet (Design.md §16.5 — the basket snapshot still needs its own
   annotation rules). Until they are, a part with no image of its own gets a
   striped placeholder rather than WooCommerce's grey square, so the slot
   reads as "drawing pending" instead of "image missing". */

.mmj-drawing {
  border: 1px solid var(--rule);
  background: var(--paper);
  overflow: hidden;
  flex: 0 0 auto;
}
.mmj-drawing img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.mmj-drawing__placeholder {
  display: block;
  width: 100%;
  height: 100%;
  background: repeating-linear-gradient(
    45deg,
    var(--paper) 0 5px,
    var(--paper-soft) 5px 10px
  );
}
.mmj-drawing--lg {
  width: 128px;
  aspect-ratio: 1;
  border-radius: var(--r-md);
}

/* ── Basket rows ─────────────────────────────────────────────────────────
   One plain list straight on the page — no card, hairlines between rows — so
   the basket reads as a list of things you are buying. A configured part and
   a cut list share ONE grid: picture, name + toggle, the money column, ×. A
   cut list's toggle opens a full-width table of its sizes (basket redesign,
   2026-09-25). */


.mmj-part {
  display: grid;
  grid-template-columns: 128px minmax(0, 1fr) 220px 44px;
  gap: var(--sp-4) var(--sp-6);
  align-items: start;
  padding: var(--sp-6) 0;
  border-bottom: 1px solid var(--rule);
}
.mmj-part__body { min-width: 0; }
.mmj-part__name {
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-18);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-tight);
}
.mmj-cutlist .mmj-part__name { margin-bottom: 2px; }
.mmj-part__sub {
  margin: 0 0 var(--sp-1);
  font-size: var(--fs-13);
  line-height: var(--lh-body);
  color: var(--ink-muted);
}
/* The × is centred on the money column's first row — the quantity stepper's
   on a part, the Total on a cut list — which is held at the stepper's 32px so
   both kinds of row seat the × the same way. */
.mmj-part > .mmj-remove { justify-self: center; }
/* The row's confirmation spans from the text column to the row's edge. */
.mmj-part > .mmj-confirm { grid-column: 2 / -1; }

/* "Product details" (a native <details>) and "Show parts" (a button driving
   the cut-list table) are one control: a quiet text label with the Materials
   page's chevron AFTER it, turned over when open. */
.mmj-part__details > summary,
.mmj-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: var(--h-btn-sm);
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: var(--fs-13);
  letter-spacing: var(--tracking-normal);
  color: var(--ink-soft);
  cursor: pointer;
  list-style: none;
  transition: color var(--dur-fast) var(--ease);
}
.mmj-part__details > summary::-webkit-details-marker { display: none; }
.mmj-part__details > summary:hover,
.mmj-toggle:hover { color: var(--ink); }
.mmj-part__details > summary:focus-visible,
.mmj-toggle:focus-visible {
  outline: 0;
  box-shadow: var(--focus-ring);
  border-radius: var(--r-xs);
}
.mmj-chevron {
  flex: 0 0 auto;
  color: var(--ink);
  transition: transform var(--dur-base) var(--ease);
}
.mmj-part__details[open] > summary .mmj-chevron,
.mmj-toggle[aria-expanded="true"] .mmj-chevron { transform: rotate(180deg); }

/* The spec itself: a compact two-column list under the toggle. One face,
   keys and values alike in Ink Muted — it is reference, not the headline.
   Values never wrap mid-measurement. */
.mmj-part__spec {
  display: grid;
  grid-template-columns: auto auto;
  justify-content: start;
  gap: 2px var(--sp-8);
  margin: var(--sp-2) 0 0 26px;
  font-size: var(--fs-13);
  line-height: var(--lh-body);
  color: var(--ink-muted);
}
.mmj-part__spec dt { color: var(--ink-muted); }
.mmj-part__spec dd {
  margin: 0;
  text-align: right;
  color: var(--ink-muted);
  white-space: nowrap;
}

.mmj-part__edit {
  display: inline-block;
  margin-top: var(--sp-2);
  font-size: var(--fs-13);
  color: var(--ink-muted);
  transition: color var(--dur-fast) var(--ease);
}
.mmj-part__edit:hover { color: var(--ink); }

/* Quantity / Item price / Total — label left, value right. Item price only
   appears at quantity 2+, where it differs from the total; a cut list shows
   its Total alone (each size carries its own quantity in the table). */
.mmj-part__money {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-rows: minmax(var(--h-btn-sm), auto);
  gap: var(--sp-3) var(--sp-4);
  align-items: center;
  margin: 0;
}
.mmj-part__money dt {
  font-size: var(--fs-13);
  color: var(--ink-muted);
}
.mmj-part__money dd {
  margin: 0;
  justify-self: end;
  font-size: var(--fs-16);
}
.mmj-part__line { font-weight: var(--fw-semibold); }
/* main.css's bare `input[type="number"]` padding (12px 16px) would crowd the
   figure out of the stepper's narrow middle track. The stepper itself is the
   bare `− 2 +` (design-base.css `.stepper--bare`). */
.mmj-qty input {
  padding: 0;
  border: 0;
}

/* ── Cut-list table ──────────────────────────────────────────────────────
   Spans from the text column to the row's right edge. Headers are generic
   (§11.12). Part and Material WRAP — they must never truncate, because the
   basket line description is canonical (§11.13) — and Size never breaks, so
   the table fits the column at every desktop width with no sideways scroll. */

.mmj-cuts {
  grid-column: 2 / -1;
  min-width: 0;
}
.mmj-cuts__table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-13);
  line-height: 1.35;
}
/* Header type, colour and rule come from the plugin's shared `.core-table th`
   (core-controls.css, loaded on every page by enqueue.php); only the flush-left
   padding is the cut list's. */
.mmj-cuts__table th {
  padding: var(--sp-1) var(--sp-3) var(--sp-1) 0;
}
.mmj-cuts__table td {
  padding: var(--sp-2) var(--sp-3) var(--sp-2) 0;
  border-bottom: 1px solid var(--rule);
  vertical-align: middle;
  overflow-wrap: anywhere;
}
.mmj-cuts__table th:last-child,
.mmj-cuts__table td.mmj-cuts__x { padding-right: 0; width: 44px; }
.mmj-cuts__table .mmj-cuts__r { text-align: right; }
.mmj-cuts__name { display: block; color: var(--ink); }
.mmj-cuts__sub {
  display: block;
  margin-top: 2px;
  font-size: var(--fs-12);
  color: var(--ink-muted);
}
.mmj-cuts__size,
.mmj-cuts__total { white-space: nowrap; overflow-wrap: normal; }
.mmj-cuts__material { color: var(--ink-soft); }
.mmj-cuts__qty .mmj-qty { vertical-align: middle; }
.mmj-cuts__confirm > td { padding: var(--sp-2) 0; }
/* The row's own hairline closes the table; its last line needs none. The last
   child is that line's (hidden) confirmation row, hence the second-to-last. */
.mmj-cuts__table tbody > tr:nth-last-child(2) > td { border-bottom: 0; }
.mmj-cuts__confirm[hidden] { display: none; }

/* ── Order summary ───────────────────────────────────────────────────────
   The basket's one rail card: subtotal, delivery with its postcode field,
   the one total (§11.8 B), the VAT already inside it, Checkout, and the
   made-to-order note. Pebble, so every key steps up from Ink Muted to Ink
   Soft (§3.3 — Ink Muted is Paper-only). The checkout and the confirmation
   reuse the same card (checkout redesign, 2026-09-25) with an item list at
   its head — makemy_journey_summary_items() — so moving from the basket to
   checkout keeps one card. */

.mmj-summary {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  padding: var(--sp-6);
  border-radius: var(--r-md);
  background: var(--paper-soft);
}
.mmj-summary__title {
  margin: 0;
  font-size: var(--fs-22);
  font-weight: var(--fw-regular);
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-tight);
}
/* The item list. Name and line price are the row (16px semibold — the basket
   row's own name/line-total pairing, scaled for the rail); spec and quantity
   step back to 13px Ink Soft. A line of 2+ reads "4 × £78.00" right-aligned
   under its price. Rows past the third fold into a native <details>. */
.mmj-summary__items {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}
.mmj-summary__item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 2px var(--sp-3);
  align-items: baseline;
  font-size: var(--fs-13);
  line-height: var(--lh-body);
}
.mmj-summary__item-name,
.mmj-summary__item-price {
  font-size: var(--fs-16);
  font-weight: var(--fw-semibold);
  color: var(--ink);
}
.mmj-summary__item-price { text-align: right; white-space: nowrap; }
.mmj-summary__item-spec { grid-column: 1; color: var(--ink-soft); }
.mmj-summary__item-each {
  grid-column: 2;
  grid-row: 2;
  text-align: right;
  white-space: nowrap;
  color: var(--ink-soft);
}
.mmj-summary__item-qty { grid-column: 1 / -1; color: var(--ink-soft); }
.mmj-summary__more {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}
.mmj-summary__more > summary {
  align-self: flex-start;
  font-size: var(--fs-13);
  color: var(--ink-soft);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
  list-style: none;
}
.mmj-summary__more > summary::-webkit-details-marker { display: none; }
.mmj-summary__more > summary:focus-visible {
  outline: 0;
  box-shadow: var(--focus-ring);
  border-radius: var(--r-xs);
}
/* Open, the toggle moves below the rows it revealed and reads "Show fewer". */
.mmj-summary__more[open] > summary { order: 2; }
.mmj-summary__more[open] .mmj-summary__more-open,
.mmj-summary__more:not([open]) .mmj-summary__more-shut { display: none; }

.mmj-summary__rows {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--sp-2) var(--sp-4);
  margin: 0;
  font-size: var(--fs-14);
  line-height: var(--lh-body);
}
.mmj-summary__rows dt { color: var(--ink-soft); }
.mmj-summary__rows dd {
  margin: 0;
  text-align: right;
  color: var(--ink);
}
/* A value that isn't a number yet — "Enter postcode", "Not delivered here".
   It states what the figure is waiting on, not an error in a money slot. */
.mmj-summary__rows dd.is-pending {
  font-size: var(--fs-13);
  color: var(--ink-soft);
}

.mmj-summary__estimate {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}
.mmj-summary__note {
  margin: 0;
  font-size: var(--fs-13);
  line-height: var(--lh-body);
  color: var(--ink-soft);
}

/* A priced postcode folds its field behind "Change". */
.mmj-summary__change > summary {
  display: block;
  font-size: var(--fs-13);
  color: var(--ink-soft);
  cursor: pointer;
  list-style: none;
}
.mmj-summary__change > summary::-webkit-details-marker { display: none; }
.mmj-summary__change-link {
  margin-left: var(--sp-1);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.mmj-summary__change[open] .mmj-summary__change-link { display: none; }
.mmj-summary__change > summary:focus-visible {
  outline: 0;
  box-shadow: var(--focus-ring);
  border-radius: var(--r-xs);
}
.mmj-summary__change .mmj-estimate__row { margin-top: var(--sp-2); }

.mmj-summary__total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-4);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--rule-strong);
}
.mmj-summary__total-label { font-size: var(--fs-16); }
.mmj-summary__total-value {
  font-size: var(--fs-28);
  line-height: var(--lh-tight);
}
/* The VAT sits directly under the figure it is part of, quieter than it. */
.mmj-summary__vat {
  display: flex;
  justify-content: space-between;
  gap: var(--sp-4);
  margin-top: calc(var(--sp-3) * -1);
  font-size: var(--fs-13);
  color: var(--ink-soft);
}
.mmj-summary__checkout {
  justify-content: center;
  gap: var(--sp-2);
}
/* Made to order — one paragraph at the foot of the card, led in bold. */
.mmj-summary__made {
  margin: 0;
  font-size: var(--fs-13);
  line-height: var(--lh-body);
  color: var(--ink-soft);
}
.mmj-summary__made strong { font-weight: var(--fw-semibold); color: var(--ink); }


/* ── Empty state ────────────────────────────────────────────────────────── */

.mmj-grid--empty { padding-top: var(--sp-12); }
.mmj-empty {
  display: flex;
  flex-direction: column;
  gap: var(--sp-6);
  max-width: var(--container-copy-cap);
}
.mmj-empty__title {
  margin: 0;
  font-size: var(--fs-28);
  font-weight: var(--fw-regular);
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-tight);
}
.mmj-empty__lead {
  margin: 0;
  max-width: var(--container-blurb-cap);
  font-size: var(--fs-16);
  line-height: var(--lh-body);
  color: var(--ink-muted);
}
.mmj-empty__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
}

/* ── Below the desktop shell ─────────────────────────────────────────────
   The cut-list table stops pretending to be a table: name and price on one
   line, size and material as one meta line, then a full-width stepper and
   the remove control. A 6-column table at 390px is unreadable, and one that
   scrolls sideways is worse. */

@media (max-width: 1179px) {
  .mmj-cuts__table,
  .mmj-cuts__table tbody { display: block; }
  .mmj-cuts__table thead { display: none; }
  .mmj-cuts__table td { padding: 0; border: 0; }

  .mmj-cuts__row {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas:
      "part part total"
      "size mat  mat"
      "qty  qty  x";
    gap: var(--sp-2) var(--sp-3);
    align-items: center;
    padding: var(--sp-4) 0;
    border-bottom: 1px solid var(--rule);
  }
  .mmj-cuts__part { grid-area: part; }
  .mmj-cuts__total { grid-area: total; }
  .mmj-cuts__size { grid-area: size; color: var(--ink-soft); }
  .mmj-cuts__size::after { content: " ·"; }
  .mmj-cuts__material { grid-area: mat; }
  .mmj-cuts__qty { grid-area: qty; }
  .mmj-cuts__x { grid-area: x; }
  .mmj-cuts__table td.mmj-cuts__x { width: auto; }
  .mmj-cuts__confirm { display: block; }
  .mmj-cuts__confirm > td { display: block; padding: var(--sp-2) 0 var(--sp-4); }

  .mmj-grid--empty { padding-top: var(--sp-8); }
}

/* Phone: the picture shrinks, the money column drops under the text, and
   the × drops with it, still centred on the stepper's row. */
@media (max-width: 720px) {
  .mmj-part {
    grid-template-columns: 88px minmax(0, 1fr) 44px;
    gap: var(--sp-3) var(--sp-4);
    padding: var(--sp-5) 0;
  }
  .mmj-drawing--lg { width: 88px; }
  .mmj-part__body { grid-column: 2; grid-row: 1; }
  .mmj-part__money { grid-column: 2; }
  .mmj-part > .mmj-remove { grid-column: 3; grid-row: 2; }
  .mmj-part > .mmj-confirm,
  .mmj-cuts { grid-column: 1 / -1; }
  .mmj-part__spec { margin-left: 0; column-gap: var(--sp-4); }
  .mmj-part__spec dd { white-space: normal; overflow-wrap: anywhere; }
}

@media (max-width: 480px) {
  .mmj-empty__actions .btn { width: 100%; justify-content: center; }
}


/* #############################################################################
   3. CHECKOUT
   ######################################################################### */

/* Three client-side steps in ONE WooCommerce form (checkout redesign,
   2026-09-25): Your Details → Delivery → Pay. Every rule that
   hides a panel or shows a step control is scoped to `.mmc--stepped`, which
   checkout.js adds when it runs — with no script all three panels stand
   stacked and the form posts as a plain WooCommerce checkout. */



/* ── Header: heading + step bar ──────────────────────────────────────────
   "Checkout" left, the three steps right, one Rule Strong line under both.
   The accent progress line (`.mmc-head__run`) starts at the header's LEFT
   edge — under the heading — and runs to the right edge of the current step;
   checkout.js measures it and it slides as the steps advance. */

.mmc-head {
  position: relative;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-8);
  border-bottom: 1px solid var(--rule-strong);
  /* Step changes scroll the header back into view; clear the site header. */
  scroll-margin-top: var(--mmj-rail-top);
}
.mmc-head__title {
  margin: 0;
  padding-bottom: var(--sp-4);
  font-size: var(--fs-36);
  font-weight: var(--fw-regular);
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-tight);
}
/* Section 1's step bar, seated on the header's rule. Its own label hairline
   would double the header's, so it goes. */
.mmc-head .mmc-head__steps {
  flex: 0 1 560px;
}
.mmc-head .mmc-head__steps .mmj-steps__label {
  border-bottom: 0;
  padding-block: var(--sp-3);
}
/* With script, the one run line replaces the per-step segments. */
.mmc--stepped .mmc-head .mmc-head__steps .mmj-steps__label::after {
  display: none;
}
.mmc-head__run {
  display: none;
  position: absolute;
  left: 0;
  bottom: -1px;
  width: 0;
  height: 2px;
  background: var(--accent);
  pointer-events: none;
  transition: width var(--dur-base) var(--ease);
}
.mmc--stepped .mmc-head__run { display: block; }
@media (prefers-reduced-motion: reduce) {
  .mmc-head__run { transition: none; }
}

/* The mobile line — current step (accent) left, "Step 2 of 3" right. */
.mmc-head__mobile {
  display: none;
  margin: 0;
  font-size: var(--fs-13);
  line-height: var(--lh-snug);
}
.mmc-head__name { color: var(--accent); }
.mmc-head__count { color: var(--ink-muted); }

@media (max-width: 767px) {
  .mmc--stepped .mmc-head {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
  }
  .mmc--stepped .mmc-head__title { padding-bottom: var(--sp-3); }
  .mmc--stepped .mmc-head .mmc-head__steps { display: none; }
  .mmc--stepped .mmc-head__mobile {
    display: flex;
    justify-content: space-between;
    gap: var(--sp-4);
    padding-bottom: var(--sp-3);
  }
  .mmc--stepped .mmc-head__run {
    width: calc(100% * var(--mmc-step-n, 1) / var(--mmc-step-total, 3)) !important;
  }
}

/* ── Step panels ─────────────────────────────────────────────────────── */

.mmc-details {
  display: flex;
  flex-direction: column;
  gap: var(--sp-8);
}
.mmc-step {
  display: flex;
  flex-direction: column;
  gap: var(--sp-6);
  min-width: 0;
}
.mmc-step[hidden] { display: none; }
/* No script: the panels stack, each opened by a hairline. */
.mmc:not(.mmc--stepped) .mmc-step + .mmc-step,
.mmc:not(.mmc--stepped) .mmc-details + .mmc-step {
  padding-top: var(--sp-8);
  border-top: 1px solid var(--rule);
}
.mmc-step__head {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}
.mmc-step__title {
  margin: 0;
  font-size: var(--fs-22);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-tight);
}
.mmc-step__title:focus { outline: 0; }
.mmc-step__title:focus-visible {
  box-shadow: var(--focus-ring);
  border-radius: var(--r-xs);
}
.mmc-step__lead,
.mmc-step__help,
.mmc-step__hint {
  margin: 0;
  font-size: var(--fs-14);
  line-height: var(--lh-body);
  color: var(--ink-muted);
}
.mmc-step__help { margin-top: var(--sp-4); font-size: var(--fs-13); }

/* Back left, Continue right. Only once script can act on them. */
.mmc-step__nav { display: none; }
.mmc--stepped .mmc-step__nav {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--sp-6);
  padding-top: var(--sp-2);
}
.mmc--stepped .mmc-step__nav .mmc-step__back {
  margin-right: auto;
  height: var(--h-control);
  color: var(--ink);
}

/* ── Fields (§7.2) ──────────────────────────────────────────────────────
   Label above, control below. WooCommerce's own markup, restyled:
   <p class="form-row"><label>…<span class="woocommerce-input-wrapper">
   <input class="input-text">. The label is the §7.2 Label role — 11px
   uppercase tracked Ink Muted — joined in design-base.css. */

.mmc .mmc-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--sp-5) var(--sp-6);
}

/* Every wrapper needs min-width:0: an input's intrinsic min-width otherwise
   blows a grid track open and takes the page's horizontal scrollbar with it. */
form .mmc .form-row {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  min-width: 0;
  margin: 0;
  padding: 0;
  width: 100%;
}

/* WooCommerce marks the wide fields itself; the half-width pairs the design
   asks for are tagged in makemy_checkout_filter_fields(). */
.mmc .mmc-grid > .form-row-wide,
.mmc .mmc-grid > .create-account {
  grid-column: 1 / -1;
}
.mmc .mmc-grid > .mmc-field--half {
  grid-column: auto;
}

form .mmc .form-row label {
  display: block;
  margin: 0;
  font-family: var(--font-sans);
  color: var(--ink-muted);
}
form .mmc .form-row label .required {
  color: var(--err);
  text-decoration: none;
}
form .mmc .form-row label .optional {
  color: var(--ink-faint);
  font-weight: var(--fw-regular);
  text-transform: none;
  letter-spacing: var(--tracking-normal);
}

form .mmc .form-row .woocommerce-input-wrapper {
  display: block;
  width: 100%;
  min-width: 0;
}

form .mmc .form-row input.input-text,
form .mmc .form-row textarea,
form .mmc .form-row select {
  display: block;
  height: var(--h-control);
  width: 100%;
  min-width: 0;
  /* 11 + 20 + 11 + two 1px borders = the 44px --h-control. The height is
     stated in padding and line-height as well as `height` because the Stripe
     plugin styles its card fields by COPYING this field's computed padding
     and line-height (it ignores `height`) — see "Stripe card fields" below. */
  padding: 11px var(--sp-3);
  line-height: 20px;
  background: var(--paper);
  /* §3.4 — the border of anything a customer operates. */
  border: 1px solid var(--rule-interactive);
  border-radius: var(--r-sm);
  font-family: var(--font-sans);
  font-size: var(--fs-14);
  letter-spacing: var(--tracking-normal);
  color: var(--ink);
  transition: border var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
form .mmc .form-row textarea {
  height: auto;
  min-height: 96px;
  padding: var(--sp-3);
  line-height: var(--lh-body);
  resize: vertical;
}
form .mmc .form-row input.input-text:focus,
form .mmc .form-row textarea:focus,
form .mmc .form-row select:focus {
  outline: 0;
  border-color: var(--ink);
  box-shadow: var(--focus-ring);
}
form .mmc .form-row input::placeholder,
form .mmc .form-row textarea::placeholder {
  /* §3.3 — Ink Faint is placeholder and disabled glyphs, and nothing else. */
  color: var(--ink-faint);
}

/* A gateway's or plugin's own help row, where one appears. */
form .mmc .form-row .description {
  display: block;
  margin-top: var(--sp-1);
  font-size: var(--fs-13);
  line-height: var(--lh-body);
  color: var(--ink-muted);
}

/* A postcode is read back character by character, so it is upper-cased —
   in the one face (Lexend), like the basket's postcode field. */
form .mmc #billing_postcode,
form .mmc #shipping_postcode {
  text-transform: uppercase;
}

/* Validation (§7.11 lives in the banner; the field itself reddens and says
   why underneath — WooCommerce's own inline message, or checkout.js's twin of
   it when Continue finds the gap). */
form .mmc .form-row.woocommerce-invalid input.input-text,
form .mmc .form-row.woocommerce-invalid textarea,
form .mmc .form-row.woocommerce-invalid select {
  border-color: var(--err);
}
form .mmc .form-row.woocommerce-validated input.input-text {
  border-color: var(--rule-interactive);
}
.mmc .checkout-inline-error-message {
  margin: 0;
  font-size: var(--fs-13);
  line-height: var(--lh-body);
  color: var(--err);
}

/* ── Checkbox rows ───────────────────────────────────────────────────────
   44px is the floor for anything a finger touches, so the whole label is the
   target, not the 18px box. */

.mmc .mmc-check {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: var(--h-control);
  font-family: var(--font-sans);
  font-size: var(--fs-14);
  font-weight: var(--fw-regular);
  letter-spacing: var(--tracking-normal);
  text-transform: none;
  line-height: var(--lh-body);
  color: var(--ink);
  cursor: pointer;
}
.mmc .mmc-checkbox,
.mmc .mmc-radio {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: var(--ink);
}
/* design-base's :focus-visible rule deliberately excludes form controls, whose
   focus is normally the border+ring pair — a checkbox has no border to darken,
   so it takes the outline instead (§3.8: always visible, always accented). */
.mmc input[type="checkbox"]:focus-visible,
.mmc input[type="radio"]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}

.mmc .mmc-account {
  margin-top: var(--sp-5);
}

/* ── Delivery address block ──────────────────────────────────────────────
   Revealed by WooCommerce's own #ship-to-different-address handler, which
   slides `div.shipping_address` — hence the inline display it manages. */

.mmc .mmc-ship-address {
  margin-top: var(--sp-4);
  padding: var(--sp-6);
  border-radius: var(--r-md);
  background: var(--paper-soft);
}
/* §3.3 — Ink Muted is Paper-only; on Pebble the label steps up to Ink Soft. */
form .mmc .mmc-ship-address .form-row label,
form .mmc .mmc-ship-address .form-row .description {
  color: var(--ink-soft);
}

/* ── Delivery or collection ──────────────────────────────────────────────
   Real radio rows, stacked, beside the route map (.mmc-ship-map below). The
   chosen row takes a 2px Ink border (1px border + 1px inset, so nothing
   shifts) and the other row steps back to Ink
   Muted; the radio carries the state too, so colour is never the only signal
   (§13). */

.mmc .mmc-ship {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}
.mmc .mmc-ship__label {
  display: block;
}
.mmc .mmc-ship__list {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}
.mmc .mmc-ship__row {
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr) auto;
  gap: var(--sp-3);
  align-items: start;
  min-height: var(--h-control);
  padding: var(--sp-4);
  border: 1px solid var(--rule-interactive);
  border-radius: var(--r-sm);
  background: var(--paper);
  cursor: pointer;
  transition: border var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.mmc .mmc-ship__row .mmc-radio { margin-top: 2px; }
.mmc .mmc-ship__row:hover {
  border-color: var(--ink);
}
/* One "chosen" look (§7.28, 2026-09-29): a real 2px Ink border, not a 1px
   border doubled by an inset ring. The padding gives back the extra 1px so
   the row's contents don't move when it is picked. */
.mmc .mmc-ship__row:has(input:checked) {
  border: 2px solid var(--ink);
  padding: calc(var(--sp-4) - 1px);
}
.mmc .mmc-ship__list:has(input:checked) .mmc-ship__row:not(:has(input:checked)) {
  color: var(--ink-muted);
}
.mmc .mmc-ship__body {
  min-width: 0;
}
.mmc .mmc-ship__name {
  display: block;
  font-size: var(--fs-16);
  font-weight: var(--fw-semibold);
  line-height: 1.35;
}
.mmc .mmc-ship__note {
  display: block;
  margin-top: var(--sp-1);
  font-size: var(--fs-13);
  line-height: var(--lh-body);
  color: var(--ink-muted);
}
.mmc .mmc-ship__price {
  font-size: var(--fs-16);
  font-weight: var(--fw-semibold);
  white-space: nowrap;
}
.mmc .mmc-ship__empty {
  margin: 0;
  padding: var(--sp-4);
  border-radius: var(--r-sm);
  background: var(--paper-soft);
  font-size: var(--fs-14);
  line-height: var(--lh-body);
  color: var(--ink-soft);
}
/* Continue found no rate chosen — the same reddened-edge signal a field gets. */
.mmc .mmc-ship.is-invalid .mmc-ship__empty {
  box-shadow: inset 0 0 0 1px var(--err);
}

/* ── Route map ───────────────────────────────────────────────────────────
   The frame is section 1's `.mmj-map`. On checkout it sits beside the
   delivery choice — the choice on the left, the map it changes on the right
   (maintainer decision, 2026-09-25: full width, the ~4:3 map left dead space
   either side of it). The canvas takes the map's own proportions there
   rather than section 1's fixed 280px, so it fills its column with no
   letterbox. Below the tablet width the two stack, map under the choice. */

.mmc .mmc-ship-map {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-4);
}
.mmc .mmc-route .mmj-map {
  max-width: none;
}
@media (min-width: 768px) {
  .mmc .mmc-ship-map {
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    gap: var(--sp-6);
    align-items: start;
  }
  .mmc .mmc-route .mmj-map__canvas {
    height: auto;
    aspect-ratio: 420 / 300;
  }
}

/* ── Payment (step 3) ────────────────────────────────────────────────────
   WooCommerce's own list, restyled. Structure (ul.wc_payment_methods >
   li.wc_payment_method > input + label + .payment_box) is untouched, because
   gateway plugins hook exactly those selectors. */

.mmc #payment {
  margin: 0;
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: 0;
}
.mmc #payment ul.payment_methods {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  margin: 0;
  padding: 0;
  border: 0;
  list-style: none;
}
.mmc #payment ul.payment_methods li.wc_payment_method {
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr);
  column-gap: var(--sp-4);
  align-items: center;
  margin: 0;
  padding: 0 0 0 var(--sp-4);
  background: var(--paper);
  border: 1px solid var(--rule-interactive);
  border-radius: var(--r-sm);
  transition: border var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
/* WooCommerce's own sheet gives the list and each row clearfix pseudo-elements
   (`content: " "; display: table`). In a flex column and a grid they are real
   items: the list's opened a gap above the first row, and each row's took the
   20px radio cell, so the radio slid into the label column and the label was
   squeezed into 20px one word per line. Floats are gone; so are these. */
.mmc #payment ul.payment_methods::before,
.mmc #payment ul.payment_methods::after,
.mmc #payment ul.payment_methods li.wc_payment_method::before,
.mmc #payment ul.payment_methods li.wc_payment_method::after {
  content: none;
  display: none;
}
/* The same 2px Ink "chosen" border as the delivery rows (§7.28). This row
   has padding on its left only, so the extra 1px is given back as a -1px
   margin instead: the box grows 1px into the list's 12px gap on each side and
   the radio, label and Stripe's payment box stay exactly where they were. */
.mmc #payment ul.payment_methods li.wc_payment_method:has(input:checked) {
  border: 2px solid var(--ink);
  margin: -1px;
}
.mmc #payment ul.payment_methods li.wc_payment_method > input {
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: var(--ink);
}
.mmc #payment ul.payment_methods li.wc_payment_method label {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: var(--h-control);
  margin: 0;
  padding: var(--sp-2) var(--sp-4) var(--sp-2) 0;
  font-family: var(--font-sans);
  font-size: var(--fs-14);
  font-weight: var(--fw-regular);
  letter-spacing: var(--tracking-normal);
  text-transform: none;
  color: var(--ink);
  cursor: pointer;
}
.mmc #payment ul.payment_methods li.wc_payment_method label img {
  display: inline-block;
  height: 22px;
  width: auto;
  margin: 0;
}
/* The selected method's own box (Stripe's card element lives here). Indented
   to the label's left edge: the 20px radio column + the 16px gap (the row's
   own 16px left padding already sits outside the grid). */
.mmc #payment div.payment_box {
  grid-column: 1 / -1;
  margin: 0;
  padding: 0 var(--sp-4) var(--sp-4) calc(var(--sp-4) + 20px);
  background: transparent;
  border-radius: 0;
  font-size: var(--fs-14);
  line-height: var(--lh-body);
  color: var(--ink-muted);
}
.mmc #payment div.payment_box::before {
  display: none;
}
.mmc #payment div.payment_box p {
  margin: 0 0 var(--sp-2);
}
.mmc #payment div.payment_box p:last-child {
  margin-bottom: 0;
}
/* A WooCommerce info notice (woocommerce.css) — only its page margin goes. */
.mmc .mmc-pay__empty {
  margin: 0;
}
/* The submit hooks and the nonce — no visible chrome of its own. */
form .mmc .form-row.mmc-place-row {
  margin: 0;
  padding: 0;
}
form .mmc .form-row.mmc-place-row:empty { display: none; }

/* ── Pay (step 3): recap, terms, wallets, methods ─────────────────────────
   Two blocks of what is about to be confirmed (Deliver to, Delivery) — label
   in dark small caps with its Edit, value in Ink Muted — then the
   made-to-order note carrying the terms checkbox, then the wallets and the
   payment methods. The recap is filled from the live form by checkout.js, so
   with no script it is hidden (every value it echoes is on screen above it). */

/* The payment methods sit a step below the terms note — or right under the
   wallets' "or pay by card" rule, which already spaces them. */
.mmc [data-mmc-step="pay"] #payment { margin-top: var(--sp-6); }
.mmc [data-mmc-step="pay"] .mmc-wallets:not([hidden]) + #payment { margin-top: 0; }

.mmc .mmc-review {
  display: none;
}
.mmc--stepped .mmc-review {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--sp-6) var(--sp-8);
}
.mmc .mmc-review__block {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  min-width: 0;
}
.mmc .mmc-review__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-3);
}
.mmc .mmc-review__label {
  font-size: var(--fs-11);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--ink);
}
.mmc .mmc-review__edit {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: var(--fs-13);
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.mmc .mmc-review__edit:focus-visible {
  outline: 0;
  box-shadow: var(--focus-ring);
  border-radius: var(--r-xs);
}
.mmc .mmc-review__value {
  margin: 0;
  font-size: var(--fs-14);
  line-height: var(--lh-body);
  color: var(--ink-muted);
  white-space: pre-line;
  overflow-wrap: anywhere;
}

/* Made to order — Pebble, the lead in semibold Ink, then the terms box. */
.mmc .mmc-made {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-5) var(--sp-6);
  border-radius: var(--r-md);
  background: var(--paper-soft);
}
.mmc .mmc-made__body {
  margin: 0;
  font-size: var(--fs-14);
  line-height: var(--lh-body);
  /* Pebble surface — Ink Soft, not Ink Muted (§3.3). */
  color: var(--ink-soft);
}
.mmc .mmc-made__body strong {
  font-weight: var(--fw-semibold);
  color: var(--ink);
}
.mmc .mmc-terms {
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr);
  gap: var(--sp-3);
  align-items: start;
  /* The label is the target, not the box inside it — and the gate on Confirm
     and pay is the last thing a customer touches before paying, so it holds
     the 44px floor (§13) even when its copy fits on one line. */
  min-height: var(--h-control);
  align-content: center;
}
.mmc .mmc-terms .mmc-checkbox {
  margin-top: 3px;
}
.mmc .mmc-terms a {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Wallets — Stripe's express buttons (Apple Pay, Google Pay, Link), moved
   here from the top of the form (Design.md §14.4): on the Pay step under the
   terms box, above the card methods. The buttons are the providers' own
   artwork inside Stripe's iframe; this only places them, labels them, and
   dims them while they are locked behind the terms box. */
.mmc .mmc-wallets {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  margin-top: var(--sp-6);
}
.mmc .mmc-wallets__label {
  margin: 0;
  font-size: var(--fs-11);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--ink-muted);
}
/* Stripe prints its own "— OR —" inside the button callback; the Pay step
   draws "or pay by card" instead. Stripe toggles it with an inline style. */
.mmc .mmc-wallets #wc-stripe-express-checkout-button-separator { display: none !important; }
.mmc .mmc-wallets[hidden] { display: none; }
.mmc .mmc-wallets__rule {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin: var(--sp-3) 0 var(--sp-2);
  font-size: var(--fs-13);
  color: var(--ink-muted);
}
.mmc .mmc-wallets__rule::before,
.mmc .mmc-wallets__rule::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  background: var(--rule-strong);
}
.mmc .mmc-wallets__buttons {
  transition: opacity var(--dur-fast) var(--ease);
}
.mmc .mmc-wallets__buttons.is-locked { opacity: 0.35; }
/* Stripe prints its container with an inline 1em top margin for the top of
   the form; the rule above already spaces it. */
.mmc .mmc-wallets #wc-stripe-express-checkout-element { margin-top: 0 !important; }

/* ── Stripe card fields ──────────────────────────────────────────────────
   The card number / expiry / CVC boxes are Stripe's, inside its iframe, so
   no rule here reaches them. The WooCommerce Stripe plugin instead builds
   Stripe's appearance by cloning #billing_first_name into a hidden row in
   the billing fields (#wc-stripe-hidden-input, plus an invalid twin) and
   copying the clone's computed padding, line-height, border, radius, font
   and colours. Those clones sit outside our `.form-row` field rules, so they
   are given the same box explicitly here — 44px from padding and line-height,
   the Rule Interactive border, 4px corners, 14px Lexend in Ink — and Stripe
   draws the card fields to match (2026-09-26). The font reaches Stripe's frame
   through makemy_checkout_stripe_font_domains() and the fonts folder's CORS
   header. */
.mmc #wc-stripe-hidden-input,
.mmc #wc-stripe-hidden-invalid-input {
  height: auto;
  padding: 11px var(--sp-3);
  line-height: 20px;
  background: var(--paper);
  border: 1px solid var(--rule-interactive);
  border-radius: var(--r-sm);
  box-shadow: none;
  font-family: var(--font-sans);
  font-size: var(--fs-14);
  letter-spacing: var(--tracking-normal);
  color: var(--ink);
}
.mmc #wc-stripe-hidden-invalid-input {
  border-color: var(--err);
}


/* ── Rail: the Order summary card ────────────────────────────────────────
   The basket's `.mmj-summary` card (section 2). On checkout the card is
   review-order.php — the fragment WooCommerce swaps — and Confirm and pay
   and Edit basket sit just after it, outside the fragment. The Pebble ground
   is moved out to `.mmc-rail__body` so all three read as one card. */

.mmc .mmc-rail__body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  padding: var(--sp-6);
  border-radius: var(--r-md);
  background: var(--paper-soft);
}
.mmc .mmc-summary {
  padding: 0;
  border-radius: 0;
  background: none;
}
.mmc .mmc-rail__actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-3);
  padding-top: var(--sp-2);
}
/* A text link, not a button: 13px and underlined like the basket drawer's
   Edit sizes in basket, centred on its own line with no button height. */
.mmc .mmc-rail__edit {
  font-size: var(--fs-13);
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* The mobile fold is hidden on the desktop shell and without script. */
.mmc .mmc-fold { display: none; }

/* ── Confirm and pay ─────────────────────────────────────────────────────
   Primary Large, full width (52px). Primary is Coal, never accent (§15.8).

   `!important` is retained against WooCommerce's own `#place_order` rules,
   which a gateway can still reach if it re-renders the button with
   WooCommerce's `.button alt` classes; this sheet loads later, so at equal
   specificity these win. */

.mmc #place_order,
.mmc .mmc-place {
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  width: 100% !important;
  height: var(--h-btn-lg) !important;
  margin: 0 !important;
  padding: 0 var(--sp-6) !important;
  background: var(--ink) !important;
  color: var(--paper) !important;
  border: 1px solid var(--ink) !important;
  border-radius: var(--r-sm) !important;
  font-family: var(--font-sans) !important;
  font-size: var(--fs-16) !important;
  font-weight: var(--fw-regular) !important;
  letter-spacing: var(--tracking-normal) !important;
  line-height: 1.3 !important;
  text-transform: none !important;
}
.mmc #place_order:hover:enabled,
.mmc .mmc-place:hover:enabled {
  background: oklch(from var(--ink) calc(l + 0.08) c h) !important;
}
.mmc #place_order:active:enabled,
.mmc .mmc-place:active:enabled {
  transform: translateY(1px);
}
/* Gated until Pay is showing and the sizes are confirmed. Pebble fill,
   Ink Faint label — §3.3's disabled-glyph use, and WCAG 2.2 §1.4.3's
   inactive-component exemption (measured and pinned in
   tests/js/Theme/design-contrast.test.js). The rail's sits on the Pebble
   card, so its edge steps up to Rule Strong to keep the button's shape
   visible; the phone foot bar's gated button is the same state, so it takes
   the same edge. */
.mmc #place_order:disabled,
.mmc .mmc-place:disabled,
.mmc .mmc-foot__cta:disabled {
  background: var(--paper-soft) !important;
  color: var(--ink-faint) !important;
  border-color: var(--rule-strong) !important;
  cursor: not-allowed !important;
  transform: none;
}

/* ── Mobile sticky foot ──────────────────────────────────────────────────
   `.mmj-foot` supplies the 84px sticky bar; this places its two halves:
   Total, and the current step's button. It needs script, so without it the
   bar is not shown and the rail's Confirm and pay sits in the flow. */

.mmc:not(.mmc--stepped) .mmc-foot { display: none; }
.mmc .mmc-foot__total {
  min-width: 0;
}
.mmc .mmc-foot__cta {
  flex: 1 1 auto;
  max-width: 260px;
}

/* ── Below the two-column shell ─────────────────────────────────────────── */

@media (max-width: 1179px) {
  /* The rail folds to a Pebble bar ABOVE the form: "Order summary · 4
     items", the total and a chevron, opening to the same card. Default
     shut; with no script the rail stays after the form, open. */
  .mmc--stepped .mmc-rail {
    order: -1;
    gap: 0;
  }
  .mmc--stepped .mmc-fold {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto 16px;
    align-items: center;
    gap: var(--sp-3);
    width: 100%;
    min-height: var(--h-control);
    padding: var(--sp-3) var(--sp-5);
    border: 0;
    border-radius: var(--r-md);
    background: var(--paper-soft);
    font: inherit;
    font-size: var(--fs-14);
    color: var(--ink);
    text-align: left;
    cursor: pointer;
  }
  .mmc--stepped .mmc-rail.is-open .mmc-fold {
    border-radius: var(--r-md) var(--r-md) 0 0;
  }
  .mmc--stepped .mmc-fold:focus-visible {
    outline: 0;
    box-shadow: var(--focus-ring);
  }
  .mmc-fold__total {
    font-size: var(--fs-16);
    font-weight: var(--fw-semibold);
  }
  /* A chevron drawn from two borders — no glyph font, no icon. */
  .mmc-fold__chevron {
    width: 8px;
    height: 8px;
    justify-self: center;
    border-right: 1.5px solid var(--ink-soft);
    border-bottom: 1.5px solid var(--ink-soft);
    transform: translateY(-2px) rotate(45deg);
    transition: transform var(--dur-fast) var(--ease);
  }
  .mmc-rail.is-open .mmc-fold__chevron {
    transform: translateY(2px) rotate(-135deg);
  }
  .mmc--stepped .mmc-rail:not(.is-open) .mmc-rail__body { display: none; }
  .mmc--stepped .mmc-rail__body {
    padding-top: var(--sp-2);
    border-radius: 0 0 var(--r-md) var(--r-md);
  }
  /* The fold already names the card. */
  .mmc--stepped .mmc-rail .mmj-summary__title { display: none; }
  /* The one visible Confirm and pay is the foot bar's; the rail's stays in
     the DOM as the form's real submit, which the foot clicks. */
  .mmc--stepped .mmc-rail__actions .mmc-place { display: none !important; }
}

/* ── Phone ──────────────────────────────────────────────────────────────── */

@media (max-width: 700px) {
  .mmc .mmc-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--sp-4);
  }
  .mmc .mmc-grid > .form-row-wide,
  .mmc .mmc-grid > .create-account,
  .mmc .mmc-grid > .mmc-field--half {
    grid-column: 1 / -1;
  }

  /* 16px text — anything smaller and iOS zooms the page on focus, which drops
     the customer into a horizontally scrolled form. The control stays on the
     44px --h-control rung (Design.md §5.4): the base rule's 11 + 20 + 11
     padding and line-height still hold, and Stripe copies those, not height. */
  form .mmc .form-row input.input-text,
  form .mmc .form-row select,
  form .mmc .form-row textarea {
    font-size: var(--fs-16);
  }

  .mmc .mmc-checkbox,
  .mmc .mmc-radio,
  .mmc #payment ul.payment_methods li.wc_payment_method > input {
    width: 20px;
    height: 20px;
  }

  .mmc .mmc-ship-address { padding: var(--sp-4); }
  .mmc--stepped .mmc-review { grid-template-columns: minmax(0, 1fr); }
  .mmc .mmc-made { padding: var(--sp-4); }
  .mmc .mmc-rail__body { padding-inline: var(--sp-4); }
  .mmc--stepped .mmc-fold { padding-inline: var(--sp-4); }
  .mmc .mmc-foot__cta { max-width: 220px; }

  /* On a phone the foot carries Continue; the in-panel button would be a
     second copy of the same action one thumb away. Back stays. */
  .mmc--stepped .mmc-step__nav .mmc-step__next { display: none; }
}


/* #############################################################################
   4. ORDER CONFIRMATION + PAYMENT STATUS
   ######################################################################### */


/* The rail's cards are their own objects, spaced like the checkout's rather
   than the basket's tighter stack. */
.mmo .mmj-rail {
  gap: var(--sp-6);
}


/* ── Header ──────────────────────────────────────────────────────────────
   The page's name left, "Order 10423 · 25 Sep 2026" right, a Rule Strong
   line beneath. On a paid order a 2px accent line covers that rule's full
   width — the checkout's progress line, completed. The status states carry
   no accent line: the journey is not finished. */

.mmo-head {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-2) var(--sp-6);
  padding-bottom: var(--sp-4);
  border-bottom: 1px solid var(--rule-strong);
}
.mmo-head__title {
  margin: 0;
  font-size: var(--fs-36);
  font-weight: var(--fw-regular);
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-tight);
}
.mmo-head__meta {
  margin: 0;
  font-size: var(--fs-16);
  line-height: var(--lh-body);
  color: var(--ink-muted);
}
.mmo-head__line {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  background: var(--accent);
  pointer-events: none;
}

/* ── Lede + facts ────────────────────────────────────────────────────────
   One sentence at 22px, then the four facts between hairlines: label above
   (the Label role, joined in design-base.css), value below at 16px Ink.
   Four across; 2×2 on a phone (below). */

.mmo-intro {
  display: flex;
  flex-direction: column;
  gap: var(--sp-6);
}
.mmo-lede {
  margin: 0;
  max-width: var(--container-copy-cap);
  font-size: var(--fs-22);
  line-height: var(--lh-snug);
  color: var(--ink);
  text-wrap: pretty;
}

.mmo-stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--sp-4) var(--sp-6);
  margin: 0;
  padding: var(--sp-5) 0;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}
.mmo-stats__cell {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  min-width: 0;
}
.mmo-stats__label {
  color: var(--ink-muted);
}
.mmo-stats__figure {
  margin: 0;
  font-size: var(--fs-16);
  line-height: var(--lh-snug);
  color: var(--ink);
  overflow-wrap: anywhere;
}

/* ── Order stages ────────────────────────────────────────────────────────
   The rows are section 1's step bar (makemy_journey_steps()); only the phone
   layout below differs on this page. */

/* ── Where it goes ───────────────────────────────────────────────────────
   One line — the label, then the address comma-joined in Ink Muted — above a
   full-width route map. */

.mmo-where {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1) var(--sp-3);
  margin: 0;
  font-size: var(--fs-14);
  line-height: var(--lh-body);
}
.mmo-where__label {
  font-weight: var(--fw-semibold);
  color: var(--ink);
}
.mmo-where__value {
  color: var(--ink-muted);
  overflow-wrap: anywhere;
}

/* ── Order summary — the payment row ─────────────────────────────────────
   The card is the basket's `.mmj-summary` (section 2). This closes it with
   what happened to the money: "Paid by Card", "Payment · Pending",
   "Payment · Not charged". The Total above stays Ink in every state (§11.8 —
   never an error string in a money slot). Pebble surface, so Ink Soft rather
   than Ink Muted (§3.3). */

.mmo-payrow {
  display: flex;
  justify-content: space-between;
  gap: var(--sp-4);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--rule);
  font-size: var(--fs-13);
  line-height: var(--lh-body);
  color: var(--ink-soft);
}

/* ── Billing address ─────────────────────────────────────────────────────
   Under the card, only when it differs from the delivery address. */

.mmo-billing {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding: 0 var(--sp-6);
}
.mmo-billing__body {
  /* <address> is italic by default and the brand ships no italic (§4.2). */
  font-style: normal;
  margin: 0;
  font-size: var(--fs-14);
  line-height: var(--lh-body);
  color: var(--ink-soft);
  overflow-wrap: break-word;
}

/* ── Status notice ───────────────────────────────────────────────────────
   Pending and refused open on a Pebble card: what happened, in a sentence,
   then — pending — the poll line, or — refused — "Try the payment again" and
   a quiet link back to the basket. Primary is Coal, never accent (§15.8).
   Pebble, so the supporting text is Ink Soft (§3.3). */

.mmo-notice {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-6);
  border-radius: var(--r-md);
  background: var(--paper-soft);
}
.mmo-notice__title {
  margin: 0;
  font-size: var(--fs-22);
  font-weight: var(--fw-regular);
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-tight);
  color: var(--ink);
}
.mmo-notice__body {
  margin: 0;
  max-width: var(--container-copy-cap);
  font-size: var(--fs-14);
  line-height: var(--lh-body);
  color: var(--ink-soft);
}
.mmo-notice__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3) var(--sp-6);
  margin-top: var(--sp-2);
}
.mmo-link {
  font-size: var(--fs-14);
  color: var(--ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
.mmo-link:hover { color: var(--ink-soft); }
.mmo-link:focus-visible {
  outline: 0;
  box-shadow: var(--focus-ring);
  border-radius: var(--r-xs);
}

/* ── The second-look line (issues.md #376) ───────────────────────────────
   Inside the pending notice on a card order that is pending only because the
   gateway's webhook has not landed yet, and says so; assets/js/order-poll.js
   reloads the page when the server's answer changes. Detail size, Ink Soft on
   the notice's Pebble (§3.3).

   The dot is the only motion. Warn colours it and never the text (§3.7), and
   it is not the only signal: the line says so in words. */

.mmo-poll {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
  margin: 0;
  font-size: var(--fs-13);
  line-height: var(--lh-body);
  color: var(--ink-soft);
}
.mmo-poll__dot {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--warn);
  animation: mmo-poll-pulse 1.6s var(--ease) infinite;
}
.mmo-poll.is-idle .mmo-poll__dot {
  background: var(--rule-strong);
  animation: none;
}

/* A plain text control, not a button shape: a filled control here would
   compete with nothing and promise more than a re-check. */
.mmo-poll__again {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.mmo-poll__again:hover { color: var(--ink-soft); }

@keyframes mmo-poll-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.25; }
}

@media (prefers-reduced-motion: reduce) {
  .mmo-poll__dot { animation: none; }
}

/* ── Mobile ──────────────────────────────────────────────────────────────
   The two-column shell already falls to one column at 1180px in the shared
   sheet, which puts the Order summary card at the end of the page. Below
   768px: facts 2×2, and the stage bar becomes a vertical list — name and
   date on one line, no detail sentence, the current stage marked by a 2px
   accent rule down its left edge instead of the line under its label. */

@media (max-width: 767px) {
  .mmo-head__title {
    font-size: var(--fs-28);
  }
  .mmo .mmj-section__heading {
    font-size: var(--fs-22);
  }

  .mmo-stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .mmo .mmj-steps {
    grid-auto-flow: row;
    grid-template-columns: minmax(0, 1fr);
    border-top: 1px solid var(--rule);
  }
  .mmo .mmj-steps__step,
  .mmo .mmj-steps__step + .mmj-steps__step {
    flex-direction: row;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--sp-4);
    padding: var(--sp-3) var(--sp-4);
    border-left: 2px solid transparent;
    border-bottom: 1px solid var(--rule);
  }
  .mmo .mmj-steps__step.is-current,
  .mmo .mmj-steps__step + .mmj-steps__step.is-current {
    border-left-color: var(--accent);
  }
  .mmo .mmj-steps__label {
    width: auto;
    padding: 0;
    border-bottom: 0;
    font-size: var(--fs-14);
    text-align: left;
  }
  .mmo .mmj-steps__step.is-run .mmj-steps__label::after {
    content: none;
  }
  .mmo .mmj-steps__detail {
    flex: none;
    padding: 0;
  }
  .mmo .mmj-steps__note {
    display: none;
  }
  .mmo .mmj-steps__when {
    font-size: var(--fs-13);
    text-align: right;
    white-space: nowrap;
  }

  .mmo-billing {
    padding: 0;
  }

  /* A 44px target is the floor for anything a finger touches (§5.4), so the
     retry goes full width. */
  .mmo-notice__actions .btn {
    width: 100%;
    justify-content: center;
  }
}


/* ── A gateway's own thank-you output ────────────────────────────────────
   Rendered after the page's own grid (it fires on `woocommerce_thankyou`, at
   the end of the template), so it re-enters the page shell to pick up the
   container width and side padding, and drops the top padding the shell would
   otherwise add to a band that is continuing the one above it. */

.mmo-gateway { padding-top: 0; }
.mmo-gateway .mmj-note { max-width: var(--container-copy); }
.mmo-gateway .mmj-note__body p:last-child { margin-bottom: 0; }
