/**
 * local_kid design system.
 * Scoped entirely under body.local-kid-app so it never leaks into the rest
 * of Moodle (other plugins, the site header/drawer, other users' pages).
 * Tokens reproduce the InterfaceEvaluation_observations React prototype's
 * DSFR-inspired palette (theme.css), adapted for server-rendered Mustache.
 */

@font-face {
  font-family: "Source Sans 3";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("fonts/SourceSans3-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122;
}

@font-face {
  font-family: "Source Sans 3";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("fonts/SourceSans3-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1E00-1E9F, U+2020, U+2C60-2C7F, U+A720-A7FF;
}

body.local-kid-app {
  --kid-primary: #000091;
  --kid-primary-contrast: #FFFFFF;
  --kid-bg: #F5F5F5;
  --kid-card: #FFFFFF;
  --kid-border: #DDDDDD;
  --kid-border-light: #EEEEEE;
  --kid-row-alt: #F8F8F8;
  --kid-text: #1E1E1E;
  --kid-muted: #6B6B6B;
  --kid-faint: #AAAAAA;
  --kid-success: #1D6B23;
  --kid-danger: #CE0500;
  --kid-accent-bg: #E8E8F4;
  --kid-sidebar-bg: #1B1B35;
  --kid-sidebar-active: #000091;
  --kid-sidebar-text: rgba(255, 255, 255, 0.7);
  --kid-sidebar-text-strong: #FFFFFF;
  --kid-radius: 0.25rem;
  --kid-font: "Source Sans 3", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  background: var(--kid-bg);
}

/* Note d'implémentation (section 28 du cahier des charges) : ce fichier ne
   redéfinit jamais de sélecteur global (body, table, a, ...) hors de
   `body.local-kid-app` — la chrome Moodle standard (en-tête, tiroir de
   navigation, pied de page) reste inchangée ; seule la zone de contenu du
   plugin adopte ce langage visuel. */

/* :not(.icon) so this never overrides Font Awesome glyphs (Moodle usually
   tags its <i> icons with the "icon" class, e.g. the Atto editor toolbar
   embedded by moodleform textareas rendered inside this region) — an icon
   glyph is a Unicode codepoint meaningless outside its icon font.
   :not(.fa) covers the exception: the filepicker's drag-and-drop markup
   (core_renderer::render_from_template's raw <i class="fa fa-arrow-circle-
   o-down fa-3x m-auto">, no "icon" class — found 2026-08-26 on
   eval_import.php/stage_import.php/capp_import_*.php, where the glyph
   rendered invisible because Source Sans 3 has no character at that
   codepoint) skips the "icon" class Moodle normally adds. Same defensive
   reasoning as the .fr-scope :not(.icon) below.
   :not(.fr-scope):not(.fr-scope *) carves out screens migrated to the real
   DSFR (see thirdparty/dsfr): without it this rule's own specificity
   (0,3,0) beats DSFR's scoped component rules (.fr-btn, .fr-input, ..., all
   (0,1,0)-(0,2,0)) regardless of load order, forcing Source Sans 3 onto
   DSFR buttons/inputs instead of Marianne. */
.local-kid-app .kid-region,
.local-kid-app .kid-region *:not(.icon):not(.fa):not(.fr-scope):not(.fr-scope *) {
  font-family: var(--kid-font);
}

/* A migrated screen's root carries .fr-scope (see templates using real
   fr-* classes) so its whole subtree inherits DSFR's own Marianne stack —
   .kid-region above still sets Source Sans 3 on ancestors outside the
   excluded subtree, so plain (non fr-*-classed) elements inside .fr-scope,
   e.g. a <td> in a migrated table, need this explicit re-assertion rather
   than just being excluded above. Value copied from thirdparty/dsfr's own
   compiled font-family declaration — keep in sync if the DSFR version
   bump ever changes it.
   :not(.icon) here too (found 2026-08-21, capp_grid.mustache's fr-scope
   wrapping Moodle's native collapsible fieldset headers): without it, this
   rule's `.fr-scope *` branch reaches Moodle core's own FontAwesome toggle
   glyphs (icon fa fa-chevron-down, the déplier/replier chevron on every
   collapsible fieldset) same as the .kid-region rule above would without
   its own :not(.icon) — Marianne has no glyph at that codepoint, so the
   chevron rendered as a fallback tofu box instead of an arrow. */
.local-kid-app .kid-region .fr-scope,
.local-kid-app .kid-region .fr-scope *:not(.icon) {
  font-family: Marianne, arial, sans-serif;
}

/* DSFR's checkbox visual (.fr-checkbox-group input+label:before) is
   positioned at left:-2rem relative to the label — designed for a fieldset
   layout with room to spare, not a table cell flush against the table's
   own left edge. Without this padding the checkbox box renders past the
   cell's left boundary and gets clipped by .fr-table's own overflow:auto.
   Used by selectable_entry_table.mustache's leading checkbox column. */
.local-kid-app .kid-checkbox-cell {
  padding-left: 2.5rem !important;
  position: relative;
}

/* Moodle's own core/initials_bar and paging_bar renderers (used as-is by
   local_kid — their HTML isn't ours to change) emit Bootstrap pagination
   markup (.pagination/.page-item/.page-link), not DSFR's fr-pagination.
   Restyled here, scoped to .fr-scope only (so unmigrated screens keep the
   Boost look), to match DSFR's own fr-pagination__link colours/spacing —
   values copied from thirdparty/dsfr's compiled CSS rather than
   reinvented. */
.local-kid-app .fr-scope .pagination {
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  margin: 0 0 0.5rem;
  padding: 0;
  list-style: none;
}

.local-kid-app .fr-scope .page-item {
  list-style: none;
}

.local-kid-app .fr-scope .page-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2rem;
  min-height: 2rem;
  margin: 0 0.25rem 0.25rem 0;
  padding: 0.25rem 0.75rem;
  border-radius: 0.25rem;
  background-color: transparent;
  color: #000091;
  font-size: 0.875rem;
  text-decoration: none;
}

.local-kid-app .fr-scope .page-link:hover {
  background-color: #f5f5fe;
}

.local-kid-app .fr-scope .page-link[aria-current="true"] {
  background-color: #000091;
  color: #f5f5fe;
  border: 1px solid #000091;
}

.local-kid-app .fr-scope .page-link[aria-current="true"]:hover {
  background-color: #1212ff;
}

.local-kid-app .fr-scope .initialbarlabel {
  font-weight: 700;
  font-size: 0.875rem;
  margin-right: 0.5rem;
  align-self: center;
}

/* DSFR's .fr-card__content is a flex column and .fr-card__title carries a
   hardcoded order:2 (it's designed as one slot in a fixed eyebrow/title/
   desc/detail card layout, meant to visually sit under an image/eyebrow
   even when authored first in the DOM) — every local_kid card only ever
   uses fr-card__title as a plain first-child section heading, never that
   full slotted structure, so left at DSFR's default it renders AFTER any
   plain (order:0) sibling content instead of before it. */
.local-kid-app .fr-scope .fr-card__title {
  order: 0;
}

/* Reskins the dépli/repli chevron of Moodle's own native collapsible
   fieldset headers ($mform->addElement('header', ...) — one per compétence
   in capp_grid_form.php/entry_grid_form.php, plus the "Appréciation
   globale"/"Commentaire global" headers) to match the real DSFR chevron
   (thirdparty/dsfr's arrow-down-s-line icon, same asset + rotation as
   fr-accordion__btn:after) instead of Moodle's fa-chevron-down/right/left.
   Visual only — Moodle's own JS/aria-expanded toggling on the .fheader
   link is untouched, this only swaps what renders inside it. Scoped to
   .fr-scope like the pagination reskin above (not .kid-region): both
   header-owning form classes are only ever rendered inside fr-scope grid
   templates (capp_grid/eval_grid/stage_grid.mustache), never a standalone
   edit-form page.
   Boost's own theme already puts a ::after on .icons-collapse-expand
   (its pre-FontAwesome caret mechanism: position:absolute;top:0;left:0
   plus a 180deg matrix() transform on the expanded state) — position/
   transform must be reset explicitly below, or this pre-existing rule
   pulls the new mask icon out of flow to the container's top-left corner
   and rotates it, instead of leaving it centred in the button.
   Boost also underlines every <a> via a background-image gradient
   (background-image: linear-gradient(currentColor, currentColor), sized/
   positioned as a thin bottom strip — its usual way of drawing a precise
   underline instead of text-decoration) rather than skipping icon-only
   links. It was always there, just visually hidden under the wider
   FontAwesome glyph before; removing that glyph exposed it as a stray
   bar under the new smaller icon. Icon-only buttons shouldn't be
   underlined like text, so it's turned off here. */
.local-kid-app .fr-scope .fheader.icons-collapse-expand .expanded-icon,
.local-kid-app .fr-scope .fheader.icons-collapse-expand .collapsed-icon {
  display: none;
}

.local-kid-app .fr-scope .fheader.icons-collapse-expand {
  background-image: none;
  background-color: transparent;
  order: 2;
  width: auto;
  height: auto;
  min-width: 0;
  margin: 0 0 0 auto;
  padding: 0;
  border-radius: 0;
}

.local-kid-app .fr-scope .fheader.icons-collapse-expand:after {
  content: "";
  display: inline-block;
  position: static;
  width: 1rem;
  height: 1rem;
  background-color: currentColor;
  -webkit-mask-image: url(../thirdparty/dsfr/icons/arrows/arrow-down-s-line.svg);
  mask-image: url(../thirdparty/dsfr/icons/arrows/arrow-down-s-line.svg);
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  transform: none;
  transition: transform 0.3s;
}

.local-kid-app .fr-scope .fheader.icons-collapse-expand[aria-expanded="true"]:after {
  transform: rotate(-180deg);
}

/* Full fr-accordion__btn treatment for the header row itself (.ftoggler,
   the flex container Moodle already wraps the toggle+title in), not just
   the chevron above: a bordered bar (fr-accordion__btn's own
   box-shadow:inset 0 0 0 1px var(--border-default-grey), #ddd — same value
   as this file's own --kid-border, reused rather than duplicated),
   blue-france title matching DSFR's accordion button text colour instead
   of Moodle's default black h3, and the icon moved to the right (order:2
   above, order:1 here) to match DSFR's constant icon-on-the-right
   convention — Moodle's DOM keeps icon-before-title, `order` only changes
   visual position, not reading/focus order for assistive tech, so this is
   safe. Light-blue fill (var(--kid-accent-bg), close to DSFR's own
   #e3e3fd background-open-blue-france) while expanded, via :has() — a
   parent selector, not supported pre-2022 browsers, but this app only
   ever targets current Chrome/Edge.
   Padding/min-height/font-size below are copied straight from
   fr-accordion__btn's own compiled values (padding:.75rem 1rem;
   min-height:3rem; font-size:1rem;line-height:1.5rem) rather than reusing
   Moodle's native h3 size — a real DSFR accordion title is regular body
   text weighted 500, not heading-sized, and the real button is a
   consistent 3rem-tall bar regardless of title length. .fheader above is
   reset to a plain inline icon (no Boost .btn-icon circle/background of
   its own) so it reads as part of the one bar, not a button-in-a-button;
   margin:0 0 0 auto there is what actually pins it flush right (order
   alone only sequences it after the title, doesn't push it to the edge). */
.local-kid-app .fr-scope .ftoggler {
  box-shadow: inset 0 0 0 1px var(--kid-border);
  border-radius: var(--kid-radius);
  min-height: 3rem;
  width: 100%;
  padding: 0.75rem 1rem;
}

.local-kid-app .fr-scope .ftoggler h3 {
  color: #000091;
  font-size: 1rem;
  line-height: 1.5rem;
  font-weight: 500;
  order: 1;
}

.local-kid-app .fr-scope .ftoggler:has(.fheader[aria-expanded="true"]) {
  background-color: var(--kid-accent-bg);
}

.local-kid-app .fr-scope .ftoggler:hover,
.local-kid-app .fr-scope .ftoggler:focus-within {
  background-color: var(--kid-accent-bg);
}

/* Reskins Moodle's own native moodleform output (select/textarea/input/
   submit buttons — e.g. entry_grid_form.php, capp_grid_form.php, and every
   promotion/competency/niveau/eval/stage/capp edit form) to look like DSFR
   form controls, without touching moodleform/HTML_QuickForm rendering
   itself — Moodle emits fixed Bootstrap classes (.custom-select,
   .form-control, .btn) from core PHP element classes, not from any
   template local_kid controls, so only CSS can reach them. Scoped to
   .kid-region (every kid page), not .fr-scope: standalone edit-form pages
   (promotion_edit.php, niveau_edit.php, ...) render moodleform directly
   with no surrounding .fr-scope wrapper, so a narrower scope would miss
   them entirely — this reskin is a plugin-wide concern, unlike the
   fr-scope-only pagination fix above. Colours/metrics copied from
   thirdparty/dsfr's compiled fr-input/fr-select/fr-btn rules rather than
   reinvented. */
.local-kid-app .kid-region .custom-select,
.local-kid-app .kid-region select.form-control,
.local-kid-app .kid-region input.form-control,
.local-kid-app .kid-region textarea.form-control {
  background-color: #eeeeee;
  border: none;
  border-radius: 0.25rem 0.25rem 0 0;
  box-shadow: inset 0 -2px 0 0 #3a3a3a;
  color: #3a3a3a;
  padding: 0.5rem 1rem;
}

.local-kid-app .kid-region .custom-select,
.local-kid-app .kid-region select.form-control {
  -webkit-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23161616' d='m12 13.1 5-4.9 1.4 1.4-6.4 6.3-6.4-6.4L7 8.1l5 5z'/%3E%3C/svg%3E");
  background-position: calc(100% - 1rem) 50%;
  background-repeat: no-repeat;
  background-size: 1rem 1rem;
  padding-right: 2.5rem;
}

.local-kid-app .kid-region .custom-select:focus,
.local-kid-app .kid-region select.form-control:focus,
.local-kid-app .kid-region input.form-control:focus,
.local-kid-app .kid-region textarea.form-control:focus {
  outline: 2px solid #0a76f6;
  outline-offset: 0;
  box-shadow: inset 0 -2px 0 0 #000091;
}

.local-kid-app .kid-region .btn.btn-primary,
.local-kid-app .kid-region .btn.btn-secondary,
.local-kid-app .kid-region .btn.btn-outline-secondary,
.local-kid-app .kid-region input[type="submit"].btn {
  border-radius: 0;
  font-weight: 500;
  padding: 0.5rem 1rem;
  min-height: 2.5rem;
  line-height: 1.5rem;
}

.local-kid-app .kid-region .btn.btn-primary,
.local-kid-app .kid-region input[type="submit"].btn-primary {
  background-color: #000091;
  border-color: #000091;
  color: #f5f5fe;
}

.local-kid-app .kid-region .btn.btn-primary:hover,
.local-kid-app .kid-region input[type="submit"].btn-primary:hover {
  background-color: #1212ff;
  border-color: #1212ff;
}

.local-kid-app .kid-region .btn.btn-secondary,
.local-kid-app .kid-region .btn.btn-outline-secondary {
  background-color: transparent;
  border-color: #000091;
  color: #000091;
}

.local-kid-app .kid-region .btn.btn-secondary:hover,
.local-kid-app .kid-region .btn.btn-outline-secondary:hover {
  background-color: #f5f5fe;
}

.local-kid-app .kid-region .btn.btn-link {
  color: #000091;
  text-decoration: underline;
}

/* Bootstrap/Boost's native .form-check-input (moodleform checkboxes, e.g.
   the "Activer" toggle on date selectors in stage_edit.php etc.) renders
   with a visibly broken/glitched glyph overlapping its label text on this
   theme. Root cause: thirdparty/dsfr's core CSS carries an unscoped
   (no .fr-checkbox-group ancestor required) `input[type=checkbox]
   {appearance:auto}` reset that, combined with this theme's own
   .form-check-input rule (position:relative, no explicit size), leaves the
   browser with an inconsistent box to render — not something local_kid's
   own markup causes, and not fixable by touching moodleform output. A
   plain explicit size/position reset resolves it. */
.local-kid-app .kid-region .form-check-input {
  appearance: auto;
  -webkit-appearance: auto;
  box-sizing: border-box;
  width: 1rem;
  height: 1rem;
  margin: 0 0.4rem 0 0;
  vertical-align: middle;
  position: static;
  float: none;
}

/* DSFR's fr-text--sm only sets font-size, unlike the kid-muted class most
   of this text was migrated from (which also set a grey color) — every
   template that switched kid-muted -> fr-text--sm for de-emphasised
   secondary text (counts, empty-state captions, timestamps, ...) silently
   lost its grey and now renders in the default dark text colour, flattening
   the visual hierarchy. Value is DSFR's own --text-mention-grey (#666),
   not kid-muted's old --kid-muted token, to stay consistent with the rest
   of the migrated screens. */
.local-kid-app .fr-scope .fr-text--sm {
  color: #666666;
}

/* Largeur explicite : sans elle, kid-region hérite en shrink-to-fit sur les
   thèmes/conteneurs Moodle où le parent de #region-main est lui-même un
   flex/grid item (variable selon le thème hôte), au lieu de toujours
   remplir la largeur de contenu disponible. */
.local-kid-app .kid-region {
  width: 100%;
}

.local-kid-app .kid-layout {
  display: flex;
  align-items: flex-start;
  gap: 0;
  max-width: 100%;
  width: 100%;
}

/* ─── Sidebar interne (reproduit Sidebar.tsx) ──────────────────────────── */

.local-kid-app .kid-sidebar {
  flex: 0 0 15rem;
  background: var(--kid-sidebar-bg);
  color: var(--kid-sidebar-text-strong);
  padding: 0;
  align-self: stretch;
}

.local-kid-app .kid-sidebar__header {
  padding: 1.1rem 1rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.local-kid-app .kid-sidebar__title {
  font-weight: 700;
  font-size: 1rem;
  line-height: 1.2;
  margin: 0;
}

.local-kid-app .kid-sidebar__sub {
  font-size: 0.75rem;
  opacity: 0.5;
  margin: 0.2rem 0 0;
}

.local-kid-app .kid-sidebar__promotion-switch {
  padding: 0.9rem 1rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.local-kid-app .kid-sidebar__promotion-label {
  display: block;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.65rem;
  font-weight: 600;
  opacity: 0.6;
  margin: 0 0 0.3rem;
}

.local-kid-app .kid-sidebar__promotion-select {
  width: 100%;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: var(--kid-radius);
  color: #FFFFFF;
  padding: 0.4rem 0.5rem;
  font-size: 0.8rem;
  font-family: inherit;
}

.local-kid-app .kid-sidebar__promotion-select option {
  color: var(--kid-text);
}

.local-kid-app .kid-sidebar__nav {
  padding: 0.6rem 0;
}

.local-kid-app .kid-sidebar__link {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0.1rem 0.6rem;
  padding: 0.55rem 1rem;
  font-size: 0.875rem;
  color: var(--kid-sidebar-text);
  text-decoration: none;
  border: none;
  border-radius: 1.5rem;
  background: transparent;
}

/* Icons are the DSFR fr-icon-* ::before pseudo-element (mask-image,
   background-color:currentColor — picks up the link's text color
   automatically in every state below). DSFR's default --icon-size is
   1.5rem, a bit large next to this 0.875rem nav label; shrunk to 1.25rem
   here only (fr-btn/fr-link icons elsewhere keep the DSFR default). */
.local-kid-app .kid-sidebar__link:before {
  --icon-size: 1.25rem;
}

/* Selector needs the "a" type to at least tie DSFR's own
   .kid-region a[href]:hover{background-color:var(--hover-tint)} on
   specificity (a[href]:hover adds an element-selector point our previous
   .kid-sidebar__link:hover, class-only, didn't have) — ties resolve by
   source order, and this file loads after dsfr.scoped.css, so it wins.
   Without the "a", DSFR's rule silently kept the hover background
   transparent (var(--hover-tint) defaults to var(--idle)). */
.local-kid-app a.kid-sidebar__link:hover {
  background: rgba(255, 255, 255, 0.08);
  color: #FFFFFF;
  text-decoration: none;
}

.local-kid-app .kid-sidebar__link.is-active {
  background: var(--kid-sidebar-active);
  color: #FFFFFF;
  font-weight: 600;
}

.local-kid-app .kid-main {
  flex: 1 1 auto;
  min-width: 0;
  padding: 1.25rem 1.5rem;
}

/* ─── En-tête de page (page_header.mustache) ───────────────────────────── */

.local-kid-app .kid-page-header {
  margin-bottom: 1rem;
}

.local-kid-app .kid-page-header__title {
  font-size: 1.375rem;
  font-weight: 600;
  color: var(--kid-text);
  margin: 0;
}

.local-kid-app .kid-page-header__subtitle {
  font-size: 0.875rem;
  color: var(--kid-muted);
  margin: 0.2rem 0 0;
}

.local-kid-app .kid-role-badge {
  display: inline-block;
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--kid-primary);
  background: var(--kid-accent-bg);
  border-radius: var(--kid-radius);
  padding: 0.15rem 0.5rem;
  margin-top: 0.35rem;
}

/* ─── Cartes / conteneurs (StatCard.tsx et cartouches génériques) ──────── */

.local-kid-app .kid-card {
  background: var(--kid-card);
  border: 1px solid var(--kid-border);
  border-radius: 0;
  padding: 1.1rem;
}

.local-kid-app .kid-card + .kid-card {
  margin-top: 1rem;
}

.local-kid-app .kid-stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 0.75rem;
  margin-bottom: 1rem;
}

.local-kid-app .kid-stat-card {
  background: var(--kid-card);
  border: 1px solid var(--kid-border);
  padding: 1.15rem;
}

.local-kid-app .kid-stat-card__value {
  font-size: 1.75rem;
  font-weight: 700;
  color: var(--kid-primary);
}

.local-kid-app .kid-stat-card__label {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--kid-text);
  margin-top: 0.15rem;
}

