/* ===== Design tokens ===== */
:root {
  --bg: #121110;
  --ink: #F4F1EA;
  --stone: #7A7670;
  --red: #EB0000;
  --red-dark: #A81A13;
  --site-red: #FF2E55;
  --site-red-dark: #C4123A;

  --font-display: 'Space Grotesk', sans-serif;
  --font-body: 'Inter', sans-serif;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

[hidden] {
  display: none !important;
}

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* Keyboard-navigation focus ring, consistent across every button on the
   site. Inputs keep their own border-color + scale treatment instead
   (see .auth-input:focus) since a second ring there would be redundant. */
button:focus-visible {
  outline: 2px solid var(--site-red);
  outline-offset: 2px;
}

/* ===== Top bar ===== */
.topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1.5rem 2rem;
}

.wordmark {
  display: block;
}

.wordmark svg {
  height: 20px;
  width: auto;
  display: block;
}

.stats-link {
  font-family: var(--font-body);
  font-size: 0.85rem;
  color: var(--stone);
  background: none;
  text-decoration: none;
  border: 1px solid #333330;
  border-radius: 999px;
  padding: 0.4rem 1rem;
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease, transform 0.15s ease;
}

.stats-link:hover {
  border-color: var(--site-red);
  color: var(--ink);
}

.stats-link:active {
  transform: scale(0.95);
}

/* ===== Menu view ===== */
.menu-view {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 3rem 1.5rem;
  gap: 2rem;
}

.menu-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.4rem;
}

.category-list {
  list-style: none;
  width: 100%;
  max-width: 26rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.category-row {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  background: #1B1A18;
  border: 1px solid #2A2926;
  border-radius: 14px;
  padding: 0.9rem 1.1rem;
  transition: border-color 0.2s ease, background 0.2s ease;
}

.category-row:hover {
  border-color: #3D3B37;
  background: #201F1C;
}

.swatch {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  flex-shrink: 0;
}

.swatch-placeholder {
  background: repeating-conic-gradient(#4a4a47 0% 25%, #2a2a28 0% 50%) 0 0/8px 8px;
  border: 1px solid #55534f;
}

.category-name {
  flex: 1;
  font-family: var(--font-body);
  font-size: 0.95rem;
  color: var(--ink);
}

.toggle {
  width: 42px;
  height: 24px;
  border-radius: 999px;
  background: #3a3a37;
  border: none;
  cursor: pointer;
  position: relative;
  padding: 0;
  transition: background 0.2s ease;
  flex-shrink: 0;
}

.toggle-knob {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--ink);
  transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.toggle-on {
  background: var(--site-red);
}

.toggle-on .toggle-knob {
  transform: translateX(18px);
}

.stats-link.is-close {
  border-color: var(--site-red);
  color: var(--ink);
  width: 2.1rem;
  padding: 0.4rem 0;
  text-align: center;
}

/* ===== Hero ===== */
.hero {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2.5rem;
  padding: 2rem 1.5rem;
  text-align: center;
}

.hero-kicker {
  font-family: var(--font-body);
  font-size: 0.95rem;
  color: var(--stone);
  max-width: 24rem;
}

.hero-sub {
  font-family: var(--font-body);
  font-size: 0.95rem;
  color: var(--stone);
}

/* Shown instead of a result when the active categories have nothing left
   to draw from (see result.js onSurpriseClick). */
.hero-empty {
  font-family: var(--font-body);
  font-size: 0.9rem;
  color: var(--stone);
  max-width: 22rem;
  animation: auth-field-in 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

/* ===== Signature element: the DZO push-button =====
   Built like a real arcade buzzer, as four stacked layers (see index.html):
   .trail-base    fixed dark bezel with a recessed well the cap sits in
   .trail-halo    a thin light arc that orbits the bezel
   .trail-wall    the cap's side wall -- same colors as the cap, just darker
   .trail-diamond the cap itself (holds .trail-fill + the logo). It's the
                  only layer that moves: it lifts a little on hover and sinks
                  onto its wall when pressed.
   Everything scales off --dzo-size, so the small-screen rule below only has
   to change that one number. */
.trail-button {
  --dzo-size: 200px;
  --cap-rest: -8px; /* the wall sits at the opposite offset, so 16px of it shows at rest */
  position: relative;
  background: none;
  border: none;
  cursor: pointer;
  padding: 1.5rem;
  -webkit-tap-highlight-color: transparent;
}

.trail-base {
  position: absolute;
  left: 50%;
  top: 50%;
  width: calc(var(--dzo-size) * 1.32);
  height: calc(var(--dzo-size) * 1.32);
  margin: calc(var(--dzo-size) * -0.66) 0 0 calc(var(--dzo-size) * -0.66);
  border-radius: 50%;
  background: radial-gradient(circle at 50% 22%, #34312e 0%, #1c1a18 55%, #100f0e 100%);
  box-shadow:
    inset 0 2px 1px rgba(255, 255, 255, 0.14),
    inset 0 -4px 8px rgba(0, 0, 0, 0.55),
    0 0 0 1px rgba(0, 0, 0, 0.9),
    0 22px 34px -10px rgba(0, 0, 0, 0.85),
    0 0 70px -14px color-mix(in srgb, var(--dzo-glow, var(--red)) 60%, transparent);
  animation: base-glow 3.4s ease-in-out infinite;
  pointer-events: none;
}

/* The recessed well the cap sits in. */
.trail-base::before {
  content: '';
  position: absolute;
  inset: 7%;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 70%, #0d0c0b 0%, #050505 100%);
  box-shadow:
    inset 0 8px 14px rgba(0, 0, 0, 0.95),
    inset 0 -1px 2px rgba(255, 255, 255, 0.07),
    0 1px 0 rgba(255, 255, 255, 0.08);
}

@keyframes base-glow {
  0%, 100% {
    box-shadow:
      inset 0 2px 1px rgba(255, 255, 255, 0.14),
      inset 0 -4px 8px rgba(0, 0, 0, 0.55),
      0 0 0 1px rgba(0, 0, 0, 0.9),
      0 22px 34px -10px rgba(0, 0, 0, 0.85),
      0 0 70px -14px color-mix(in srgb, var(--dzo-glow, var(--red)) 60%, transparent);
  }
  50% {
    box-shadow:
      inset 0 2px 1px rgba(255, 255, 255, 0.14),
      inset 0 -4px 8px rgba(0, 0, 0, 0.55),
      0 0 0 1px rgba(0, 0, 0, 0.9),
      0 22px 34px -10px rgba(0, 0, 0, 0.85),
      0 0 95px -6px color-mix(in srgb, var(--dzo-glow, var(--red)) 85%, transparent);
  }
}

/* A comet-like arc (bright head, fading tail) orbiting just outside the
   bezel. The mask cuts the full disc down to a 3px ring. */
.trail-halo {
  position: absolute;
  left: 50%;
  top: 50%;
  width: calc(var(--dzo-size) * 1.44);
  height: calc(var(--dzo-size) * 1.44);
  margin: calc(var(--dzo-size) * -0.72) 0 0 calc(var(--dzo-size) * -0.72);
  border-radius: 50%;
  background: conic-gradient(
    from 0deg,
    transparent 0deg,
    transparent 190deg,
    var(--dzo-glow, var(--red)) 360deg
  );
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 2.5px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 2.5px));
  animation: halo-spin 4.5s linear infinite;
  pointer-events: none;
}

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

/* Its background is set from JS (categories.js) to match .trail-fill, then
   darkened here, so the side wall always has the same hue as the cap --
   including the multi-category rainbow. */
.trail-wall {
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--dzo-size);
  height: var(--dzo-size);
  margin: calc(var(--dzo-size) / -2) 0 0 calc(var(--dzo-size) / -2);
  border-radius: 50%;
  transform: translateY(calc(var(--cap-rest) * -1));
  background: radial-gradient(circle at 35% 30%, var(--red) 0%, var(--red-dark) 100%);
  filter: brightness(0.55) saturate(1.3);
  box-shadow: 0 6px 10px -2px rgba(0, 0, 0, 0.6);
  pointer-events: none;
}

.trail-diamond {
  position: relative;
  width: var(--dzo-size);
  height: var(--dzo-size);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transform: translateY(var(--cap-rest));
  transition: transform 0.12s cubic-bezier(0.3, 0.7, 0.4, 1);
}

.trail-button:hover .trail-diamond {
  transform: translateY(-12px);
}

/* Pressed: the cap drops onto its wall (only ~4px of it left showing),
   squashing a hair wider than tall. */
.trail-button:active .trail-diamond {
  transform: translateY(4px) scale(1.015, 0.985);
  transition-duration: 0.06s;
}

.trail-button:active .trail-fill {
  filter: brightness(0.88);
}

@keyframes buzzer-bounce {
  0% { transform: translateY(4px) scale(1.015, 0.985); }
  45% { transform: translateY(-17px) scale(0.985, 1.015); }
  72% { transform: translateY(-4px); }
  100% { transform: translateY(var(--cap-rest)); }
}

/* Added briefly on release (result.js) so letting go feels like a springy
   rubber button popping back up, not just an instant snap. */
.trail-diamond.buzzer-bounce {
  animation: buzzer-bounce 0.5s cubic-bezier(0.34, 1.3, 0.64, 1) both;
}

/* Holds the actual color fill, separate from .trail-diamond, so a click can
   spin just the colors (see .dzo-loading .trail-fill below) without also
   spinning the logo or the lighting on top. Its background is set from JS
   (categories.js); the one here is only the pre-JS fallback. */
.trail-fill {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  z-index: 0;
  background: radial-gradient(circle at 35% 30%, var(--red) 0%, var(--red-dark) 100%);
  transition: filter 0.1s ease;
}

/* Dome lighting laid over the fill: a crisp rim, darker underside, lighter
   top. Static (not on .trail-fill) so it doesn't spin with the colors. */
.trail-diamond::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  z-index: 0;
  pointer-events: none;
  box-shadow:
    inset 0 0 0 2px rgba(255, 255, 255, 0.16),
    inset 0 -16px 24px rgba(0, 0, 0, 0.32),
    inset 0 8px 14px rgba(255, 255, 255, 0.2);
}

