/*
 * Booking — the shared skin of every public reservation surface.
 *
 * Written once and read by all four: the assistant, /reserver,
 * /mes-reservations, and the shop pages that carry a picker.
 *
 * WHY THIS FILE EXISTS. Before it, the same colour had three values: the
 * picker defined six `--nb-*` tokens and used them 108 times; /reserver
 * consumed them 33 times WITHOUT ever defining them, falling back on
 * #e4ddd2 / #6a635c / #d9cfc0 — three different "sands"; and
 * /mes-reservations used no token at all, carrying 21 hard-coded colours.
 * Every page also embedded its own <style> block. Measured 2026-08-13.
 *
 * WHERE IT LIVES. These pages sit inside the merchant's own website, whose
 * typography and colours we do not control. So everything here is scoped
 * under `.nb` and never touches a bare element selector: the sheet is an
 * island, not a theme. For the same reason there are no `:has()` rules —
 * one of those leaked out of the webmail layout and repainted half a desk.
 */

.nb {
  /* Paper */
  --nb-paper: #faf3ea;
  --nb-paper-bright: #fffdf8;
  --nb-sand: #e8ddd0;
  --nb-sand-soft: #f4ede4;

  /* Clay — the only saturated accent. Never an action button. */
  --nb-clay: #d68a59;
  --nb-clay-ink: #b96f3e;
  --nb-clay-wash: #faefe6;
  --nb-clay-tint: #fdf7f2;

  /* Ink — type AND solid action buttons */
  --nb-ink: #141414;
  --nb-muted: #6b6156;
  --nb-faint: #c6bcb0;

  --nb-success: #2f6e4e;
  --nb-success-bg: #e6f4ea;
  --nb-warn: #a16207;
  --nb-warn-bg: #fdf3dc;
  --nb-danger: #c2410c;
  --nb-danger-bg: #fdeae4;

  --nb-radius-sm: 10px;
  --nb-radius-md: 14px;
  --nb-radius-lg: 20px;
  --nb-radius-pill: 999px;

  --nb-font-title: "Forum", Georgia, serif;
  --nb-font-ui: "Karla", system-ui, -apple-system, sans-serif;

  --nb-ease: cubic-bezier(0.32, 0.72, 0, 1);

  font-family: var(--nb-font-ui);
  color: var(--nb-ink);
  line-height: 1.55;
}

/* ---------------------------------------------------------------------------
 * Primitives
 * ------------------------------------------------------------------------ */

/* The frame that isolates us from the host site. Borders before shadows —
   the system has no shadows at all. */
.nb-frame {
  background: var(--nb-paper);
  border: 1px solid var(--nb-sand);
  border-radius: var(--nb-radius-lg);
  padding: 28px;
}

.nb-panel {
  background: var(--nb-paper-bright);
  border: 1px solid var(--nb-sand);
  border-radius: var(--nb-radius-md);
  padding: 26px;
}

.nb-card {
  background: var(--nb-paper-bright);
  border: 1px solid var(--nb-sand);
  border-radius: var(--nb-radius-md);
  padding: 20px;
}

.nb-eyebrow {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--nb-clay-ink);
}

.nb-eyebrow--muted {
  color: var(--nb-muted);
}

.nb-title {
  font-family: var(--nb-font-title);
  font-weight: 400;
  font-size: 28px;
  line-height: 1.15;
  margin: 0;
}

.nb-title--lg {
  font-size: 36px;
}
.nb-title--sm {
  font-size: 22px;
}

/* Money and countdowns are titles too: they are read, not scanned. */
.nb-amount {
  font-family: var(--nb-font-title);
  font-weight: 400;
  font-size: 24px;
}

.nb-muted {
  color: var(--nb-muted);
  font-size: 13px;
}

.nb-rule {
  border: 0;
  border-top: 1px solid var(--nb-sand);
  margin: 18px 0;
}