.local-kid-app .kid-stat-card__sub {
  font-size: 0.75rem;
  color: var(--kid-muted);
  margin-top: 0.1rem;
}

/* ─── Onglets internes (tabs.mustache) ──────────────────────────────────── */

.local-kid-app .kid-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem;
  border-bottom: 1px solid var(--kid-border);
  margin-bottom: 1rem;
}

.local-kid-app .kid-tabs__link {
  padding: 0.55rem 0.9rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--kid-muted);
  text-decoration: none;
  border-bottom: 2px solid transparent;
}

.local-kid-app .kid-tabs__link:hover {
  color: var(--kid-primary);
  text-decoration: none;
}

.local-kid-app .kid-tabs__link.is-active {
  color: var(--kid-primary);
  border-bottom-color: var(--kid-primary);
}

/* ─── Étapes de workflow (workflow_stepper.mustache ← WorkflowStepper.tsx) */

.local-kid-app .kid-stepper {
  display: flex;
  align-items: center;
  background: var(--kid-card);
  border: 1px solid var(--kid-border);
  padding: 0.9rem 1.1rem;
  overflow-x: auto;
  margin-bottom: 1rem;
}

.local-kid-app .kid-stepper__step {
  display: flex;
  align-items: center;
  flex: 1 1 auto;
  min-width: max-content;
}