.trail-clip {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

.trail-text {
  position: relative;
  z-index: 1;
  color: var(--ink);
}

.trail-text svg {
  height: 130px;
  width: auto;
  display: block;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.35));
}

/* The glossy reflection near the top of the dome. Lives inside .trail-clip
   (under the logo, which is z-index 1) so it never washes out the logo. */
.trail-clip::before {
  content: '';
  position: absolute;
  top: 5%;
  left: 16%;
  width: 68%;
  height: 40%;
  border-radius: 50% 50% 46% 46% / 62% 62% 38% 38%;
  background: linear-gradient(to bottom, rgba(255, 255, 255, 0.55) 0%, rgba(255, 255, 255, 0.06) 100%);
  pointer-events: none;
}

/* click ripple */
.ripple {
  position: absolute;
  border-radius: 50%;
  background: rgba(244, 241, 234, 0.55);
  transform: scale(0);
  animation: ripple-expand 0.6s ease-out forwards;
  pointer-events: none;
}

@keyframes ripple-expand {
  to {
    transform: scale(2.2);
    opacity: 0;
  }
}

@media (max-width: 480px) {
  .trail-button {
    --dzo-size: 170px;
  }
  .trail-text svg {
    height: 110px;
  }
}

/* ===== Footer ===== */
.foot {
  text-align: center;
  padding: 1.5rem;
  font-family: var(--font-body);
  font-size: 0.8rem;
  color: var(--stone);
}

.foot-link {
  background: none;
  border: none;
  color: var(--stone);
  font-family: var(--font-body);
  font-size: 0.8rem;
  text-decoration: underline;
  cursor: pointer;
  transition: color 0.15s ease;
}

.foot-link:hover {
  color: var(--ink);
}

/* ===== Cookie / local-storage consent banner ===== */
.consent-banner {
  position: fixed;
  left: 1rem;
  right: 1rem;
  bottom: 1rem;
  z-index: 1000;
  max-width: 40rem;
  margin: 0 auto;
  background: #1B1A18;
  border: 1px solid #333330;
  border-radius: 16px;
  padding: 1.1rem 1.25rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
  box-shadow: 0 20px 45px -15px rgba(0, 0, 0, 0.6);
  animation: consent-in 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

@keyframes consent-in {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: translateY(0); }
}

.consent-text {
  flex: 1 1 16rem;
  font-family: var(--font-body);
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--stone);
}

.consent-text-short {
  display: none;
}

.consent-more {
  background: none;
  border: none;
  padding: 0;
  margin-left: 0.3rem;
  color: var(--ink);
  text-decoration: underline;
  font-family: var(--font-body);
  font-size: 0.85rem;
  cursor: pointer;
}

/* Both actions are the same size and equally easy to reach -- refusing
   should never be harder to spot or click than accepting. */
.consent-actions {
  display: flex;
  gap: 0.6rem;
  flex-shrink: 0;
}

.consent-btn {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.85rem;
  padding: 0.55rem 1.1rem;
  border-radius: 999px;
  cursor: pointer;
  transition: transform 0.15s ease, border-color 0.2s ease, background 0.2s ease, filter 0.15s ease;
}

