@import url("/assets/shared-7864dc17.css");
@import url("/assets/public_carts-32b64cc2.css");
@import url("/assets/public_products-f688f9f8.css");
@import url("/assets/desktop-905287de.css");

html {
  margin: 0 2rem;
}

html,
body {
  background-color: var(--color-surface);
  color: var(--color-text);
  font-family: "PT Sans", sans-serif;
  font-style: normal;
  font-weight: 400;
  height: 100%;
  min-height: 100dvh;
  min-height: 100vh;
}

h1,
h2,
h3 {
  /*font-family: "Trade Winds", system-ui;*/
  font-weight: 400;
  font-style: normal;
}

h1 {
  font-size: 2.5rem;
}

h2 {
  font-size: 2rem;
}

h3 {
  font-size: 1.5rem;
}

.input {
  color: var(--color-text-inverted);
}

#main {
  display: flex;
  align-items: flex-start;
}

#view {
  font-size: 1.5rem;
  max-width: 1200px;
  margin: 0 auto;
  min-height: 100vh;
  min-height: 100dvh;
  padding-top: 100px;
  padding-bottom: 20rem;
  width: 100%;
  flex: 1;
  min-width: 0;
  z-index: 10;
  position: relative;
  view-transition-name: main-content;
}

/* ============================================================
   ÉCHELLE PUBLIQUE — .ui-button
   Le corps de texte public tourne à 24px (#view ci-dessus) — bien
   au-dessus de l'échelle fulgore, calibrée pour l'admin (--lg y
   vaut 16px). On ne touche ni aux couleurs, ni au focus-ring, ni
   au radius des variantes fulgore (hérités tels quels depuis
   button.css) : on redéfinit uniquement font-size / padding /
   gap / taille d'icône, et seulement ici.

   Isolation : application.css est chargée par DEUX layouts —
   application.html.erb:19 (public, le vrai layout) ET
   lookbook.html.erb:5 (previews Lookbook, montées en dev via
   routes.rb:2). La garde n'est donc PAS l'exclusivité du fichier :
   lookbook.html.erb n'a pas de wrapper #view, donc #view .ui-button
   n'y matche jamais. Si #view est un jour ajouté à ce layout, les
   previews hériteraient de l'échelle publique. #view existe AUSSI
   dans admin.html.erb:30, mais ce layout charge "admin" (admin.css),
   jamais "application" : l'admin est isolé par le FICHIER chargé,
   pas par le sélecteur. Ne JAMAIS déplacer ce bloc vers shared.css,
   qui est chargé par application.css ET admin.css.
   ============================================================ */
#view .ui-button {
  /* fulgore (button.css) impose font-family: var(--font-family-base),
     mappée sur une pile système par palette.css — on la neutralise
     ici pour hériter PT Sans du body, propre à l'échelle publique. */
  font-family: inherit;
  gap: var(--space-3);
  font-size: var(--font-size-xl);
  padding: var(--space-3) var(--space-6);

  .svg {
    height: var(--space-5);
    min-width: var(--space-5);
    max-width: none;
  }
}

#view .ui-button--sm {
  font-size: var(--font-size-base);
  padding: var(--space-2) var(--space-4);
}

#view .ui-button--lg {
  gap: var(--space-4);
  font-size: var(--font-size-2xl);
  padding: var(--space-4) var(--space-8);

  .svg {
    height: var(--space-6);
    min-width: var(--space-6);
  }
}

.back-link {
  margin: var(--space-12) auto;
  grid-column: span 2;
}

/* Homepage */

#view > #logo {
  width: min(80%, 800px);
  height: auto;
  margin-inline: auto;
  display: block;
}

.links-container {
  display: grid;
  gap: 1rem;
  height: fit-content;
  text-align: center;
}

/* LoginForm */

