/*
 * This is a manifest file that'll be compiled into application.css.
 *
 * With Propshaft, assets are served efficiently without preprocessing steps. You can still include
 * application-wide styles in this file, but keep in mind that CSS precedence will follow the standard
 * cascading order, meaning styles declared later in the document or manifest will override earlier ones,
 * depending on specificity.
 *
 * Consider organizing styles into separate files for maintainability.
 */

/* ==========================================================================
   TOAST ANIMATIONS
   ========================================================================== */

/* Slide in from right */
@keyframes slide-in-right {
  from {
    transform: translateX(100%);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

/* Slide out to right */
@keyframes slide-out-right {
  from {
    transform: translateX(0);
    opacity: 1;
  }
  to {
    transform: translateX(100%);
    opacity: 0;
  }
}

/* Fade in */
@keyframes fade-in {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Indeterminate progress bar */
@keyframes progress-indeterminate {
  0% {
    width: 0%;
    margin-left: 0%;
  }
  50% {
    width: 50%;
    margin-left: 25%;
  }
  100% {
    width: 0%;
    margin-left: 100%;
  }
}

/* Pulse once for button feedback */
@keyframes pulse-once {
  0%, 100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.05);
  }
}

/* Shimmer effect for skeletons */
@keyframes shimmer {
  0% {
    background-position: -200% 0;
  }
  100% {
    background-position: 200% 0;
  }
}

/* Animation classes */
.animate-slide-in {
  animation: slide-in-right 0.3s ease-out forwards;
}

.animate-slide-out {
  animation: slide-out-right 0.3s ease-in forwards;
}

.animate-fade-in {
  animation: fade-in 0.2s ease-out forwards;
}

.animate-progress-indeterminate {
  animation: progress-indeterminate 1.5s ease-in-out infinite;
}

.animate-pulse-once {
  animation: pulse-once 0.3s ease-in-out;
}

.animate-shimmer {
  background: linear-gradient(90deg, #f1f5f9 25%, #e2e8f0 50%, #f1f5f9 75%);
  background-size: 200% 100%;
  animation: shimmer 1.5s infinite;
}

/* ==========================================================================
   DRAG & DROP IMPROVEMENTS
   ========================================================================== */

/* Smooth transitions for dropzone */
[data-upload-target="dropzone"] {
  transition: all 0.2s ease-out;
}

/* Scale effect when dragging over */
[data-upload-target="dropzone"].scale-\[1\.02\] {
  transform: scale(1.02);
}

/* ==========================================================================
   TOAST CONTAINER POSITIONING
   ========================================================================== */

#toast-container {
  pointer-events: none;
}

#toast-container > * {
  pointer-events: auto;
}

/* ==========================================================================
   PROCESSING STATUS INDICATOR
   ========================================================================== */

/* Pulsing dot for "current step" indicator */
.animate-pulse-dot {
  animation: pulse 1.5s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

/* Status badge transitions */
.status-badge {
  transition: all 0.2s ease-out;
}

/* ==========================================================================
   CARD HOVER EFFECTS
   ========================================================================== */

/* Document cards lift on hover */
.document-card {
  transition: transform 0.2s ease-out, box-shadow 0.2s ease-out, border-color 0.2s ease-out;
}

.document-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
}

/* ==========================================================================
   SCROLLBAR STYLING (for webkit browsers)
   ========================================================================== */

.custom-scrollbar::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

.custom-scrollbar::-webkit-scrollbar-track {
  background: transparent;
}

.custom-scrollbar::-webkit-scrollbar-thumb {
  background: #cbd5e1;
  border-radius: 3px;
}

.custom-scrollbar::-webkit-scrollbar-thumb:hover {
  background: #94a3b8;
}

/* ==========================================================================
   FOCUS RING UTILITIES
   ========================================================================== */

.focus-ring {
  outline: none;
  box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.3);
}