.consent-btn:active {
  transform: scale(0.95);
}

.consent-decline {
  background: none;
  border: 1px solid #333330;
  color: var(--stone);
}

.consent-decline:hover {
  border-color: var(--ink);
  color: var(--ink);
}

.consent-accept {
  background: var(--site-red);
  border: 1px solid var(--site-red);
  color: var(--ink);
}

.consent-accept:hover {
  filter: brightness(0.92);
}

@media (max-width: 480px) {
  .consent-banner {
    left: 0.6rem;
    right: 0.6rem;
    bottom: 0.6rem;
    padding: 0.9rem 1rem;
    gap: 0.75rem;
    flex-direction: column;
    align-items: stretch;
  }
  .consent-text {
    /* .consent-text's base "flex: 1 1 16rem" sizes it along the row
       layout's main axis (width). In this column layout the main axis is
       vertical, so that same 16rem would size its HEIGHT instead and
       force a tall empty block -- reset it to size by content. */
    flex: 0 0 auto;
    font-size: 0.8rem;
  }
  /* The full explanation is redundant with "En savoir plus" (which opens
     the full legal page) once space is this tight -- a one-line summary
     keeps the banner from eating half the screen. */
  .consent-text-full {
    display: none;
  }
  .consent-text-short {
    display: inline;
  }
  .consent-actions {
    gap: 0.5rem;
  }
  .consent-btn {
    flex: 1;
    text-align: center;
    padding: 0.6rem 0.5rem;
  }
}

/* ===== Legal / privacy view ===== */
.legal-view {
  flex: 1;
  display: flex;
  justify-content: center;
  padding: 2rem 1.5rem 3rem;
}

.legal-card {
  width: 100%;
  max-width: 34rem;
  display: flex;
  flex-direction: column;
  gap: 1.4rem;
}

.legal-section {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.legal-heading {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--ink);
}

.legal-section p {
  font-family: var(--font-body);
  font-size: 0.9rem;
  line-height: 1.65;
  color: #C9C6BE;
}

.legal-section a {
  color: var(--site-red);
}

.legal-disclaimer {
  font-family: var(--font-body);
  font-size: 0.78rem;
  line-height: 1.5;
  color: var(--stone);
  font-style: italic;
}

/* ===== Journal link (in menu) ===== */
.journal-link {
  width: 100%;
  max-width: 26rem;
  background: #1B1A18;
  border: 1px solid #2A2926;
  border-radius: 14px;
  padding: 0.9rem 1.1rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  cursor: pointer;
  color: var(--stone);
  transition: border-color 0.2s ease, background 0.2s ease;
}

.journal-link:hover {
  border-color: #3D3B37;
  background: #201F1C;
}

.journal-link svg {
  flex-shrink: 0;
}

.journal-link-text {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  text-align: left;
}

.journal-link-title {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.95rem;
  color: var(--ink);
}

.journal-link-sub {
  font-family: var(--font-body);
  font-size: 0.8rem;
  color: var(--stone);
}

/* ===== Journal view (visited itineraries + canton badges) ===== */
.journal-view {
  flex: 1;
  display: flex;
  justify-content: center;
  padding: 2rem 1.5rem 3rem;
}

.journal-card {
  width: 100%;
  max-width: 34rem;
  display: flex;
  flex-direction: column;
  gap: 1.4rem;
}

.journal-section {
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
}

.badge-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(72px, 1fr));
  gap: 0.9rem 0.6rem;
}

.badge-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  text-align: center;
}

.badge-img {
  width: 100%;
  max-width: 64px;
  aspect-ratio: 1 / 1;
  object-fit: contain;
  transition: filter 0.2s ease, opacity 0.2s ease;
}

.badge-locked .badge-img {
  filter: grayscale(1) brightness(0.4);
  opacity: 0.55;
}

.badge-name {
  font-family: var(--font-body);
  font-size: 0.68rem;
  color: var(--stone);
}

.badge-unlocked .badge-name {
  color: var(--ink);
}

.journal-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.journal-row {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  background: #1B1A18;
  border: 1px solid #2A2926;
  border-radius: 12px;
  padding: 0.7rem 0.9rem;
}

.journal-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
}

.journal-name {
  flex: 1;
  min-width: 0;
  font-family: var(--font-body);
  font-size: 0.88rem;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.journal-date {
  font-family: var(--font-body);
  font-size: 0.78rem;
  color: var(--stone);
  flex-shrink: 0;
}

.journal-loading,
.journal-empty {
  font-family: var(--font-body);
  font-size: 0.85rem;
  color: var(--stone);
}

/* ===== Result view ===== */
.result-view {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem 1.25rem;
}

.result-card {
  width: 100%;
  max-width: 26rem;
  display: flex;
  flex-direction: column;
  animation: card-in 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}

@keyframes card-in {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: translateY(0); }
}

.result-photo {
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 4;
  border-radius: 24px;
  background-color: #1B1A18;
  border: 1px solid #2A2926;
  overflow: hidden;
  box-shadow:
    0 30px 50px -22px var(--cat-color, rgba(0,0,0,0.5)),
    0 12px 28px -14px var(--cat-color-2, rgba(0,0,0,0.4));
}

.result-photo-img {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  /* Fades in once the photo has actually loaded (see result.js) instead of
     popping in or briefly showing a broken-image icon. */
  opacity: 0;
  transition: opacity 0.35s ease;
}

.result-photo.is-loaded .result-photo-img {
  opacity: 1;
}

/* Branded loader shown in the photo slot until the real photo resolves --
   a continuous flowing dash-trace along the wordmark, not a generic spinner.
   Sits above .result-photo-img and fades out once .is-loaded lands. */
.result-photo-loader {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 1;
  transition: opacity 0.3s ease;
  animation: breathe-soft 2.6s ease-in-out infinite;
}

.result-photo.is-loaded .result-photo-loader {
  opacity: 0;
  pointer-events: none;
}

.result-photo-loader svg {
  width: 110px;
  height: auto;
  display: block;
}

.result-photo-loader path {
  stroke-dasharray: 0.16 0.42;
  animation: loader-flow 1.8s linear infinite;
}

@keyframes loader-flow {
  to { stroke-dashoffset: -0.58; }
}

/* Darkens the photo top-to-bottom so the overlaid text stays legible
   regardless of how bright the underlying photo is -- a faint hood at the
   very top (for the category badge) and a heavy pool at the bottom (for
   title/meta/description), with the middle third left clear so the photo
   itself still reads as the hero, not just a texture behind a text block. */