/* ---------------------------------------------------------------------------
 * Buttons — the primary action is INK, never clay.
 * Clay is for eyebrows, links, selected states and the hold banner. An
 * assistant covered in clay loses its point of entry.
 * ------------------------------------------------------------------------ */

.nb-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--nb-font-ui);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.2;
  padding: 13px 26px;
  border-radius: var(--nb-radius-sm);
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  transition: background 160ms var(--nb-ease), border-color 160ms var(--nb-ease),
    transform 120ms var(--nb-ease);
  /* Touch targets never go under 44px. */
  min-height: 44px;
}

.nb-btn:active {
  transform: scale(0.98);
}

.nb-btn[disabled],
.nb-btn.is-disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
}

.nb-btn--ink {
  background: var(--nb-ink);
  color: var(--nb-paper-bright);
}
.nb-btn--ink:hover {
  background: #000;
  color: var(--nb-paper-bright);
}

.nb-btn--outline {
  background: transparent;
  border-color: var(--nb-sand);
  color: var(--nb-ink);
}
.nb-btn--outline:hover {
  background: var(--nb-paper);
  color: var(--nb-ink);
}

.nb-btn--clay {
  background: transparent;
  border-color: var(--nb-clay);
  color: var(--nb-clay-ink);
}
.nb-btn--clay:hover {
  background: var(--nb-clay-tint);
}

/* The only solid red in the module. Cancelling is the one irreversible thing
   a customer sets off alone, and the amount due is read BEFORE it. */
.nb-btn--danger {
  background: var(--nb-danger);
  color: #fff;
}

.nb-btn--quiet {
  background: transparent;
  color: var(--nb-muted);
  font-weight: 500;
  padding: 13px 8px;
}
.nb-btn--quiet:hover {
  color: var(--nb-ink);
}

/* ⚠️ Le gabarit du site client habille TOUS les <button> : fond, bordure,
   padding. Un lien-bouton en héritait et sortait encadré de gris au milieu
   d'une carte. On remet donc tout à zéro explicitement plutôt que d'espérer. */
.nb-link {
  color: var(--nb-clay-ink);
  text-decoration: none;
  font-weight: 600;
  font-size: 14px;
  font-family: inherit;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  box-shadow: none;
  cursor: pointer;
  min-height: 0;
  line-height: inherit;
}
.nb-link:hover {
  color: var(--nb-clay-ink);
  text-decoration: underline;
}

/* ---------------------------------------------------------------------------
 * State pill — a tinted capsule, a 6px dot, and no other hue than these four.
 * Two axes are shown side by side and never merged: a confirmed booking can
 * be unpaid. The first pill carries the dot, the second does not — that alone
 * ranks them without adding a colour.
 * ------------------------------------------------------------------------ */

.nb-pill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 13.5px;
  font-weight: 500;
  padding: 4px 11px;
  border-radius: var(--nb-radius-pill);
  background: var(--nb-sand-soft);
  color: var(--nb-muted);
  white-space: nowrap;
}

.nb-pill__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}

.nb-pill--success {
  background: var(--nb-success-bg);
  color: var(--nb-success);
}
.nb-pill--warn {
  background: var(--nb-warn-bg);
  color: var(--nb-warn);
}
.nb-pill--danger {
  background: var(--nb-danger-bg);
  color: var(--nb-danger);
}

/* ---------------------------------------------------------------------------
 * Hold banner — "tenu pour vous", with its countdown.
 * The duration is never written in the copy: it comes from
 * Booking Settings.hold_minutes (20 by default) and each merchant sets it.
 * Only the countdown shows a figure.
 * ------------------------------------------------------------------------ */

.nb-hold {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--nb-clay-tint);
  border: 1px solid var(--nb-clay);
  border-radius: 12px;
  padding: 14px 18px;
}

.nb-hold__icon {
  width: 34px;
  height: 34px;
  flex: none;
  border: 1.75px solid var(--nb-clay);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--nb-clay-ink);
}

.nb-hold__body {
  flex: 1 1 auto;
  min-width: 0;
}