.admin-login-form {
  border-color: var(--color-border);
  border-radius: 1rem;
  border: 1px var(--color-border) solid;
  margin: 3rem auto;

  form {
    height: 100%;

    .form-inputs-container {
      align-content: center;
      height: 80%;
      margin: 0 auto;
      width: 80%;

      .input-container {
        color: var(--color-text-inverted);
        display: block;
        font-size: 2rem;
        grid-row-gap: 0.5rem;
        margin: 1rem auto;

        .input {
          width: -webkit-fill-available;
        }
      }
    }
    .form-buttons-container {
      text-align: center;
    }
  }
}

/* STATIC_PAGES */

.page-title {
  font-size: 2rem;
  margin: 0 auto;
  text-transform: uppercase;
  width: fit-content;
}

.static-page-container {
  display: grid;
  align-items: center;
  gap: 1rem;
}

.page-body {
  p {
    margin: 1rem 0.5rem;
  }
  ul {
    margin: 1rem 0.5rem 1rem 2rem;
    list-style: disc;
  }
  h3 {
    text-decoration: underline;
  }
}
.page-body.f-1 {
  font-size: 1.5rem;
}

#contact-button {
  display: flex;
  margin: var(--space-8) auto auto auto;
}

.links {
  display: grid;
  gap: var(--space-4);
  margin: var(--space-12) auto 0 auto;
  text-align: center;
  width: fit-content;

  /* Liens sociaux : ni cadre ni fer à gauche (JC, 2026-07-27). Le cadre vient
     de `.ui-button--secondary` (fulgore), neutralisé ici et ici seulement — le
     langage de boutons du reste du site public n'est pas touché. */
  .ui-button {
    border: none;
    justify-content: center;
    width: 12rem;
  }
}

#band {
  margin: 2rem auto;
}

/* GRILLES PUBLIQUES — albums, produits et vidéos */

/* Échelle de colonnes des grilles publiques : POINT DE RÉGLAGE UNIQUE.
   Ne jamais redéclarer grid-template-columns pour .albums-index,
   .products-container ni .videos-index ailleurs — surtout pas dans
   desktop.css ni medias.css, tous deux @importés en TÊTE de ce fichier
   (medias.css via shared.css) : leurs règles sont insérées AVANT ce corps,
   et à spécificité égale c'est ce bloc qui l'emporte. Une media query posée
   là-bas serait annulée en silence (régression 7bce86f : /albums est resté
   bloqué sur une seule colonne jusqu'au 2026-07-27). */
.albums-index,
.products-container,
.videos-index {
  display: grid;
  gap: var(--space-4);
  /* Un seul item par rangée en mobile (JC, 2026-07-27) : à deux colonnes, une
     pochette tombait sous 160 px de large et les titres wrappaient sur trois
     lignes. La 2ᵉ colonne n'arrive qu'à 768 px. */
  grid-template-columns: minmax(0, 1fr);
  margin-top: var(--space-12);
}