.result-scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    rgba(10, 9, 8, 0.45) 0%,
    rgba(10, 9, 8, 0) 24%,
    rgba(10, 9, 8, 0) 42%,
    rgba(10, 9, 8, 0.6) 66%,
    rgba(10, 9, 8, 0.95) 100%
  );
  pointer-events: none;
}

.result-overlay {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 2rem 1.5rem 1.5rem;
  text-align: left;
}

.result-category {
  display: inline-block;
  background: linear-gradient(135deg, var(--cat-color, #6b6b68), var(--cat-color-2, #3a3a38));
  color: var(--ink);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  padding: 0.35rem 0.7rem;
  border-radius: 999px;
  box-shadow: 0 8px 16px -8px rgba(0, 0, 0, 0.5);
}

.result-name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.7rem;
  margin: 0.6rem 0 0.5rem;
  color: var(--ink);
  text-shadow: 0 2px 16px rgba(0, 0, 0, 0.45);
}

.result-meta {
  font-family: var(--font-body);
  font-size: 0.88rem;
  color: rgba(244, 241, 234, 0.75);
  margin-bottom: 0.65rem;
}

.result-meta .dot {
  margin: 0 0.4rem;
}

.result-desc {
  font-family: var(--font-body);
  font-size: 0.92rem;
  line-height: 1.5;
  color: rgba(244, 241, 234, 0.88);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.result-pending-hint {
  font-family: var(--font-body);
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--stone);
  margin-top: 1rem;
  animation: auth-field-in 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Partner links under the result card (see js/affiliation.js) */
.result-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
  margin-top: 1rem;
}

.aff-link {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 0.85rem;
  color: var(--ink);
  text-decoration: none;
  border: 1px solid #333330;
  border-radius: 999px;
  padding: 0.45rem 1rem;
  transition: border-color 0.2s ease, transform 0.15s ease;
}

.aff-link:hover {
  border-color: var(--cat-color, var(--site-red));
}

.aff-link:active {
  transform: scale(0.96);
}

.aff-note {
  font-size: 0.72rem;
  color: var(--stone);
}

.result-actions {
  display: flex;
  gap: 0.75rem;
  margin-top: 1.25rem;
}

.action-btn {
  flex: 1;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.92rem;
  padding: 0.95rem 1rem;
  border-radius: 14px;
  cursor: pointer;
  border: none;
  transition: transform 0.15s ease, background 0.15s ease;
}

.action-btn:active {
  transform: scale(0.96);
}

.action-no {
  background: #1B1A18;
  border: 1px solid #333330;
  color: var(--stone);
}

.action-no:hover {
  border-color: var(--stone);
  color: var(--ink);
}

.action-yes {
  background: linear-gradient(135deg, var(--cat-color, var(--site-red)), var(--cat-color-2, var(--site-red-dark)));
  color: var(--ink);
}

.action-yes:hover {
  filter: brightness(0.9);
}

@media (max-width: 480px) {
  .result-name {
    font-size: 1.35rem;
  }
}

/* ===== Auth view ===== */
.auth-view {
  position: relative;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem 1.5rem;
  overflow: hidden;
}

.auth-blob {
  position: absolute;
  border-radius: 50%;
  filter: blur(60px);
  opacity: 0.35;
  pointer-events: none;
}

.auth-blob-1 {
  width: 380px;
  height: 380px;
  background: var(--site-red);
  top: -10%;
  left: -12%;
  animation: blob-float-1 9s ease-in-out infinite;
}

.auth-blob-2 {
  width: 300px;
  height: 300px;
  background: #FF7A45;
  bottom: -12%;
  right: -8%;
  animation: blob-float-2 11s ease-in-out infinite;
}

@keyframes blob-float-1 {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(30px, 40px) scale(1.15); }
}

@keyframes blob-float-2 {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(-25px, -30px) scale(1.1); }
}

.auth-mark {
  position: relative;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, var(--site-red) 0%, var(--site-red-dark) 100%);
  margin: 0 auto 1.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink);
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--site-red) 25%, transparent),
    0 12px 24px -8px color-mix(in srgb, var(--site-red) 55%, transparent);
  animation: breathe-soft 3s ease-in-out infinite;
}

.auth-mark svg {
  height: 42px;
  width: auto;
  display: block;
}

@keyframes breathe-soft {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.08); }
}

.auth-card {
  position: relative;
  width: 100%;
  max-width: 22rem;
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  animation: card-in 0.45s cubic-bezier(0.22, 1, 0.36, 1);
  text-align: center;
}

.auth-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.4rem;
  margin-bottom: 0.5rem;
}

.auth-input {
  background: #1B1A18;
  border: 1px solid #333330;
  border-radius: 12px;
  padding: 0.85rem 1rem;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 0.95rem;
  text-align: left;
  transition: border-color 0.2s ease, transform 0.15s ease;
}

.auth-input:focus {
  outline: none;
  border-color: var(--site-red);
  transform: scale(1.01);
}

.auth-google {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  width: 100%;
  background: #1B1A18;
  border: 1px solid #333330;
  border-radius: 12px;
  padding: 0.85rem 1rem;
  color: var(--ink);
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.9rem;
  cursor: pointer;
  transition: border-color 0.2s ease, background 0.15s ease, transform 0.15s ease;
}

.auth-google:hover {
  border-color: var(--stone);
  background: #221F1B;
}

.auth-google:active {
  transform: scale(0.98);
}

.auth-google:disabled {
  opacity: 0.6;
  cursor: default;
  pointer-events: none;
}

.auth-google-icon {
  width: 19px;
  height: 19px;
  flex-shrink: 0;
}

/* Same "or" divider convention as elsewhere in the card: a centered label
   with hairlines filling the rest of the row via ::before/::after. */
.auth-divider {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  color: var(--stone);
  font-family: var(--font-body);
  font-size: 0.8rem;
}

.auth-divider::before,
.auth-divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: #333330;
}

.auth-error {
  color: var(--site-red);
  background: color-mix(in srgb, var(--site-red) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--site-red) 30%, transparent);
  border-radius: 10px;
  padding: 0.6rem 0.85rem;
  font-family: var(--font-body);
  font-size: 0.85rem;
  text-align: left;
  animation: shake 0.4s ease;
}

.auth-consent {
  font-family: var(--font-body);
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--stone);
  text-align: left;
}

.auth-consent .foot-link {
  font-size: inherit;
}

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-4px); }
  75% { transform: translateX(4px); }
}

/* Neutral counterpart to .auth-error -- for confirmations ("email envoyé")
   rather than problems, so it doesn't borrow the red/shake error treatment. */