.nb-hold__title {
  font-size: 15px;
  font-weight: 600;
}

.nb-hold__note {
  font-size: 13px;
  color: var(--nb-muted);
}

.nb-hold__clock {
  font-family: var(--nb-font-title);
  font-size: 26px;
  color: var(--nb-clay-ink);
  flex: none;
  font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------------------
 * Summary block — one line per element, then a total on paper.
 * ------------------------------------------------------------------------ */

.nb-summary {
  border: 1px solid var(--nb-sand);
  border-radius: 12px;
  overflow: hidden;
}

.nb-summary__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 18px;
  border-top: 1px solid var(--nb-sand);
}

.nb-summary__row:first-child {
  border-top: 0;
}

.nb-summary__total {
  background: var(--nb-paper);
  padding: 16px 18px;
}

.nb-summary__total .nb-amount {
  font-size: 30px;
}

/* Ce qui vient AVEC une prestation se lit sous elle, décalé : la bouteille de
   gaz est une conséquence du barbecue, pas un article qu'on aurait ajouté. */
.nb-summary__row--extra {
  padding-left: 34px;
  border-top-style: dashed;
  color: var(--nb-muted);
}

/* ---------------------------------------------------------------------------
 * Option line — four cases, and they are not interchangeable.
 *
 * `included`  : ticked grey, not clickable, "Compris" spelled out — never
 *               CHF 0.–, which reads as a display error;
 * `mandatory` : ticked ink with a clay label, no cross;
 * per person / per night : the arithmetic is written under the name;
 * free qty    : NO checkbox — the counter is the only control and 0 means
 *               "not taken". Two controls for one state end up contradicting
 *               each other, which is exactly what happened in the first draft
 *               (a cleared box with a counter at 1, counted in the total).
 * ------------------------------------------------------------------------ */

.nb-option {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 14px 16px;
  border: 1px solid var(--nb-sand);
  border-radius: 12px;
  background: var(--nb-paper-bright);
}

.nb-option + .nb-option {
  margin-top: 8px;
}

.nb-option--included {
  background: var(--nb-paper);
}

.nb-option__box {
  width: 20px;
  height: 20px;
  flex: none;
  border: 1px solid var(--nb-sand);
  border-radius: 6px;
  background: var(--nb-paper-bright);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--nb-paper-bright);
  margin-top: 2px;
}

.nb-option__box--on {
  background: var(--nb-ink);
  border-color: var(--nb-ink);
}

.nb-option__box--fixed {
  background: var(--nb-faint);
  border-color: var(--nb-faint);
}

/* The spacer that keeps a counter-only line aligned with its neighbours.
   Without it the row shifts left by the width of the box plus its gap. */
.nb-option__spacer {
  width: 20px;
  flex: none;
}

.nb-option__body {
  flex: 1 1 auto;
  min-width: 0;
}

.nb-option__name {
  font-size: 15px;
  font-weight: 600;
}

.nb-option__tag {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--nb-clay-ink);
  margin-left: 8px;
}

.nb-option__how {
  font-size: 13px;
  color: var(--nb-muted);
}

.nb-option__price {
  flex: none;
  font-size: 15px;
  font-weight: 600;
  white-space: nowrap;
}

.nb-option__price--words {
  font-weight: 500;
  color: var(--nb-muted);
}

.nb-counter {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--nb-sand);
  border-radius: var(--nb-radius-sm);
  overflow: hidden;
  flex: none;
}

.nb-counter button {
  width: 34px;
  height: 34px;
  border: 0;
  background: transparent;
  color: var(--nb-ink);
  font-size: 16px;
  cursor: pointer;
}

.nb-counter button[disabled] {
  color: var(--nb-faint);
  cursor: not-allowed;
}

.nb-counter output {
  min-width: 28px;
  text-align: center;
  font-size: 15px;
  font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------------------
 * Calendar — shared by both modes. What differs is what a day says:
 * a slot mode day is free or not; a period mode day carries how many units
 * are left ("6 dispo").
 * ------------------------------------------------------------------------ */

.nb-cal__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}