@media (min-width: 768px) {
  .albums-index,
  .products-container,
  .videos-index {
    gap: var(--space-6);
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (min-width: 1400px) {
  .albums-index,
  .products-container,
  .videos-index {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* Carte de grille : un seul traitement, pour un album comme pour un produit.
   Aucune surface derrière le visuel — le fond noir de la page porte la
   profondeur, et une carte grise l'aplatissait (JC, 2026-07-27). Les pochettes
   livrées sur carré noir se fondent donc dans la page : c'est voulu. */
.album-item,
.product-item,
.video-item {
  border-radius: var(--radius-md);
  padding: var(--space-3);
  transition: box-shadow var(--duration-normal) ease;

  &:hover {
    box-shadow: 0 4px 20px rgba(255, 255, 255, 0.08);
  }
}

/* Le lien remplit la carte : c'est lui qui aligne les prix d'une même rangée.
   Chaque enfant porte sa piste explicitement, pour que l'absence de statut ne
   décale rien. */
.album-link,
.product-link,
.video-link {
  color: inherit;
  display: grid;
  /* minmax(0, 1fr) et non `auto` : une colonne de grille implicite se
     dimensionne au max-content, et WebKit laisse alors l'image déborder sa
     carte (mesuré : 211 px dans une carte de 155 px). */
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-2);
  height: 100%;
  line-height: 1.3;
  text-decoration: none;
}

.album-link,
.video-link {
  grid-template-rows: auto 1fr;
}

/* image · statut · titre (extensible) · prix.
   La ligne « statut » garde une hauteur minimale même vide : sans elle, elle se
   replie à 0 sur les produits sans pastille et les titres se décalent de 25 px
   d'une carte à l'autre. `var(--space-6)` vaut exactement la marge négative de
   la pastille, donc la ligne réserve ce que la pastille occupe réellement.
   ⚠️ Ne PAS chercher à superposer la pastille et l'image dans la même cellule :
   éprouvé le 2026-07-27, WebKit écrase alors la piste de l'image (242 px → 90)
   dès qu'un second élément partage la cellule. */
.product-link {
  grid-template-rows: auto minmax(var(--space-6), auto) 1fr auto;
}

.album-item .main-picture,
.product-item .main-picture {
  display: block;
  grid-row: 1;
}

.album-item .main-picture img,
.product-item .main-picture img {
  aspect-ratio: 1 / 1;
  border-radius: var(--radius-md);
  display: block;
  object-fit: cover;
  width: 100%;
}

/* La pastille partage la ligne 1 avec l'image : c'est un CALQUE sur le bas du
   visuel, pas une ligne de la carte. Lui donner sa propre ligne la ferait se
   replier à 0 sur les produits sans statut, et les titres se décalaient alors
   de 25 px d'une carte à l'autre (mesuré à 1440 : 491 contre 466).
   `max-width` + `padding-inline` la contiennent : dimensionnée par son texte
   (`width: fit-content` + `padding-inline: var(--space-8)` dans
   public_products.css), « Précommande » débordait sur la carte voisine à
   390 px. */
.product-item .product-status {
  grid-row: 2;
  max-width: 100%;
  padding-inline: var(--space-3);
}

/* Titres de carte : sous la taille du visuel qu'ils légendent. Scopé aux
   grilles — .product-title sert AUSSI la fiche produit et la ligne de panier,
   qui ne doivent pas bouger. */
.albums-index .album-title,
.products-container .product-title,
.videos-index .video-title {
  align-self: start;
  font-size: var(--font-size-xl);
  line-height: 1.3;
  margin: 0;
  padding-top: 0;
  text-align: center;
}

.albums-index .album-title {
  grid-row: 2;
}

.products-container .product-title {
  grid-row: 3;
}

.product-item .current-price {
  grid-row: 4;
}

.videos-index .video-title {
  grid-row: 2;
}

/* Couverture vidéo : emboîtement absolu, et NON l'aspect-ratio-sur-l'image
   des pochettes. Trois raisons, toutes vérifiées :
   1. les couvertures sont en 16/9 (1280×720, 480×360) — les rogner en carré
      coûterait 44 % de la largeur sur un plan live rarement centré ;
   2. une vidéo sans couverture garde sa boîte au lieu de se replier sur son
      texte alternatif ;
   3. `inset: 0` neutralise le `style="aspect-ratio:4/3"` INLINE que
      UI::Display::Picture#dev_placeholder pose en développement — sans quoi
      la vignette rendrait 4/3 en dev quoi qu'on déclare ici.
   Motif repris tel quel de .public-videos-facade (app/components/public/videos/
   facade.css), déjà éprouvé sur ces mêmes images. */
.video-cover {
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-md);
  display: block;
  grid-row: 1;
  overflow: hidden;
  position: relative;
}

/* Cible à la fois <picture> et <img> : UI::Display::Picture porte la même
   classe sur les deux. */
.video-item .main-picture {
  display: block;
  height: 100%;
  inset: 0;
  position: absolute;
  width: 100%;
}

.video-item img.main-picture {
  object-fit: cover;
}

/* Calque de lecture, posé DANS .video-cover et non dans une cellule de
   grille : la superposition en cellule écrase la piste de l'image en WebKit
   (cf. l'avertissement de .product-link plus haut). Purement décoratif —
   le lien est déjà lu par le titre de la vidéo.
   rgba volontaire : le picto flotte sur une couverture arbitraire, claire ou
   sombre selon la vidéo, jamais sur un fond connu. */
.video-play {
  align-items: center;
  background: rgba(0, 0, 0, 0.55);
  border-radius: var(--radius-full);
  color: var(--color-text);
  display: flex;
  height: var(--space-12);
  justify-content: center;
  left: 50%;
  pointer-events: none;
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  transition: background var(--duration-fast) var(--easing-default);
  width: var(--space-12);
  z-index: var(--z-raised);
}

.video-link:hover .video-play,
.video-link:focus-visible .video-play {
  background: rgba(0, 0, 0, 0.7);
}

.video-play .play-icon {
  height: var(--icon-size-md);
  width: var(--icon-size-md);
}

/* NAVIGATION */

#navbar {
  align-items: center;
  background-color: var(--color-surface);
  color: var(--color-text);
  display: grid;
  grid-template-columns: auto 1fr;
  height: 90px;
  left: 0;
  position: fixed;
  text-align: center;
  top: 0;
  width: 100%;
  z-index: 1000;
  view-transition-name: navbar;

  .logo-toggle {
    background: none;
    border: none;
    cursor: pointer;
    padding: 0.5rem 1rem;
    display: flex;
    align-items: center;

    #logo {
      height: 70%;
      width: 5rem;
    }
  }

}