.auth-notice {
  color: var(--ink);
  background: color-mix(in srgb, var(--stone) 15%, transparent);
  border: 1px solid color-mix(in srgb, var(--stone) 30%, transparent);
  border-radius: 10px;
  padding: 0.6rem 0.85rem;
  font-family: var(--font-body);
  font-size: 0.85rem;
  text-align: left;
  animation: auth-field-in 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

.auth-submit {
  position: relative;
  margin-top: 0.5rem;
  width: 100%;
  background: var(--site-red);
  box-shadow: 0 12px 24px -10px color-mix(in srgb, var(--site-red) 60%, transparent);
  transition: transform 0.15s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.15s ease, filter 0.15s ease;
}

.auth-submit:hover {
  transform: translateY(-2px);
  filter: brightness(0.92);
}

.auth-submit:active {
  transform: translateY(0) scale(0.97);
}

/* Loading state while awaiting the Supabase response: hide the label, spin
   a small ring in its place, and block further clicks. */
.auth-submit.is-loading {
  color: transparent;
  pointer-events: none;
}

.auth-submit.is-loading::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 18px;
  height: 18px;
  margin: -9px 0 0 -9px;
  border: 2px solid rgba(244, 241, 234, 0.35);
  border-top-color: var(--ink);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}

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

/* ===== Auth card entrance: fields cascade in one after another instead of
   the whole card fading in as a single block (delays set inline per field,
   same convention as the quiz-option and category-row stagger). ===== */
.auth-field {
  animation: auth-field-in 0.5s cubic-bezier(0.22, 1, 0.36, 1) both;
}

@keyframes auth-field-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

.auth-switch {
  background: none;
  border: none;
  color: var(--stone);
  font-family: var(--font-body);
  font-size: 0.85rem;
  cursor: pointer;
  margin-top: 0.25rem;
  transition: color 0.15s ease, transform 0.15s ease;
}

.auth-switch:hover {
  color: var(--site-red);
}

.auth-switch:active {
  transform: scale(0.96);
}

.auth-forgot {
  align-self: center;
  margin-top: -0.4rem;
}

/* ===== Quiz view ===== */
.quiz-view {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem 1.5rem;
}

.quiz-card {
  width: 100%;
  max-width: 24rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  animation: card-in 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}

.quiz-progress {
  font-family: var(--font-body);
  font-size: 0.8rem;
  color: var(--stone);
}

.quiz-question {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.3rem;
  margin-bottom: 0.5rem;
}