.local-kid-app .kid-stepper__step:last-child {
  flex: 0 0 auto;
}

.local-kid-app .kid-stepper__bullet {
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.7rem;
  font-weight: 600;
  flex-shrink: 0;
  background: var(--kid-border-light);
  color: var(--kid-faint);
}

.local-kid-app .kid-stepper__step.is-done .kid-stepper__bullet {
  background: var(--kid-success);
  color: #FFFFFF;
}

.local-kid-app .kid-stepper__step.is-active .kid-stepper__bullet {
  background: var(--kid-primary);
  color: #FFFFFF;
}

.local-kid-app .kid-stepper__label {
  font-size: 0.75rem;
  color: var(--kid-faint);
  margin-left: 0.5rem;
  white-space: nowrap;
}

.local-kid-app .kid-stepper__step.is-done .kid-stepper__label {
  color: var(--kid-success);
}

.local-kid-app .kid-stepper__step.is-active .kid-stepper__label {
  color: var(--kid-primary);
  font-weight: 600;
}

.local-kid-app .kid-stepper__bar {
  height: 1px;
  flex: 1 1 2rem;
  min-width: 2rem;
  margin: 0 0.75rem;
  background: var(--kid-border);
}

.local-kid-app .kid-stepper__step.is-done .kid-stepper__bar {
  background: var(--kid-success);
}

