    /* ─── Castflow UI motion kit ──────────────────────────────────────────────
       Reusable hover / focus / active states + entrance animations.
       Built first for the onboarding flow but designed to spread to every
       button site-wide (`.cf-btn-primary`, `.cf-btn-secondary`, `.cf-btn-ghost`).
       Respects prefers-reduced-motion for accessibility. */
    @keyframes cfFadeIn   { from { opacity: 0; }                              to { opacity: 1; } }
    @keyframes cfSlideUp  { from { opacity: 0; transform: translateY(12px); }  to { opacity: 1; transform: translateY(0); } }
    @keyframes cfPopIn    { from { opacity: 0; transform: scale(.96); }        to { opacity: 1; transform: scale(1); } }
    @keyframes cfShimmer  { 0% { background-position: -240px 0; } 100% { background-position: 240px 0; } }
    @keyframes cfPulse    { 0%,100% { box-shadow: 0 0 0 0 rgba(0,106,133,.35); } 50% { box-shadow: 0 0 0 8px rgba(0,106,133,0); } }

    /* Base button — adds smooth transitions + a focus ring without
       overriding visual styles (so inline styles still win on color/size). */
    .cf-btn {
      transition: transform .18s cubic-bezier(.2,.7,.3,1),
                  box-shadow .22s ease,
                  background-color .18s ease,
                  border-color .18s ease,
                  color .18s ease,
                  filter .18s ease;
      will-change: transform, box-shadow;
      -webkit-user-select: none; user-select: none;
    }
    .cf-btn:focus-visible {
      outline: none;
      box-shadow: 0 0 0 3px rgba(0,106,133,.28);
    }
    .cf-btn:active { transform: translateY(0) scale(.98); }
    .cf-btn[disabled], .cf-btn[aria-disabled="true"] {
      opacity: .55; cursor: not-allowed; transform: none !important; box-shadow: none !important;
    }

    /* Primary (teal): lift + tinted shadow + slight brightness bump on hover. */
    .cf-btn-primary:hover {
      transform: translateY(-1px);
      box-shadow: 0 8px 18px -8px rgba(0,106,133,.55), 0 2px 4px rgba(0,106,133,.18);
      filter: brightness(1.06);
    }
    /* Secondary / outline: warm the surface and darken the border on hover. */
    .cf-btn-secondary:hover {
      transform: translateY(-1px);
      background-color: #f0f7f9 !important;
      border-color: #006a85 !important;
      color: #004a5e !important;
      box-shadow: 0 6px 14px -8px rgba(15,23,42,.18);
    }
    /* Ghost / text-only: subtle teal tint on hover. */
    .cf-btn-ghost:hover {
      background-color: rgba(0,106,133,.07) !important;
      color: #006a85 !important;
    }
    /* Exception - the "Mes outils" tiles. They already carry a pastel pastille
       behind the icon, so the ghost tint drew a second, square surface behind it:
       the grey rectangle. Only the label turning teal is kept.
       The dark selector repeats the class (0,4,1) to beat the
       `body.dark-theme .cf-btn-ghost:hover` (0,3,1) that 09a_ui_core.js injects
       after this stylesheet - see the specificity note there. */
    .cf-tool-tile:hover,
    body.dark-theme .cf-tool-tile.cf-tool-tile:hover {
      background-color: transparent !important;
    }
    /* Exception - the selected sidebar row that fills solid teal (Decouverte).
       It paints #007692 inline while its label keeps an inline color:#fff, and
       the ghost tint above is !important - so hovering swapped the teal for a
       7% wash and left white text on near-white. Keep a teal surface and just
       darken it one notch, which is the hover feedback the row needs anyway.
       Doubled class (0,4,1) beats the dark-theme ghost override injected later
       by 09a_ui_core.js. */
    .cf-nav-solid:hover,
    body.dark-theme .cf-nav-solid.cf-nav-solid:hover {
      background-color: #006a85 !important;
    }
    /* CFT-1597: the wizard's blue bottom-right "next" button (.floating-nav-arrow.right,
       always ALSO .cf-btn-ghost — see the comment on .cf-btn-ghost:hover above) sits
       over the talent-photo grid on the Talents/Tri step only, where its ordinary 7%
       teal wash hover blends straight into the photos behind it. renderFloatingNav()
       (10_app_core.js) adds .cf-nav-tri to that one button ONLY while state.step is
       the Tri step (wizardTriStep()) — every other wizard page keeps today's
       translucent hover untouched. Doubled class on the dark selector for the same
       reason as .cf-nav-solid just above: it needs to outrank
       body.dark-theme .cf-btn-ghost:hover, injected by 09a_ui_core.js AFTER this
       stylesheet. Text goes dark teal, not black, to stay on-brand on the white fill. */
    .floating-nav-arrow.cf-nav-tri:hover,
    body.dark-theme .cf-nav-tri.cf-nav-tri:hover {
      background-color: #ffffff !important;
      color: #004a5e !important;
      box-shadow: 0 3px 10px rgba(15, 23, 42, 0.18);
    }
    /* Destructive: red lift. */
    .cf-btn-destructive:hover {
      transform: translateY(-1px);
      background-color: #b91c1c !important;
      box-shadow: 0 8px 18px -8px rgba(185,28,28,.55);
    }

    /* Clickable cards: gentle lift + teal-tinted shadow on hover. */
    .cf-card-hover {
      transition: transform .22s cubic-bezier(.2,.7,.3,1),
                  box-shadow .22s ease,
                  border-color .18s ease;
    }
    .cf-card-hover:hover {
      transform: translateY(-3px);
      box-shadow: 0 14px 28px -16px rgba(15,23,42,.18), 0 2px 6px rgba(15,23,42,.06);
      border-color: rgba(0,106,133,.55) !important;
    }

    /* Entrance animations applied per element or per group. */
    .cf-fade-in   { animation: cfFadeIn  .35s ease both; }
    .cf-slide-up  { animation: cfSlideUp .45s cubic-bezier(.2,.7,.3,1) both; }
    .cf-pop-in    { animation: cfPopIn   .35s cubic-bezier(.2,.7,.3,1) both; }
    /* Step container: header slides + each child appears with a small stagger. */
    .cf-step-enter > *                            { animation: cfSlideUp .45s cubic-bezier(.2,.7,.3,1) both; }
    .cf-step-enter > *:nth-child(1)               { animation-delay: 0ms;   }
    .cf-step-enter > *:nth-child(2)               { animation-delay: 70ms;  }
    .cf-step-enter > *:nth-child(3)               { animation-delay: 140ms; }
    .cf-step-enter > *:nth-child(4)               { animation-delay: 210ms; }
    .cf-step-enter > *:nth-child(5)               { animation-delay: 280ms; }

    /* Active stepper dot subtly pulses to draw the eye to "you are here". */
    .cf-stepper-active { animation: cfPulse 2.2s ease-in-out infinite; }

    /* Inputs: focus ring matches the button focus style for consistency. */
    .cf-input {
      transition: border-color .18s ease, box-shadow .22s ease, background-color .18s ease;
    }
    .cf-input:focus, .cf-input:focus-visible {
      outline: none;
      border-color: #006a85 !important;
      box-shadow: 0 0 0 3px rgba(0,106,133,.18);
    }

    /* On/off pill switch — a visual skin over a REAL <input type=checkbox> (the
       checkbox stays the functional source of truth; JS reads its .checked). The
       Oui/Non text flips purely via :checked, no JS. Teal #006a85 on-state. */
    .cf-switch { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; user-select: none; }
    .cf-switch input { position: absolute; opacity: 0; width: 0; height: 0; margin: 0; }
    .cf-switch-slider {
      position: relative; width: 34px; height: 20px; flex-shrink: 0;
      border-radius: 999px; background: #d1d5db; transition: background .15s ease;
    }
    .cf-switch-slider::after {
      content: ''; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px;
      border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,.25);
      transition: transform .15s ease;
    }
    .cf-switch input:checked + .cf-switch-slider { background: #006a85; }
    .cf-switch input:checked + .cf-switch-slider::after { transform: translateX(14px); }
    .cf-switch input:focus-visible + .cf-switch-slider { box-shadow: 0 0 0 3px rgba(0,106,133,.28); }
    .cf-switch-txt::after { content: attr(data-off); font-size: 12px; font-weight: 600; color: #9ca3af; }
    .cf-switch input:checked ~ .cf-switch-txt::after { content: attr(data-on); color: #111827; }
    @media (prefers-reduced-motion: reduce) {
      .cf-switch-slider, .cf-switch-slider::after { transition: none !important; }
    }

    /* Respect users who asked the OS to reduce motion — kill animations and
       transitions so the hover/entrance UX collapses to a flat (but accessible)
       state. Never override a user accessibility setting. */
    @media (prefers-reduced-motion: reduce) {
      .cf-btn, .cf-btn:hover,
      .cf-card-hover, .cf-card-hover:hover,
      .cf-fade-in, .cf-slide-up, .cf-pop-in,
      .cf-step-enter > *, .cf-stepper-active, .cf-input {
        animation: none !important;
        transition: none !important;
        transform: none !important;
      }
    }

    * {
      font-family: 'Inter', sans-serif;
    }

