/* ==========================================================================
   TAYEBOOKS — Composants partagés (v2 « marchande »)
   Boutons, badges, prix, puces de filtre, champs, notices, fil d'Ariane.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Boutons
   Le bouton d'achat est ocre : c'est la seule surface colorée sur laquelle on
   clique pour acheter, et elle se repère sans lire. Le reste est neutre.
   -------------------------------------------------------------------------- */

.tb-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-block-size: var(--tap-target);
  padding: var(--space-3) var(--space-5);
  border: 1px solid var(--color-accent-hover);
  border-radius: var(--radius-lg);
  background-color: var(--color-accent);
  color: var(--tb-ink);
  font-family: inherit;
  font-size: var(--fs-button);
  font-weight: var(--fw-bold);
  line-height: 1;
  text-align: center;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease);
}

.tb-btn:hover,
.tb-btn:focus-visible {
  background-color: var(--color-accent-hover);
  color: var(--tb-white);
}

.tb-btn--ghost {
  background-color: var(--color-background);
  border-color: var(--color-border);
  color: var(--color-text);
}

.tb-btn--ghost:hover,
.tb-btn--ghost:focus-visible {
  background-color: var(--color-surface);
  color: var(--color-text);
}

.tb-btn--block { inline-size: 100%; }
.tb-btn--sm    { min-block-size: 34px; padding: var(--space-2) var(--space-4); font-weight: var(--fw-regular); }

.tb-btn[disabled],
.tb-btn[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}

/* Lien texte bleu — convention du commerce en ligne. */
.tb-link {
  color: var(--color-link);
  font-size: var(--fs-body);
}

.tb-link:hover { text-decoration: underline; }

/* La flèche accompagne le sens de lecture. */
.tb-more::after { content: " \203A"; }
:dir(rtl) .tb-more::after { content: " \2039"; }


/* --------------------------------------------------------------------------
   Puces de filtre. §29, §30
   -------------------------------------------------------------------------- */

.tb-chip {
  display: inline-flex;
  align-items: center;
  min-block-size: 34px;
  padding: var(--space-1) var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  background-color: var(--color-surface);
  font-size: var(--fs-body);
  color: var(--color-text);
  white-space: nowrap;
  transition: background-color var(--dur-fast) var(--ease);
}

.tb-chip:hover { background-color: var(--color-surface-alt); }

.tb-chip.is-on {
  background-color: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-text-invert);
}


/* --------------------------------------------------------------------------
   Badges. §77 — un seul par livre.
   -------------------------------------------------------------------------- */

.tb-badge {
  display: inline-block;
  padding: 2px var(--space-2);
  background-color: var(--color-primary);
  color: var(--color-text-invert);
  font-size: 11px;
  font-weight: var(--fw-bold);
  line-height: 1.5;
  white-space: nowrap;
}

.tb-badge--deal { background-color: var(--color-deal); }
.tb-badge--out  { background-color: var(--color-surface-alt); color: var(--color-text-soft); }

.tb-badge--pinned {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  z-index: var(--z-base);
}


/* --------------------------------------------------------------------------
   Prix
   Le prix est le deuxième élément le plus visible après la couverture.
   -------------------------------------------------------------------------- */

.tb-price {
  font-size: var(--fs-price);
  font-weight: var(--fw-bold);
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
}

.tb-price del {
  font-size: var(--fs-meta);
  font-weight: var(--fw-regular);
  color: var(--color-text-soft);
  margin-inline-end: var(--space-2);
}

.tb-price ins {
  color: var(--color-deal);
  text-decoration: none;
}

.tb-price--lg { font-size: var(--fs-price-lg); }


/* --------------------------------------------------------------------------
   Titres de zone et de rangée
   -------------------------------------------------------------------------- */

.tb-zone__title {
  font-size: var(--fs-zone);
  font-weight: var(--fw-bold);
  margin-block-end: var(--space-1);
}

.tb-rowhead {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  margin-block-end: var(--row-gap);
}

.tb-rowhead__title {
  font-size: var(--fs-row);
  font-weight: var(--fw-bold);
}


/* --------------------------------------------------------------------------
   Champs. §53
   -------------------------------------------------------------------------- */

.tb-field { display: block; margin-block-end: var(--space-4); }

.tb-field__label {
  display: block;
  margin-block-end: var(--space-1);
  font-size: var(--fs-body);
  font-weight: var(--fw-bold);
}