/* Niveau badges — fixed 5-level palette matching the InterfaceEvaluation
   React prototype, keyed off local_kid_niveau.code (COMPETENCE0..4, the
   only immutable per-level identifier — libelle/couleur/sortorder are all
   admin-editable) via niveau_repository::badge_class(). Deliberately not
   the admin-configurable `couleur` field used elsewhere (admin_niveaux) —
   this fixed palette is a distinct, intentional design decision.
   4 independent render sites share this exact palette by convention, not by
   any shared code (CSS can't be read from PHP/JS): this file (web, via
   niveau_badge.mustache + the direct-PHP capp_grid_form.php/
   entry_grid_form.php badges), amd/src/comparateur.js's drawer badge (same
   kid-level-* classes, DOM-built), and classes/local/pdf_service.php's
   niveau_badge_html()/Bilan header (own inline-style hex, since TCPDF can't
   read a stylesheet — sourced from niveau_repository::badge_colors()/
   bucket_colors(), the actual single point of truth for the hex values).
   Change a color in exactly one place (below) and mirror it into
   niveau_repository's BADGE_COLORS/BUCKET_COLORS consts, or the PDF drifts
   from the screen silently. */
.local-kid-app .kid-level-badge {
  display: inline-flex;
  align-items: center;
  padding: 0.125rem 0.5rem;
  font-size: 0.75rem;
  font-weight: 700;
  line-height: 1rem;
  border-radius: 0.25rem;
}