/* ==========================================================================
   SKELETON LOADING
   ========================================================================== */

.skeleton {
  background: linear-gradient(90deg, #f1f5f9 25%, #e2e8f0 50%, #f1f5f9 75%);
  background-size: 200% 100%;
  animation: shimmer 1.5s infinite;
  border-radius: 4px;
}

.skeleton-text {
  height: 1em;
  margin-bottom: 0.5em;
}

.skeleton-text:last-child {
  width: 80%;
}

.skeleton-circle {
  border-radius: 50%;
}

/* ==========================================================================
   BLOG ARTICLE BODY — typography for Markdown rendered into .blog-body
   (Redcarpet HTML; the project has no @tailwindcss/forms/typography plugin)
   ========================================================================== */
.blog-body { color: #334155; font-size: 1.0625rem; line-height: 1.75; }
.blog-body > :first-child { margin-top: 0; }
.blog-body h2 { font-size: 1.75rem; line-height: 1.25; font-weight: 600; color: #0f172a; margin: 2.5rem 0 1rem; letter-spacing: -0.01em; }
.blog-body h3 { font-size: 1.3rem; line-height: 1.3; font-weight: 600; color: #0f172a; margin: 1.75rem 0 0.6rem; }
.blog-body p { margin: 1rem 0; }
.blog-body a { color: #0f172a; text-decoration: underline; text-decoration-color: #bef264; text-underline-offset: 2px; }
.blog-body a:hover { text-decoration-color: #65a30d; }
.blog-body strong { font-weight: 600; color: #0f172a; }
.blog-body ul, .blog-body ol { margin: 1rem 0; padding-left: 1.4rem; }
.blog-body ul { list-style: disc; }
.blog-body ol { list-style: decimal; }
.blog-body li { margin: 0.4rem 0; }
.blog-body li::marker { color: #84cc16; }
.blog-body blockquote { margin: 1.5rem 0; padding: 0.75rem 1.25rem; border-left: 3px solid #84cc16; background: #f7fee7; border-radius: 0 0.5rem 0.5rem 0; color: #3f6212; }
.blog-body blockquote p { margin: 0.25rem 0; }
.blog-body code { background: #f1f5f9; padding: 0.1rem 0.35rem; border-radius: 0.3rem; font-size: 0.9em; }
.blog-body pre { background: #0f172a; color: #f1f5f9; padding: 1rem 1.25rem; border-radius: 0.75rem; overflow-x: auto; margin: 1.5rem 0; }
.blog-body pre code { background: transparent; padding: 0; }
.blog-body hr { border: 0; border-top: 1px solid #e2e8f0; margin: 2.5rem 0; }

/* Comparison tables */
.blog-body table { width: 100%; border-collapse: collapse; margin: 1.75rem 0; font-size: 0.95rem; display: block; overflow-x: auto; }
.blog-body thead { background: #f8fafc; }
.blog-body th, .blog-body td { border: 1px solid #e2e8f0; padding: 0.65rem 0.9rem; text-align: left; vertical-align: top; }
.blog-body th { font-weight: 600; color: #0f172a; }
.blog-body tbody tr:nth-child(even) { background: #f8fafc; }

/* ==========================================================================
   HUB SIDEBAR — full ⇆ mini icon-rail
   ==========================================================================
   The rail is the collapsed state of the SAME markup, not a second sidebar:
   `.is-mini` (set server-side for pages that default to it, toggled client-side
   by hub_sidebar_controller) hides the labels and centres the icons.
   Plain CSS on purpose — Tailwind's JIT only emits classes it can see at build
   time, so classes a controller adds at runtime would come out unstyled. */

.hub-sidebar { width: 16rem; transition: width 200ms ease; }
.hub-sidebar.is-mini { width: 4rem; }

/* Geometry kept in step with the Knowledge cockpit's nav items
   (app/views/knowledge/_nav_section.html.erb): gap-2.5, rounded-lg, px-2.5 py-2.
   The collapsed rail overrides padding and gap below, so it is unaffected. */
.hub-item {
  display: flex; align-items: center; gap: 0.625rem;
  border-radius: 0.5rem; padding: 0.5rem 0.625rem;
  font-size: 15px; font-weight: 500;
}
.hub-sidebar.is-mini .hub-item { justify-content: center; gap: 0; padding: 0.625rem; }

/* Labels and the full-width-only blocks (Récents, the user's name). */
.hub-sidebar.is-mini .hub-label,
.hub-sidebar.is-mini .hub-full-only { display: none; }

/* Keeps the footer pinned to the bottom once Récents is hidden. */
.hub-mini-spacer { display: none; }
.hub-sidebar.is-mini .hub-mini-spacer { display: block; flex: 1 1 0%; }

/* Sous 768 px le rail se replie D'OFFICE : il n'avait aucune media query, et
   256 px sur un écran de 375 laissaient 119 px au contenu. Les pages de
   Réglages qui viennent d'emménager ici (tableaux de membres, clés API) y
   étaient inutilisables. On réapplique les règles .is-mini, qui sont du CSS
   pur — donc rien à ajouter côté JS, et tout le hub en profite. */
@media (max-width: 767px) {
  .hub-sidebar { width: 4rem; }
  .hub-sidebar .hub-item { justify-content: center; gap: 0; padding: 0.625rem; }
  .hub-sidebar .hub-label,
  .hub-sidebar .hub-full-only { display: none; }
  .hub-sidebar .hub-mini-spacer { display: block; flex: 1 1 0%; }
  .hub-sidebar .hub-head { flex-direction: column; gap: 0.375rem; padding-left: 0.5rem; padding-right: 0.5rem; }
  .hub-sidebar .hub-head-actions { flex-direction: column; gap: 0.375rem; }
  .hub-sidebar .hub-nav,
  .hub-sidebar .hub-foot { align-items: center; padding-left: 0.5rem; padding-right: 0.5rem; }
}

/* ── Le tiroir : le cockpit Connaissance, sur téléphone ─────────────────────
   Sous 768 px, le rail de 64 px répond à la mauvaise question. Il économise de
   la largeur, mais il la paie en icônes muettes : « Objectifs & gabarits » et
   « Lacunes & conflits » deviennent deux glyphes qu'il faut avoir déjà appris.
   Sur un module dont la copie dit elle-même de dicter depuis un téléphone,
   c'est la navigation qui disparaît, pas seulement les libellés.

   Le tiroir rend les mots : la barre sort du flux, glisse par-dessus la page
   avec ses libellés entiers, et se referme d'un geste. On ne dispute plus
   119 px au contenu — il a la largeur entière.

   Réservé au cockpit (classe posée par layouts/knowledge.html.erb) : le Hub
   partage ce markup et garde son rail, faute d'avoir été mesuré ici. */
@media (max-width: 767px) {
  .hub-sidebar--drawer {
    position: fixed; inset: 0 auto 0 0; z-index: 40;
    width: 16rem; transform: translateX(-100%);
    transition: transform 200ms ease; box-shadow: 0 10px 15px rgba(15, 23, 42, 0.1);
  }
  .hub-sidebar--drawer.is-open { transform: translateX(0); }

  /* Annule les replis du rail : dans le tiroir, les libellés sont le sujet. */
  .hub-sidebar--drawer .hub-item { justify-content: flex-start; gap: 0.625rem; padding: 0.5rem 0.625rem; }
  .hub-sidebar--drawer .hub-label,
  .hub-sidebar--drawer .hub-full-only { display: revert; }
  .hub-sidebar--drawer .hub-mini-spacer { display: none; }
  .hub-sidebar--drawer .hub-head { flex-direction: row; gap: 0; padding-left: 0.75rem; padding-right: 0.75rem; }
  .hub-sidebar--drawer .hub-head-actions { flex-direction: row; gap: 0.375rem; }
  .hub-sidebar--drawer .hub-nav,
  .hub-sidebar--drawer .hub-foot { align-items: stretch; padding-left: 1rem; padding-right: 1rem; }
}
@media (prefers-reduced-motion: reduce) {
  .hub-sidebar--drawer { transition: none; }
}

/* Header stacks vertically in the rail so the bell and the toggle stay reachable. */
.hub-sidebar.is-mini .hub-head { flex-direction: column; gap: 0.375rem; padding-left: 0.5rem; padding-right: 0.5rem; }
.hub-sidebar.is-mini .hub-head-actions { flex-direction: column; gap: 0.375rem; }
.hub-sidebar.is-mini .hub-nav,
.hub-sidebar.is-mini .hub-foot { align-items: center; padding-left: 0.5rem; padding-right: 0.5rem; }

/* ── Partner portal: focus safety net ─────────────────────────────────────────
   Tailwind implements `ring` as a box-shadow, which Windows forced-colors mode
   strips entirely — a keyboard user there gets no focus indicator at all. An
   `outline` survives it. This is the floor; components may still style focus
   themselves, they just can no longer remove it by omission. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid #4d7c0f; /* lime-700 — 4.99:1 on white, clears the 3:1 minimum */
  outline-offset: 2px;
  border-radius: 0.25rem;
}

@media (forced-colors: active) {
  :where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
    outline: 2px solid CanvasText;
  }
}

/* ── Rendered markdown in the document viewer ──────────────────────────────
   Applied by hub/documents/show only when the document IS markdown (see
   DocumentsHelper#document_markdown?). Tailwind's typography plugin is not
   installed in this project, and the Tailwind reset strips heading and list
   styling, so rendered markdown needs its own rules or it comes out as one
   undifferentiated block. Tables matter as much as headings here: the document
   that surfaced this had 27 table rows. */
.document-prose > * + * { margin-top: 1rem; }

.document-prose h1,
.document-prose h2,
.document-prose h3,
.document-prose h4 { color: #0f172a; font-weight: 600; line-height: 1.3; }
.document-prose h1 { font-size: 1.5rem; margin-top: 2rem; }
.document-prose h2 { font-size: 1.25rem; margin-top: 1.75rem; }
.document-prose h3 { font-size: 1.0625rem; margin-top: 1.5rem; }
.document-prose h4 { font-size: 1rem; margin-top: 1.25rem; }
.document-prose > :first-child { margin-top: 0; }

.document-prose p { line-height: 1.75; }
.document-prose strong { color: #0f172a; font-weight: 600; }
.document-prose em { font-style: italic; }
.document-prose a { color: #1d4ed8; text-decoration: underline; text-underline-offset: 2px; }
.document-prose a:hover { color: #1e40af; }

.document-prose ul,
.document-prose ol { padding-left: 1.5rem; }
.document-prose ul { list-style: disc; }
.document-prose ol { list-style: decimal; }
.document-prose li { margin-top: 0.375rem; line-height: 1.7; }
.document-prose li > ul,
.document-prose li > ol { margin-top: 0.375rem; }

/* Wide tables scroll inside their own box rather than pushing the page. */
.document-prose table {
  display: block; overflow-x: auto; width: 100%;
  border-collapse: collapse; font-size: 0.875rem;
}
.document-prose th,
.document-prose td { border: 1px solid #e2e8f0; padding: 0.5rem 0.75rem; text-align: left; vertical-align: top; }
.document-prose th { background: #f8fafc; color: #0f172a; font-weight: 600; white-space: nowrap; }

.document-prose blockquote {
  border-left: 3px solid #cbd5e1; padding-left: 1rem; color: #475569; font-style: italic;
}
.document-prose code {
  background: #f1f5f9; border-radius: 0.25rem; padding: 0.1rem 0.3rem;
  font-size: 0.875em; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.document-prose pre {
  background: #0f172a; color: #e2e8f0; border-radius: 0.5rem;
  padding: 0.875rem 1rem; overflow-x: auto; font-size: 0.8125rem;
}
.document-prose pre code { background: none; color: inherit; padding: 0; }
.document-prose hr { border: 0; border-top: 1px solid #e2e8f0; margin: 1.75rem 0; }

/* ==========================================================================
   TRIBAL KNOWLEDGE — le langage d'état, et la page qui se remplit
   ==========================================================================
   Un carré de 8 px, cinq formes. Il sert de puce d'état dans le registre, de
   progression au-dessus de la question, et de puce de section dans la page :
   un seul vocabulaire, appris une fois, lu partout.

   Il ne porte JAMAIS l'information seul — le mot l'accompagne toujours
   (« Document créé », « Prêt à rédiger », « En cours »). Une pastille teintée
   qui dit « complété » par sa seule couleur ne dit rien à qui ne la distingue
   pas, et les couleurs de statut sont précisément celles qui se confondent.
   D'où aussi l'attribut title : la forme a un nom accessible.

   Palette : celle du cockpit (slate/lime de Tailwind), pas une nouvelle. */
.tk-mark {
  display: inline-block; width: 8px; height: 8px; flex-shrink: 0;
  border-radius: 2px; vertical-align: middle;
}
/* application.css est chargée APRÈS tailwind.css : sans cette ligne, le
   `display` ci-dessus l'emporte sur `.hidden` et une pastille « masquée »
   reste à l'écran — un carré vert seul, sans le mot qui le rend lisible. */
.tk-mark.hidden { display: none; }
/* acquis */
.tk-mark--done { background: #4d7c0f; }
/* commencé — à moitié rempli, et cerclé pour rester lisible sur fond clair */
.tk-mark--half {
  background: linear-gradient(90deg, #4d7c0f 50%, transparent 50%);
  box-shadow: inset 0 0 0 1px #94a3b8;
}
/* à venir */
.tk-mark--todo { border: 1px solid #94a3b8; }
/* en cours — le seul qui porte un point : c'est ici que la personne écrit */
.tk-mark--now {
  display: inline-flex; align-items: center; justify-content: center;
  border: 1.5px solid #0f172a;
}
.tk-mark--now::after {
  content: ""; width: 3px; height: 3px; border-radius: 1px; background: #0f172a;
}
/* sauté — un tiret, pas un carré : sauter n'est pas un échec, c'est un choix */
.tk-mark--skip { width: 8px; height: 2px; border-radius: 1px; background: #64748b; }
/* dégradé — les questions n'ont pas pu être générées */
.tk-mark--warn { background: #b45309; }

/* La page, à droite : ce qui vient d'être dit s'y allume brièvement.
   220 ms, une seule fois, sans son — c'est la seule notification du module. */
.tk-fresh {
  margin: -4px; border-radius: 6px; padding: 4px;
  background: #f7fee7; transition: background-color 220ms ease;
}

/* La rédaction consomme le texte source : les réponses déjà avalées pâlissent
   l'une après l'autre pendant que le modèle écrit. Purement décoratif — la
   page reste lisible si l'animation ne tourne pas. */
.tk-consumed { animation: tk-consume 2.4s ease-in-out infinite; }
.tk-consumed:nth-child(2) { animation-delay: 0.3s; }
.tk-consumed:nth-child(3) { animation-delay: 0.6s; }
.tk-consumed:nth-child(4) { animation-delay: 0.9s; }
.tk-consumed:nth-child(5) { animation-delay: 1.2s; }
.tk-consumed:nth-child(6) { animation-delay: 1.5s; }
@keyframes tk-consume {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}
@media (prefers-reduced-motion: reduce) {
  .tk-consumed { animation: none; opacity: 0.7; }
  .tk-fresh { transition: none; }
}