#cart-wrapper {
  margin-left: auto;
  padding-right: 1.5rem;
  position: relative;
  display: flex;
  align-items: center;

  #cart-button {
    padding: 0;
    border: none;
    background: none;
    cursor: pointer;
  }

  svg {
    height: 3rem;
    width: 3rem;
  }

  #cart-counter {
    background-color: var(--color-text);
    color: var(--color-text-inverted);
    border-radius: 9999px;
    font-size: 0.85rem;
    font-weight: 700;
    line-height: 1;
    min-width: 1.5rem;
    height: 1.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 0.4rem;
    position: absolute;
    top: -0.5rem;
    right: 1rem;
    pointer-events: none;
  }
}

/* ORDERS */

#checkout {
  .public-orders-news-consent-form,
  .preorder-message {
    margin: 3rem auto;
    text-align: center;
  }
}

#comment-thanks,
#comment {
  text-align: center;
  margin: 3rem auto;

  .leave-comment {
    margin: 3rem auto 1rem auto;
  }
}
#comment-thanks {
  font-size: 3rem;
}

#success {
  #message {
    text-align: center;

    .icon {
      font-size: 3rem;
    }
  }

  .email-sent {
    text-align: center;
  }
}

/* UI */

.facebook,
#bandcamp,
#instagram,
#spotify {
  height: 2rem;
}

/* USERS */


/* ERRORS */

.public-errors-address-error,
.public-errors-country-error,
.public-errors-cart-error,
.public-errors-error500,
.public-errors-error404 {
  text-align: center;
}

.album-show {
  .accordion-section {
    font-size: 2rem;
    margin: 1rem;
    padding: 1rem 0;

    .collapsible-header {
      border-bottom: 1px solid var(--color-border-strong);
      margin-bottom: 2rem;
    }
  }
  .public-albums-making-of {
    .container {
      display: grid;
      gap: 2rem;
    }
    .public-image {
      display: grid;
      gap: 1rem;
    }
  }
  .share-buttons {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    width: fit-content;
    margin-left: auto;
  }
  .public-albums-products {
    .container {
      display: grid;
      gap: 2rem;
    }
    .product-show {
      border-bottom: 1px solid var(--color-border-strong);

      .product-title {
        display: none;
      }
    }
  }
}