/* Tokens système DSFR (@gouvfr/dsfr 1.15.2, dist/core/core.css, thème clair) :
   badges pleins sans bordure, fond+texte de la même famille sémantique.
   Non observé = neutre, Non acquis = erreur, En cours = avertissement,
   Acquis = succès, Dépasse les attentes = info (choisi pour le distinguer
   d'Acquis plutôt qu'une variante de vert). */
.local-kid-app .kid-level-nonobserve { background-color: #eeeeee; color: #666666; }
.local-kid-app .kid-level-nonacquis { background-color: #ffe9e9; color: #ce0500; }
.local-kid-app .kid-level-encours { background-color: #ffe9e6; color: #b34000; }
.local-kid-app .kid-level-acquis { background-color: #b8fec9; color: #18753c; }
.local-kid-app .kid-level-depasse { background-color: #e8edff; color: #0063cb; }

/* ─── Tableaux (competency_matrix_table et grilles) ─────────────────────── */

.local-kid-app .kid-table-wrap {
  overflow-x: auto;
  border: 1px solid var(--kid-border);
  background: var(--kid-card);
}

.local-kid-app table.kid-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
}

.local-kid-app table.kid-table th {
  text-align: left;
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--kid-muted);
  background: var(--kid-row-alt);
  border-bottom: 1px solid var(--kid-border);
  padding: 0.55rem 0.75rem;
  white-space: nowrap;
}

/* Compétence column headers in crossed tables (dashboard_competencies) now
   show the full libellé instead of the short code — override the default
   nowrap/uppercase header so a long name wraps onto a controlled width
   instead of forcing the whole table to overflow. Full code available as
   a title tooltip (see dashboard_competencies.mustache). */
.local-kid-app table.kid-table th.kid-th-competency {
  text-transform: none;
  letter-spacing: normal;
  white-space: normal;
  width: 8rem;
  max-width: 8rem;
  vertical-align: bottom;
}

.local-kid-app table.kid-table td {
  padding: 0.55rem 0.75rem;
  border-bottom: 1px solid var(--kid-border-light);
  vertical-align: top;
}

.local-kid-app table.kid-table tbody tr:last-child td {
  border-bottom: none;
}

.local-kid-app table.kid-table tbody tr:hover {
  background: var(--kid-row-alt);
}

.local-kid-app .kid-sort-btn {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  text-transform: inherit;
  letter-spacing: inherit;
  color: inherit;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
}

/* Client-side sortable dashboard cross-tabs (sortable_table.js) — the
   ascending/descending arrow is pure CSS off aria-sort, which the module
   also uses for its own state instead of a separate visual-only class. */
.local-kid-app th.kid-sortable[aria-sort="ascending"] .kid-sort-btn::after {
  content: "▲";
  font-size: 0.65em;
}

.local-kid-app th.kid-sortable[aria-sort="descending"] .kid-sort-btn::after {
  content: "▼";
  font-size: 0.65em;
}

.local-kid-app .kid-inline-form {
  display: inline;
}

/* Bootstrap's .btn sets its own font-size/line-height, which makes a
   button-styled-as-link (the delete action) render at a different size
   than the plain <a> action links next to it — force it back to match. */
.local-kid-app table.kid-table .btn-link {
  font-size: inherit;
  line-height: inherit;
  vertical-align: baseline;
}

/* Discreet comment indicator next to a cell's niveau badge — the comment
   text itself only ever shows on hover/focus (Bootstrap tooltip via
   data-toggle="tooltip", native title as fallback), never inline, so a
   cross-tab row stays scannable. */
.local-kid-app .kid-comment-icon {
  margin-left: 0.35rem;
  color: var(--kid-muted);
  cursor: help;
}

/* ─── États vides ───────────────────────────────────────────────────────── */

.local-kid-app .kid-empty {
  text-align: center;
  padding: 2.5rem 1rem;
  color: var(--kid-muted);
  border: 1px dashed var(--kid-border);
  background: var(--kid-card);
}

/* ─── Boutons (respectent les classes bouton Moodle, juste retintés) ──── */

.local-kid-app .btn-primary,
.local-kid-app a.btn-primary {
  background-color: var(--kid-primary);
  border-color: var(--kid-primary);
}

.local-kid-app .btn-primary:hover,
.local-kid-app a.btn-primary:hover {
  background-color: #00006e;
  border-color: #00006e;
}

/* ─── Cartouche de publication ─────────────────────────────────────────── */

.local-kid-app .kid-publication {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  background: var(--kid-accent-bg);
  border: 1px solid var(--kid-border);
  padding: 0.75rem 1rem;
  margin-bottom: 1rem;
}

/* ─── Barre d'actions groupées (sélection multiple, modèle Devoirs Moodle) ── */

.local-kid-app table.kid-table th.kid-th-check,
.local-kid-app table.kid-table td.kid-th-check {
  width: 2rem;
  text-align: center;
}

.local-kid-app .kid-bulk-actions {
  background: var(--kid-accent-bg);
  border: 1px solid var(--kid-border);
  padding: 0.75rem 1rem;
  margin-bottom: 1rem;
}

.local-kid-app .kid-bulk-actions__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
}

.local-kid-app .kid-bulk-result {
  font-size: 0.85rem;
}

.local-kid-app .kid-bulk-result:not(:empty) {
  margin-top: 0.5rem;
  padding-top: 0.5rem;
  border-top: 1px solid var(--kid-border-light);
}

/* ─── Divers (liens d'action inline, liste de documents, texte atténué) ── */

.local-kid-app .kid-actions-inline {
  font-size: 0.85rem;
  margin: 0 0 1rem;
}

.local-kid-app .kid-doc-list {
  list-style: none;
  margin: 0 0 0.75rem;
  padding: 0;
  font-size: 0.85rem;
}

.local-kid-app .kid-doc-list li {
  padding: 0.35rem 0;
  border-bottom: 1px solid var(--kid-border-light);
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.local-kid-app .kid-muted {
  color: var(--kid-muted);
  font-size: 0.8rem;
}

.local-kid-app .kid-filter-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 1rem;
  margin-bottom: 1rem;
  font-size: 0.85rem;
}

.local-kid-app .kid-filter-form label {
  margin: 0;
  color: var(--kid-muted);
  font-weight: 600;
}

/* ─── En-tête de navigation entre élèves (Évaluations/Stages/CAPP) ─────── */

.local-kid-app .kid-student-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 1rem;
  background: var(--kid-accent-bg);
  border: 1px solid var(--kid-border);
  border-radius: var(--kid-radius);
  padding: 0.6rem 0.85rem;
  margin-bottom: 1rem;
}

.local-kid-app .kid-student-nav__form {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.local-kid-app .kid-student-nav__form label {
  margin: 0;
  color: var(--kid-muted);
  font-weight: 600;
  font-size: 0.85rem;
}

.local-kid-app .kid-student-nav__counter {
  margin-left: auto;
  color: var(--kid-muted);
  font-weight: 600;
  font-size: 0.85rem;
  white-space: nowrap;
}

.local-kid-app .kid-student-nav a.disabled {
  pointer-events: none;
  opacity: 0.45;
}

.local-kid-app [aria-busy="true"] {
  opacity: 0.6;
}

.local-kid-app .kid-journal__diffline {
  margin-bottom: 0.25rem;
}

.local-kid-app .kid-journal__diffline:last-child {
  margin-bottom: 0;
}

/* ─── Annuaire des élèves — espacement des deux barres d'initiales natives Moodle ── */

.local-kid-app .kid-annuaire__initials {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

/* ─── Boutons DSFR (fr-btn) — jusqu'ici utilisés (Journal, Annuaire) mais
   jamais réellement stylés : ce bloc complète la classe déjà en usage
   plutôt que d'en introduire une nouvelle. Bleu France plein / contour. ── */

.local-kid-app .kid-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.5rem 1rem;
  font-size: 0.875rem;
  font-weight: 700;
  font-family: inherit;
  border: 1px solid var(--kid-primary);
  border-radius: var(--kid-radius);
  cursor: pointer;
  text-decoration: none;
  line-height: 1.2;
}

.local-kid-app .kid-btn--primary {
  background: var(--kid-primary);
  color: var(--kid-primary-contrast);
}

.local-kid-app .kid-btn--primary:hover {
  background: #1212ff;
  border-color: #1212ff;
}

.local-kid-app .kid-btn--secondary {
  background: var(--kid-card);
  color: var(--kid-primary);
}

.local-kid-app .kid-btn--secondary:hover {
  background: var(--kid-accent-bg);
}

.local-kid-app .kid-btn--sm {
  padding: 0.35rem 0.6rem;
  font-size: 0.8rem;
}

.local-kid-app .kid-btn:focus-visible,
.local-kid-app .kid-linkbtn:focus-visible {
  outline: 2px solid var(--kid-primary);
  outline-offset: 2px;
}

.local-kid-app .kid-linkbtn {
  background: none;
  border: 0;
  color: var(--kid-primary);
  font-size: 0.75rem;
  font-weight: 600;
  cursor: pointer;
  padding: 0;
}

.local-kid-app .kid-fchip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  border: 1px solid var(--kid-border);
  background: var(--kid-card);
  border-radius: 999px;
  padding: 0.25rem 0.65rem;
  font-size: 0.75rem;
  color: var(--kid-muted);
  cursor: pointer;
}

.local-kid-app .kid-fchip input {
  margin: 0;
}

.local-kid-app .kid-fchip--pressed {
  border-color: var(--kid-primary);
  color: var(--kid-primary);
  background: var(--kid-accent-bg);
  font-weight: 700;
}

/* ─── Comparateur de bilans ──────────────────────────────────────────── */

.local-kid-app .kid-comparateur__layout {
  display: grid;
  grid-template-columns: 20rem 1fr;
  align-items: start;
  gap: 1.5rem;
}

@media (max-width: 64rem) {
  .local-kid-app .kid-comparateur__layout {
    grid-template-columns: 1fr;
  }
}

.local-kid-app .kid-comparateur__filters {
  position: sticky;
  top: 0.5rem;
  max-height: calc(100vh - 1rem);
  overflow-y: auto;
  background: var(--kid-card);
  border: 1px solid var(--kid-border);
  border-radius: var(--kid-radius);
  padding: 1rem;
}

.local-kid-app .kid-comparateur__fgroup {
  margin-bottom: 1.1rem;
}

.local-kid-app .kid-comparateur__fgroup summary {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--kid-muted);
  font-weight: 700;
  cursor: pointer;
  margin-bottom: 0.5rem;
}