.tb-field__label .required { color: var(--color-deal); text-decoration: none; }

.tb-input,
.tb-select,
.tb-textarea {
  inline-size: 100%;
  min-block-size: var(--tap-target);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background-color: var(--color-background);
  color: var(--color-text);
  /* 15px minimum : en dessous, iOS zoome au focus et décadre la page. §52 */
  font-size: var(--fs-input);
  font-family: inherit;
}

.tb-input:focus-visible,
.tb-select:focus-visible,
.tb-textarea:focus-visible {
  outline: var(--focus-ring) solid var(--color-focus);
  outline-offset: 1px;
}

.tb-input[aria-invalid="true"] { border-color: var(--color-deal); }

.tb-field__error {
  display: block;
  margin-block-start: var(--space-1);
  color: var(--color-deal);
  font-size: var(--fs-meta);
}


/* --------------------------------------------------------------------------
   Notices. §73
   -------------------------------------------------------------------------- */

.tb-notice {
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border);
  border-inline-start: 3px solid var(--color-text);
  background-color: var(--color-surface);
  font-size: var(--fs-body);
}

.tb-notice--success { border-inline-start-color: var(--color-success); }
.tb-notice--warning { border-inline-start-color: var(--color-warning); }
.tb-notice--error   { border-inline-start-color: var(--color-deal); }


/* --------------------------------------------------------------------------
   Fil d'Ariane. §32
   -------------------------------------------------------------------------- */

.tb-breadcrumb {
  font-size: var(--fs-meta);
  color: var(--color-text-soft);
  padding-block: var(--space-3);
}

.tb-breadcrumb a { color: var(--color-link); }
.tb-breadcrumb a:hover { text-decoration: underline; }
.tb-breadcrumb__sep { margin-inline: var(--space-2); color: var(--color-border); }


/* --------------------------------------------------------------------------
   Chargement et états vides. §72, §74, §75
   -------------------------------------------------------------------------- */

.tb-is-loading { opacity: 0.55; pointer-events: none; }

.tb-spinner {
  inline-size: 15px;
  block-size: 15px;
  border: 2px solid currentColor;
  border-block-start-color: transparent;
  border-radius: 50%;
  animation: tb-spin 700ms linear infinite;
}

@keyframes tb-spin { to { transform: rotate(360deg); } }

.tb-empty { padding-block: var(--space-9); text-align: center; }
.tb-empty__title { font-size: var(--fs-page); margin-block-end: var(--space-3); }
.tb-empty__text {
  color: var(--color-text-soft);
  margin-block-end: var(--space-4);
  margin-inline: auto;
  max-inline-size: 46ch;
}

/* Un prix ne se coupe jamais en deux lignes. */
.tb-price { white-space: nowrap; }
.tb-price del { white-space: nowrap; }


/* --------------------------------------------------------------------------
   Rien à afficher
   --------------------------------------------------------------------------
   Panier vide, recherche sans résultat, page 404 : trois pages différentes,
   un même état. Ces classes vivent donc ici, dans la feuille chargée partout,
   et non dans celle d'une seule page — `.tb-empty` a été un temps décrite
   dans cart.css, si bien que la 404 utilisait une classe sans style.
   -------------------------------------------------------------------------- */

.tb-empty {
  max-inline-size: var(--content-max);
  margin-inline: auto;
  padding-block: var(--space-9);
  text-align: center;
}

.tb-empty__title {
  margin-block-end: var(--space-3);
  font-size: var(--fs-page);
  font-weight: var(--fw-bold);
  line-height: var(--lh-tight);
}

.tb-empty__text {
  margin-block-end: var(--space-5);
  font-size: var(--fs-body);
  line-height: var(--lh-relaxed);
  color: var(--color-text-soft);
}

.tb-empty form,
.tb-empty .tb-search {
  margin-block-end: var(--space-5);
  margin-inline: auto;
  max-inline-size: 26rem;
}

/* Mentions courtes et liens de texte, utilisés par plusieurs gabarits. */
.tb-label { font-size: var(--fs-meta); letter-spacing: 0.02em; }
.tb-muted { color: var(--color-text-soft); }

.tb-link {
  color: var(--color-link);
  text-decoration: underline;
}

@media (max-width: 620px) {
  .tb-empty { padding-block: var(--space-7); }
}