.nb-cal__month {
  font-family: var(--nb-font-title);
  font-size: 20px;
}

.nb-cal__nav {
  width: 30px;
  height: 30px;
  border: 1px solid var(--nb-sand);
  border-radius: 8px;
  background: transparent;
  color: var(--nb-ink);
  cursor: pointer;
  line-height: 1;
}

.nb-cal__dow,
.nb-cal__days {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 6px;
}

.nb-cal__dow span {
  text-align: center;
  font-size: 12px;
  color: var(--nb-muted);
  padding-bottom: 4px;
}

.nb-day {
  padding: 8px 0;
  text-align: center;
  font-size: 14px;
  border: 1px solid transparent;
  border-radius: var(--nb-radius-sm);
  background: transparent;
  color: var(--nb-muted);
  cursor: pointer;
  line-height: 1.25;
}

.nb-day__left {
  display: block;
  font-size: 11px;
  color: var(--nb-muted);
}

.nb-day--out {
  color: var(--nb-faint);
  cursor: default;
}

.nb-day--free {
  border-color: var(--nb-sand);
}

.nb-day--full {
  background: var(--nb-paper);
  opacity: 0.5;
  cursor: not-allowed;
}

.nb-day--on {
  background: var(--nb-ink);
  border-color: var(--nb-ink);
  color: var(--nb-paper-bright);
  font-weight: 600;
}

.nb-day--on .nb-day__left {
  color: var(--nb-paper-bright);
  opacity: 0.75;
}

/* Nights between the two ends of a range. */
.nb-day--between {
  background: var(--nb-clay-wash);
  border-color: var(--nb-clay-wash);
  color: var(--nb-clay-ink);
}

.nb-day--blocked {
  border-color: var(--nb-danger);
  color: var(--nb-danger);
}

.nb-legend {
  display: flex;
  align-items: center;
  gap: 16px;
  border-top: 1px solid var(--nb-sand);
  margin-top: 12px;
  padding-top: 10px;
  font-size: 12px;
  color: var(--nb-muted);
}

.nb-legend i {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 3px;
  margin-right: 6px;
  vertical-align: -1px;
}

/* ---------------------------------------------------------------------------
 * Slot — the whole range is shown, not just the start. A customer books an
 * hour, and wants to read when it ends.
 * ------------------------------------------------------------------------ */

.nb-slots {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}

.nb-slot {
  padding: 12px;
  border: 1px solid var(--nb-sand);
  border-radius: var(--nb-radius-sm);
  background: var(--nb-paper-bright);
  text-align: left;
  cursor: pointer;
  min-height: 44px;
}

.nb-slot__time {
  font-size: 15px;
  font-weight: 600;
}

.nb-slot__left {
  font-size: 12px;
  color: var(--nb-muted);
}

.nb-slot--on {
  background: var(--nb-ink);
  border-color: var(--nb-ink);
  color: var(--nb-paper-bright);
}

.nb-slot--on .nb-slot__left {
  color: var(--nb-paper-bright);
  opacity: 0.75;
}

.nb-slot--full {
  background: var(--nb-paper);
  opacity: 0.6;
  cursor: not-allowed;
}

.nb-slot--full .nb-slot__time {
  text-decoration: line-through;
}

/* ---------------------------------------------------------------------------
 * Stepper — each step carries the choice made, in clay, under its name.
 * That is what replaces the cart: the recap builds itself under the
 * customer's eyes instead of living on another page.
 * ------------------------------------------------------------------------ */