.local-kid-app .kid-comparateur__label {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--kid-muted);
  font-weight: 700;
  margin-bottom: 0.5rem;
}

.local-kid-app .kid-comparateur__search {
  width: 100%;
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--kid-border);
  border-radius: var(--kid-radius);
  font-size: 0.8rem;
  margin-bottom: 0.4rem;
}

.local-kid-app .kid-comparateur__actions {
  display: flex;
  gap: 0.6rem;
  margin-bottom: 0.4rem;
}

.local-kid-app .kid-comparateur__optlist {
  max-height: 12rem;
  overflow: auto;
  border: 1px solid var(--kid-border-light);
  border-radius: var(--kid-radius);
}

.local-kid-app .kid-comparateur__opt {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  padding: 0.35rem 0.6rem 0.35rem 2.5rem;
  font-size: 0.8rem;
  cursor: pointer;
  position: relative;
}

/* DSFR's fr-checkbox-group label only sizes to its own text content, unlike
   the plain <label> this row used before the DSFR migration (which wrapped
   the whole row, so clicking anywhere in it toggled the checkbox). Without
   this, only the glyph and the label text itself are clickable — dead
   space in the row does nothing, a real regression on a fast multi-select
   filter list. */
.local-kid-app .kid-comparateur__opt label {
  flex: 1;
  cursor: pointer;
}

.local-kid-app .kid-comparateur__opt:hover {
  background: var(--kid-row-alt);
}

.local-kid-app .kid-comparateur__optgroup {
  padding: 0.4rem 0.6rem 0.2rem;
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--kid-faint);
  font-weight: 700;
}

.local-kid-app .kid-comparateur__chipset {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.local-kid-app .kid-comparateur__switch {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.8rem;
  padding: 0.3rem 0;
  cursor: pointer;
}

.local-kid-app .kid-comparateur__apply {
  width: 100%;
  justify-content: center;
}

.local-kid-app .kid-comparateur__favgroup {
  border-bottom: 1px solid var(--kid-border);
  padding-bottom: 1rem;
  margin-bottom: 1rem;
}

.local-kid-app .kid-comparateur__favsave {
  display: flex;
  gap: 0.4rem;
  margin-bottom: 0.5rem;
}

.local-kid-app .kid-comparateur__favsave input {
  flex: 1;
  min-width: 0;
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--kid-border);
  border-radius: var(--kid-radius);
  font-size: 0.8rem;
}