.quiz-options {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.quiz-option {
  background: #1B1A18;
  border: 1px solid #333330;
  border-radius: 12px;
  padding: 0.9rem 1.1rem;
  text-align: left;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 0.95rem;
  cursor: pointer;
  transition: border-color 0.15s ease, transform 0.15s ease;
}

.quiz-option:hover {
  border-color: var(--site-red);
  transform: translateX(3px);
}

/* ===== Account box (in menu) ===== */
.menu-title-spaced {
  margin-top: 0.5rem;
}

.account-box {
  width: 100%;
  max-width: 26rem;
  background: #1B1A18;
  border: 1px solid #2A2926;
  border-radius: 14px;
  padding: 0.9rem 1.1rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.account-email {
  flex: 1;
  min-width: 0; /* let the flex item actually shrink so ellipsis can kick in */
  font-family: var(--font-body);
  font-size: 0.88rem;
  color: var(--stone);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.account-action {
  background: none;
  border: 1px solid #333330;
  border-radius: 999px;
  padding: 0.4rem 0.9rem;
  color: var(--stone);
  font-family: var(--font-body);
  font-size: 0.82rem;
  cursor: pointer;
  flex-shrink: 0;
  transition: border-color 0.2s ease, color 0.2s ease, transform 0.15s ease;
}

.account-action:hover {
  border-color: var(--site-red);
  color: var(--ink);
}

.account-action:active {
  transform: scale(0.95);
}

/* ===== View transitions ===== */
.view-enter {
  animation: view-in 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}

@keyframes view-in {
  from {
    opacity: 0;
    transform: translateY(14px) scale(0.985);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

/* ===== Row stagger entrance (menu + quiz) ===== */
@keyframes row-in {
  from {
    opacity: 0;
    transform: translateX(-10px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

/* ===== Quiz progress bar ===== */
.quiz-progress-track {
  width: 100%;
  height: 5px;
  border-radius: 999px;
  background: #2A2926;
  overflow: hidden;
  margin-bottom: 0.25rem;
}

.quiz-progress-fill {
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg, var(--site-red), #FF7A45);
  border-radius: 999px;
  transition: width 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

.quiz-option-selected {
  border-color: var(--site-red) !important;
  background: color-mix(in srgb, var(--site-red) 12%, #1B1A18) !important;
  transform: translateX(3px) scale(1.01);
  opacity: 1 !important;
}

.quiz-option {
  transition: border-color 0.15s ease, transform 0.15s ease, opacity 0.2s ease, background 0.15s ease;
}

/* ===== Auth mark wrapper ===== */
.auth-mark-wrap {
  position: relative;
  width: 64px;
  margin: 0 auto 1.5rem;
  perspective: 400px;
}

/* ===== Auth mode switch animation (Connexion <-> Inscription) ===== */
.mode-swap-out {
  animation: mode-swap-out 0.16s ease forwards;
}

.mode-swap-in {
  animation: mode-swap-in 0.3s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}

@keyframes mode-swap-out {
  to {
    opacity: 0;
    transform: translateY(-6px);
  }
}

@keyframes mode-swap-in {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.auth-mark.mode-flip {
  animation: mode-flip 0.5s cubic-bezier(0.45, 0, 0.55, 1);
}

@keyframes mode-flip {
  0% { transform: rotateY(0) scale(1); }
  50% { transform: rotateY(180deg) scale(0.82); }
  100% { transform: rotateY(360deg) scale(1); }
}

/* ===== Auth mark: branded loading state while an account is being created.
   Only the inner arc spins (a ring turning around the glyph); the glyph
   itself never rotates, per the brand's "it's a letter" rule. ===== */
.auth-mark.is-spinning .mark-inner {
  transform-box: view-box;
  transform-origin: 30.6px 69.68px;
  animation: mark-inner-spin 0.85s linear infinite;
}

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

/* ===== Cinematic film grain + vignette overlay ===== */
.film-grain {
  position: fixed;
  inset: -10%;
  width: 120%;
  height: 120%;
  z-index: 999;
  pointer-events: none;
  opacity: 0.05;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='120'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  animation: grain-shift 0.5s steps(4) infinite;
}

@keyframes grain-shift {
  0%   { transform: translate(0, 0); }
  25%  { transform: translate(-2%, 1%); }
  50%  { transform: translate(1%, -2%); }
  75%  { transform: translate(-1%, 2%); }
  100% { transform: translate(0, 0); }
}

.film-vignette {
  position: fixed;
  inset: 0;
  z-index: 998;
  pointer-events: none;
  background: radial-gradient(
    ellipse at center,
    transparent 45%,
    rgba(0, 0, 0, 0.45) 100%
  );
}

/* ===== Menu title row with select-all toggle ===== */
.menu-title-row {
  width: 100%;
  max-width: 26rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.select-all-btn {
  background: none;
  border: 1px solid #333330;
  border-radius: 999px;
  padding: 0.35rem 0.85rem;
  color: var(--stone);
  font-family: var(--font-body);
  font-size: 0.78rem;
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease, transform 0.15s ease;
}

.select-all-btn:hover {
  border-color: var(--site-red);
  color: var(--ink);
}

.select-all-btn:active {
  transform: scale(0.95);
}

/* ===== Loading feedback on DZO press ===== */
.dzo-loading {
  animation: dzo-loading-pulse 0.24s ease-in-out infinite;
}

/* A rapid buzz: the cap vibrates down onto its wall and back. */
@keyframes dzo-loading-pulse {
  0%, 100% { transform: translateY(var(--cap-rest)); filter: brightness(1); }
  50% { transform: translateY(4px) scale(0.985); filter: brightness(1.25); }
}

.trail-button:has(.dzo-loading) .trail-halo {
  animation-duration: 0.6s;
}

/* The color fill itself spins/twists during the loading window, like a
   wheel settling on a result -- independent of the text and glow, which
   stay put (see .trail-fill above). Duration matches the JS loading delay. */
.dzo-loading .trail-fill {
  animation: fill-twist 0.9s cubic-bezier(0.5, 0, 0.25, 1);
}

@keyframes fill-twist {
  from { transform: rotate(0deg); }
  to { transform: rotate(720deg); }
}

/* ===== Category row: gear button ===== */
.category-row {
  gap: 0.6rem;
}

.category-name {
  cursor: pointer;
}

.gear-btn {
  background: none;
  border: none;
  color: var(--stone);
  cursor: pointer;
  padding: 0.3rem;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color 0.15s ease, transform 0.25s ease;
}

.gear-btn svg {
  display: block;
}

.gear-btn:hover {
  color: var(--ink);
  transform: rotate(50deg);
}

.gear-btn:active {
  transform: rotate(50deg) scale(0.88);
}

/* ===== Category settings view ===== */
.cat-settings-view {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem 1.5rem;
}

.cat-settings-card {
  width: 100%;
  max-width: 26rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

/* ===== Back button (category settings, legal page) ===== */
.back-btn {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  background: none;
  border: 1px solid #333330;
  border-radius: 999px;
  padding: 0.4rem 0.9rem 0.4rem 0.65rem;
  color: var(--stone);
  font-family: var(--font-body);
  font-size: 0.85rem;
  cursor: pointer;
  margin-bottom: 0.5rem;
  transition: border-color 0.2s ease, color 0.2s ease, transform 0.15s ease;
}

.back-btn svg {
  display: block;
  flex-shrink: 0;
}

.back-btn:hover {
  border-color: var(--site-red);
  color: var(--ink);
}

.back-btn:active {
  transform: scale(0.95);
}

.cat-settings-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.3rem;
  margin-bottom: 0.5rem;
}

.cat-settings-empty {
  color: var(--stone);
  font-family: var(--font-body);
  font-size: 0.9rem;
}

.cat-field {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.cat-field-label {
  font-family: var(--font-body);
  font-size: 0.85rem;
  color: var(--stone);
}

.cat-field-input {
  width: 100%;
}

.cat-checkbox-group {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.cat-chip {
  background: #1B1A18;
  border: 1px solid #333330;
  border-radius: 999px;
  padding: 0.5rem 0.95rem;
  color: var(--stone);
  font-family: var(--font-body);
  font-size: 0.85rem;
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}

.cat-chip-on {
  border-color: var(--site-red);
  color: var(--ink);
  background: color-mix(in srgb, var(--site-red) 15%, #1B1A18);
}

.cat-settings-save {
  margin-top: 1rem;
  width: 100%;
}

/* ===== Boot splash: one-shot brand animation on first paint =====
   Two variants share the markup (see index.html); only one is ever
   display:block at a time, so only its animation ever actually runs.
   Timing is driven from here -- js/splash.js just waits out the total
   before it fades the whole overlay. */
.boot-splash {
  position: fixed;
  inset: 0;
  z-index: 1200;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
  opacity: 1;
  transition: opacity 0.35s ease;
}

.boot-splash.is-hidden {
  opacity: 0;
  pointer-events: none;
}

.boot-wordmark,
.boot-mark {
  display: none;
  align-items: center;
  justify-content: center;
}

.boot-wordmark svg {
  width: min(60vw, 380px);
  height: auto;
  display: block;
  overflow: visible;
  transform: scale(0.94);
  animation: boot-settle 0.3s cubic-bezier(0.22, 1, 0.36, 1) 0.85s both;
}

.boot-mark svg {
  width: 96px;
  height: auto;
  display: block;
  overflow: visible;
  transform: scale(0.94);
  animation: boot-settle 0.3s cubic-bezier(0.22, 1, 0.36, 1) 0.75s both;
}

.boot-wordmark path,
.boot-mark path {
  stroke-dasharray: 1 1;
  stroke-dashoffset: 1;
  opacity: 0;
  animation: boot-draw 0.4s cubic-bezier(0.22, 1, 0.36, 1) both;
}

@keyframes boot-draw {
  from { stroke-dashoffset: 1; opacity: 0; }
  to   { stroke-dashoffset: 0; opacity: 1; }
}

@keyframes boot-settle {
  from { transform: scale(0.94); }
  to   { transform: scale(1); }
}

@media (max-width: 480px) {
  .boot-mark { display: flex; }
}

@media (min-width: 481px) {
  .boot-wordmark { display: flex; }
}

/* ===== Reduced motion =====
   Nothing on this site checked prefers-reduced-motion before the animated
   logo work above; fixing that site-wide here rather than just for the new
   pieces, since the gap was pre-existing. The boot splash also gets a hard
   display:none, so a reduced-motion visitor never sees a static logo stuck
   over the app waiting on a JS timer it isn't accelerating for them. */
@media (prefers-reduced-motion: reduce) {
  .boot-splash {
    display: none !important;
  }

  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}


/* ===== Result: inline steps ("Tout de suite / Plus tard", "Pas pour moi") ===== */
.result-step {
  margin-top: 1.25rem;
  display: flex;
  flex-direction: column;
  animation: auth-field-in 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}

.result-step .result-actions {
  margin-top: 0.75rem;
}

.step-q {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.02rem;
  color: var(--ink);
}

.step-back,
.step-link {
  align-self: center;
  background: none;
  border: none;
  color: var(--stone);
  font-family: var(--font-body);
  font-size: 0.85rem;
  cursor: pointer;
  margin-top: 0.9rem;
  padding: 0.3rem 0.5rem;
  transition: color 0.15s ease;
}

.step-link {
  align-self: flex-start;
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
  padding-left: 0;
}

.step-back:hover,
.step-link:hover {
  color: var(--ink);
}

.why-options {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin-top: 0.75rem;
}

.why-option {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.15rem;
  width: 100%;
  text-align: left;
  background: #1B1A18;
  border: 1px solid #333330;
  border-radius: 14px;
  padding: 0.9rem 1rem;
  color: var(--ink);
  cursor: pointer;
  transition: border-color 0.15s ease, transform 0.15s ease;
}

.why-option:hover {
  border-color: var(--cat-color, var(--site-red));
}

.why-option:active {
  transform: scale(0.98);
}

.why-label {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.95rem;
}

.why-hint {
  font-family: var(--font-body);
  font-size: 0.8rem;
  color: var(--stone);
}

/* ===== Detail sheet ("Tout de suite") ===== */
.detail-view {
  flex: 1;
  display: flex;
  justify-content: center;
  padding: 1rem 1.5rem 3rem;
}

.detail-card {
  width: 100%;
  max-width: 34rem;
  display: flex;
  flex-direction: column;
  gap: 1.3rem;
  animation: card-in 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}

.detail-name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.9rem;
  line-height: 1.15;
  margin: 0.7rem 0 0.4rem;
}

.detail-meta {
  font-family: var(--font-body);
  font-size: 0.88rem;
  color: var(--stone);
}

.detail-meta .dot {
  margin: 0 0.4rem;
}

.detail-text {
  font-family: var(--font-body);
  font-size: 0.95rem;
  line-height: 1.65;
  color: #DDD9D0;
}

.detail-body {
  display: flex;
  flex-direction: column;
  gap: 1.3rem;
}

.detail-body:empty {
  display: none;
}

.detail-section {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.6rem;
  border-top: 1px solid #262523;
  padding-top: 1.1rem;
}

.detail-list {
  font-family: var(--font-body);
  font-size: 0.92rem;
  line-height: 1.6;
  color: #DDD9D0;
  padding-left: 1.2rem;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.detail-card .result-links {
  margin-top: 0;
}

@media (max-width: 480px) {
  .detail-name {
    font-size: 1.55rem;
  }
}

/* ===== Rating line on the result card ===== */
.result-rating {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 0.82rem;
  color: #FFD166;
  margin-bottom: 0.5rem;
}

/* ===== Reviews in the detail sheet ===== */
.detail-text.muted {
  color: var(--stone);
  font-size: 0.88rem;
}

.review-item {
  width: 100%;
  background: #1B1A18;
  border: 1px solid #2A2926;
  border-radius: 12px;
  padding: 0.75rem 0.9rem;
}

.review-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.3rem;
}

.review-stars {
  color: #FFD166;
  font-size: 0.85rem;
  letter-spacing: 0.08em;
}

.review-date {
  font-size: 0.75rem;
  color: var(--stone);
}

.review-comment {
  font-family: var(--font-body);
  font-size: 0.9rem;
  line-height: 1.55;
  color: #DDD9D0;
  white-space: pre-line;
  overflow-wrap: anywhere;
}

/* ===== Review form (end of an activity) ===== */
.star-row {
  display: flex;
  gap: 0.35rem;
}

.star-btn {
  background: none;
  border: none;
  font-size: 2.1rem;
  line-height: 1;
  color: #34322E;
  cursor: pointer;
  padding: 0.1rem;
  transition: color 0.15s ease, transform 0.15s ease;
}

.star-btn.is-on {
  color: #FFD166;
  text-shadow: 0 0 18px rgba(255, 209, 102, 0.45);
}

.star-btn.pop {
  animation: star-pop 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
}

@keyframes star-pop {
  0% { transform: scale(1); }
  45% { transform: scale(1.45) rotate(-12deg); }
  100% { transform: scale(1); }
}

.review-input {
  width: 100%;
  resize: vertical;
  background: #1B1A18;
  border: 1px solid #333330;
  border-radius: 12px;
  padding: 0.8rem 0.9rem;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 0.92rem;
  line-height: 1.5;
}

.review-input:focus {
  outline: none;
  border-color: var(--cat-color, var(--site-red));
}

.review-note {
  font-size: 0.75rem;
  color: var(--stone);
}

.redo-row {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  width: 100%;
}

.redo-btn {
  width: 100%;
  text-align: left;
  background: #1B1A18;
  border: 1px solid #333330;
  border-radius: 12px;
  padding: 0.8rem 1rem;
  color: var(--ink);
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 0.92rem;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.redo-btn.is-on {
  border-color: var(--cat-color, var(--site-red));
  background: color-mix(in srgb, var(--cat-color, #FF2E55) 14%, #1B1A18);
}

/* ===== Hidden ideas ===== */
.journal-link-second {
  margin-top: 0.6rem;
}

.hidden-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem 0;
  border-bottom: 1px solid #262523;
}

.hidden-row.is-leaving {
  animation: row-out 0.35s ease forwards;
}

@keyframes row-out {
  to { opacity: 0; transform: translateX(24px); }
}

.hidden-text {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  min-width: 0;
}

.hidden-name {
  font-size: 0.92rem;
  color: var(--ink);
}

.hidden-reason {
  font-size: 0.78rem;
  color: var(--stone);
}

.hidden-btn {
  flex-shrink: 0;
  background: none;
  border: 1px solid #333330;
  border-radius: 999px;
  padding: 0.4rem 0.9rem;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 0.82rem;
  cursor: pointer;
}

.hidden-btn:hover {
  border-color: var(--site-red);
}

/* ===== Badge celebration ===== */
.celebrate {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  background: rgba(10, 9, 8, 0.88);
  overflow: hidden;
}

.celebrate.is-on {
  animation: celebrate-in 0.3s ease;
}

@keyframes celebrate-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

.celebrate-rays {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 160vmax;
  height: 160vmax;
  transform: translate(-50%, -50%);
  background: repeating-conic-gradient(from 0deg, rgba(255, 209, 102, 0.09) 0deg 9deg, transparent 9deg 22deg);
  mask-image: radial-gradient(circle, #000 0%, transparent 45%);
  -webkit-mask-image: radial-gradient(circle, #000 0%, transparent 45%);
  animation: rays-spin 18s linear infinite;
}

@keyframes rays-spin {
  to { transform: translate(-50%, -50%) rotate(360deg); }
}

.celebrate-box {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  width: 100%;
  max-width: 20rem;
}

.celebrate-kicker {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #FFD166;
  opacity: 0;
  animation: rise-in 0.5s 0.15s ease forwards;
}

.celebrate-badge {
  position: relative;
  width: 11rem;
  height: 11rem;
  margin: 1rem 0 0.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
}

.celebrate-glow {
  position: absolute;
  inset: -20%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 209, 102, 0.55), rgba(255, 46, 85, 0.15) 45%, transparent 70%);
  animation: glow-pulse 1.8s ease-in-out infinite;
}

@keyframes glow-pulse {
  0%, 100% { transform: scale(0.9); opacity: 0.75; }
  50% { transform: scale(1.1); opacity: 1; }
}

.celebrate-img {
  position: relative;
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter: drop-shadow(0 12px 28px rgba(0, 0, 0, 0.6));
  animation: badge-drop 1s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

@keyframes badge-drop {
  0% { transform: scale(0) rotate(-200deg); opacity: 0; }
  60% { transform: scale(1.18) rotate(12deg); opacity: 1; }
  80% { transform: scale(0.95) rotate(-4deg); }
  100% { transform: scale(1) rotate(0); }
}

.celebrate-name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 2rem;
  color: var(--ink);
  opacity: 0;
  animation: rise-in 0.5s 0.7s ease forwards;
}

.celebrate-progress {
  width: 100%;
  height: 8px;
  border-radius: 999px;
  background: #2A2926;
  margin-top: 1rem;
  overflow: hidden;
  opacity: 0;
  animation: rise-in 0.4s 0.8s ease forwards;
}

.celebrate-bar {
  display: block;
  height: 100%;
  width: 0;
  border-radius: inherit;
  background: linear-gradient(90deg, #FFD166, #FF2E55);
  transition: width 0.9s cubic-bezier(0.22, 1, 0.36, 1);
}

.celebrate-count {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--ink);
  margin-top: 0.6rem;
  opacity: 0;
  animation: rise-in 0.4s 0.9s ease forwards;
}

.celebrate-next {
  font-size: 0.85rem;
  color: var(--stone);
  margin-top: 0.2rem;
  opacity: 0;
  animation: rise-in 0.4s 1s ease forwards;
}

.celebrate-close {
  width: 100%;
  margin-top: 1.5rem;
  opacity: 0;
  animation: rise-in 0.4s 1.2s ease forwards;
}

@keyframes rise-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

.confetti-layer {
  position: absolute;
  top: 42%;
  left: 50%;
  width: 0;
  height: 0;
  pointer-events: none;
}

.confetti {
  position: absolute;
  border-radius: 2px;
  animation: confetti-burst 1.6s cubic-bezier(0.15, 0.7, 0.3, 1) forwards;
}

@keyframes confetti-burst {
  0% { transform: translate(0, 0) rotate(0); opacity: 1; }
  70% { opacity: 1; }
  100% { transform: translate(var(--dx), calc(var(--dy) + 260px)) rotate(var(--rot)); opacity: 0; }
}

/* ===== Toast ===== */
.toast {
  position: fixed;
  left: 50%;
  bottom: 1.5rem;
  z-index: 90;
  transform: translateX(-50%);
  background: #F4F1EA;
  color: #121110;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.9rem;
  padding: 0.7rem 1.2rem;
  border-radius: 999px;
  box-shadow: 0 12px 30px -10px rgba(0, 0, 0, 0.6);
  max-width: calc(100% - 2rem);
  text-align: center;
}

.toast.is-on {
  animation: toast-in 0.45s cubic-bezier(0.34, 1.56, 0.64, 1);
}

@keyframes toast-in {
  from { transform: translate(-50%, 20px) scale(0.9); opacity: 0; }
  to { transform: translate(-50%, 0) scale(1); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .celebrate-rays,
  .celebrate-glow,
  .celebrate-img,
  .star-btn.pop {
    animation: none;
  }
}


/* ===== Menu: "Toutes les idées" as a card link ===== */
a.journal-link {
  text-decoration: none;
}

/* ===== Badge celebration: full-screen extras ===== */
.celebrate-badge {
  width: min(68vw, 20rem);
  height: min(68vw, 20rem);
}

.celebrate-name {
  font-size: clamp(2.2rem, 9vw, 3.4rem);
}

.celebrate-flash {
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 50% 42%, #FFF6D8, rgba(255, 209, 102, 0.6) 30%, transparent 70%);
  opacity: 0;
  pointer-events: none;
}

.celebrate.is-on .celebrate-flash {
  animation: flash 0.9s 0.45s ease-out;
}

@keyframes flash {
  0% { opacity: 0; }
  15% { opacity: 0.9; }
  100% { opacity: 0; }
}

.celebrate-ring {
  position: absolute;
  inset: 10%;
  border-radius: 50%;
  border: 3px solid rgba(255, 209, 102, 0.8);
  opacity: 0;
  pointer-events: none;
}

.celebrate.is-on .celebrate-ring {
  animation: shockwave 1.2s 0.55s cubic-bezier(0.1, 0.7, 0.3, 1);
}

.celebrate.is-on .celebrate-ring.r2 {
  animation-delay: 0.8s;
  border-color: rgba(255, 46, 85, 0.7);
}

@keyframes shockwave {
  0% { transform: scale(0.6); opacity: 1; }
  100% { transform: scale(3.2); opacity: 0; }
}

.celebrate.is-on .celebrate-box {
  animation: screen-shake 0.45s 0.55s ease-in-out;
}

@keyframes screen-shake {
  0%, 100% { transform: translate(0, 0); }
  20% { transform: translate(-6px, 3px); }
  40% { transform: translate(5px, -4px); }
  60% { transform: translate(-4px, 2px); }
  80% { transform: translate(3px, -1px); }
}

.rain-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
}

.rain {
  position: absolute;
  top: -24px;
  border-radius: 2px;
  animation-name: rain-fall;
  animation-timing-function: cubic-bezier(0.3, 0.2, 0.6, 1);
  animation-fill-mode: forwards;
}

@keyframes rain-fall {
  0% { transform: translate(0, 0) rotate(0); opacity: 1; }
  85% { opacity: 1; }
  100% { transform: translate(var(--sway), 110vh) rotate(var(--rot)); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .celebrate.is-on .celebrate-flash,
  .celebrate.is-on .celebrate-ring,
  .celebrate.is-on .celebrate-box {
    animation: none;
  }
}

.celebrate { z-index: 1000; background: rgba(10, 9, 8, 0.94); }