.nb-stepper {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.nb-step {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid transparent;
  border-radius: 12px;
}

.nb-step--now {
  background: var(--nb-paper-bright);
  border-color: var(--nb-sand);
}

.nb-step__mark {
  width: 26px;
  height: 26px;
  flex: none;
  border-radius: 50%;
  border: 1px solid var(--nb-sand);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  color: var(--nb-muted);
}

.nb-step--now .nb-step__mark {
  background: var(--nb-ink);
  border-color: var(--nb-ink);
  color: var(--nb-paper-bright);
  font-weight: 600;
}

.nb-step--done .nb-step__mark {
  background: var(--nb-success);
  border-color: var(--nb-success);
  color: var(--nb-paper-bright);
}

.nb-step__label {
  font-size: 15px;
  font-weight: 500;
}

.nb-step--now .nb-step__label {
  font-weight: 600;
}

.nb-step__value {
  font-size: 13px;
  color: var(--nb-clay-ink);
}

/* ---------------------------------------------------------------------------
 * Skeletons — "we are asking about availability", not a spinner. A spinner
 * says the page is busy; these say what is about to appear.
 * ------------------------------------------------------------------------ */

.nb-skel {
  height: 52px;
  border-radius: var(--nb-radius-sm);
  background: var(--nb-sand-soft);
}

.nb-skel + .nb-skel {
  margin-top: 8px;
}

@media (prefers-reduced-motion: no-preference) {
  .nb-skel {
    animation: nb-pulse 1.6s ease-in-out infinite;
  }
  @keyframes nb-pulse {
    0%,
    100% {
      opacity: 1;
    }
    50% {
      opacity: 0.55;
    }
  }
}

/* ---------------------------------------------------------------------------
 * Mobile — the side stepper is a desktop pattern. Below 900px it becomes a
 * progress bar, and the action moves to a bar stuck at the bottom of the frame.
 * ------------------------------------------------------------------------ */

.nb-progress {
  height: 4px;
  border-radius: var(--nb-radius-pill);
  background: var(--nb-sand);
  overflow: hidden;
}

.nb-progress__fill {
  height: 100%;
  background: var(--nb-clay);
  border-radius: var(--nb-radius-pill);
  transition: width 240ms var(--nb-ease);
}

.nb-actionbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  background: var(--nb-paper-bright);
  border-top: 1px solid var(--nb-sand);
  padding: 14px 16px;
}

@media (max-width: 900px) {
  .nb-frame {
    padding: 16px;
  }
  .nb-panel {
    padding: 18px;
  }
  .nb-cal__dow,
  .nb-cal__days {
    gap: 4px;
  }
  .nb-actionbar {
    margin: 4px -16px -16px;
    border-bottom-left-radius: var(--nb-radius-lg);
    border-bottom-right-radius: var(--nb-radius-lg);
  }
  .nb-title {
    font-size: 24px;
  }
  .nb-title--lg {
    font-size: 28px;
  }
  .nb-summary__total .nb-amount {
    font-size: 24px;
  }
  .nb-hold__clock {
    font-size: 22px;
  }
}

/* ---------------------------------------------------------------------------
 * The assistant — the frame that carries the whole booking, from the first
 * choice to the payment. Below 900px the side column goes away: the stepper is
 * a desktop pattern, and the phone gets a progress line instead.
 * ------------------------------------------------------------------------ */

.nba-grid {
  display: grid;
  grid-template-columns: 264px 1fr;
  gap: 24px;
  align-items: start;
}

.nba-side {
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-height: 100%;
}

.nba-house {
  font-family: var(--nb-font-title);
  font-size: 22px;
  line-height: 1.2;
}

/* The foot rises under the stepper rather than the column stretching: three
   steps in a column sized for five would otherwise float. */