.local-kid-app .kid-comparateur__favlist {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.local-kid-app .kid-comparateur__favitem {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.3rem 0.4rem;
  border: 1px solid var(--kid-border);
  border-radius: var(--kid-radius);
}

.local-kid-app .kid-comparateur__favload {
  flex: 1;
  min-width: 0;
  text-align: left;
  background: none;
  border: 0;
  color: var(--kid-primary);
  font-weight: 600;
  font-size: 0.8rem;
  cursor: pointer;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.local-kid-app .kid-comparateur__favicon {
  background: none;
  border: 0;
  color: var(--kid-faint);
  cursor: pointer;
  padding: 0.15rem 0.3rem;
  border-radius: var(--kid-radius);
  line-height: 1;
}

.local-kid-app .kid-comparateur__favicon:hover {
  background: var(--kid-row-alt);
  color: var(--kid-text);
}

.local-kid-app .kid-comparateur__favicon--danger {
  color: var(--kid-danger);
}

.local-kid-app .kid-comparateur__favicon--danger:hover {
  background-color: #8F0400 !important;
  color: #fff;
}

.local-kid-app .kid-comparateur__favempty {
  font-size: 0.75rem;
}

.local-kid-app .kid-comparateur__toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 1rem;
}

.local-kid-app .kid-comparateur__exportbtns {
  display: flex;
  gap: 0.5rem;
}

.local-kid-app .kid-comparateur__results[aria-busy="true"] {
  opacity: 0.5;
  transition: opacity 0.15s ease;
  pointer-events: none;
}

.local-kid-app .kid-comparateur__card {
  background: var(--kid-card);
  border: 1px solid var(--kid-border);
  border-radius: var(--kid-radius);
  margin-bottom: 1.25rem;
  overflow: hidden;
}

.local-kid-app .kid-comparateur__cardhead {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  align-items: baseline;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--kid-border);
}

.local-kid-app .kid-comparateur__name {
  font-weight: 700;
  font-size: 1rem;
}

.local-kid-app .kid-comparateur__scroll {
  overflow: auto;
}

.local-kid-app table.kid-comparateur__matrix th,
.local-kid-app table.kid-comparateur__matrix td {
  padding: 0.55rem 0.75rem;
  vertical-align: top;
}

.local-kid-app .kid-comparateur__typehead {
  background: var(--kid-bg);
  color: var(--kid-muted);
  text-transform: uppercase;
  font-size: 0.65rem;
  letter-spacing: 0.05em;
  text-align: center;
}

.local-kid-app .kid-comparateur__corner,
.local-kid-app .kid-comparateur__corner--2 {
  position: sticky;
  left: 0;
  z-index: 2;
  background: var(--kid-bg);
  text-align: left;
  min-width: 14rem;
}

.local-kid-app td.kid-comparateur__comp {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--kid-card);
  min-width: 14rem;
  font-weight: 600;
}

.local-kid-app .kid-comparateur__code {
  color: var(--kid-faint);
  font-weight: 800;
  font-size: 0.7rem;
  margin-right: 0.4rem;
}

.local-kid-app td.kid-comparateur__cell {
  text-align: center;
  min-width: 9rem;
}

.local-kid-app td.kid-comparateur__cell--clickable {
  cursor: pointer;
}

.local-kid-app td.kid-comparateur__cell--clickable:hover {
  background: var(--kid-row-alt);
}

.local-kid-app .kid-comparateur__dash {
  color: var(--kid-border);
  font-weight: 700;
}

.local-kid-app .kid-comparateur__comment {
  display: block;
  margin-top: 0.4rem;
  color: var(--kid-muted);
  font-size: 0.72rem;
  text-align: left;
  line-height: 1.4;
}

.local-kid-app .kid-comparateur__more {
  color: var(--kid-primary);
  font-weight: 600;
}

.local-kid-app a.kid-comparateur__srclink {
  color: var(--kid-primary);
  font-weight: 700;
  text-decoration: none;
}

.local-kid-app a.kid-comparateur__srclink:hover {
  text-decoration: underline;
}

.local-kid-app .kid-comparateur__scrim {
  position: fixed;
  inset: 0;
  background: rgba(20, 20, 50, 0.28);
  opacity: 0;
  pointer-events: none;
  transition: 0.15s;
  z-index: 40;
}

.local-kid-app .kid-comparateur__scrim.show {
  opacity: 1;
  pointer-events: auto;
}

.local-kid-app .kid-comparateur__drawer {
  position: fixed;
  top: 0;
  right: 0;
  height: 100%;
  width: min(28rem, 92vw);
  background: var(--kid-card);
  box-shadow: -0.9rem 0 2.5rem rgba(20, 20, 60, 0.18);
  transform: translateX(100%);
  transition: transform 0.18s ease;
  z-index: 50;
  display: flex;
  flex-direction: column;
}

.local-kid-app .kid-comparateur__drawer.show {
  transform: none;
}

.local-kid-app .kid-comparateur__drawer header {
  padding: 1rem 1.1rem;
  border-bottom: 1px solid var(--kid-border);
  display: flex;
  justify-content: space-between;
  align-items: start;
  gap: 0.75rem;
}

.local-kid-app .kid-comparateur__drawer header h3 {
  margin: 0;
  font-size: 1rem;
}

.local-kid-app .kid-comparateur__close {
  background: none;
  border: 0;
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
  color: var(--kid-muted);
}

.local-kid-app .kid-comparateur__drawerbody {
  padding: 1.1rem;
  overflow: auto;
}

.local-kid-app .kid-comparateur__drawerbody .kv {
  margin-bottom: 0.9rem;
}

.local-kid-app .kid-comparateur__drawerbody .kv .k {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--kid-faint);
  font-weight: 700;
  margin-bottom: 0.2rem;
}

.local-kid-app .kid-comparateur__drawerbody .cmt-full {
  background: var(--kid-bg);
  border-radius: var(--kid-radius);
  padding: 0.75rem 0.8rem;
  font-size: 0.85rem;
  line-height: 1.5;
}

@media (max-width: 48rem) {
  .local-kid-app .kid-layout {
    flex-direction: column;
  }

  .local-kid-app .kid-sidebar {
    flex-basis: auto;
    width: 100%;
  }
}