.nba-foot {
  margin-top: auto;
  border-top: 1px solid var(--nb-sand);
  padding-top: 14px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.nba-due {
  display: flex;
  flex-direction: column;
  background: var(--nb-paper-bright);
  border: 1px solid var(--nb-sand);
  border-radius: 12px;
  padding: 12px 14px;
}

.nba-panel {
  display: flex;
  flex-direction: column;
  gap: 18px;
  min-height: 420px;
}

.nba-pane {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.nba-when {
  display: grid;
  grid-template-columns: 320px 1fr;
  gap: 24px;
}

.nba-slots {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.nba-with {
  display: flex;
  align-items: center;
  gap: 10px;
}

.nba-fields {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}

.nba-fields label,
.nba-wide {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 13px;
  color: var(--nb-muted);
}

.nba-wide {
  grid-column: 1 / -1;
}

.nba-input {
  /* Le gabarit du site client ne garantit pas `border-box` : sans lui, un champ
     a 100% deborde de sa colonne de la valeur de son padding et de sa bordure. */
  box-sizing: border-box;
  max-width: 100%;
  border: 1px solid var(--nb-sand);
  border-radius: var(--nb-radius-sm);
  padding: 12px 14px;
  font-size: 15px;
  font-family: inherit;
  color: var(--nb-ink);
  background: var(--nb-paper-bright);
  min-height: 44px;
}

.nba-input:focus {
  outline: none;
  border-color: var(--nb-clay);
}

.nba-input::placeholder {
  color: var(--nb-faint);
}

/* "Is that you?" — recognition, never a reproach, and never the word
   "register": the customer is booking, not signing up. */
.nba-known {
  background: var(--nb-clay-tint);
  border: 1px solid var(--nb-clay);
  border-radius: 12px;
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: flex-start;
}

/* Se connecter est une proposition, jamais une condition : le second bouton
   doit être aussi atteignable que le premier. */
.nba-known__row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.nba-known__title {
  font-size: 16px;
  font-weight: 600;
}

.nba-note {
  border-top: 1px solid var(--nb-sand);
  padding-top: 12px;
}

.nba-gate {
  border: 1px dashed var(--nb-clay);
  border-radius: 12px;
  padding: 18px;
  background: var(--nb-paper);
}

.nba-err {
  color: var(--nb-danger);
  font-size: 13px;
}

.nba-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  border-top: 1px solid var(--nb-sand);
  padding-top: 18px;
  margin-top: auto;
}

.nba-actions--center {
  justify-content: center;
}

.nba-done {
  align-items: center;
  text-align: center;
  padding: 24px 0;
}

.nba-check {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: var(--nb-success-bg);
  color: var(--nb-success);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* ---------------------------------------------------------------------------
 * Ce qui va avec — la ligne d'option, et le bloc de questions.
 *
 * Quatre cas tiennent dans la même ligne, et c'est voulu : ce qui est compris,
 * ce qui est obligatoire, ce qui se compte par personne et par nuit, ce qui se
 * prend en quantité. Le lecteur apprend UNE forme et la relit ensuite.
 * ------------------------------------------------------------------------ */

.nba-optlist {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 18px;
}

.nba-opt {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 14px 16px;
  background: var(--nb-paper-bright);
  border: 1px solid var(--nb-sand);
  border-radius: var(--nb-radius-sm);
  cursor: pointer;
  transition: border-color 160ms var(--nb-ease), background 160ms var(--nb-ease);
}

.nba-opt:hover {
  border-color: var(--nb-clay);
}

.nba-opt.is-on {
  border-color: var(--nb-ink);
}

/* Ce qui est imposé ne se donne pas l'air d'un choix : pas de curseur main,
   pas de survol qui invite à cliquer. */
.nba-opt.is-mandatory,
.nba-opt.is-free {
  cursor: default;
}

.nba-opt.is-mandatory:hover,
.nba-opt.is-free:hover {
  border-color: var(--nb-sand);
}

.nba-opt.is-free {
  background: var(--nb-sand-soft);
}

.nba-opt__box {
  width: 20px;
  height: 20px;
  flex: none;
  margin: 2px 0 0;
  border-radius: 6px;
  accent-color: var(--nb-ink);
  cursor: pointer;
}

.nba-opt__box:disabled {
  cursor: default;
}

/* 🔴 L'espaceur d'une ligne à quantité libre. Elle n'a PAS de case — le
   compteur est son seul contrôle — mais sans cette colonne inerte elle se
   décale de 20 px par rapport à toutes les autres, et la pile part de travers. */
.nba-opt__gap {
  width: 20px;
  flex: none;
}

.nba-opt__body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.nba-opt__name {
  font-size: 15px;
  font-weight: 600;
  line-height: 1.3;
}

.nba-opt__desc,
.nba-opt__calc {
  font-size: 13px;
  color: var(--nb-muted);
}

.nba-opt__tag {
  margin-left: 8px;
  font-size: 11px;
  font-style: normal;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--nb-clay-ink);
}

.nba-opt__tag--free {
  color: var(--nb-success);
}

.nba-opt__amount {
  flex: none;
  font-size: 15px;
  font-weight: 600;
  white-space: nowrap;
  padding-top: 1px;
}

/* Le compteur : bordé, jamais rempli. C'est un réglage, pas une action. */
.nba-opt__count {
  flex: none;
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--nb-sand);
  border-radius: var(--nb-radius-sm);
  overflow: hidden;
  background: var(--nb-paper-bright);
}

.nba-opt__step {
  width: 34px;
  height: 34px;
  border: 0;
  background: transparent;
  color: var(--nb-ink);
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
  font-family: inherit;
}

.nba-opt__step:hover {
  background: var(--nb-paper);
}

.nba-opt__step:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

.nba-opt__n {
  min-width: 30px;
  text-align: center;
  font-size: 15px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* Le total des options a sa propre ligne : c'est un chiffre qu'on vérifie,
   pas une mention en bas d'une carte. */
.nba-opttotal {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin-top: 16px;
  padding: 16px 18px;
  background: var(--nb-paper);
  border-radius: var(--nb-radius-sm);
}

/* Le bloc des questions du commerçant — dernier bloc de la même étape, séparé
   par un filet sable comme le demande la maquette. */
.nb-questions {
  margin-top: 24px;
  padding-top: 22px;
  border-top: 1px solid var(--nb-sand);
}

.nb-q-list {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  margin-top: 14px;
}

.nb-q {
  display: flex;
  flex-direction: column;
  gap: 5px;
  font-size: 13px;
  color: var(--nb-muted);
  /* Une réponse longue ne doit pas pousser la colonne : sans ça, un champ
     déborde de la grille au lieu de rétrécir. */
  min-width: 0;
}

.nb-q input,
.nb-q select,
.nb-q textarea {
  width: 100%;
  box-sizing: border-box;
  font-family: var(--nb-font-ui);
  font-size: 15px;
  color: var(--nb-ink);
  background: var(--nb-paper-bright);
  border: 1px solid var(--nb-sand);
  border-radius: var(--nb-radius-sm);
  padding: 11px 13px;
}

.nb-q input:focus,
.nb-q select:focus,
.nb-q textarea:focus {
  outline: none;
  border-color: var(--nb-ink);
}

.nb-q-file {
  color: var(--nb-clay-ink);
  font-size: 12px;
}

@media (max-width: 900px) {
  .nba-grid {
    grid-template-columns: 1fr;
  }
  .nb-q-list {
    grid-template-columns: 1fr;
  }
  /* Sur un téléphone, le nom et le montant ne tiennent plus sur une ligne :
     le compteur passe dessous plutôt que d'écraser le libellé. */
  .nba-opt {
    flex-wrap: wrap;
  }
  .nba-opt__count {
    margin-left: 34px;
  }
  .nba-side {
    min-height: 0;
  }
  /* The stepper is a desktop pattern: on a phone it collapses to the step
     the customer is on, and the choices already made live in the panel. */
  .nba-side .nb-stepper {
    flex-direction: row;
    overflow-x: auto;
  }
  .nba-side .nb-step__value {
    display: none;
  }
  .nba-when {
    grid-template-columns: 1fr;
  }
  .nba-fields {
    grid-template-columns: 1fr;
  }
  .nba-actions {
    position: sticky;
    bottom: 0;
    background: var(--nb-paper-bright);
    margin: 4px -18px -18px;
    padding: 14px 16px;
    border-bottom-left-radius: var(--nb-radius-md);
    border-bottom-right-radius: var(--nb-radius-md);
  }
}