/**
 * Prévention des conflits sur les commentaires (amd/src/unsaved_guard.js,
 * amd/src/conflict_view.js). Both render into a core/modal instance, which
 * Moodle attaches directly under <body> rather than inside .local-kid-app —
 * these rules are deliberately NOT scoped under that wrapper, unlike
 * everything else in this file. The --kid-* custom properties above are
 * still available here: they're set on body.local-kid-app itself, so every
 * element under <body> inherits them regardless of which container it was
 * appended into.
 */
.kid-conflict-card {
  border: 1px solid var(--kid-border);
  border-radius: var(--kid-radius);
  padding: 1rem;
  margin-bottom: 1rem;
  font-family: var(--kid-font);
}

.kid-conflict-card__title {
  font-size: 1rem;
  font-weight: 700;
  margin: 0 0 0.25rem;
  color: var(--kid-text);
}

.kid-conflict-card__subtitle {
  font-size: 0.85rem;
  color: var(--kid-muted);
  margin: 0 0 0.75rem;
}

.kid-conflict-card__cols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
  margin-bottom: 0.75rem;
}

@media (max-width: 40rem) {
  .kid-conflict-card__cols {
    grid-template-columns: 1fr;
  }
}

.kid-conflict-card__col {
  border: 1px solid var(--kid-border-light);
  border-radius: var(--kid-radius);
  padding: 0.6rem 0.7rem;
  background: var(--kid-bg);
}

.kid-conflict-card__col--db {
  border-color: var(--kid-danger);
  background: #FDECEC;
}

.kid-conflict-card__collabel {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--kid-faint);
  font-weight: 700;
  margin: 0 0 0.35rem;
}

.kid-conflict-card__col--db .kid-conflict-card__collabel {
  color: var(--kid-danger);
}

.kid-conflict-card__text {
  font-size: 0.85rem;
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--kid-text);
}

.kid-conflict-card__actions {
  display: flex;
  gap: 0.5rem;
}

/**
 * Historique du commentaire, lecture seule (amd/src/comment_history.js).
 * Also renders into a core/modal instance appended under <body> — same
 * "not scoped under .local-kid-app" note as the conflict-view rules above.
 */
.kid-history-link {
  background: none;
  border: none;
  padding: 0;
  margin: 0.3rem 0 1rem;
  font-family: var(--kid-font);
  font-size: 0.8rem;
  color: var(--kid-primary);
  text-decoration: underline;
  cursor: pointer;
}

.kid-history-link:hover,
.kid-history-link:focus {
  text-decoration: none;
}

.kid-history-subtitle {
  font-size: 0.85rem;
  color: var(--kid-muted);
  margin: -0.5rem 0 1rem;
}

.kid-history-version {
  border: 1px solid var(--kid-border-light);
  border-radius: var(--kid-radius);
  padding: 0.85rem 1rem;
  margin-bottom: 0.75rem;
  font-family: var(--kid-font);
}

.kid-history-version--current {
  border-color: var(--kid-primary);
  background: var(--kid-accent-bg);
}

.kid-history-version__head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
  flex-wrap: wrap;
}

.kid-history-version__avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 50%;
  background: var(--kid-sidebar-bg);
  color: #FFFFFF;
  font-size: 0.7rem;
  font-weight: 700;
  flex-shrink: 0;
}

.kid-history-version__author {
  font-weight: 700;
  font-size: 0.85rem;
  color: var(--kid-text);
}

.kid-history-version__date {
  font-size: 0.8rem;
  color: var(--kid-muted);
}

.kid-history-version__badge {
  margin-left: auto;
  background: var(--kid-primary);
  color: var(--kid-primary-contrast);
  font-size: 0.7rem;
  font-weight: 700;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
}

.kid-history-version__text {
  font-size: 0.85rem;
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--kid-text);
}

.kid-history-version:not(.kid-history-version--current) .kid-history-version__text {
  color: var(--kid-muted);
}

/* ─── Cartes de statistiques du tableau de bord (dashboard_overview) ────
   Hiérarchie voulue par nature de donnée, DSFR-only tokens (jamais de hex
   en dur) : Élèves = contexte neutre (gris, carte plus large) ; Évaluations/
   Stages/CAPP "à compléter" = action en attente, une seule couleur
   d'avertissement partagée (--text-default-warning/--background-contrast-
   warning, les mêmes tokens que fr-badge--warning — cohérent avec le badge
   posé sur ces 3 cartes) ; CAPP finalisées = résultat, couleur succès
   (--text-default-success/--background-contrast-success, idem
   fr-badge--success). Ces tokens sont ceux-là mêmes qui alimentent déjà
   .kid-level-encours/.kid-level-acquis (niveau_repository) — mêmes teintes
   orange/vert réutilisées, pas une nouvelle palette. */
.local-kid-app .kid-stat-card {
  border-left: 0.25rem solid transparent;
  height: 100%;
}

.local-kid-app .kid-stat-card--neutral {
  border-left-color: var(--text-title-grey);
}

.local-kid-app .kid-stat-card--warning {
  border-left-color: var(--text-default-warning);
}

.local-kid-app .kid-stat-card--success {
  border-left-color: var(--text-default-success);
}

/* Column, not row: at fr-col-md-2 (~104px card incl. fr-card--sm's 1.5rem
   padding) there isn't room for a 2.75rem icon pastille next to a badge
   on the same line without either wrapping mid-word — stacking keeps both
   readable at this width. Verified against the narrowest real title
   ("En attente" next to the icon) before settling on this over shrinking
   the icon or the badge text further. */
.local-kid-app .kid-stat-card__head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}

/* .kid-stat-card__icon carries its own fr-icon-* class (same pattern as
   the sidebar nav links) — the pastille is this same element, its
   background/color set per modifier below, the fr-icon-* mask glyph picks
   up that color automatically via currentColor. */
.local-kid-app .kid-stat-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
}

.local-kid-app .kid-stat-card--neutral .kid-stat-card__icon {
  background-color: var(--background-alt-grey);
  color: var(--text-title-grey);
}

.local-kid-app .kid-stat-card--warning .kid-stat-card__icon {
  background-color: var(--background-contrast-warning);
  color: var(--text-default-warning);
}

.local-kid-app .kid-stat-card--success .kid-stat-card__icon {
  background-color: var(--background-contrast-success);
  color: var(--text-default-success);
}

.local-kid-app .kid-stat-card--neutral .kid-stat-card__value {
  color: var(--text-title-grey);
}

.local-kid-app .kid-stat-card--warning .kid-stat-card__value {
  color: var(--text-default-warning);
}

.local-kid-app .kid-stat-card--success .kid-stat-card__value {
  color: var(--text-default-success);
}
