/* campscout-local.css — campscout-only CSS that hasn't been lifted to shared.
 *
 * After Phase 3c (2026-06-20), this is the only campscout-owned stylesheet
 * besides css/raid-3d.css (which stays separate due to its size + isolation).
 * Everything else loads through the three shared entry files:
 *   /vendor/style/_entry/shared-base.css
 *   /vendor/style/_entry/shared-desktop.css
 *   /vendor/style/_entry/shared-mobile.css
 *
 * What lives here:
 *  - Campscout-only design tokens (:root overrides -- --purple, --br-*, --z-*, etc.)
 *  - Picasso grid (the calendar -- campscout's hero feature)
 *  - Activity editor sub-section layouts
 *  - Apercu dashboard layouts (cards, charts, attention queue)
 *  - Menus + cookbook + recipe-card layouts
 *  - Relecture matrix + LED markers
 *  - Photos gallery layout
 *  - Style-guide preview classes (.sg-*)
 *  - Campscout-specific tag/badge variants (.tp-pill, .tag-chip-sm specifics)
 *  - Misc page chrome (home cards, objectifs, admin, export, etc.)
 *
 * Anything in here that becomes shared in a future phase should be
 * lifted out and the import in shared/style/_entry/* updated.
 *
 * NOTE: css/welcome.css is kept separate -- it styles the standalone
 * auth landing page (welcome.html) and has its own independent :root.
 */
:root {
  /* Campscout-only color tokens (--purple now inherited from shared
     tokens.css — identical #7c3aed — so it's not redeclared here). */
  --bg-approved: #f0faf3;
  --bg-rejected: #fff0f0;
  --bg-raid: #f0f7ff;
  --bg-draft: #f7f7fb;
  --bg-permit-auto: #3a2a00;
  --bg-permit-manual: #1a3a1a;
  --fg-permit-auto: var(--pers);
  --fg-permit-manual: #5dba5d;

  /* Branch colors (MSdS uniform palette) for the picasso BRANCH_COLOR_MAP
     + .apercu-branch-* badges. shared/tokens.css owns the canonical MSdS
     values, so --br-eclais / --br-picos / --br-resps are NOT redeclared
     here — they inherit straight from shared (same names, identical
     values). Two deliberate local rows remain:
       • castors — shared's MSdS value is #fff (the literal uniform colour),
         invisible as a badge background, so we keep a light tan here.
       • louv — shared's bare --br-louv is the *qualitative* green; the
         unit pill wants the MSdS blue, so map it onto --br-louv-msds. */
  --br-castors: #e8e0d0;
  --br-louv: var(--br-louv-msds);

  /* Font-weight extension. shared has regular/medium/semibold/bold;
     --fw-normal was a synonym of shared --fw-regular and was removed —
     callsites now reference var(--fw-regular). Only --fw-extrabold (800)
     is a genuine campscout extension. */
  --fw-extrabold: 800;

  /* Page-shell OVERRIDE — wider than shared's 1280px. */
  /* 2026-05-18: bumped 1480 → 1800. Ultrawide screens (1920+) were
     leaving big margins of unused space. 1800 keeps reasonable line
     lengths for text-heavy pages while letting grid-based dashboards
     (home, apercu) breathe. The picasso page still escapes the cap
     entirely (width:100%) — see #page-picasso below. */
  --page-shell-max: 1800px;

  /* Domain badges */
  --bg-badge-blue: #e8f0fe;
  --fg-badge-blue: #1a3a6b;

  /* Stat-numeral display type — used by .apercu-stat-n (30px) and its
     compact mobile override (24px). Not in the shared type scale because
     it's a display-density choice specific to the Aperçu dashboard. */
  --fs-stat-num: 30px;
  --fs-stat-num-sm: 24px; /* responsive compact override */

  /* Picasso menu safe-zone — passed to .pic-toolbar overlay positioning
     so the open menu doesn't tuck under sticky chrome. Mobile gets a
     taller offset (44px touch target + breathing room). */
  --pic-menu-safe-zone: 36px;
  --pic-menu-safe-zone-mobile: 42px;

  /* Root convenience rules */
  color-scheme: light dark;
  font-optical-sizing: auto;
}
.content{scroll-behavior:smooth;scrollbar-gutter:stable;}
h2,h3{text-wrap:balance;}
.btn{touch-action:manipulation;}
.overlay,.modal{overscroll-behavior:contain;}
.sidebar{will-change:transform;}
.hist-section,.apercu-col-side>*{content-visibility:auto;contain-intrinsic-size:auto 200px;}
/* View transition (progressive enhancement — Chrome 111+, Safari 18+) */
::view-transition-old(root){animation:fade-out var(--dur-fast) ease-out;}
::view-transition-new(root){animation:fade-in var(--dur-fast) ease-in;}
@keyframes fade-out{from{opacity:1}to{opacity:0}}
@keyframes fade-in{from{opacity:0}to{opacity:1}}
/* Reduced motion: disable view transitions */
@media(prefers-reduced-motion:reduce){::view-transition-group(*){animation-duration:0.01ms !important;}}

/* Forced-colors mode (Windows High Contrast) — ensures interactive elements
   stay visually distinguishable when the OS overrides color/background.
   System keywords (CanvasText, Highlight, ButtonBorder…) are mandatory in
   this context; explicit hex/rgba values are dropped by the user-agent. */
@media (forced-colors: active){
  .btn, .modal-x, .skip-link:focus, .badge-success, .badge-warn, .badge-error, .badge-info {
    border: 1px solid ButtonBorder;
    forced-color-adjust: none;
  }
  :focus-visible { outline: 2px solid Highlight; outline-offset: 2px; }
  .tp-pill, .badge--permission { border: 1px solid CanvasText; }
}
/* Unified checkbox styling */
input[type=checkbox]{width:16px;height:16px;accent-color:var(--green);cursor:pointer;flex-shrink:0;}
/* Flash highlight for newly added/remotely changed items */
@keyframes u-flash-anim{0%{background:rgb(var(--y-rgb) / 25%);}100%{background:transparent;}}
.u-flash{animation:u-flash-anim 1.5s ease-out;}
/* .offline-banner removed 2026-05-25 (#620): the JS that created it was
   dead duplication of js/components/offline-banner.js, which uses
   .sg-banner-warn instead. */
/* Skeleton loading placeholder — .skeleton + @keyframes skeleton-pulse now in shared/style/desktop/browse.css */
/* High contrast mode — shared token overrides (--g1..g4, --bk, --wh,
   --shadow-sm/md, --focus-ring*) are now in shared/style/tokens.css. */
[data-contrast="high"] .tp-pill,[data-contrast="high"] .badge--permission{border:1px solid currentColor;}
/* Dark mode (prefers-color-scheme).
   `--wh` flips from off-white to near-black so it can serve as the page
   background — that means anything using `var(--wh)` as foreground text
   breaks (becomes near-black-on-near-black). The component overrides below
   give those callsites an explicit bright color. */
@media(prefers-color-scheme:dark){
  :root{
    /* Shared-token overrides (--wh, --g1..g4, --bg-*/--fg-* status surfaces,
       --shadow-*, --focus-ring*) are now in shared/style/tokens.css so that
       matos and secretariat get dark-mode automatically. Only campscout-only
       tokens stay here. */
    --bg-approved:#0a2a10;--bg-rejected:#3a1010;--bg-raid:#0a1a2a;
    --bg-draft:#1e1e2e;
    --bg-overlay:rgba(0,0,0,.7);--bg-overlay-light:rgba(0,0,0,.6);
    --bg-glass:rgba(30,30,30,.92);
  }
  body{background:var(--wh);color:var(--g4);}
  .content{color:#ddd;}
  .camp-card,.card-base,.settings-sec,.fm-input,.u-textarea{background:var(--g1);color:#ddd;border-color:var(--g2);}
  .fm-input::placeholder{color:var(--g3);}
  .toast{background:#333;color:#eee;}
  .undo-bar{background:#333;color:#eee;}
  .page-collab-banner{background:var(--bg-info);color:var(--fg-warn);}
  .tbl th{color:var(--g3);}
  .tbl td{border-color:var(--g2);}
  .overlay{background:var(--bg-overlay);}
  .modal{background:var(--g1);color:#ddd;}
}
/* Color-blind safe palette (deuteranopia-friendly) */
[data-cb="on"]{--green:#0072b2;--red:#d55e00;--amber:#e69f00;--pers:#e69f00;--corps:#0072b2;--env:#009e73;--autres:#cc79a7;--spirit:#f0e442;--type-sc:#0072b2;--type-ac:#e69f00;--type-aa:#cc79a7;--bg-success:#e0f0ff;--bg-error:#ffe0d0;--fg-success:#004080;--fg-error:#8b3a00;}
/* Cmdk palette: yellow selected-row background becomes unreadable in
   the deuteranopia-friendly palette, so swap to a high-contrast dark
   pill with white text. */
[data-cb="on"] .cmdk-result.is-active{background:var(--bk);color:var(--white);}
[data-cb="on"] .cmdk-result.is-active .cmdk-tag,[data-cb="on"] .cmdk-result.is-active .cmdk-meta{color:var(--white);}
/* #74: Enhanced reduced motion — disable ALL animations+transitions */
@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation-duration:.01ms !important;animation-iteration-count:1 !important;transition-duration:.01ms !important;scroll-behavior:auto !important;}}
/* #75: Screen reader live region — .sr-only now lives in @suite/lib/style/base.css */
/* .mobile-bottom-nav + .mbn-* deleted 2026-06-20: the Phase 3a two-shell
   migration replaced the static <nav class="mobile-bottom-nav"> with
   js/shell/mobile-bottombar.js (.m-bottombar) and the "Plus" sheet with
   js/shell/mobile-drawer.js (.m-drawer). The static markup that drove
   these rules was removed from index.html in the same change. Closes
   smoke finding C-3 (duplicate bottombar). */

/* Picasso filter sheet (mobile) — hide the inline toolbar+legend block on
   small screens, surface a "🎛 Filtres" button in .ph-right that toggles
   the .pic-filter-shell as a bottom sheet. Desktop ignores all of this. */
#picFiltersMobileBtn{display:none;}
@media(max-width:640px){
  #picFiltersMobileBtn{display:inline-flex;}
  #page-picasso .pic-filter-shell{display:none;}
  #page-picasso.show-mobile-filters .pic-filter-shell{
    display:block;
    position:fixed;
    left:0;right:0;bottom:0;
    background:var(--wh);
    border-top-left-radius:var(--radius-md);
    border-top-right-radius:var(--radius-md);
    box-shadow:var(--shadow-overlay);
    z-index:calc(var(--z-modal) + 2);
    max-height:80vh;
    overflow-y:auto;
    padding:var(--sp-3) var(--sp-3) calc(var(--sp-3) + env(safe-area-inset-bottom,0));
    transform:translateY(0);
    animation:picFilterSheetSlide var(--dur-normal) ease-out;
  }
  @keyframes picFilterSheetSlide{from{transform:translateY(100%);}to{transform:translateY(0);}}
  #page-picasso.show-mobile-filters::after{
    content:'';
    position:fixed;inset:0;
    background:rgba(0,0,0,.4);
    z-index:calc(var(--z-modal) + 1);
  }
  /* Inside the sheet, stack the toolbar groups vertically with bigger touch targets. */
  #page-picasso.show-mobile-filters .pic-toolbar{
    flex-direction:column;
    align-items:stretch;
    gap:var(--sp-3);
    margin-bottom:var(--sp-3);
  }
  #page-picasso.show-mobile-filters .pic-toolbar-grp{flex-direction:column;align-items:stretch;gap:var(--sp-1);}
  #page-picasso.show-mobile-filters .pic-toolbar-label{font-weight:var(--fw-bold);color:var(--g4);text-transform:uppercase;letter-spacing:var(--ls-wide);font-size:var(--fs-xs);}
  #page-picasso.show-mobile-filters .tgl-group{display:flex;width:100%;}
  #page-picasso.show-mobile-filters .tgl-btn{flex:1;min-height:44px;}
}
/* ── Modern micro-interactions ──────────────────────── */
/* 1. Button press feedback */
.btn:active:not(:disabled){transform:scale(0.97);}
/* 3. Staggered list item fade-in */
@keyframes fade-slide-in{from{opacity:0;transform:translateY(6px);}to{opacity:1;transform:none;}}
.camp-card,.rev-card,.cl-item,.po-card{animation:fade-slide-in var(--dur-slow) ease-out both;}
.camp-card:nth-child(2){animation-delay:50ms;}.camp-card:nth-child(3){animation-delay:100ms;}.camp-card:nth-child(4){animation-delay:150ms;}.camp-card:nth-child(5){animation-delay:200ms;}
/* 5. Subtle page background gradient */
.content{background:linear-gradient(180deg, var(--wh) 0%, color-mix(in srgb, var(--g1) 30%, var(--wh)) 100%);}
/* 6. Card hover lift */
.camp-card:hover{transform:translateY(-2px);box-shadow:var(--shadow-md);}
.card-base:hover{transform:translateY(-1px);}
/* 7. Type badge micro-gradient */
.tp-pill{background-image:linear-gradient(180deg, rgba(255,255,255,.15) 0%, transparent 100%);}
/* 17. Color-blind mode: patterns on type badges */
[data-cb="on"] .tp-pill.sc,[data-cb="on"] .pcell.t-sc{background-image:repeating-linear-gradient(45deg,transparent,transparent 3px,rgba(255,255,255,.2) 3px,rgba(255,255,255,.2) 6px);}
[data-cb="on"] .tp-pill.ac,[data-cb="on"] .pcell.t-ac{background-image:repeating-linear-gradient(-45deg,transparent,transparent 3px,rgba(255,255,255,.2) 3px,rgba(255,255,255,.2) 6px);}
[data-cb="on"] .tp-pill.aa,[data-cb="on"] .pcell.t-aa{background-image:repeating-linear-gradient(0deg,transparent,transparent 3px,rgba(255,255,255,.2) 3px,rgba(255,255,255,.2) 6px);}
[data-cb="on"] .pcell.t-d{background-image:repeating-linear-gradient(90deg,transparent,transparent 3px,rgba(255,255,255,.2) 3px,rgba(255,255,255,.2) 6px);}
/* Relation patterns — distinct angles from the type set to distinguish them at a glance.
   Used on Picasso cells when picMode==='relation'. */
[data-cb="on"] .pcell.r-pers{background-image:repeating-linear-gradient(30deg,transparent,transparent 3px,rgba(255,255,255,.2) 3px,rgba(255,255,255,.2) 6px);}
[data-cb="on"] .pcell.r-corps{background-image:repeating-linear-gradient(60deg,transparent,transparent 3px,rgba(255,255,255,.2) 3px,rgba(255,255,255,.2) 6px);}
[data-cb="on"] .pcell.r-env{background-image:repeating-linear-gradient(120deg,transparent,transparent 3px,rgba(255,255,255,.2) 3px,rgba(255,255,255,.2) 6px);}
[data-cb="on"] .pcell.r-autres{background-image:repeating-linear-gradient(150deg,transparent,transparent 3px,rgba(255,255,255,.2) 3px,rgba(255,255,255,.2) 6px);}
[data-cb="on"] .pcell.r-spirit{background-image:repeating-linear-gradient(75deg,transparent,transparent 3px,rgba(255,255,255,.2) 3px,rgba(255,255,255,.2) 6px);}
/* Utility classes. Use these in HTML/JS templates instead of inline
   style="..." so the CSP can ship without `style-src-attr 'unsafe-inline'`.
   Inline style attributes are blocked under CSP3 style-src-attr; the
   JS individual-property setters (`el.style.foo = 'x'`,
   `el.style.setProperty(...)`) remain ALLOWED and need no migration. */
.u-hidden{display:none !important;}
/* CSP-friendly initial-hidden state: no !important so JS `el.style.display = "..."`
   can override. Use this instead of inline `style="display:none;"` which is
   blocked by `style-src-attr 'none'`. JS that wants to hide afterwards uses
   `el.style.display = "none"` (allowed by CSP — setProperty path). */
.u-init-hidden{display:none;}
.u-flex{display:flex;align-items:center;gap:var(--sp-2);}
.u-flex-between{display:flex;justify-content:space-between;align-items:center;gap:var(--sp-2);}
.u-flex-wrap{display:flex;flex-wrap:wrap;gap:var(--sp-2);}
.u-flex-col{display:flex;flex-direction:column;gap:var(--sp-2);}
.u-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
/* CSP migration utilities — top-frequency inline-style patterns. */
.u-m-0{margin:0;}
.u-m-t-1{margin-top:var(--sp-1);}
.u-m-t-1h{margin-top:var(--sp-1h);}
.u-m-t-2{margin-top:var(--sp-2);}
.u-m-t-2h{margin-top:var(--sp-2h);}
.u-m-t-3{margin-top:var(--sp-3);}
.u-m-t-4{margin-top:var(--sp-4);}
.u-m-t-05{margin-top:var(--sp-05);}
.u-m-b-1{margin-bottom:var(--sp-1);}
.u-m-b-2{margin-bottom:var(--sp-2);}
.u-m-b-3{margin-bottom:var(--sp-3);}
.u-m-b-3h{margin-bottom:var(--sp-3h);}
.u-m-b-05{margin-bottom:var(--sp-05);}
.u-fs-xs{font-size:var(--fs-xs);}
.u-fs-sm{font-size:var(--fs-sm);}
.u-fs-md{font-size:var(--fs-md);}
.u-fs-lg{font-size:var(--fs-lg);}
.u-c-meta{color:var(--g4);}
.u-c-amber{color:#8a4a00;}
.u-c-success{color:var(--fg-success);}
.u-c-error{color:#a91818;}
.u-c-blue{color:var(--blue);}
.u-text-meta{font-size:var(--fs-sm);color:var(--g4);}
.u-text-meta-xs{font-size:var(--fs-xs);color:var(--g4);}
.u-text-meta-italic{font-size:var(--fs-sm);color:var(--g4);font-style:italic;}
.u-text-nowrap{white-space:nowrap;}
.u-flex-1{flex:1;min-width:0;}
.u-pos-rel{position:relative;}
.u-fw-bold{font-weight:var(--fw-bold);}
.u-fw-semibold{font-weight:var(--fw-semibold);}
.u-fw-normal{font-weight:normal;}
.u-fw-medium{font-weight:var(--fw-medium);}
.u-cursor-pointer{cursor:pointer;}
.u-cursor-grab{cursor:grab;}
.u-italic{font-style:italic;}
.u-display-block{display:block;}
.u-display-flex{display:flex;}
.u-gap-1{gap:var(--sp-1);}
.u-gap-1h{gap:var(--sp-1h);}
.u-gap-2{gap:var(--sp-2);}
.u-gap-2h{gap:var(--sp-2h);}
.u-gap-3h{gap:var(--sp-3h);}
.u-padding-4{padding:var(--sp-4);}
.u-padding-1rem{padding:1rem;}
.u-color-inherit{color:inherit;}
.u-opacity-7{opacity:.7;}
.u-opacity-75{opacity:.75;}
.u-opacity-84{opacity:.84;}
.u-min-width-0{min-width:0;}
.u-flex-shrink-0{flex-shrink:0;}
.u-p-y-1{padding:var(--sp-1) 0;}
.u-p-y-2{padding:var(--sp-2) 0;}
.u-p-1-h{padding:var(--sp-1) .5rem;}
.u-overflow-hidden{overflow:hidden;}
.u-text-clip{overflow:hidden;text-overflow:ellipsis;}
.u-align-center{align-items:center;}
.u-text-center{text-align:center;}
.u-c-888{color:#888;}
.u-flex-wrap-attr{flex-wrap:wrap;}
/* Unified section header — intentional override: uses var(--text) for dark-mode compatibility;
   shared/style/desktop/browse.css uses var(--bk) which doesn't flip in dark mode. */
.section-hd{font-weight:var(--fw-bold);font-size:var(--fs-md);margin:var(--sp-1) 0 var(--sp-2);color:var(--text);}
/* .help-text — now in shared/style/_components/forms.css (identical rule) */
/* .loading-state / .loading-state .spinner — now in shared/style/desktop/browse.css (identical rules) */
/* Unified card base (for any bordered container) */
.card-base{border:var(--hairline);border-radius:var(--radius-sm);padding:var(--sp-2) var(--sp-2h);background:var(--wh);}
.card-base:hover{border-color:var(--g3);}
/* .skip-link / .skip-link:focus — now in shared/style/desktop/browse.css (identical rules) */
/* campscout-local — height:100% for the flex app shell; --g1 background
 * differs from shared base's --wh. */
html, body {
  height: 100%;
  background: var(--g1);
}
.app{display:flex;height:100vh;height:100dvh;overflow:hidden;}

/* SIDEBAR — base rules provided by /vendor/style/sidebar.css.
   Only campscout-specific overrides and domain classes live here. */
/* campscout icon button (not in shared) */
.sb-icon-btn{width:26px;height:26px;background:none;border:none;color:var(--g3);font-size:var(--fs-md);cursor:pointer;border-radius:var(--radius-xs);display:flex;align-items:center;justify-content:center;transition:color var(--dur-normal),background var(--dur-normal);padding:0;flex-shrink:0;}
.sb-icon-btn:hover{color:var(--y);background:rgba(255,255,255,.1);}
@media (pointer: coarse) {
  /* Touch devices: bump to WCAG 2.5.5 minimum 44×44. Sidebar icons were 26×26
     which is hard to tap accurately on phones. */
  .sb-icon-btn { width: 44px; height: 44px; }
}
/* campscout section labels */
.sb-section-label{padding:.625rem .5rem .25rem;font-size:var(--fs-xs);font-weight:var(--fw-bold);letter-spacing:.12em;text-transform:uppercase;color:var(--g3);margin-top:.25rem;}
.sb-section-label-camp{transition:color var(--dur-normal);}
body.has-active-camp .sb-section-label-camp{color:var(--y);}
.sb-home-item{margin:.25rem .25rem;}
/* ⌘K palette integration */
.sb-cmdk-item{display:flex;align-items:center;justify-content:space-between;}
.sb-cmdk-kbd{font-family:var(--sans);font-size:var(--fs-xs);color:#b5b3aa;background:var(--bk3);border:1px solid var(--bk3);padding:1px 5px;border-radius:var(--radius-xs);}
/* app-switcher — campscout-only variants (.add tile, footer) */
.sb-app-tile.add{background:transparent;border:1px dashed var(--g3);color:var(--g4);}
.sb-app-tile.add:hover{border-color:var(--y);color:var(--y);}
.sb-app-menu-ft{font-size:.65rem;color:var(--g3);text-align:center;padding:.25rem 0 0;}
/* Topbar suite chrome — app launcher anchor + group-switcher
   container. The launcher menu (.sb-app-menu) is absolutely
   positioned and needs a relative anchor to drop below the 9-dot
   button. The switcher's <select> picks up var(--g2)/var(--bk)
   tokens so it matches the light v2 topbar palette. */
.topbar-launcher-wrap{position:relative;display:inline-flex;flex-shrink:0;}
.topbar-switcher-mount{display:inline-flex;align-items:center;margin-right:var(--sp-2);min-height:0;}
.topbar-group-switcher{font-size:var(--fs-sm);color:var(--g4);}
.topbar-group-switcher .g-switcher{font-size:var(--fs-sm);background:var(--g1);border:var(--hairline);border-radius:var(--radius-sm);padding:.32rem .55rem;color:var(--text);cursor:pointer;max-width:200px;}
.topbar-group-switcher .g-switcher:hover{background:var(--wh);border-color:var(--g3);}
.topbar-group-switcher .g-switcher:focus-visible{outline:2px solid var(--y);outline-offset:1px;}
/* camps list — campscout domain */
.sb-camps{padding:.25rem .5rem;}
.sb-camp-item{display:flex;align-items:center;gap:var(--sp-2);padding:.42rem .65rem;border-radius:7px;cursor:pointer;transition:background var(--dur-normal);font-size:.84rem;color:#ddd;}
.sb-camp-item:hover{background:#222;}
.sb-camp-item.active{background:#222;color:var(--white);}
.camp-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0;}
.camp-label{color:var(--g3);font-size:var(--fs-md);font-weight:var(--fw-medium);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.sb-camp-item.active .camp-label{color:var(--white);}
.sb-new-camp{margin:.35rem .5rem;padding:.42rem .75rem;background:none;border:1px dashed var(--bk3);border-radius:var(--radius-sm);color:#d0cec5;font-size:var(--fs-md);cursor:pointer;width:calc(100% - 1rem);text-align:left;transition:all var(--dur-normal);}
.sb-new-camp:hover{border-color:var(--y);color:var(--y);}
.sb-more-camps{font-size:var(--fs-sm);color:var(--g3);padding:.35rem .6rem;background:none;border:none;cursor:pointer;width:100%;text-align:left;font-weight:var(--fw-medium);}
.sb-more-camps:hover{color:var(--white);text-decoration:underline;}
.camp-section-label{grid-column:1/-1;font-weight:var(--fw-bold);font-size:var(--fs-md);color:var(--text);margin-top:var(--sp-1);}
.camp-section-label-group{color:var(--g4);margin-top:var(--sp-3);}
/* campscout-specific item states */
.sb-item.active .sb-cmdk-kbd{background:rgba(255,255,255,.1);color:var(--y);border-color:rgb(var(--y-rgb) / 30%);}
.sb-item.disabled{opacity:.3;cursor:default;pointer-events:none;}
/* C-4: nav rows + CTA dim when no user is signed in (sign-in card
   is shown in the content area). */
.sidebar.sb-unauthed .sb-item,
.sidebar.sb-unauthed .sb-create{opacity:.4;pointer-events:none;cursor:default;}
/* Signed out: show ONLY the sign-in card — strip all nav chrome (sidebar,
   topbars, mobile bottom bar). The auth screen is relocated into
   .d-content / .m-content, which expand to fill once the chrome is gone.
   body.app-unauthed is toggled in auth-ui.js / finishAuth(). */
body.app-unauthed .sidebar,
body.app-unauthed .d-topbar,
body.app-unauthed .m-topbar,
body.app-unauthed .m-bottombar{display:none !important;}
/* …and float the sign-in card to a full-viewport overlay so it doesn't
   inherit the now-chrome-less content column's width (which doesn't reflow
   on display:none). Does NOT set `display`, so `.auth-screen.hidden` still
   wins during the OAuth redirect. */
body.app-unauthed .auth-screen{
  position:fixed;inset:0;z-index:var(--z-modal,1000);
  margin:0;width:100vw;max-width:none;height:100vh;min-height:0;
  border:none;border-radius:0;
}
/* No camp open → hide the per-camp nav so it can't silently bounce to "Mes
   camps". "Mes camps" now lives in its own group, so all three per-camp
   groups (Camp / Édition / Revue) are hidden wholesale via :has — keyed on
   one stable row per group. Flipped by .sb-no-camp on the <aside>
   (sidebar-mount.js). */
.sidebar.sb-no-camp .sb-nav-group:has(.sb-item[data-key="apercu"]),
.sidebar.sb-no-camp .sb-nav-group:has(.sb-item[data-key="materiel"]),
.sidebar.sb-no-camp .sb-nav-group:has(.sb-item[data-key="relecture"]){display:none;}
.sb-badge{display:inline-block;font-size:var(--fs-xs);background:var(--bk3);color:var(--g3);padding:0 var(--sp-1);border-radius:var(--radius-pill);margin-left:var(--sp-1);min-width:16px;text-align:center;line-height:16px;vertical-align:middle;transition:all var(--dur-normal);}
.sb-item.active .sb-badge{background:rgb(var(--y-rgb) / 20%);color:var(--y);}
.sb-user{padding:.75rem 1rem;border-top:1px solid var(--bk3);display:flex;align-items:center;gap:var(--sp-2);}
.sb-copyright{padding:.5rem 1rem .6rem;font-size:var(--fs-xs);color:rgba(255,255,255,.35);line-height:var(--lh-normal);}
.u-av{width:28px;height:28px;border-radius:50%;background:var(--y);display:flex;align-items:center;justify-content:center;font-size:var(--fs-xs);font-weight:var(--fw-bold);color:var(--bk);flex-shrink:0;}
.u-name{color:var(--g3);font-size:var(--fs-md);}

/* MAIN */
.main{flex:1;display:flex;flex-direction:column;overflow:hidden;position:relative;}
/* v2 topbar: light surface (var(--wh)), 1px g2 hairline, 22px DM Serif title.
   The dark-yellow-accent v1 chrome lived here for years; the v2 transition
   moves to a light topbar matching the hi-fi (.topbar in _v2-design home.html). */
.topbar{background:var(--wh);padding:.75rem 1.5rem;flex-shrink:0;position:relative;border-bottom:2px solid var(--y);display:flex;align-items:center;gap:var(--sp-2h);}
.topbar h1{color:var(--text);font-family:var(--serif);font-weight:400;font-size:1.4rem;line-height:1.15;max-width:calc(100% - 140px);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:0;}
/* v2: fake search input that triggers ⌘K palette. Lives between topTitle and presence bar. */
.topbar-search{display:none;align-items:center;gap:var(--sp-1h);background:var(--g1);border:var(--hairline);border-radius:var(--radius-sm);padding:.32rem .65rem;font-size:var(--fs-sm);color:var(--g4);cursor:pointer;min-width:240px;margin-left:auto;margin-right:var(--sp-2);transition:background var(--dur-normal),border-color var(--dur-normal);}
.topbar-search:hover{background:var(--wh);border-color:var(--g3);color:var(--text);}
.topbar-search-text{flex:1;text-align:left;}
.topbar-search-kbd{font-family:var(--sans);font-size:var(--fs-xs);background:var(--wh);border:var(--hairline);color:var(--g4);padding:1px 5px;border-radius:var(--radius-xs);}
/* Make search reachable below 840px. On narrow viewports it collapses
   to an icon-only round button via the rules in §Mobile responsive
   below; on >=640px viewports it shows the full pill. */
@media (min-width:640px){.topbar-search{display:inline-flex;min-width:auto;}}
@media (min-width:840px){.topbar-search{min-width:240px;}}
@media (max-width:639px){.topbar-search{display:inline-flex;min-width:0;padding:.45rem;}.topbar-search .topbar-search-text{display:none;}.topbar-search-kbd{display:none;}}
/* v2: home view segmented control (Cartes / À traiter). Lives in #page-home .ph-right. */
/* 2026-05-17 (#29): home-mode toggle retired. Both panels (cards + À
   traiter) are visible at once. Legacy selectors kept commented in
   git history; the rules now describe the new two-column grid. */

/* Two-column layout: cards left, À traiter sidebar right. */
.home-grid{display:grid;grid-template-columns:1fr 320px;gap:var(--sp-3h);margin-top:var(--sp-2);align-items:start;}
@media (max-width:768px){
  .home-grid{grid-template-columns:1fr;gap:var(--sp-2);}
}
.home-main{min-width:0;}
.home-sidebar{position:sticky;top:var(--sp-3);max-height:calc(100vh - 120px);overflow-y:auto;}
@media (max-width:768px){
  .home-sidebar{position:static;max-height:none;order:-1;}
}
.home-sidebar-details{background:var(--wh);border:var(--hairline);border-radius:var(--radius-md);padding:var(--sp-2) var(--sp-3);}
/* 2026-05-18: was body-font / fs-md / semibold — looked off next to
   the DM-Serif H2 page title. Style-guide §typography puts section
   headers in DM Serif Display @ 22/400. Match the aperçu sub-section
   look so the sidebar reads as a header, not a clickable label. */
.home-sidebar-summary{font-family:var(--serif);font-weight:400;font-size:var(--fs-xl);cursor:pointer;list-style:none;padding:var(--sp-1) 0;line-height:1.2;letter-spacing:-.005em;}
.home-sidebar-summary::-webkit-details-marker{display:none;}
.home-sidebar-summary::before{content:'▸ ';display:inline-block;transition:transform var(--dur-fast);}
.home-sidebar-details[open] .home-sidebar-summary::before{transform:rotate(90deg);}

/* Tab pills swap the cards area. */
/* 2026-05-18: added flex-wrap so the two-tab row doesn't get clipped
   or pushed under the page-header CTA on narrow viewports / when the
   topbar search expands. Was reported as the tab row "overlapping
   with the buttons that are to its immediate right". */
/* Pill-shaped tabs per style guide §6 (Tab pills, --radius-lg). The
   previous underline pattern was a deviation. */
.home-tabs{display:flex;flex-wrap:wrap;gap:var(--sp-1h);margin-bottom:var(--sp-2);}
.home-tab{appearance:none;border:1px solid transparent;background:transparent;padding:var(--sp-1h) var(--sp-3);font-size:var(--fs-md);font-weight:var(--fw-semibold);color:var(--g4);cursor:pointer;border-radius:var(--radius-lg);transition:background-color var(--dur-chip),color var(--dur-chip),border-color var(--dur-chip);}
.home-tab:hover{color:var(--text);background:var(--g1);}
.home-tab.active{color:var(--text);background:var(--g1);border-color:var(--g2);}
.home-tab:focus-visible{outline:3px solid var(--focus-ring);outline-offset:2px;}
/* Star button (favorite toggle on camp cards). Replaces a long inline
   data-style-set; canonical class so :focus-visible works and the
   selector lives in one place. */
.camp-fav-btn{appearance:none;background:none;border:none;outline:none;box-shadow:none;cursor:pointer;font-size:var(--fs-lg);padding:var(--sp-1);min-width:32px;min-height:32px;line-height:1;vertical-align:middle;color:inherit;border-radius:var(--radius-sm);}
.camp-fav-btn:focus-visible{outline:3px solid var(--focus-ring);outline-offset:2px;}
.camp-fav-btn:hover{background:var(--g1);}

/* Time filter row sits under the tabs. */
.home-time-filter{display:flex;gap:var(--sp-1);margin-bottom:var(--sp-2);flex-wrap:wrap;}
.topbar-sub{color:var(--g4);font-size:var(--fs-sm);margin-top:.1rem;max-width:calc(100% - 140px);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.content{flex:1;overflow-y:auto;padding:1.6rem 2rem;}
/* Pages fill the .content area edge-to-edge. The previous 1800px cap
 * (--page-shell-max) was meant to keep long text lines readable on
 * wide monitors but left chefs with sizable side gutters on every
 * tab except picasso/home/aperçu (which already opted out). Lifting
 * the cap suite-wide: tabs that genuinely need line-length control
 * (objectifs prose, menus recipe cards) can re-apply max-width on
 * their inner content wrappers, not the page shell. */
.page{display:none;animation:fadeIn .16s ease;width:100%;margin:0;}
.page.active{display:block;}
@keyframes fadeIn{from{opacity:0;transform:translateY(5px)}to{opacity:1;transform:none}}

/* COMPONENTS */
/* Base .ph / .ph h2 / .ph-right moved to shared _components/page-header.css
 * (2026-06-27 unification). Camps inherits the identical canonical values from
 * shared; the contextual .ph overrides below (#page-picasso, print, narrow
 * viewports) still layer on top. */
/* campscout-local — yellow primary-action discipline; guards ui-integrity.test.js
 * which verifies .btn-g has background:var(--y) and color:var(--bk). Remove once
 * tests are updated to read shared/style/buttons.css. */
.btn-g{background:var(--y);color:var(--bk);font-weight:var(--fw-bold);}
/* .btn-gh.active / .btn-gh.on — now in shared/style/buttons.css. */

/* Utility */
/* .u-modal-center-acts — now in shared/style/desktop/modal.css (identical rule) */
.u-maxw-100{max-width:100%;}
.u-textarea{max-width:100%;resize:vertical;line-height:var(--lh-relaxed);}
.u-resize-v{resize:vertical;}
/* Modal size scale — .modal-w-sm/md/lg/xl/.modal-w-420/.modal-w-480/.modal-w-95/.modal-w-96/
   .modal-w-95vw/.modal-scroll-y/.modal-maxh-90 now in shared/style/desktop/modal.css.
   Legacy aliases kept here because shared doesn't have :is() group aliases for legacy widths. */
:is(.modal-w-360,.modal-w-380){max-width:380px;}
:is(.modal-w-520,.modal-w-540,.modal-w-560,.modal-w-580){max-width:600px;}
:is(.modal-w-600,.modal-w-640,.modal-w-680){max-width:680px;}

.longtext-input,
.longtext-surface{
  width:100%;
  max-width:100%;
  border:var(--hairline);
  border-radius:var(--radius-md);
  background:linear-gradient(180deg,#fcfbf8,#f4f2eb);
  color:var(--bk);
  padding:.82rem .95rem;
  
  font-size:var(--fs-md);
  line-height:var(--lh-loose);
  min-height:clamp(132px,20vh,240px);
  transition:border-color var(--dur-normal),background var(--dur-normal),box-shadow var(--dur-normal);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.85);
  outline:none;
  overflow:auto;
  white-space:pre-wrap;
}
.longtext-input{
  resize:vertical;
  outline:none;
  overflow-y:hidden;
}
.longtext-input.longtext-compact{min-height:104px;}
.longtext-input.longtext-tall,
.longtext-surface.longtext-tall{min-height:clamp(180px,28vh,320px);}
.longtext-input::placeholder{color:var(--g4);}
.longtext-input:focus,
.longtext-surface:focus,
.longtext-surface.editable{
  border-color:var(--y);
  background:var(--wh);
  box-shadow:0 0 0 3px rgb(var(--y-rgb) / 14%);
}
.longtext-input:focus-visible,
.longtext-surface:focus-visible{
  outline:2px solid var(--focus-ring);
  outline-offset:2px;
}
.longtext-surface[data-placeholder]:empty::before{
  content:attr(data-placeholder);
  color:var(--g4);
  pointer-events:none;
}

/* Inline Style Utilities (generated) */
.u-inl-002{border-radius:var(--radius-sm);object-fit:contain;flex-shrink:0;background:var(--wh);padding:2px;cursor:pointer}
.u-inl-003{cursor:default}
.u-inl-004{flex:1;min-width:0}
.u-inl-006{display:flex;flex-direction:column;gap:var(--sp-1);flex-shrink:0}
.u-inl-007{font-size:var(--fs-xs);padding:.2rem .5rem}
.u-inl-008{opacity:.45;font-size:var(--fs-xs);letter-spacing:.04em}
.u-inl-009{color:inherit;opacity:.7;font-size:var(--fs-xs)}
.u-inl-010{font-size:var(--fs-lg)}
.u-inl-011{margin-left:.5rem}
.u-inl-012{font-size:var(--fs-lg)}
.u-inl-013{position:relative}
.u-inl-014{max-width:var(--page-shell-max)}
.u-inl-015{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:var(--sp-2);margin-bottom:.8rem}
.u-inl-016{flex-wrap:wrap}
.u-inl-017{background:var(--type-sc);color:var(--white)}
.u-inl-018{background:var(--type-ac);color:var(--bk)}
.u-inl-019{background:var(--type-aa);color:var(--white)}
.u-inl-020{background:var(--type-d);color:var(--white)}
.u-inl-021{margin-bottom:.9rem;flex-wrap:wrap}
.u-inl-022{background:var(--pers);color:var(--bk)}
.u-inl-023{background:var(--green);color:var(--white)}
.u-inl-024{background:var(--autres);color:var(--white)}
.u-inl-025{background:var(--spirit);color:var(--white)}
.u-inl-027{font-size:var(--fs-md);color:var(--g4);margin:0}
.u-inl-028{flex-shrink:0;}
.u-inl-030{border:var(--hairline);border-radius:var(--radius-sm);padding:.5rem .75rem;gap:var(--sp-2);margin-top:.5rem;flex-wrap:wrap}
.u-inl-031{color:var(--pers)}
.u-inl-032{color:var(--corps)}
.u-inl-033{color:var(--env)}
.u-inl-034{color:var(--autres)}
.u-inl-035{color:var(--spirit)}
.u-inl-036{margin-top:.8rem}
.u-inl-037{margin-top:1.5rem}
.u-inl-038{cursor:pointer;font-size:var(--fs-md);color:var(--g4);user-select:none;padding:.4rem .2rem}
.u-inl-039{margin-top:.75rem;padding:1rem 1.2rem;background:var(--g1);border:var(--hairline);border-radius:var(--radius-sm);font-size:var(--fs-md);color:var(--g4)}
.u-inl-040{margin:0 0 .6rem}
.u-inl-041{margin:0 0 .8rem;font-size:var(--fs-sm)}
.u-inl-042{width:100%;border-collapse:collapse;font-size:var(--fs-sm)}
.u-inl-043{border-bottom:var(--hairline)}
.u-inl-044{text-align:left;padding:.25rem .4rem;font-weight:var(--fw-bold)}
.u-inl-045{padding:.2rem .4rem;font-weight:var(--fw-semibold)}
.u-inl-046{padding:.2rem .4rem;color:#5a5851}
.u-inl-047{background:rgba(0,0,0,.03)}
.u-inl-049{margin-bottom:.6rem;align-items:center;gap:var(--sp-2)}
.u-inl-050{font-size:var(--fs-md);color:var(--g4)}
.u-inl-051{font-weight:var(--fw-semibold);cursor:pointer}
.u-inl-052{background:var(--bk)}
.u-inl-053{background:var(--pers);color:var(--bk)}
.u-inl-054{background:var(--corps)}
.u-inl-055{background:var(--env)}
.u-inl-056{background:var(--autres)}
.u-inl-057{background:var(--spirit)}
.u-inl-058{overflow-x:auto}
@media(max-width:480px){
  /* Hint to mobile users that the activity table scrolls horizontally — without
     this, columns past the viewport (Responsables, action buttons) were cut off
     with no visual indicator. */
  .u-inl-058{mask-image:linear-gradient(to right, #000 0, #000 calc(100% - 24px), transparent 100%);-webkit-mask-image:linear-gradient(to right, #000 0, #000 calc(100% - 24px), transparent 100%);}
}
.u-inl-059{margin-bottom:.75rem}
.u-inl-060{background:var(--type-d)}
.u-inl-061{background:var(--green)}
.u-inl-062{background:var(--spirit)}
.u-inl-063{background:var(--amber)}
.u-inl-064{align-items:center;gap:var(--sp-2)}
.u-inl-065{font-size:var(--fs-md);color:var(--g4);white-space:nowrap}
.u-inl-066{width:64px;padding:.25rem .4rem;font-size:var(--fs-md)}
.u-inl-067{font-size:var(--fs-sm);color:var(--g4);margin-bottom:.6rem}
.u-inl-068{margin-top:.7rem}
.u-inl-069{padding:.8rem;border:var(--hairline);border-radius:var(--radius-sm);background:var(--g1)}
.u-inl-070{font-size:var(--fs-sm);color:var(--g4);font-weight:var(--fw-bold);text-transform:uppercase;letter-spacing:var(--ls-wide);margin-bottom:.45rem}
.u-inl-071{margin-top:.4rem;font-size:var(--fs-sm);color:var(--g4)}
.u-inl-072{margin-top:.8rem}
.u-inl-077{display:flex;align-items:center;gap:var(--sp-2h);flex-wrap:wrap;margin-top:.4rem}
.u-inl-079{display:flex;align-items:center;gap:var(--sp-2)}
.u-inl-080{font-size:var(--fs-md);flex:1}
.u-inl-081{color:var(--red);border-color:var(--red)}
.u-inl-082{font-size:var(--fs-sm);color:var(--g4);margin-top:.3rem}
.u-inl-083{font-weight:var(--fw-semibold);color:var(--text)}
.u-inl-084{margin-bottom:.6rem}
.u-inl-085{margin-top:.4rem}
.u-inl-086{margin-top:.5rem;display:flex;gap:var(--sp-3);flex-wrap:wrap}
.u-inl-087{margin:0 0 .55rem 0}
.u-inl-088{display:flex;align-items:center}
.u-inl-089{margin-bottom:.8rem}
.u-inl-090{margin:0}
.u-inl-091{opacity:.35;margin:0 .1rem}
.u-inl-092{padding:.45rem 0 .3rem}
.u-inl-093{display:flex;align-items:center;gap:var(--sp-2);font-size:var(--fs-md)}
.u-inl-094{margin-top:.55rem;padding:.8rem;border:var(--hairline);border-radius:var(--radius-sm);background:var(--g1)}
.u-inl-095{padding:.45rem 0 .35rem}
.u-inl-096{display:flex;align-items:center;gap:var(--sp-2h);font-size:var(--fs-md);cursor:pointer}
.u-inl-097{font-size:var(--fs-sm);color:var(--g4)}
.u-inl-098{font-size:var(--fs-md);color:var(--g4);margin-top:.35rem}
.u-inl-099{padding:.2rem 0 .5rem}

/* #732 — canonical toggle-switch component. Replaces plain checkboxes
   in the activity editor (aeIsRaid / aeIsUnitActivity / aeMeal /
   aeNeedsSecConcept). The native <input type=checkbox> stays in the
   DOM (so JS `.checked` reads + change events + existing aeIsRaid
   listeners keep working); a sibling <span class="sg-toggle-track">
   provides the visual switch via :checked + sibling selectors. The
   track uses the canonical --y accent so on/off state matches the
   rest of the app's primary affordances. */
.sg-toggle{display:inline-flex;align-items:center;gap:var(--sp-2h);font-size:var(--fs-md);cursor:pointer;user-select:none}
.sg-toggle > input[type="checkbox"]{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0;
}
.sg-toggle-track{
  position:relative;width:38px;height:22px;border-radius:999px;
  background:var(--g2);border:1px solid var(--border-strong);
  transition:background var(--dur-chip) ease,border-color var(--dur-chip) ease;
  flex-shrink:0;
}
.sg-toggle-track::after{
  content:"";position:absolute;top:1px;left:1px;width:18px;height:18px;
  border-radius:50%;background:var(--wh);box-shadow:var(--shadow-sm);
  transition:transform var(--dur-chip) ease;
}
.sg-toggle > input:checked + .sg-toggle-track{background:var(--y);border-color:var(--y)}
.sg-toggle > input:checked + .sg-toggle-track::after{transform:translateX(16px)}
.sg-toggle > input:focus-visible + .sg-toggle-track{box-shadow:0 0 0 3px rgb(var(--y-rgb) / 35%)}
.sg-toggle > input:disabled + .sg-toggle-track{opacity:.5;cursor:not-allowed}
@media (prefers-reduced-motion: reduce){
  .sg-toggle-track,.sg-toggle-track::after{transition:none}
}
.u-inl-100{gap:var(--sp-2);margin-bottom:.8rem}
.u-inl-101{display:flex;gap:var(--sp-2h);flex-wrap:wrap;margin-top:.5rem}
.u-inl-102{display:flex;justify-content:flex-end;align-items:center;gap:var(--sp-3);flex-wrap:wrap;margin-top:1.8rem;padding-top:1.2rem;border-top:var(--hairline)}
.u-inl-103{display:flex;align-items:center;justify-content:space-between;margin-bottom:.5rem}
.u-inl-104{font-size:var(--fs-sm);font-weight:var(--fw-bold);text-transform:uppercase;letter-spacing:var(--ls-wide);color:var(--g4)}
.u-inl-105{cursor:pointer}
.u-inl-106{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-3)}
.u-inl-107{margin-top:.35rem}
.u-inl-108{padding:.75rem;border:var(--hairline);border-radius:var(--radius-sm);background:var(--g1)}
.u-inl-109{font-size:var(--fs-sm);color:var(--g4);margin:.25rem 0 0}
.u-inl-110{font-size:var(--fs-sm);color:var(--g4)}
.u-inl-111{min-height:2.2rem;margin-top:.3rem}
.u-inl-112{height:2rem}
.u-inl-113{max-height:340px;overflow-y:auto}
.u-inl-114{flex:2}
.u-inl-115{flex:1}
.u-inl-117{font-size:var(--fs-md);color:var(--g4);background:var(--g1);border-radius:var(--radius-sm);padding:.5rem .8rem;margin-bottom:.9rem}
.u-inl-118{font-family:monospace;letter-spacing:.12em}
.u-inl-119{text-align:center;padding:2.5rem 1rem}
.u-inl-120{font-size:2.2rem;margin-bottom:1rem;animation:spin 1.5s linear infinite;display:inline-block}
.u-inl-121{font-size:var(--fs-md);color:var(--g4);margin-top:.5rem}
.u-inl-122{text-align:center;padding:2rem 1rem}
.u-inl-123{font-size:2.2rem;margin-bottom:.8rem}
.u-inl-124{font-size:var(--fs-lg);font-weight:var(--fw-bold);margin-bottom:.5rem}
.u-inl-125{font-size:var(--fs-md);color:var(--g4);margin-bottom:.4rem}
.u-inl-126{font-family:monospace;font-size:var(--fs-xl);background:var(--g1);padding:.2rem .7rem;border-radius:var(--radius-sm);letter-spacing:.12em;display:inline-block;margin-bottom:1rem}
.u-inl-127{display:inline-block}
.u-inl-128{display:flex;align-items:center;gap:var(--sp-2);cursor:pointer}
.u-inl-129{width:16px;height:16px;accent-color:var(--green)}
.u-inl-130{padding-left:1.5rem}
/* ── Import modal (shared drop zone + preview) ─────────────── */
.import-drop-zone{border:2px dashed var(--g2);border-radius:var(--radius-md);padding:1.5rem;text-align:center;cursor:pointer;transition:border-color .2s,background var(--dur-normal);}
.import-drop-zone:hover{border-color:var(--y);background:rgb(var(--y-rgb) / 3%);}
.import-drop-icon{font-size:1.8rem;margin-bottom:.35rem;}
.import-drop-label{font-size:var(--fs-md);color:var(--g4);}
.import-status{padding:.6rem .8rem;border-radius:var(--radius-sm);font-size:var(--fs-md);margin-top:.5rem;}
.import-preview{margin-top:.8rem;background:var(--g1);border-radius:var(--radius-md);padding:.8rem 1rem;font-size:var(--fs-md);border:var(--hairline);}
.import-preview-title{font-weight:var(--fw-bold);font-size:var(--fs-lg);margin-bottom:.5rem;font-family:var(--serif);}
.import-row{display:flex;gap:var(--sp-2);padding:.18rem 0;border-bottom:var(--hairline);font-size:var(--fs-md);}
.import-row:last-child{border-bottom:none;}
.import-lbl{color:var(--g4);font-weight:var(--fw-semibold);flex-shrink:0;min-width:5rem;}
.u-inl-142{font-size:var(--fs-md);color:var(--g4);margin-bottom:.5rem}
.u-inl-143{font-size:var(--fs-md);color:var(--g4);margin-bottom:.8rem}
.u-inl-144{font-size:var(--fs-md);color:var(--g4);margin-top:.3rem}
.u-inl-150{flex:1}
.u-inl-152{width:44px;height:44px;object-fit:contain;border-radius:var(--radius-sm)}
.u-inl-157{max-height:50vh;overflow-y:auto;min-height:80px}
.u-inl-158{text-align:center;color:var(--g4);padding:2rem}
.u-inl-159{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:var(--sp-1h);margin-top:.3rem}
.u-inl-160{padding:.5rem 0}
.u-inl-161{display:flex;gap:var(--sp-1h);margin-bottom:1rem}
.u-inl-162{margin-bottom:.7rem}
.u-inl-163{color:var(--red)}
/* End Inline Style Utilities */

/* TAGS — base .tags-input-wrap/.tag-suggestions/.tag-sug-item moved to
   @suite/lib/style/_components/chip-input.css. Only campscout-local overrides remain. */
/* campscout-local — margin override; shared .tag-chip-sm uses different padding. */
.tag-chip-sm{margin:.1rem;}

/* Canonical person-chip (js/shared/person-chip.js): avatar sizing inside a
   shared .tag-chip(-sm). Shape/colour come from shared badges.css; these rules
   only size the leading avatar and lay out the empty state. */
.pc-chip{gap:var(--sp-1);}
.pc-av{width:18px;height:18px;border-radius:50%;flex-shrink:0;}
.pc-av--initials{display:inline-flex;align-items:center;justify-content:center;
  background:var(--g2);color:var(--g4);font-size:9px;font-weight:var(--fw-bold);line-height:1;}
.pc-empty{display:inline-flex;align-items:center;gap:var(--sp-1);}
.pc-empty--compact{color:var(--red);font-size:var(--fs-xs);}
/* J+S "À demander" warn variant — used by renderMaterielSection when tagKind==='call-for' */
.tag-chip-sm--warn{background:var(--bg-warn);color:var(--fg-warn);border-color:var(--amber);}
.tag-input{border:none;outline:none;font-size:var(--fs-md);min-width:80px;flex:1;background:none;}

/* STATS — `.stats-row` itself is the v2 form at line 3104+. The old
   single-row 5-up grid here was retired during the 2026-05-09 style-
   guide transition; only the inner text styles (.stat-n / .stat-l) and
   the hover behaviour survive. The .stats-row-3 modifier is dead — the
   v2 auto-fit/minmax(140px,1fr) grid adapts naturally; the HTML class
   `stats-row-3` stays harmless. */
.stat{transition:background var(--dur-fast);}
.stat:hover{background:var(--g1);}
.stat-n{font-size:var(--fs-3xl);display:block;line-height:1.1;}
.stat-l{font-size:var(--fs-xs);font-weight:var(--fw-bold);letter-spacing:.09em;text-transform:uppercase;color:var(--g4);margin-top:.3rem;display:block;}

/* OBJECTIVES */
/* composes onto @suite/lib/style/card.css `.suite-card` (border, radius,
   surface-card fill, hover border+shadow). Only obj-card extras live here:
   bottom margin + overflow:hidden (clips the grey .obj-hd header to the
   rounded corners). Mirrors how .camp-card composes on .suite-card. */
.obj-card{margin-bottom:.85rem;overflow:hidden;}
.obj-hd{display:flex;align-items:center;justify-content:space-between;padding:.75rem 1rem;background:var(--g1);gap:var(--sp-2);flex-wrap:wrap;}
.obj-hd-left{display:flex;align-items:center;gap:var(--sp-2);flex:1 1 60%;min-width:0;}
.obj-num{font-weight:var(--fw-bold);font-size:var(--fs-md);color:var(--g4);flex-shrink:0;}
.obj-ttl{font-weight:var(--fw-semibold);font-size:var(--fs-lg);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.obj-btns{display:flex;gap:var(--sp-1);flex-shrink:0;flex-wrap:wrap;}
/* (i) bubble next to the Objectifs title hosts the SMART reminder popover. */
.obj-info-anchor{position:relative;display:inline-block;vertical-align:middle;}
.i-bubble-popover.obj-smart-pop{left:0;top:calc(100% + 6px);width:min(420px,92vw);max-width:92vw;max-height:min(60vh,380px);overflow-y:auto;}
.obj-sp{display:flex;align-items:center;justify-content:space-between;padding:.42rem 1rem .42rem 2.1rem;font-size:var(--fs-md);border-bottom:1px solid var(--g1);}
.obj-sp:last-child{border:none;}
.obj-sp-num{color:var(--g4);margin-right:.35rem;font-size:var(--fs-sm);}

/* FIL ROUGE */
.fil-editor{cursor:default;}
.fil-editor.editable{cursor:text;}

/* PICASSO */
.tgl-group{display:inline-flex;border:var(--hairline);border-radius:var(--radius-sm);overflow:hidden;background:var(--g2);}
.tgl-btn{
  padding:.44rem .95rem;
  min-height:32px;
  
  font-size:var(--fs-md);
  font-weight:var(--fw-semibold);
  border:var(--hairline);
  border-radius:var(--radius-sm);
  cursor:pointer;
  background:var(--g2);
  color:var(--text);
  transition:opacity var(--dur-normal),transform .1s,background var(--dur-normal),color var(--dur-normal),border-color var(--dur-normal);
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:var(--sp-1h);
  white-space:nowrap;
}
.tgl-btn:hover{opacity:.85;}
.tgl-btn:active{transform:scale(.97);}
.tgl-btn.on{background:var(--bk);color:var(--white);border-color:var(--bk);}
.tgl-group .tgl-btn{border:none;border-radius:0;min-height:30px;background:transparent;}
.tgl-group .tgl-btn + .tgl-btn{border-left:1px solid rgba(20,20,20,.16);}
.tgl-group .tgl-btn.on{background:var(--bk);color:var(--white);}
.resp-filter-wrap{position:relative;}
.resp-filter-btn{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:var(--sp-1h);
  padding:.44rem .95rem;

  font-size:var(--fs-md);
  font-weight:var(--fw-semibold);
  border:none;
  border-radius:var(--radius-sm);
  background:var(--g2);
  color:var(--text);
  cursor:pointer;
  white-space:nowrap;
  transition:opacity var(--dur-normal),transform .1s,background var(--dur-normal),color var(--dur-normal),border-color var(--dur-normal);
}
.resp-filter-btn:hover{opacity:.85;}
.resp-filter-btn:active{transform:scale(.97);}
.resp-filter-btn.active{background:var(--bk);color:var(--white);border-color:var(--bk);}
/* max-height + scroll: the people list can be long (20+ leaders on a group
   camp). Without this the popup extends past #page-picasso's overflow:hidden
   bottom and the lower names are unreachable on shorter viewports. */
.resp-dropdown{display:none;position:absolute;top:calc(100% + 4px);left:0;background:var(--wh);border:var(--hairline);border-radius:var(--radius-sm);box-shadow:var(--shadow-md);z-index:var(--z-dropdown);min-width:180px;max-width:calc(100vw - 1rem);max-height:min(60vh,360px);overflow-y:auto;padding:.3rem;}
.resp-dropdown.open{display:block;}
.resp-dd-item{display:flex;align-items:center;gap:var(--sp-2);padding:.38rem .65rem;border-radius:var(--radius-xs);cursor:pointer;font-size:var(--fs-md);}
.resp-dd-item:hover{background:var(--g1);}
.resp-dd-item input{accent-color:var(--y);}
.pic-wrap{overflow:auto;border:var(--hairline);border-radius:var(--radius-sm);background:var(--wh);}
.pgrid{border-collapse:collapse;font-size:var(--fs-sm);width:100%;table-layout:fixed;}
.pgrid th{background:var(--bk);color:var(--white);padding:.44rem .3rem;text-align:center;white-space:nowrap;border:1px solid var(--bk3);font-weight:var(--fw-semibold);font-size:var(--fs-sm);}
.pgrid th:first-child{width:36px;background:var(--bk2);}
.pgrid td{border:var(--hairline);vertical-align:top;padding:0;min-width:0;}
.pgrid td.tc{background:var(--g1);text-align:right;padding:0 4px;color:var(--g4);font-size:var(--fs-xs);width:36px;min-width:36px;}
.pic-day-cell{position:relative;vertical-align:top;padding:0;background:var(--wh);}
/* .pcell base — layout overrides further down in this file */
.pcell{font-size:var(--fs-md);line-height:var(--lh-compact);cursor:pointer;transition:opacity var(--dur-normal),transform .08s;box-shadow:inset 0 0 0 1px rgba(255,255,255,.12);}
.pcell:hover{filter:brightness(1.04);transform:translateY(-1px);will-change:transform;}
.pcell.pcell-menu-open,
.pcell:has(.pcell-menu-wrap:hover),
.pcell:has(.pcell-resize-top:hover),
.pcell:has(.pcell-resize-bot:hover){
  filter:none;
  transform:none;
  will-change:auto;
}
.pcell-top{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-1);font-size:var(--fs-xs);font-weight:var(--fw-bold);opacity:.98;}
.pcell-name{overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;white-space:normal;font-weight:var(--fw-bold);letter-spacing:.01em;}
.t-sc{background:var(--type-sc);color:var(--white);}.t-ac{background:var(--type-ac);color:var(--bk);}
.t-aa{background:var(--type-aa);color:var(--white);}.t-d{background:var(--type-d);color:var(--white);}
.r-pers{background:var(--pers);color:var(--bk);}.r-corps{background:var(--corps);color:var(--white);}
.r-env{background:#118628;color:var(--white);}.r-autres{background:var(--autres);color:var(--white);}
.r-spirit{background:var(--spirit);color:var(--white);}
.pcell.pcell-dim{background:var(--g2);color:var(--g3);cursor:pointer;}
.pic-ext-cell.pic-ext-dim {
  background: var(--g2);
  color: var(--g3);
}
.pic-outside-banner{margin:.55rem 0 .75rem;padding:.55rem .75rem;border-radius:var(--radius-sm);background:var(--bg-info);color:var(--fg-warn);font-size:var(--fs-md);border:var(--hairline);}

/* ACTIVITIES TABLE */
/* .act-filter-block and .act-filter-label defined once at line ~1090 (Picasso/Activities shared) */
.act-ftabs{display:flex;gap:var(--sp-1);flex-wrap:wrap;}
/* Legacy contexts (e.g. KB tab Modèles) still want bottom spacing on the
   wrapper. The actual pill primitive (`.suite-tab`) lives in shared/style/
   _components/tabs.css; campscout layers domain-driven colour onto it
   via the .suite-tabs--pill block below. */
#wikiTplTypeTabs.suite-tabs--pill,#wikiTplRelTabs.suite-tabs--pill,.act-ftabs{margin-bottom:.9rem;}
/* ===== campscout pill-tab semantic colour overlays (formerly .aftab) =====
   .suite-tab.is-active fills + foreground per domain enum. The shared
   .suite-tabs--pill primitive provides the base pill shape; campscout
   layers domain-driven colour here, consuming the same data-* attributes
   used in JS state management. data-rev-type-filter added 2026-05-17 (#22) —
   the relecture type-filter row uses data-rev-type-filter, not data-type. */
.suite-tabs--pill .suite-tab.is-active[data-type="all"],
.suite-tabs--pill .suite-tab.is-active[data-rel="all"],
.suite-tabs--pill .suite-tab.is-active[data-rev-filter="all"],
.suite-tabs--pill .suite-tab.is-active[data-rev-type-filter="all"],
.suite-tabs--pill .suite-tab.is-active[data-groupby]{background:var(--bk);color:var(--white);border-color:var(--bk);}
/* Active type chips fill with their type colour */
.suite-tabs--pill .suite-tab.is-active[data-type="sc"],
.suite-tabs--pill .suite-tab.is-active[data-rev-type-filter="sc"]{background:var(--type-sc);color:var(--white);border-color:var(--type-sc);}
.suite-tabs--pill .suite-tab.is-active[data-type="ac"],
.suite-tabs--pill .suite-tab.is-active[data-rev-type-filter="ac"]{background:var(--type-ac);color:var(--bk);border-color:var(--type-ac);}
.suite-tabs--pill .suite-tab.is-active[data-type="aa"],
.suite-tabs--pill .suite-tab.is-active[data-rev-type-filter="aa"]{background:var(--type-aa);color:var(--white);border-color:var(--type-aa);}
.suite-tabs--pill .suite-tab.is-active[data-type="d"],
.suite-tabs--pill .suite-tab.is-active[data-rev-type-filter="d"]{background:var(--g3);color:var(--bk);border-color:var(--g3);}
/* Active relation chips fill with their relation colour */
.suite-tabs--pill .suite-tab.is-active[data-rel="pers"]{background:var(--pers);color:var(--bk);border-color:var(--pers);}
.suite-tabs--pill .suite-tab.is-active[data-rel="corps"]{background:var(--corps);color:var(--white);border-color:var(--corps);}
.suite-tabs--pill .suite-tab.is-active[data-rel="env"]{background:var(--env);color:var(--white);border-color:var(--env);}
.suite-tabs--pill .suite-tab.is-active[data-rel="autres"]{background:var(--autres);color:var(--white);border-color:var(--autres);}
.suite-tabs--pill .suite-tab.is-active[data-rel="spirit"]{background:var(--spirit);color:var(--white);border-color:var(--spirit);}
/* Relecture filter chips */
.suite-tabs--pill .suite-tab.is-active[data-rev-filter="pending"]{background:var(--amber);color:var(--bk);border-color:var(--amber);}
.suite-tabs--pill .suite-tab.is-active[data-rev-filter="approved"]{background:var(--green);color:var(--white);border-color:var(--green);}
.suite-tabs--pill .suite-tab.is-active[data-rev-filter="rejected"]{background:var(--red);color:var(--white);border-color:var(--red);}
.suite-tabs--pill .suite-tab.is-active[data-rev-filter="issues"]{background:var(--bg-warn);color:var(--fg-warn);border-color:var(--amber);}
/* Home filter chips — yellow active per v2 hi-fi (.chip y on) */
.suite-tabs--pill .suite-tab.is-active[data-home-filter]{background:var(--y);color:var(--bk);border-color:var(--y);}
/* Actifs / Tous / Archivés must match the Mes camps / Camps du groupe tabs
   (.home-tab): pill shape, neutral grey active (NOT yellow — keeps "one
   yellow per screen": the "+ Nouveau camp" CTA owns the accent), and no
   .suite-tabs underline. */
.home-time-filter.suite-tabs{border-bottom:none;gap:var(--sp-1h);}
.home-time-filter .suite-tab{border:1px solid transparent;border-radius:var(--radius-lg);padding:var(--sp-1h) var(--sp-3);font-size:var(--fs-md);font-weight:var(--fw-semibold);color:var(--g4);}
.home-time-filter .suite-tab:hover{color:var(--text);background:var(--g1);}
.home-time-filter .suite-tab.is-active[data-time-filter]{background:var(--g1);color:var(--text);border-color:var(--g2);}
/* Home camp-filter row container */
.home-filter-row{display:flex;gap:var(--sp-1);margin-bottom:var(--sp-2);flex-wrap:wrap;align-items:center;}
.tbl{width:100%;border-collapse:collapse;}
.tbl th{text-align:left;padding:.5rem .65rem;border-bottom:2px solid var(--g2);font-size:var(--fs-xs);font-weight:var(--fw-bold);letter-spacing:var(--ls-wide);text-transform:uppercase;color:var(--g4);}
.tbl td{padding:.55rem .65rem;border-bottom:var(--hairline);font-size:var(--fs-md);vertical-align:middle;height:36px;}
/* Inline table pattern (people overview, settings tables) */
#settingsPeopleOverview{overflow-x:auto;-webkit-overflow-scrolling:touch;}
.sp-tbl{width:100%;min-width:420px;border-collapse:collapse;font-size:var(--fs-md);margin-bottom:.8rem;}
.sp-tbl th{text-align:left;padding:5px 8px;background:var(--g1);border-bottom:2px solid var(--g2);}
.sp-tbl td{padding:6px 8px;}
.sp-tbl td.sp-name{font-weight:var(--fw-bold);}
.sp-tbl td.sp-meta{font-size:var(--fs-sm);color:var(--g4);}
.sp-section-hd{font-weight:var(--fw-bold);font-size:var(--fs-md);margin:.3rem 0 .45rem;color:var(--text);}
.sp-hint{font-size:var(--fs-sm);color:var(--g4);margin-bottom:.45rem;line-height:var(--lh-normal);}
/* People overview v2: unified card layout */
.po-stats{display:flex;gap:var(--sp-2);flex-wrap:wrap;margin-bottom:.8rem;}
.po-stat{flex:1;min-width:80px;background:var(--wh);border:var(--hairline);border-radius:var(--radius-md);padding:.5rem .6rem;text-align:center;}
.po-stat-n{font-size:var(--fs-xl);font-weight:var(--fw-extrabold);line-height:var(--lh-tight);}
.po-stat-l{font-size:var(--fs-xs);color:var(--g4);margin-top:.1rem;}
/* layout only — visual styling comes from .fm-input.fm-input--sm on the input */
.po-search{width:100%;margin-bottom:.5rem;}
.po-list{display:flex;flex-direction:column;gap:var(--sp-1h);margin-bottom:.8rem;}
/* .po-card composes onto @suite/lib/style/card.css `.suite-card` (border,
 * radius, background, base transition). Only the people-overview extras
 * live here: horizontal avatar + info + actions flex layout with a
 * denser padding scale than the base card. The warn variant maps 1:1
 * to `.suite-card--alert` in markup (amber left rail) so its rule is
 * gone. The hover override is a no-op restating the base behaviour but
 * kept removed since `.suite-card:hover` already provides border-color
 * change + soft shadow. */
.po-card{display:flex;align-items:flex-start;gap:var(--sp-2h);padding:.55rem .65rem;}
.po-av{width:34px;height:34px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--white);flex-shrink:0;}
.po-info{flex:1;min-width:0;}
.po-name{font-weight:var(--fw-bold);font-size:var(--fs-md);display:flex;align-items:center;gap:var(--sp-1);flex-wrap:wrap;}
.po-me{font-size:var(--fs-xs);color:var(--blue);font-weight:var(--fw-medium);}
.po-tags{display:flex;gap:.2rem;flex-wrap:wrap;margin-top:.15rem;}
.po-usage{font-size:var(--fs-xs);color:var(--g4);margin-top:.1rem;}
.po-acts{display:flex;gap:var(--sp-1);flex-wrap:wrap;margin-top:.25rem;align-items:center;}
.po-acts select,.po-acts button{font-size:var(--fs-sm);}
.po-acts select{border:1px solid var(--border-strong);border-radius:var(--radius-sm);padding:.15rem .3rem;background:var(--wh);}
.po-empty{text-align:center;padding:1.2rem;color:var(--g4);font-size:var(--fs-md);}
@media(max-width:520px){.po-card{flex-direction:column;gap:var(--sp-1);}.po-av{width:26px;height:26px;font-size:var(--fs-xs);}.po-stats{gap:var(--sp-1);}.po-stat{min-width:65px;padding:.35rem .4rem;}}
.tbl tr:hover td{background:var(--g1);}
/* campscout-local — .type-badge alias shares base display/padding/radius/size with
 * .tp-pill (the shared base); keep the rule so legacy .type-badge markup still renders. */
.type-badge{display:inline-block;padding:.15rem .45rem;border-radius:var(--radius-lg);font-size:var(--fs-xs);font-weight:var(--fw-bold);letter-spacing:.02em;}
/* campscout-local — solid-color modifiers override shared's pastel base intentionally. */
.tp-pill.sc{background:var(--type-sc);color:var(--white);}
.tp-pill.ac{background:var(--type-ac);color:var(--bk);}
.tp-pill.aa{background:var(--type-aa);color:var(--white);}
.tp-pill.d{background:var(--type-d);color:var(--white);}

/* MATERIAL PAGE */
.mat-section{margin-bottom:1.75rem;}
.mat-section-wide{grid-column:1/-1;}
/* Matos cross-app section. Standalone above the grid so it doesn't
   share column width with the two legacy checklists. */
/* layout only — visual styling comes from .fm-input.fm-input--sm on the input */
.matos-search-row input{width:100%;}
.matos-search-panel{position:absolute;left:0;right:0;top:calc(100% + 4px);background:var(--surface-card);border:var(--hairline);border-radius:var(--radius-sm);box-shadow:var(--shadow-lg);z-index:30;max-height:40vh;overflow-y:auto;padding:var(--sp-1);}
/* sg-cmdk-* — progressive matos typeahead rows (aligned with .cmdk-* vocabulary) */
.sg-cmdk-grp{font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:var(--ls-wide,0.06em);color:var(--g4);font-weight:var(--fw-semibold);padding:var(--sp-2) var(--sp-2) var(--sp-1) var(--sp-2);}
.sg-cmdk-row{display:flex;align-items:center;gap:var(--sp-2);width:100%;height:36px;padding:0 var(--sp-2h,10px);border:0;border-radius:var(--radius-sm);background:transparent;cursor:pointer;font-size:var(--fs-md);color:var(--text);text-align:left;transition:background var(--dur-fast,.1s);}
.sg-cmdk-row:hover{background:var(--g1);}
.sg-cmdk-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.sg-cmdk-tag{flex-shrink:0;font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:0.04em;color:var(--g4);background:var(--g1);border:var(--hairline);border-radius:var(--radius-xs);padding:1px 6px;}
/* Source chip for bound logical rows: subtle neutral distinguishes J+S / dépôt source labels */
.suite-chip--source{background:var(--g1);color:var(--g4);border-color:var(--g2);}
.matos-search-row-item{display:block;width:100%;text-align:left;padding:.5rem .75rem;border:0;background:transparent;cursor:pointer;font-size:var(--fs-md);}
.matos-search-row-item:hover{background:var(--g1);}
.matos-search-empty{padding:.5rem .75rem;color:var(--g4);font-size:var(--fs-sm);}
.matos-resv-row{display:flex;align-items:center;gap:var(--sp-2);padding:.5rem 0;border-bottom:var(--hairline);min-height:44px;}
.matos-resv-row input[type="checkbox"]{width:18px;height:18px;cursor:pointer;}
/* 2026-05-17 redesign: aggregated row has a top line + a flat chip row
   underneath listing all bindings (Général + each activity). */
.matos-resv-row-aggregated{flex-direction:column;align-items:stretch;gap:var(--sp-1);}
.matos-resv-top{display:flex;align-items:center;gap:var(--sp-2);min-height:32px;}
.matos-resv-bindings{display:flex;flex-wrap:wrap;gap:var(--sp-1);padding:0 0 var(--sp-1) calc(18px + var(--sp-2));}
.matos-binding-qty{opacity:.85;font-weight:var(--fw-medium);}
.matos-binding-x{appearance:none;background:transparent;border:0;color:inherit;font-size:var(--fs-sm);line-height:1;cursor:pointer;padding:0 0 0 .25rem;opacity:.6;}
.matos-binding-x:hover{opacity:1;}
.matos-binding-x:disabled{opacity:.25;cursor:wait;}
.matos-resv-flash{animation:matos-resv-flash 1.5s ease-out;}
@keyframes matos-resv-flash{0%{background:var(--bg-info);}100%{background:transparent;}}
.matos-state{padding:2px 8px;border-radius:var(--radius-pill);font-size:var(--fs-xs);font-weight:600;}
/* Task-3: binding chips row inside .mm-card */
.mm-bindings{display:flex;flex-wrap:wrap;gap:var(--sp-1);padding:var(--sp-1) 0 0 calc(18px + var(--sp-2));}
/* Task-3: header slot — flex row pushing actions to the right.
   justify-content:flex-end keeps the controls clustered on the right of the
   card-hd and wrapping as a group on narrow widths. */
.section-label{display:flex;align-items:center;justify-content:space-between;}
.mat-section-actions{display:flex;align-items:center;justify-content:flex-end;gap:var(--sp-2);flex-wrap:wrap;}
/* matos typeahead in the header slot: a bounded, growable field rather than a
   full-width block (the bare `input{width:100%}` rule needs a sized parent). */
.mat-section-actions .matos-search-row{flex:1 1 180px;min-width:150px;max-width:260px;}
/* Task-4: J+S headcount control — read as a status pill ("X (≤20 ans)") with
   the edit pencil hugging it, rather than loose grey text + a stray button. */
.js-headcount-wrap{display:inline-flex;align-items:center;gap:var(--sp-1);}
.js-headcount-display{font-size:var(--fs-xs);color:var(--g4);font-weight:var(--fw-semibold);font-variant-numeric:tabular-nums;background:var(--g1);border:var(--hairline);padding:.2rem .55rem;border-radius:var(--radius-pill);white-space:nowrap;}
.js-headcount-edit{padding-inline:var(--sp-1h);}
.mat-section-hd,.mat-hd{display:flex;align-items:center;justify-content:space-between;margin-bottom:.9rem;}
.mat-section-hd h3,.mat-hd h3{font-size:var(--fs-xl);}
.mat-meta{font-size:var(--fs-xs);color:var(--g4);font-weight:var(--fw-semibold);background:var(--g1);border:var(--hairline);padding:.18rem .55rem;border-radius:var(--radius-pill);}
.checklist{border:var(--hairline);border-radius:var(--radius-md);overflow:hidden;}
.mat-wide-grid > *{min-width:0;}
.cl-item{display:flex;align-items:flex-start;gap:var(--sp-2h);padding:.35rem .2rem;border-bottom:1px solid var(--g1);flex-wrap:wrap;min-width:0;}
.cl-item:last-child{border:none;}
.cl-item input[type=checkbox]{margin-top:.05rem;}
.cl-item.checked .cl-item-label{text-decoration:line-through;color:var(--g3);}
.cl-item-label{font-size:var(--fs-md);flex:1 1 220px;min-width:0;overflow-wrap:anywhere;word-break:break-word;}
.cl-item-qty{font-size:var(--fs-sm);color:var(--g4);white-space:nowrap;}
.cl-empty{padding:1.2rem;text-align:center;color:var(--g4);font-size:var(--fs-md);font-style:italic;}
/* Add item row at bottom of checklist */
.cl-add-row{display:flex;gap:var(--sp-1h);padding:.5rem .8rem;background:var(--g1);border-top:var(--hairline);}
/* layout only — visual styling comes from .fm-input.fm-input--sm on the inputs */
.cl-add-row input{flex:1 1 180px;min-width:0;}
.cl-add-row input.qty{flex:0 0 62px;}

/* SETTINGS */
/* v2 hi-fi names (.set-grid, .set-section, .set-field) aliased onto production .settings-sec */
.set-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,420px),1fr));gap:var(--sp-3);margin-bottom:var(--sp-3);}
.settings-sec,.set-section{margin-bottom:1.5rem;background:var(--wh);border:var(--hairline);border-radius:var(--radius-md);padding:1rem 1.1rem;}
.settings-sec h3,.set-section h3{font-size:var(--fs-lg);margin-bottom:.85rem;padding-bottom:.38rem;border-bottom:2px solid var(--y);}
.set-grid > .settings-sec,.set-grid > .set-section{margin-bottom:0;}
.set-section.danger{border-color:var(--red);}
.set-section.danger h3{border-bottom-color:var(--red);}

/* .fm-field / .fm-input / .fm-row deleted 2026-06-21 — shared owns the canonical
   sizing (height:36px) which this local block was silently stripping. Only the
   campscout-specific uppercase label treatment is kept. */
.fm-field label{display:block;font-size:var(--fs-sm);font-weight:var(--fw-semibold);text-transform:uppercase;letter-spacing:var(--ls-wide);color:var(--g4);margin-bottom:.26rem;}

/* On-blur form-validation feedback (FN-1-4 / shared/form-validation.js) */
.is-invalid{border-color:var(--red) !important;}
.is-valid{border-color:var(--green) !important;}
.field-err{display:block;margin-top:.25rem;color:var(--fg-error);font-size:var(--fs-xs);}
.field-ok{display:block;margin-top:.25rem;color:var(--fg-success);font-size:var(--fs-xs);}

/* ACTIVITY EDITOR PANEL — full-screen overlay within .content.
   Guide §15 specifies a right-side slide-over, but per user preference
   2026-05-09 the editor stays full-screen so the form has the full
   content-area width to work with. The slide-over geometry was tried
   in commit 1fb506e and reverted. */
.panel{display:none;position:absolute;inset:0;background:var(--wh);z-index:100;flex-direction:column;}
.panel.open{display:flex;animation:panelOpen .22s cubic-bezier(.2,.7,.3,1);}
/* Mobile editor uses .modal-fullscreen (shared/style/desktop/modal.css:172),
   which defaults to display:flex — meaning the activity-editor chrome was
   ALWAYS visible at boot on mobile, even with no camp / activity selected
   (smoke finding CS-2, 2026-06-20). Gate the editor panel on .open so the
   .panel / .modal-fullscreen pair behave identically across shells. */
#actPanel.modal-fullscreen:not(.open){display:none;}
@keyframes panelOpen{from{opacity:0;transform:translateY(8px) scale(.995);} to{opacity:1;transform:none;}}
@media (prefers-reduced-motion: reduce){.panel.open{animation:none;}}
/* Editor TOC sidebar — borrowed from guide §15 .sg-so-toc.
   Editor stays full-screen (per user pref); TOC lives on the left
   of the main area as a navigable section index. */
.panel-main{flex:1;display:flex;min-height:0;overflow:hidden;}
.panel-main > .panel-body{flex:1;}
/* 2026-05-14: .ae-toc desktop aside removed. The main app sidebar
   already handles top-level navigation; nesting a second sidebar
   inside the activity editor created a confusing two-sidebar layout.
   The mobile bottom-tab equivalent below remains for ≤720px. */
/* Tablet/mobile bottom-tab equivalent. Hidden on desktop where the
   side aside is visible; sticky to bottom of the editor panel so the
   user can jump between sections without scrolling back up. */
.ae-toc-bottom{display:none;}
@media (max-width: 720px){
  .ae-toc-bottom{
    display:flex;justify-content:space-around;align-items:stretch;
    position:sticky;bottom:0;left:0;right:0;z-index:5;
    background:var(--wh);border-top:var(--hairline);
    box-shadow:0 -2px 8px rgba(0,0,0,.04);
  }
  .ae-toc-bottom a{
    flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;
    padding:.4rem .25rem;gap:2px;
    color:var(--g4);text-decoration:none;font-size:var(--fs-xs);font-weight:var(--fw-medium);
    transition:color var(--dur-chip);
    border-top:2px solid transparent;
    min-height:48px; /* WCAG 2.5.5 tap target */
  }
  .ae-toc-bottom a span{display:block;}
  .ae-toc-bottom a:hover{color:var(--text);}
  .ae-toc-bottom a.on{color:var(--text);border-top-color:var(--y);font-weight:var(--fw-semibold);}
  .ae-toc-bottom a[hidden]{display:none;}
}
/* v2 panel-top: light header matching the editor hi-fi (.ed-hd, background #fafaf8 + 1px g2 border).
   The dark header was a v1 leftover; flipped to light surface so the editor reads as one continuous
   white card from header to body. */
/* Editor panel header — guide §15 inner layout, full-screen variant.
   Three logical rows: breadcrumb, title+actions, pill summary. */
.panel-top{background:var(--wh);padding:.65rem 1.6rem .85rem;display:flex;flex-direction:column;gap:var(--sp-1h);flex-shrink:0;position:sticky;top:0;z-index:10;border-bottom:var(--hairline);}
.panel-top h2{color:var(--text);font-family:var(--serif);font-weight:400;flex:1;font-size:var(--fs-2xl);margin:0;line-height:1.05;letter-spacing:-.01em;}
.ae-breadcrumb{display:flex;align-items:center;gap:var(--sp-1);font-size:var(--fs-sm);color:var(--g4);min-height:1.6rem;flex-wrap:wrap;}
.ae-breadcrumb .ae-bc-item{color:var(--g4);}
.ae-breadcrumb .ae-bc-sep{color:var(--g3);}
.ae-breadcrumb .ae-bc-current{color:var(--text);font-weight:var(--fw-semibold);max-width:42ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.ae-breadcrumb .ae-saved-indicator{margin-left:auto;}
.ae-header-main{display:flex;align-items:center;gap:var(--sp-3h);}
.ae-pill-row{display:flex;align-items:center;gap:var(--sp-1h);min-height:1.4rem;}
.ae-pill-row:empty{display:none;}
/* Edit-history subtitle (audit-driven 2026-05-24): "Modifié il y a 5 min par X". */
.ae-history{color:var(--g4);font-size:var(--fs-xs);margin-top:var(--sp-1);}
/* Reuse .rel-pill from the pill family for relation display */
.rel-pill{display:inline-flex;align-items:center;padding:.15rem .55rem;border-radius:var(--radius-pill);font-size:var(--fs-xs);font-weight:var(--fw-bold);letter-spacing:.02em;}
.rel-pill.pers{background:var(--pers);color:var(--bk);}
.rel-pill.corps{background:var(--corps);color:var(--white);}
.rel-pill.env{background:#118628;color:var(--white);}
.rel-pill.autres{background:var(--autres);color:var(--white);}
.rel-pill.spirit{background:var(--spirit);color:var(--white);}
.panel-body{flex:1;overflow-y:auto;min-width:0;}
/* Mobile activity editor: .m-content has no shell styling inside the
   .modal-fullscreen overlay, so it didn't establish a flex column and the
   inner .panel-body never got a bounded height → the form wasn't scrollable.
   Make it a column flex child so .panel-body (flex:1; overflow-y:auto) scrolls. */
#actPanel.modal-fullscreen .m-content{display:flex;flex-direction:column;flex:1;min-height:0;overflow:hidden;}
/* The mobile bottom bar is position:fixed (56px + safe-area), so the shell's
   scrollable content needs matching bottom padding — otherwise the last page
   elements (e.g. the Enregistrer / MiData / Dupliquer action row) sit behind
   it. Scoped to the direct shell child via `>` so the editor's .m-content
   (inside #actPanel, which has its own .m-save-bar) is unaffected. */
.m-app > .m-content{padding-bottom:calc(56px + env(safe-area-inset-bottom, 22px) + var(--sp-2));}
.panel-inner{padding:1.6rem 1.5rem 3rem;width:100%;min-width:0;max-width:100%;box-sizing:border-box;}
/* v2: sticky save footer — sibling of panel-body, anchored to bottom of .panel */
.panel-bottom{flex-shrink:0;display:flex;align-items:center;gap:var(--sp-3);padding:.6rem 1.6rem;background:var(--wh);border-top:var(--hairline);box-shadow:0 -1px 6px rgba(0,0,0,.04);}
/* 2026-06-02 a11y: meta text was on `--g3` (#b8b5ab on white = 2.05:1,
 * fails WCAG AA). Body text needs `--g4` (#6e6b62 on white = 5.4:1,
 * AA-pass). `--g3` stays the hairline / disabled-control token. */
.panel-bottom .panel-bottom-meta{margin-left:auto;font-size:var(--fs-xs);color:var(--g4);letter-spacing:.04em;}
.panel-bottom #aeSave3{margin-left:0;}
.section-sep{text-align:center;font-size:var(--fs-xs);font-weight:var(--fw-bold);letter-spacing:.13em;text-transform:uppercase;color:var(--g4);margin:1.8rem 0 1.1rem;padding-top:1.4rem;border-top:var(--hairline);}
.section-sep.first{border-top:none;margin-top:0;padding-top:0;}
/* v2: compact segmented control — white default, type-color bg when .active */
.type-tabs{display:inline-flex;flex-wrap:wrap;gap:0;margin-bottom:1.2rem;border:var(--hairline);border-radius:var(--radius-sm);overflow:hidden;background:var(--wh);box-shadow:var(--shadow-sm);}
.type-tab{flex:0 1 auto;padding:.4rem .85rem;border:none;border-right:var(--hairline);cursor:pointer;font-size:var(--fs-sm);font-weight:var(--fw-bold);background:var(--wh);color:var(--g4);text-align:center;transition:background var(--dur-fast),color var(--dur-fast);opacity:1;}
.type-tab:last-child{border-right:none;}
.type-tab:hover:not(.active){background:var(--g1);color:var(--text);}
.type-tab.active[data-t="sc"]{background:var(--type-sc);color:var(--white);}
.type-tab.active[data-t="ac"]{background:var(--type-ac);color:var(--bk);}
.type-tab.active[data-t="aa"]{background:var(--type-aa);color:var(--white);}
.type-tab.active[data-t="d"]{background:var(--type-d);color:var(--white);}
/* Per-type colour accent on EVERY option (inset shadow = no layout shift) so
   the four activity types are recognisable at a glance, not only when active.
   The active tab fills with its colour, so it drops the accent. */
.type-tab[data-t="sc"]{box-shadow:inset 4px 0 0 var(--type-sc);}
.type-tab[data-t="ac"]{box-shadow:inset 4px 0 0 var(--type-ac);}
.type-tab[data-t="aa"]{box-shadow:inset 4px 0 0 var(--type-aa);}
.type-tab[data-t="d"]{box-shadow:inset 4px 0 0 var(--type-d);}
.type-tab.active{box-shadow:none;}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-3h);}
.grid3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:var(--sp-3h);}
/* Activity editor — date/time sub-box inputs */
/* width:fit-content so the date/time box hugs its segments instead of
   stretching to fill the whole grid column (was unnecessarily wide). */
.ae-dt-box{display:flex;align-items:center;gap:.15rem;flex-wrap:nowrap;width:fit-content;max-width:100%;border:var(--hairline);border-radius:var(--radius-xs);background:var(--wh);padding:.3rem .4rem;transition:border-color var(--dur-normal);overflow:hidden;}
.ae-dt-box:focus-within{border-color:var(--y);}
.ae-sub{border:none;outline:none;font-size:var(--fs-md);background:transparent;color:var(--text);text-align:center;padding:.1rem .15rem;-moz-appearance:textfield;}
.ae-sub::-webkit-inner-spin-button,.ae-sub::-webkit-outer-spin-button{-webkit-appearance:none;margin:0;}
.ae-sub{width:2rem;}
.ae-sub.ae-sub-yr{width:3rem;}
.ae-sub.ae-sub-t{width:1.8rem;}
.ae-dt-sep{color:var(--g3);font-size:var(--fs-md);flex-shrink:0;user-select:none;}
/* Material editor inside activity.
   2026-06-27 Task-11 purge: deleted dead bespoke rules (.mat-editor,
   .mat-editor-hd, .mat-editor-items, .mat-item-row, .mat-suggestions,
   .mat-sug-item, .mat-sug-badge — zero refs in js/ or index.html).
   Kept: .mat-editor-wrap (still in editor/index.js:230 as class on aeMatWrap),
   .mat-item-label/.mat-item-qty (still emitted by materials.js).
   (.mat-add-inline rules removed 2026-06-28 — that container is no longer
   emitted; the "À préparer" add-row is now .suite-card-ft + .fm-input.)
   Added canonical #aeMatWrap id-based grid rule alongside .mat-editor-wrap. */
.mat-editor-wrap,
#aeMatWrap{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-3h);min-width:0;}
/* 2026-05-14: collapse the 2-col Matériel grid to a single column on
   narrow desktop windows so the boxes don't overflow the panel-body
   horizontally. The breakpoint sits below the typical 1024-1200px
   tablet/narrow-desktop range; phones already collapse via the broader
   ≤720px rule below. min-width:0 on the wrap + #aeMatWrap allows
   grid children to shrink below their content's intrinsic width
   (the default `auto` blows the grid out on long item names). */
@media(max-width:1100px){
  .mat-editor-wrap,#aeMatWrap{grid-template-columns:1fr;}
}
.mat-item-label{flex:1;border:none;border-bottom:1px solid transparent;padding:.18rem .25rem;font-size:var(--fs-md);background:none;outline:none;}
.mat-item-label:focus{border-bottom-color:var(--y);}
.mat-item-qty{width:58px;border:none;border-bottom:1px solid transparent;padding:.18rem .25rem;font-size:var(--fs-sm);color:var(--g4);background:none;outline:none;}
.mat-item-qty:focus{border-bottom-color:var(--y);}

/* MODALS */
.overlay{display:none;position:fixed;inset:0;background:var(--bg-overlay);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);z-index:var(--z-modal);align-items:center;justify-content:center;contain:layout style;}
.overlay.open{display:flex;}
/* `.modal-overlay` is the u-hidden-toggled variant: visible by default in
   the flex-centered state, hidden by adding `.u-hidden` (display:none
   !important wins). Used by the Aperçu widget customise modal. */
.modal-overlay{position:fixed;inset:0;background:var(--bg-overlay);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);z-index:var(--z-modal);display:flex;align-items:center;justify-content:center;contain:layout style;}
.modal{background:var(--wh);border-radius:var(--radius-md);padding:1.5rem;max-width:420px;width:92%;animation:su .15s cubic-bezier(.2,.7,.3,1);max-height:88vh;overflow-y:auto;box-shadow:var(--shadow-overlay);}
@keyframes su{from{transform:translateY(12px) scale(.985);opacity:0}to{transform:none;opacity:1}}
@media (prefers-reduced-motion: reduce){.modal{animation:none;}}
.modal-hd{display:flex;align-items:center;justify-content:space-between;margin-bottom:1rem;padding-bottom:.75rem;border-bottom:var(--hairline);}
.modal-hd h3{font-family:var(--serif);font-weight:400;font-size:var(--fs-xl);}
.modal-x{background:none;border:none;cursor:pointer;font-size:var(--fs-lg);color:var(--g4);padding:.1rem .3rem;border-radius:var(--radius-xs);transition:background var(--dur-fast);min-width:44px;min-height:44px;display:inline-flex;align-items:center;justify-content:center;outline:none;}
.modal-x:hover{background:var(--g2);}
.modal-x:focus-visible{outline:3px solid var(--focus-ring);outline-offset:2px;}
.modal-acts{display:flex;gap:var(--sp-2h);justify-content:flex-end;margin-top:1.1rem;padding:.9rem 0 0;border-top:var(--hairline);position:sticky;bottom:-1.5rem;background:var(--wh);margin-bottom:-1.5rem;padding-bottom:1.5rem;z-index:1;}

/* CAMPS HOME */
.camps-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:var(--sp-4);margin-top:1.2rem;}
/* v2 camp card: signature hover lifts the card with a warm yellow-tinted shadow,
   the top accent stripe grows from 3→4px, and a subtle paper-warm wash slides in
   from the top so the card feels like it's catching ambient light. */
/* .camp-card builds on @suite/lib/style/card.css `.suite-card` (border,
 * border-radius, background, base transition). Only the camp-specific
 * extras live here: a 3px yellow top bar, ambient-light gradient overlay,
 * dramatic translateY hover, and a yellow focus ring. */
.camp-card{padding:1.1rem;cursor:pointer;transition:transform .22s cubic-bezier(.2,.7,.3,1), box-shadow .22s ease, border-color .18s ease;position:relative;overflow:hidden;}
.camp-card::before{content:'';position:absolute;top:0;left:0;right:0;height:3px;background:var(--y);transition:height .22s cubic-bezier(.2,.7,.3,1);}
.camp-card::after{content:'';position:absolute;inset:0;background:linear-gradient(180deg, rgb(var(--y-rgb) / 6%), transparent 40%);opacity:0;transition:opacity .22s ease;pointer-events:none;border-radius:inherit;}
.camp-card:hover{border-color:var(--y);transform:translateY(-3px);box-shadow:0 14px 32px -14px rgb(var(--y-rgb) / 35%), 0 6px 18px -10px rgba(0,0,0,.18);}
.camp-card:hover::before{height:4px;}
.camp-card:hover::after{opacity:1;}
.camp-card:focus-visible{outline:none;border-color:var(--y);box-shadow:0 0 0 3px rgb(var(--y-rgb) / 35%), 0 6px 18px -10px rgba(0,0,0,.18);}
.camp-card h3{font-size:var(--fs-lg);margin-bottom:.35rem;margin-top:.2rem;}
.camp-card p{font-size:var(--fs-md);color:var(--g4);line-height:var(--lh-normal);}
.camp-card-sub{margin-top:var(--sp-1);font-size:var(--fs-sm);color:var(--g4);}
.camp-card-meta{display:flex;gap:var(--sp-1h);margin-top:.65rem;flex-wrap:wrap;}
/* v2: per-card progress bar — visualizes the planification % the meta line used to spell out as a chip. */
.camp-card-progress{margin-top:var(--sp-2h);}
.camp-card-progress-bar{height:6px;background:var(--g1);border-radius:var(--radius-pill);overflow:hidden;}
.camp-card-progress-bar > span{display:block;height:100%;background:var(--y);border-radius:var(--radius-pill);transition:width var(--dur-slow);}
.camp-card-progress-bar.archived > span{background:var(--g3);}
.camp-card-progress-meta{display:flex;justify-content:space-between;margin-top:var(--sp-05);font-size:var(--fs-xs);color:var(--g4);}
.camp-card-progress-pending{opacity:.45;}
.camp-card-progress-pending .camp-card-progress-bar{background:var(--g2);}
/* v2: home "À traiter" view skeleton — basic list of items needing the user's attention. */
/* À traiter list: simplified to a single column since it now lives in
   the sidebar (which is already narrow). 2026-05-17 (#29). */
.home-attention{margin-top:var(--sp-2);display:flex;flex-direction:column;gap:var(--sp-2);}
/* .home-attention-panel composes onto @suite/lib/style/card.css `.suite-card`
 * (background, border, radius, padding all inherited). Only the page-local
 * h3 sizing remains here. */
.home-attention-panel h3{font-size:var(--fs-lg);margin-bottom:var(--sp-3);}
.home-attention-empty{color:var(--g4);font-size:var(--fs-sm);font-style:italic;padding:var(--sp-2) 0;}
/* v2 phase 4: Picasso single inline toolbar (replaces two stacked filter-block cards) */
.pic-toolbar{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap;padding:var(--sp-2) 0 var(--sp-3);margin-bottom:var(--sp-2);border-bottom:var(--hairline);}
.pic-toolbar-grp{display:inline-flex;align-items:center;gap:var(--sp-1h);position:relative;}
.pic-toolbar-grp + .pic-toolbar-grp::before{content:'';position:absolute;left:calc(var(--sp-3) * -.5 - 1px);top:50%;transform:translateY(-50%);width:1px;height:18px;border-left:1px dashed var(--g3);}
.pic-toolbar-label{font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:var(--ls-wide);color:var(--g4);font-weight:var(--fw-bold);}
@media (max-width:680px){.pic-toolbar{gap:var(--sp-2);}.pic-toolbar-grp + .pic-toolbar-grp::before{display:none;}}
/* v2 phase 5: Activités chip-row filters (replaces stacked .act-filter-block cards) */
/* Horizontal row of label+pill groups on desktop (no dashed dividers, unlike
   .pic-toolbar); stacks to full-width rows at <=680px. */
.act-toolbar{display:flex;flex-direction:row;align-items:center;flex-wrap:wrap;gap:var(--sp-1) var(--sp-3);padding:var(--sp-2) 0 var(--sp-3);margin-bottom:var(--sp-2);border-bottom:var(--hairline);}
.act-toolbar-grp{display:flex;align-items:center;gap:var(--sp-1h);flex-wrap:wrap;}
.act-toolbar-label{font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:var(--ls-wide);color:var(--g4);font-weight:var(--fw-bold);min-width:78px;}
.act-toolbar-meta{margin-left:auto;font-size:var(--fs-xs);color:var(--g4);}
@media (max-width:680px){.act-toolbar{flex-direction:column;align-items:stretch;gap:var(--sp-1h);}.act-toolbar-label{min-width:0;}}
.apercu-tab-panel[hidden]{display:none !important;}
.apercu-stats-divider{height:1px;background:var(--g2);margin:var(--sp-3) 0;}
/* Chart legend dot — 10×10 circle whose fill comes from data via `--c`.
   Used by apercu/charts.js. The dynamic part stays inline as a custom
   property (`data-style-set="--c:${color}"`); static layout is here. */
.chart-legend-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0;display:inline-block;background:var(--c);}
/* Health cards: vertical narrative list */
.health-cards{display:flex;flex-direction:column;gap:var(--sp-2);max-width:780px;}
/* v2 health card: subtle status-tinted background wash + 4px left rule.
   The wash (a near-imperceptible color tint) cues the eye to the status before
   the user reads the title — green for good, amber for warn, neutral for info. */
.health-card{display:flex;gap:var(--sp-2h);align-items:flex-start;padding:var(--sp-2h) var(--sp-3);background:var(--wh);border:var(--hairline);border-radius:var(--radius-md);box-shadow:var(--shadow-sm);border-left:4px solid var(--g3);transition:transform var(--dur-fast),box-shadow var(--dur-fast);}
.health-card:hover{transform:translateY(-1px);box-shadow:var(--shadow-md);}
.health-card.is-good{border-left-color:var(--green);background:linear-gradient(90deg, rgba(32,187,69,.045), var(--wh) 60%);}
.health-card.is-warn{border-left-color:var(--amber);background:linear-gradient(90deg, rgba(217,119,6,.05), var(--wh) 60%);}
.health-card.is-info{border-left-color:var(--g3);}
/* 2026-05-14: `must` status = a blocking issue (driver permit missing,
   <6h sleep, every-objective rule). Red left rail + red score, similar
   to .is-warn but visually stronger. */
.health-card.is-must{border-left-color:var(--red);background:linear-gradient(90deg, rgba(220,39,40,.06), var(--wh) 60%);}
.health-card .hc-icon{font-size:1.4rem;line-height:1;flex-shrink:0;width:32px;text-align:center;}
.health-card .hc-body{flex:1;min-width:0;}
.health-card .hc-title{font-size:var(--fs-md);font-weight:var(--fw-bold);color:var(--text);margin:0;}
.health-card .hc-score{font-size:var(--fs-md);font-weight:var(--fw-semibold);margin-top:.15rem;}
.health-card.is-good .hc-score{color:#0f7a26;}
.health-card.is-warn .hc-score{color:#8a4a00;}
.health-card.is-info .hc-score{color:var(--g4);}
.health-card.is-must .hc-score{color:#a91818;}
/* Aperçu toolbar (gear button row above the health + stats areas). */
.apercu-toolbar{display:flex;justify-content:flex-end;align-items:center;gap:var(--sp-2);margin-bottom:var(--sp-2);}
/* Customise-widgets modal — list of rows with checkbox + up/down arrows. */
.widget-customise-list{display:flex;flex-direction:column;gap:var(--sp-1);max-height:50vh;overflow-y:auto;}
/* Phase presets — 4-up button grid at the top of the modal. Each is a
   semantic action: click to apply that phase's recommended widget set
   to the working layout. The "🪄 auto" sub-text marks the button that
   matches the camp's actual current phase. */
.widget-customise-presets{
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(140px, 1fr));
  gap:var(--sp-1h);
  margin-bottom:var(--sp-3);
}
.widget-customise-preset{
  appearance:none;background:var(--surface-card);
  border:var(--hairline);border-radius:var(--radius-md);
  padding:var(--sp-2) var(--sp-1h);
  display:flex;flex-direction:column;align-items:center;gap:4px;
  cursor:pointer;
  transition:background var(--dur-fast), border-color var(--dur-fast),
    transform var(--dur-fast), box-shadow var(--dur-fast);
  min-height:80px;text-align:center;
}
.widget-customise-preset:hover{
  background:var(--g1);border-color:var(--bk3);
  transform:translateY(-1px);box-shadow:var(--shadow-md);
}
.widget-customise-preset:focus-visible{
  outline:3px solid var(--focus-ring);outline-offset:2px;border-color:var(--y);
}
.widget-customise-preset.is-active{
  border-color:var(--y);background:var(--bg-info);
  box-shadow:var(--shadow-sm);
}
.widget-customise-preset-icon{font-size:var(--fs-xl);line-height:1;}
.widget-customise-preset-label{
  font-size:var(--fs-sm);font-weight:600;color:var(--text);line-height:1.2;
}
.widget-customise-preset-sub{
  font-size:var(--fs-xs);color:var(--g4);font-weight:600;min-height:14px;
  letter-spacing:.04em;text-transform:uppercase;
}
.widget-customise-preset-sub:empty{visibility:hidden;}
.widget-customise-preset.is-current-phase .widget-customise-preset-sub{color:var(--text);}
.widget-customise-section-hd{
  font-family:var(--sans);
  font-weight:700;font-size:var(--fs-xs);line-height:1.4;
  letter-spacing:.12em;text-transform:uppercase;
  color:var(--g4);
  margin:0 0 var(--sp-1h);
  padding-bottom:var(--sp-1);
  border-bottom:var(--hairline);
}
.widget-customise-row{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-2);padding:var(--sp-2) var(--sp-2h);border:var(--hairline);border-radius:var(--radius-sm);background:var(--wh);}
.widget-customise-toggle{display:flex;align-items:center;gap:var(--sp-2);cursor:pointer;flex:1;min-width:0;}
.widget-customise-toggle input{flex-shrink:0;}
.widget-customise-icon{font-size:var(--fs-lg);flex-shrink:0;}
.widget-customise-title{font-size:var(--fs-md);color:var(--text);overflow:hidden;text-overflow:ellipsis;}
.widget-customise-actions{display:flex;gap:var(--sp-1);flex-shrink:0;align-items:center;}
.widget-customise-actions .btn{min-width:32px;padding:.2rem .4rem;}
.widget-customise-size{font-size:var(--fs-sm);padding:.2rem .35rem;border:var(--hairline);border-radius:var(--radius-xs);background:var(--wh);color:var(--text);}
/* ── Mobile-style widget picker (2026-05-16) ──────────────────
   Replaces the flat checkbox list with two card grids: "Vos
   widgets" (active, draggable) at the top, "À ajouter" (category-
   grouped, single-tap add) below. Every card carries a small
   preview vignette (.wp-*) so users recognise the widget before
   adding it. The grid is mobile-style (auto-fill ~210px columns)
   so it feels like adding a widget on iOS / Android. */
/* `.widget-picker-modal` overrides the default 420px modal so the
   picker can use the available viewport width, AND restructures the
   modal as a flex column so there is exactly one vertical scrollbar:
   the body. The default `.modal` rule allows the whole modal to
   scroll AND the inner `.widget-picker-list` to scroll — two bars
   side-by-side, which felt broken. */
.widget-picker-modal{max-width:min(960px,95vw);width:100%;display:flex;flex-direction:column;max-height:88vh;overflow:hidden;padding:0;}
.widget-picker-modal > .modal-hd{margin:0;padding:1.25rem 1.5rem .75rem;border-bottom:var(--hairline);flex:0 0 auto;}
.widget-picker-modal > .modal-bd{padding:1rem 1.5rem;overflow-y:auto;flex:1 1 auto;min-height:0;}
.widget-picker-modal > .modal-acts{margin:0;padding:.9rem 1.5rem;border-top:var(--hairline);position:static;bottom:auto;background:var(--wh);flex:0 0 auto;}
.widget-picker-list{display:flex;flex-direction:column;gap:var(--sp-3);padding-right:var(--sp-1);}
.widget-picker-section{display:flex;flex-direction:column;gap:var(--sp-1h);}
.widget-picker-section-hd{display:flex;align-items:center;gap:var(--sp-2);margin:0;padding-bottom:var(--sp-1);border-bottom:var(--hairline);}
.widget-picker-section-title{font-family:var(--sans);font-weight:700;font-size:var(--fs-xs);line-height:1.4;letter-spacing:.12em;text-transform:uppercase;color:var(--g4);margin:0;}
.widget-picker-section-count{font-size:var(--fs-xs);font-weight:600;color:var(--text);background:var(--g1);border:var(--hairline);border-radius:999px;padding:.05rem .45rem;line-height:1.5;}
.widget-picker-empty{font-size:var(--fs-sm);color:var(--g4);font-style:italic;text-align:center;padding:var(--sp-3) var(--sp-2);border:1px dashed var(--g2);border-radius:var(--radius-md);background:var(--g1);margin:0;}
.widget-picker-category{display:flex;flex-direction:column;gap:var(--sp-1);margin-top:var(--sp-1);}
.widget-picker-category-hd{font-family:var(--sans);font-size:var(--fs-xs);font-weight:600;color:var(--g4);margin:0;display:flex;align-items:center;gap:.4rem;}
.widget-picker-grid{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(auto-fill, minmax(210px, 1fr));gap:var(--sp-2);}
/* Active cards stack vertically as full-width rows — the order is
   meaningful (renders top-to-bottom on the Aperçu), so a grid would
   confuse users about where the next-added widget will land. */
.widget-picker-grid[data-picker-active]{grid-template-columns:1fr;gap:var(--sp-1h);}
.widget-card{position:relative;display:flex;flex-direction:column;gap:var(--sp-1h);padding:var(--sp-2);background:var(--surface-card);border:var(--hairline);border-radius:var(--radius-md);box-shadow:var(--shadow-sm);transition:border-color var(--dur-fast), box-shadow var(--dur-fast), transform var(--dur-fast);}
.widget-card:hover{border-color:var(--g3);box-shadow:var(--shadow-md);}
.widget-card--active{flex-direction:row;align-items:center;gap:var(--sp-2);}
.widget-card--active .widget-card-preview{width:120px;flex-shrink:0;}
.widget-card--active .widget-card-body{flex:1;min-width:0;}
.widget-card--available .widget-card-body{flex:1;}
.widget-card-preview{display:flex;align-items:center;justify-content:center;height:78px;padding:var(--sp-1);background:var(--g1);border:var(--hairline);border-radius:var(--radius-sm);overflow:hidden;}
.widget-card-body{display:flex;flex-direction:column;gap:.15rem;min-width:0;}
.widget-card-title{display:flex;align-items:center;gap:.4rem;font-size:var(--fs-md);font-weight:600;color:var(--text);line-height:1.25;}
.widget-card-icon{font-size:1rem;flex-shrink:0;}
.widget-card-desc{font-size:var(--fs-xs);color:var(--g4);line-height:1.35;}
.widget-card-actions{display:flex;gap:.3rem;align-items:center;flex-shrink:0;}
.widget-card-size{font-size:var(--fs-xs);padding:.18rem .35rem;border:var(--hairline);border-radius:var(--radius-xs);background:var(--wh);color:var(--text);max-width:90px;}
.widget-card-btn{appearance:none;display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;font-size:var(--fs-md);border:var(--hairline);border-radius:var(--radius-xs);background:var(--wh);color:var(--text);cursor:pointer;transition:background var(--dur-fast), border-color var(--dur-fast);}
.widget-card-btn:hover{background:var(--g1);border-color:var(--g3);}
.widget-card-btn:disabled{opacity:.35;cursor:not-allowed;}
.widget-card-btn--remove{color:#a91818;}
.widget-card-btn--remove:hover{background:var(--bg-error);border-color:#a91818;color:#a91818;}
/* `+ Ajouter` is repeated for every available widget, so it must NOT be
   primary-yellow — that would violate the "one yellow per screen" rule
   (Enregistrer is the single primary in this modal). Ghost styling
   keeps the action discoverable without competing with Enregistrer. */
.widget-card-add{margin-top:auto;appearance:none;font-family:inherit;font-size:var(--fs-sm);font-weight:600;color:var(--text);background:var(--wh);border:var(--hairline);border-radius:var(--radius-sm);padding:.4rem .75rem;cursor:pointer;transition:background var(--dur-fast),border-color var(--dur-fast),transform var(--dur-fast);}
.widget-card-add:hover{background:var(--g1);border-color:var(--g3);transform:translateY(-1px);}
.widget-card-add:focus-visible{outline:3px solid var(--focus-ring);outline-offset:2px;}
/* ── Preview vignettes (.wp-*) ─────────────────────────────────
   Tiny illustrations rendered inside .widget-card-preview to show
   the widget *shape* without a live data fetch. All are pure CSS
   (no JS), sized to fit the 78px-tall preview box. Stripped to the
   minimum that conveys "this is a chart of bars" vs "this is a pie"
   etc. — viewers fill in the rest. */
.wp-stats{display:grid;grid-template-columns:repeat(5,1fr);gap:3px;width:100%;height:100%;}
.wp-stat{display:flex;flex-direction:column;align-items:center;justify-content:center;border-radius:4px;padding:2px;color:var(--bk);font-size:var(--fs-xs);line-height:1.1;text-align:center;}
.wp-stat b{font-size:var(--fs-sm);font-weight:700;font-family:var(--serif);}
.wp-stat i{font-style:normal;font-size:7px;letter-spacing:.04em;text-transform:uppercase;opacity:.7;}
.wp-stat[data-rel=pers]{background:var(--pers);}
.wp-stat[data-rel=corps]{background:var(--corps);color: var(--white);}
.wp-stat[data-rel=env]{background:var(--env);}
.wp-stat[data-rel=autres]{background:var(--autres);color: var(--white);}
.wp-stat[data-rel=spirit]{background:var(--spirit);color: var(--white);}
.wp-js{display:flex;flex-direction:column;gap:3px;width:100%;}
.wp-js-row{display:flex;align-items:center;gap:6px;font-size:var(--fs-xs);color:var(--g4);}
.wp-js-row span{flex-shrink:0;width:16px;}
.wp-js-bar{flex:1;height:8px;background:var(--g1);border-radius:4px;overflow:hidden;}
.wp-js-bar i{display:block;height:100%;background:var(--green);}
.wp-pico{display:flex;flex-direction:column;gap:2px;width:100%;}
.wp-pico-row{display:flex;align-items:center;gap:3px;}
.wp-pico-cells{display:grid;grid-template-columns:repeat(12,1fr);gap:1px;flex:1;}
.wp-pico-cells i{display:block;height:6px;background:var(--g1);border-radius:1px;}
.wp-pico-cells i[data-pt=sc]{background:var(--type-sc);}
.wp-pico-cells i[data-pt=ac]{background:var(--type-ac);}
.wp-pico-cells i[data-pt=aa]{background:var(--type-aa);}
.wp-pico-cells i[data-pt=d]{background:var(--type-d);}
.wp-bars{display:flex;flex-direction:column;gap:3px;width:100%;}
.wp-bar-row{display:flex;align-items:center;gap:6px;font-size:var(--fs-xs);color:var(--g4);}
.wp-bar-row span{flex-shrink:0;width:22px;text-align:right;}
.wp-bar-track{flex:1;height:7px;background:var(--g1);border-radius:4px;overflow:hidden;}
.wp-bar-track i{display:block;height:100%;background:var(--y);}
.wp-hist{display:flex;flex-direction:column;gap:2px;width:100%;font-size:var(--fs-xs);color:var(--g4);}
.wp-hist-row{display:flex;align-items:center;gap:5px;line-height:1.2;}
.wp-hist-row span{color:var(--g3);font-variant-numeric:tabular-nums;}
.wp-hist-row b{color:var(--text);font-weight:600;}
.wp-hist-row i{font-style:normal;color:var(--g4);}
.wp-sleep{display:flex;align-items:stretch;justify-content:space-around;gap:2px;width:100%;height:100%;padding-top:6px;}
.wp-sleep-col{display:flex;flex-direction:column;align-items:center;justify-content:flex-end;gap:2px;width:14px;height:100%;}
.wp-sleep-bar{width:100%;background:var(--blue);border-radius:2px 2px 0 0;min-height:2px;}
.wp-sleep-col span{font-size:8px;color:var(--g4);}
.wp-heat{display:grid;grid-template-columns:repeat(6,1fr);gap:2px;width:100%;}
.wp-heat i{display:flex;align-items:center;justify-content:center;height:22px;font-size:var(--fs-xs);font-weight:600;border-radius:3px;color:var(--text);font-style:normal;}
.wp-pie{display:flex;align-items:center;justify-content:center;}
.wp-density{width:100%;}
.wp-objgrid{display:flex;flex-direction:column;gap:3px;width:100%;}
.wp-objgrid-row{display:grid;grid-template-columns:repeat(5,1fr);gap:3px;}
.wp-objgrid-row i{display:block;height:10px;background:var(--g1);border-radius:2px;}
.wp-objgrid-row i[data-on]{background:var(--y);}
.wp-mat{display:flex;flex-direction:column;gap:3px;width:100%;align-items:flex-start;}
.wp-mat-row b{font-size:var(--fs-lg);font-family:var(--serif);font-weight:700;color:var(--text);}
.wp-mat-track{width:100%;height:6px;background:var(--g1);border-radius:3px;overflow:hidden;}
.wp-mat-track i{display:block;height:100%;background:var(--green);}
.wp-mat-meta{font-size:var(--fs-xs);color:var(--g4);}
.wp-live{display:flex;flex-direction:column;gap:2px;width:100%;font-size:var(--fs-xs);color:var(--g4);text-align:left;}
.wp-live-feature{align-items:flex-start;}
.wp-live-meta{font-size:8px;letter-spacing:.08em;text-transform:uppercase;color:var(--y);font-weight:700;}
.wp-live b{font-size:var(--fs-xs);color:var(--text);font-weight:600;line-height:1.2;}
.wp-live-sub{font-size:var(--fs-xs);color:var(--g4);line-height:1.3;}
.wp-live-line{display:flex;align-items:center;gap:5px;}
.wp-live-line span{color:var(--g3);font-variant-numeric:tabular-nums;}
.wp-live-line b{font-size:var(--fs-xs);}
.wp-live-weather{display:flex;align-items:center;gap:4px;}
.wp-live-temp{font-family:var(--serif);font-size:var(--fs-lg);font-weight:700;color:var(--text);}
.wp-live-icon{font-size:var(--fs-lg);}
.wp-live-chefs{display:flex;gap:-2px;}
.wp-live-av{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:50%;background:var(--y);color:var(--bk);font-size:7px;font-weight:700;margin-right:-4px;border:1.5px solid var(--white);}
.wp-live-progress{width:100%;height:6px;background:var(--g1);border-radius:3px;overflow:hidden;}
.wp-live-progress i{display:block;height:100%;background:var(--green);}
@media (max-width:640px){
  .widget-card--active{flex-direction:column;align-items:stretch;}
  .widget-card--active .widget-card-preview{width:100%;}
  .widget-card-actions{justify-content:flex-end;}
  .widget-picker-grid{grid-template-columns:1fr;}
}
.health-card .hc-desc{font-size:var(--fs-sm);color:var(--g4);margin-top:.25rem;line-height:var(--lh-body);}
/* Modular tiles: drag-and-drop grid (v1: static order) */
.modular-tiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:var(--sp-3);align-items:start;}
.modular-tile{background:var(--wh);border:var(--hairline);border-radius:var(--radius-md);box-shadow:var(--shadow-sm);padding:var(--sp-2h);min-height:80px;transition:transform var(--dur-fast),box-shadow var(--dur-fast),border-color var(--dur-fast);}
.modular-tile:hover{transform:translateY(-1px);box-shadow:var(--shadow-md);border-color:var(--g3);}
.modular-tile-empty{color:var(--g4);font-style:italic;font-size:var(--fs-sm);text-align:center;padding:var(--sp-3) 0;}
@media (max-width:680px){.modular-tiles{grid-template-columns:1fr;}}
/* Empty responsable warning: red ⚠ vide instead of em-dash placeholder */
/* .resp-empty retired 2026-07-09 — activités missing-leader now uses
   renderRespEmpty (.badge-error) from js/shared/person-chip.js. */
/* v2 phase 6: editor saved indicator (green dot + relative-time text in panel header) */
.ae-saved-indicator{display:inline-flex;align-items:center;gap:var(--sp-1);font-size:var(--fs-xs);color:var(--g4);background:var(--g1);border:var(--hairline);border-radius:var(--radius-pill);padding:.18rem .55rem;margin-left:var(--sp-2);}
.ae-saved-indicator[hidden]{display:none;}
.ae-saved-dot{width:7px;height:7px;border-radius:50%;background:var(--green);box-shadow:0 0 0 2px rgba(32,187,69,.18);flex-shrink:0;}
.ae-saved-indicator.saving .ae-saved-dot{background:var(--y);box-shadow:0 0 0 2px rgb(var(--y-rgb) / 18%);animation:pulse .7s ease-in-out infinite alternate;}
.att-item{display:flex;align-items:flex-start;gap:var(--sp-2);padding:var(--sp-2) var(--sp-1);border-bottom:1px solid var(--g1);}
.att-item:last-child{border-bottom:none;}
.att-item .icon{width:24px;height:24px;flex-shrink:0;display:grid;place-items:center;border-radius:var(--radius-pill);font-size:var(--fs-xs);font-weight:var(--fw-bold);}
.att-item.bad .icon{background:var(--bg-error);color:var(--red);}
.att-item.warn .icon{background:var(--bg-warn);color:var(--amber);}
.att-item.good .icon{background:var(--bg-success);color:var(--green);}
.att-item.info .icon{background:var(--g1);color:var(--g4);}
.att-item .col{flex:1;min-width:0;}
.att-item .ttl{font-size:var(--fs-md);color:var(--text);font-weight:var(--fw-semibold);}
.att-item .meta{font-size:var(--fs-xs);color:var(--g4);margin-top:.1rem;}
.att-item .right{font-size:var(--fs-xs);color:var(--g4);flex-shrink:0;background:var(--g1);padding:.1rem .45rem;border-radius:var(--radius-xs);}
.online-count{display:inline-flex;align-items:center;gap:var(--sp-05);font-size:var(--fs-xs);color:var(--green);padding:var(--sp-05) var(--sp-1);border-radius:var(--radius-pill);background:rgba(32,187,69,.1);}
.online-count::before{content:'';width:6px;height:6px;border-radius:50%;background:var(--green);}
.sb-item-dirty::before{content:'';position:absolute;left:2px;top:50%;transform:translateY(-50%);width:5px;height:5px;border-radius:50%;background:var(--amber);}
.sb-item-active-other::after{content:'';position:absolute;right:6px;top:50%;transform:translateY(-50%);width:6px;height:6px;border-radius:50%;background:var(--green);box-shadow:0 0 4px var(--green);}
.sb-item{position:relative;}
.act-row{content-visibility:auto;contain-intrinsic-size:auto 44px;cursor:pointer;transition:background var(--dur-fast),box-shadow var(--dur-fast);}
/* The shared .d-trow pins height:44px for single-line `.nm` browse rows.
   campscout's browse lists (activités, rôles définis, roster / Vue
   d'ensemble, modèles, favoris, corbeille) put wrapping multi-line text +
   stacked chips in their cells, which overflowed the 44px and overlapped the
   next row. Let any campscout browse row grow to fit its content; single-line
   rows still settle at 44px via min-height. */
.d-browse .d-trow{height:auto;min-height:44px;align-items:start;padding-top:8px;padding-bottom:8px;}
/* Lift the content-visibility estimate for the (taller) activité rows so
   scroll-in doesn't jump from the 44px default. */
.act-row{contain-intrinsic-size:auto 72px;}
.act-row:nth-child(even){background:rgba(0,0,0,.015);}
.act-row:hover{background:rgb(var(--y-rgb) / 6%);box-shadow:inset 3px 0 0 var(--y);}
.act-row-focused{outline:2px solid var(--y);outline-offset:-2px;background:rgb(var(--y-rgb) / 6%);}
.act-lock-badge{font-size:var(--fs-xs);color:var(--amber);font-weight:var(--fw-medium);}
.act-row-locked{opacity:.7;}
/* .ctag* rules deleted 2026-06-21 — promoted to .badge--event-status* in
   shared/style/_components/badges.css. */

/* .toast / .toast.show deleted 2026-06-21 — shared/style/_components/notifications.css
   owns the canonical rule. Mobile override + dark-mode override remain. */

/* PICASSO LEGEND */
.pic-legend{display:flex;flex-wrap:wrap;gap:var(--sp-1h);margin-bottom:.45rem;}
.pic-legend-item{display:flex;align-items:center;gap:var(--sp-1);font-size:var(--fs-sm);color:var(--g4);}
.pic-legend-dot{width:10px;height:10px;border-radius:2px;flex-shrink:0;background:var(--c);}

/* OBJECTIVE ACTIVITY LINKS */
.obj-act-links{padding:.4rem 1rem .4rem 2.1rem;background:var(--wh);display:none;}
.obj-act-links.show{display:block;}
.obj-act-link-item{display:inline-flex;align-items:center;gap:var(--sp-1);font-size:var(--fs-sm);padding:.15rem .45rem;border-radius:var(--radius-xs);margin:.15rem .2rem .15rem 0;cursor:pointer;}
.obj-act-link-item:hover{filter:brightness(.9);}

/* MATERIAL ACTIVITY TAG */
.cl-item-acts{display:flex;gap:.2rem;flex-wrap:wrap;align-items:center;justify-content:flex-end;min-width:0;flex:1 1 220px;}
.cl-item-act-tag{font-size:var(--fs-xs);color:var(--g4);padding:.1rem .32rem;background:var(--g2);border-radius:var(--radius-xs);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;}
.cl-item-qty-total{font-size:var(--fs-sm);font-weight:var(--fw-semibold);color:var(--text);background:var(--g2);padding:.1rem .38rem;border-radius:var(--radius-xs);white-space:nowrap;}

/* ANNEXES */
.annex-section{margin-top:1.2rem;padding-top:1rem;border-top:2px solid var(--g2);}
.annex-list{display:flex;flex-direction:column;gap:var(--sp-1h);margin-top:.5rem;}
.annex-item{display:flex;align-items:center;gap:var(--sp-2);padding:.4rem .7rem;background:var(--g1);border-radius:var(--radius-xs);border:var(--hairline);}
.annex-item-name{flex:1;font-size:var(--fs-md);font-weight:var(--fw-medium);}
.annex-item-size{font-size:var(--fs-sm);color:var(--g4);}

/* PDF EXPORT MODAL */
.export-check-list{display:flex;flex-direction:column;gap:var(--sp-2);margin:.8rem 0;}
.export-check-item{display:flex;align-items:center;gap:var(--sp-2h);padding:.38rem .6rem;border-radius:var(--radius-xs);background:var(--g1);cursor:pointer;}
.export-check-item input{accent-color:var(--y);width:15px;height:15px;}
.export-check-item label{font-size:var(--fs-md);cursor:pointer;flex:1;}

/* PRINT */
@media print {
  .sidebar,.topbar,.ph-right,.obj-btns,.btn,.panel,.toast,.overlay,.confirm-overlay,.pic-toolbar,.mobile-bottom-nav,.scroll-to-top,.scroll-to-top-btn,.undo-bar,.online-count,.skip-link,.sb-badge,.presence-bar,.page-collab-banner,.section-modified-label,.banner-stack,.banner-stack > *,.ro-banner,.conflict-banner,.session-expired-banner,.sg-banner,.sg-banner-warn,.sg-banner-error,.sg-banner-info,.sg-banner-success { display:none !important; }
  .app { display:block; height:auto; }
  .main { overflow:visible; }
  .content { padding:.5rem; overflow:visible; }
  .page { display:block !important; page-break-after:always; }
  .pic-wrap { overflow:visible; }
  .pgrid { width:100%; }
  body { background:var(--wh); }
  .camp-card,.card-base,.hist-section,.stats-row { break-inside:avoid; }
  .act-day-head { break-after:avoid; }
  a { text-decoration:none !important; color:inherit !important; }
  .tbl th,.tbl td { border:var(--hairline) !important; padding:4px 8px !important; }
  .tp-pill { border:1px solid currentColor !important; }
  body.print-picasso-only .page{display:none !important;}
  body.print-picasso-only #page-picasso{display:flex !important;page-break-after:auto;padding:0 !important;}

  /* ── APERÇU PRINT (v3, 2026-05-16) ───────────────────────
     Render Aperçu as a one-page printable summary: identity →
     readiness → numbers → key charts. Hides live widgets (no
     auto-refresh on paper), the Customise button, and the empty-
     state CTAs. Uses print-safe colors (no gradients, no shadows). */
  #page-apercu .apercu-toolbar,
  #page-apercu .apercu-empty,
  #page-apercu [data-subzone="live"],
  #page-apercu #apercuCustomiseBtn,
  #page-apercu .suite-chip--button,
  #page-apercu .apercu-status-alert-cta {
    display: none !important;
  }
  #page-apercu .apercu-section { margin-bottom: 1rem; }
  #page-apercu .apercu-glance {
    background: var(--wh) !important;
    box-shadow: none !important;
    border: 1px solid var(--border-strong) !important;
    padding: 1rem !important;
  }
  #page-apercu .apercu-glance::after { display: none !important; }
  #page-apercu .apercu-glance-title { font-size: 24pt !important; }
  #page-apercu .apercu-glance-stats {
    grid-template-columns: repeat(4, 1fr) !important;
  }
  #page-apercu .apercu-stat,
  #page-apercu .apercu-tile {
    box-shadow: none !important;
    border: 1px solid var(--border-strong) !important;
    break-inside: avoid;
  }
  #page-apercu .apercu-stat-n {
    font-size: 22pt !important; color:var(--text) !important;
  }
  #page-apercu .apercu-status-progress {
    box-shadow: none !important;
    border: 1px solid var(--border-strong) !important;
  }
  #page-apercu .apercu-status-progress-fill {
    background: var(--g3) !important;
  }
  #page-apercu .apercu-section-title { font-size: 16pt !important; }
  #page-apercu .apercu-subzone-title { font-size: 10pt !important; }
  /* Charts are dense; let them break across pages if needed. */
  #page-apercu .apercu-tile--chart { break-inside: avoid-page; }
  /* Hide the bar-chart permit badges (decorative, color-dependent). */
  #page-apercu .permit-mini { display: none !important; }
  /* Phase pill keeps its color via the semantic tokens (already
     print-safe per the style guide). */
  body.print-picasso-only #page-picasso .ph{padding:0 0 .4rem;margin-bottom:.45rem;}
  body.print-picasso-only #page-picasso .ph-right{display:none !important;}
  body.print-picasso-only #page-picasso .pic-wrap{overflow:visible !important;}
  body.print-picasso-only #page-picasso .pgrid thead th,
  body.print-picasso-only #page-picasso .pgrid td.tc,
  body.print-picasso-only #page-picasso .pic-ext-label-cell{position:static;}
}

/* EMPTY */
.empty{text-align:center;padding:2.5rem 1rem;color:var(--g4);}
.empty-icon{font-size:2.2rem;margin-bottom:.65rem;}
.empty p{font-size:var(--fs-md);line-height:var(--lh-relaxed);}
/* .empty-camp* + @keyframes emptyDrift deleted 2026-06-21 — structurally
   identical to shared/style/_components/empty-state.css. JS path is via
   renderEmptyState from @suite/lib/empty-state (home.js:7). */

/* CONFIRM DIALOG */
.confirm-overlay{display:none;position:fixed;inset:0;background:var(--bg-overlay-light);z-index:var(--z-skip);align-items:center;justify-content:center;}
.confirm-overlay.open{display:flex;}
.confirm-box{background:var(--wh);border-radius:var(--radius-md);padding:1.4rem;max-width:360px;width:90%;box-shadow:var(--shadow-lg);animation:su var(--dur-normal) ease;}
.confirm-box h3{font-family:var(--serif);font-weight:400;font-size:var(--fs-xl);margin-bottom:.5rem;}
.confirm-box p{font-size:var(--fs-md);color:var(--g4);line-height:var(--lh-normal);margin-bottom:1.1rem;}
.confirm-acts{display:flex;gap:var(--sp-2);justify-content:flex-end;flex-wrap:wrap;}

/* Responsibility-card component removed 2026-07-09 — never wired up in js/
   (superseded by the flat roster table + mobile cards in admin-roster.js). */

/* TEMPLATES */
.tpl-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:var(--sp-3);margin-top:.5rem;}
/* .tpl-card composes onto .suite-card; only adds template-picker
 * specifics (denser padding, hover lift, yellow border on hover). */
.tpl-card{padding:.9rem;cursor:pointer;transition:all var(--dur-normal);position:relative;}
.tpl-card:hover{border-color:var(--y);transform:translateY(-2px);}
.tpl-card-badge{display:inline-block;padding:.13rem .42rem;border-radius:var(--radius-lg);font-size:var(--fs-xs);font-weight:var(--fw-bold);margin-bottom:.4rem;}
.tpl-card-name{font-weight:var(--fw-semibold);font-size:var(--fs-md);margin-bottom:.25rem;}
.tpl-card-meta{font-size:var(--fs-sm);color:var(--g4);}
.tpl-card-del{position:absolute;top:.5rem;right:.5rem;background:none;border:none;color:var(--g3);cursor:pointer;font-size:var(--fs-sm);opacity:0;transition:opacity var(--dur-normal);}
.tpl-card:hover .tpl-card-del{opacity:1;}
.tpl-card-del:hover{color:var(--red);}

/* MULTI-USER: PRESENCE BAR */
.presence-bar{display:flex;align-items:center;gap:var(--sp-1h);position:absolute;top:50%;right:1.5rem;transform:translateY(-50%);z-index:5;}
.presence-avatar{width:26px;height:26px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:var(--fs-xs);font-weight:var(--fw-bold);border:2px solid var(--bk);cursor:default;flex-shrink:0;transition:transform var(--dur-normal);}
.presence-avatar:hover{transform:scale(1.15);}
.presence-avatar[title]:hover::after{content:attr(title);position:absolute;top:calc(100% + 4px);right:0;background:var(--bk);color:var(--white);font-size:var(--fs-sm);padding:.2rem .5rem;border-radius:var(--radius-xs);white-space:nowrap;pointer-events:none;}
.presence-dot{width:7px;height:7px;border-radius:50%;background:var(--green);border:1.5px solid var(--bk);position:absolute;bottom:0;right:0;}
.sync-badge{display:flex;align-items:center;gap:var(--sp-1);font-size:var(--fs-xs);color:var(--g4);padding:.2rem .5rem;border-radius:var(--radius-pill);background:var(--g1);border:var(--hairline);}
/* v2 topbar icon-buttons (feedback, tour help, change-feed): 30×30 with hairline border, white bg, ghost-style. */
.topbar .tour-help-btn,.topbar #changeFeedToggle{appearance:none;width:30px;height:30px;display:inline-flex;align-items:center;justify-content:center;background:var(--wh);border:var(--hairline);border-radius:var(--radius-sm);color:var(--text);font-size:var(--fs-md);cursor:pointer;padding:0;transition:background var(--dur-normal),border-color var(--dur-normal);}
.topbar .tour-help-btn:hover,.topbar #changeFeedToggle:hover{background:var(--g1);border-color:var(--g3);}
.topbar .backup-indicator,.topbar .online-count{color:var(--g4);}
.sync-dot{width:6px;height:6px;border-radius:50%;background:var(--green);}
.sync-dot.syncing{background:var(--y);animation:pulse .7s ease-in-out infinite alternate;}
.sync-dot.conflict{background:var(--red);}
@keyframes pulse{from{opacity:.5}to{opacity:1}}

/* IDENTITY MODAL */

/* VERSION CONFLICT BANNER */
.conflict-banner{display:none;background:var(--bg-warn);border-bottom:2px solid var(--y);padding:.5rem 1.5rem;font-size:var(--fs-md);align-items:center;gap:var(--sp-2h);flex-shrink:0;}
.conflict-banner.show{display:flex;}

/* SESSION EXPIRED BANNER */
.session-expired-banner{display:none;background:var(--bg-error);border-bottom:3px solid var(--red);padding:.65rem 1.5rem;font-size:var(--fs-md);align-items:center;gap:var(--sp-2h);flex-shrink:0;font-weight:var(--fw-medium);color:var(--fg-error);animation:session-pulse 2s ease-in-out infinite;}
.session-expired-banner.show{display:flex;}
@keyframes session-pulse{0%,100%{background:var(--bg-error);}50%{background:#fecaca;}}

/* READ-ONLY BANNER */
.ro-banner{background:var(--bg-badge-blue);border-bottom:2px solid #4a90d9;padding:.4rem 1.5rem;font-size:var(--fs-md);align-items:center;gap:var(--sp-2h);flex-shrink:0;color:var(--fg-badge-blue);}
.camp-card-ro{display:inline-flex;align-items:center;gap:var(--sp-1);font-size:var(--fs-sm);padding:.15rem .45rem;border-radius:var(--radius-lg);background:var(--bg-badge-blue);color:var(--fg-badge-blue);font-weight:var(--fw-medium);}
.camp-card-badge{display:inline-flex;align-items:center;font-size:var(--fs-xs);padding:.1rem .4rem;border-radius:var(--radius-lg);font-weight:var(--fw-bold);margin-left:.35rem;vertical-align:middle;}
.camp-card-badge-owner{background:var(--bg-warn);color:var(--fg-warn);}
.camp-card-badge-editor{background:var(--bg-raid);color:var(--blue);}
.camp-card-group{opacity:.85;border-style:dashed;}

/* RAID stats */
.raid-stats-grid{display:flex;gap:var(--sp-2);flex-wrap:wrap;margin:.5rem 0;padding:.55rem .6rem;background:var(--g1);border-radius:var(--radius-sm);}
.raid-stat{display:flex;flex-direction:column;align-items:center;min-width:58px;padding:.3rem .55rem;background:var(--wh);border-radius:var(--radius-sm);border:var(--hairline);gap:.1rem;}
.raid-stat-val{font-size:var(--fs-lg);font-weight:var(--fw-bold);color:var(--blue);line-height:var(--lh-tight);}
.raid-stat-lbl{font-size:var(--fs-xs);color:var(--g4);text-align:center;line-height:var(--lh-tight);}
/* Raid endpoint labels — small, opaque, no arrow tail. Used for permanent
   "Départ" / "Arrivée" tooltips so touch users can read them without hover. */
.leaflet-tooltip.raid-endpoint-label{padding:1px 6px;font-size:var(--fs-xs);font-weight:var(--fw-bold);background:var(--bg-glass);border:1px solid var(--g2,#E4E2DB);box-shadow:0 1px 2px rgba(0,0,0,.12);color:var(--bk,#141414);}
.leaflet-tooltip.raid-endpoint-label::before{display:none;}
/* SwissMobile track picker */
/* Security concept badge */
.act-sec-badge{display:inline-flex;align-items:center;gap:var(--sp-1);font-size:var(--fs-xs);padding:.1rem .4rem;border-radius:var(--radius-xs);background:var(--bg-warn);color:var(--fg-warn);font-weight:var(--fw-semibold);border:1px solid #ffc107;}

/* ── AUTH SCREEN ─────────────────────────────────────────── */
/* C-4 (2026-06-20): the sign-in surface is no longer a fullscreen
   overlay (was position:fixed; inset:0; z-index:var(--z-skip)). It
   mounts INSIDE the content area as a centered card so the SPA chrome
   (sidebar + topbar) stays visible behind/around it. js/main.js moves
   #authScreen into .d-content / .m-content after building the shell.
   Layout: two-panel card on desktop (brand | login), stacked on
   mobile (already handled by the existing 680px breakpoint below). */
.auth-screen{
  display:flex;
  margin:2rem auto;
  width:100%;max-width:840px;
  min-height:520px;
  border-radius:var(--radius-lg);
  overflow:hidden;
  box-shadow:var(--shadow-lg);
  border:var(--hairline);
  background:var(--bk);
}
.auth-screen.hidden{display:none;}

/* Left branding panel */
.auth-brand-panel{
  flex:1;
  background:var(--y);
  display:flex;flex-direction:column;justify-content:center;
  padding:3rem 2.4rem;
  position:relative;overflow:hidden;
  animation:authPanelIn .45s cubic-bezier(.22,.68,0,1.15);
}
.auth-brand-panel::before{
  content:'';position:absolute;
  top:-15%;right:-12%;
  width:340px;height:340px;border-radius:50%;
  background:rgba(0,0,0,.06);
}
.auth-brand-panel::after{
  content:'';position:absolute;
  bottom:-10%;left:-8%;
  width:220px;height:220px;border-radius:50%;
  background:rgba(0,0,0,.04);
}
@keyframes authPanelIn{from{opacity:0;transform:translateX(-24px)}to{opacity:1;transform:none}}

.auth-logo{
  width:64px;height:64px;
  background:#141414;border-radius:var(--radius-md);
  display:flex;align-items:center;justify-content:center;
  margin-bottom:1.8rem;
  box-shadow:0 8px 24px rgba(0,0,0,.25);
  position:relative;z-index:1;
}
.auth-brand-title{
  
  color:var(--text);font-size:2.4rem;font-weight:var(--fw-regular);
  letter-spacing:-.03em;line-height:1;
  margin:0 0 .5rem;
  position:relative;z-index:1;
}
.auth-brand-tagline{
  color:rgba(20,20,20,.65);font-size:var(--fs-md);
  margin:0 0 2.4rem;letter-spacing:.02em;
  position:relative;z-index:1;
}
.auth-feature-list{
  list-style:none;padding:0;margin:0;
  display:flex;flex-direction:column;gap:var(--sp-3);
  position:relative;z-index:1;
}
.auth-feature-list li{
  display:flex;align-items:center;gap:var(--sp-2h);
  font-size:var(--fs-md);color:rgba(20,20,20,.75);font-weight:var(--fw-medium);
}

/* Right login panel */
.auth-login-panel{
  width:380px;flex-shrink:0;
  background:var(--bk);
  display:flex;flex-direction:column;justify-content:center;
  padding:2.6rem 2.4rem;
  border-left:1px solid var(--bk3);
  animation:authLoginIn .45s .08s cubic-bezier(.22,.68,0,1.15) both;
}
@keyframes authLoginIn{from{opacity:0;transform:translateX(18px)}to{opacity:1;transform:none}}

.auth-login-inner{width:100%;max-width:320px;margin:0 auto;}
.auth-login-heading{
  
  color:var(--white);font-size:1.7rem;font-weight:var(--fw-regular);
  letter-spacing:-.02em;margin-bottom:.4rem;
}
.auth-login-sub{
  color:#b5b3aa;font-size:var(--fs-md);line-height:var(--lh-normal);
  margin-bottom:2rem;
}
.auth-beta-disclosure{
  margin:0 0 1.35rem;
  padding:1rem 1.05rem;
  border:1px solid rgb(var(--y-rgb) / 38%);
  border-radius:var(--radius-md);
  background:linear-gradient(180deg,rgb(var(--y-rgb) / 20%),rgb(var(--y-rgb) / 8%));
  box-shadow:var(--shadow-overlay);
}
.auth-beta-kicker{
  color:var(--y);
  font-size:var(--fs-sm);
  font-weight:var(--fw-extrabold);
  text-transform:uppercase;
  letter-spacing:.14em;
  margin-bottom:.45rem;
}
.auth-beta-copy{
  color:var(--white);
  font-size:var(--fs-lg);
  line-height:var(--lh-normal);
  font-weight:var(--fw-semibold);
}
.auth-midata-btn{
  width:100%;padding:1rem 1.2rem;
  background:var(--y);border:none;border-radius:var(--radius-md);
  font-size:var(--fs-lg);
  color:var(--bk);cursor:pointer;
  display:flex;align-items:center;justify-content:center;gap:.65rem;
  transition:opacity var(--dur-normal),transform .1s,box-shadow var(--dur-normal);
  font-weight:var(--fw-semibold);letter-spacing:.01em;
  box-shadow:0 4px 18px rgb(var(--y-rgb) / 25%);
}
.auth-midata-btn:hover{opacity:.92;transform:translateY(-1px);box-shadow:0 6px 24px rgb(var(--y-rgb) / 38%);}
.auth-midata-btn:active{transform:scale(.98);box-shadow:none;}
.auth-midata-btn:disabled{opacity:.5;cursor:not-allowed;transform:none;box-shadow:none;}
.auth-midata-btn .midata-icon{
  width:26px;height:26px;background:var(--bk);border-radius:var(--radius-sm);
  display:flex;align-items:center;justify-content:center;flex-shrink:0;
}
.auth-error{
  background:#3d1212;color:#ff8a8a;border-radius:var(--radius-sm);
  padding:.6rem .85rem;font-size:var(--fs-md);margin-bottom:.9rem;
  display:none;
}
.auth-error.show{display:block;}
/* 1b — remediation hint below the error message. Slightly muted so
   the main error stays primary. */
.auth-error-hint{
  margin-top:.4rem;font-size:var(--fs-sm);color:#ffd0d0;font-style:italic;
}
/* 1a — FAQ accordion at the bottom of the login pane. */
.auth-faq{
  margin-top:1.2rem;padding-top:1rem;border-top:1px solid var(--bk3);
  font-size:var(--fs-sm);
}
.auth-faq summary{
  cursor:pointer;color:var(--g3);user-select:none;padding:.3rem 0;
}
.auth-faq[open] summary{color:var(--white);font-weight:600;}
.auth-faq-body{margin-top:.5rem;color:#bdbdbd;line-height:1.5;}
.auth-faq-body p{margin:0 0 .7rem 0;}
.auth-faq-body strong{color:var(--white);}
/* 1f — mobile-specific hint, hidden on desktop. */
.auth-mobile-hint{display:none;}
@media (max-width:768px){
  .auth-mobile-hint{
    display:block;margin-top:.8rem;padding:.5rem .7rem;
    background:var(--bk3);border-radius:var(--radius-sm);
    font-size:var(--fs-sm);color:#cbcaba;line-height:1.4;
  }
}
.auth-oauth-status{
  text-align:center;padding:2rem 1rem;
  color:var(--g3);font-size:var(--fs-md);
}
.auth-oauth-status .spinner{
  width:32px;height:32px;border:3px solid var(--bk3);
  border-top-color:var(--y);border-radius:50%;
  animation:spin .8s linear infinite;margin:0 auto .8rem;
}
@keyframes spin{to{transform:rotate(360deg)}}
@keyframes shimmer{0%{background-position:-200% 0}100%{background-position:200% 0}}
@keyframes wave{0%,100%{transform:translateY(0)}50%{transform:translateY(-3px)}}
.auth-remember-me{
  display:flex;align-items:center;justify-content:center;gap:.5rem;
  margin-top:1rem;font-size:var(--fs-sm);color:#b5b3aa;
  cursor:pointer;user-select:none;
}
.auth-remember-me input{cursor:pointer;}
.auth-remember-hint{
  text-align:center;margin-top:.3rem;
  font-size:var(--fs-xs);color:var(--g3);font-style:italic;
}
.auth-footer{
  text-align:center;margin-top:1.4rem;
  font-size:var(--fs-sm);color:#b5b3aa;line-height:var(--lh-relaxed);
}
.auth-footer a{color:var(--g3);text-decoration:none;}
.auth-footer a:hover{color:var(--y);}

/* Mobile: stacked (card stays inside content area, sidebar/topbar
   chrome remains visible — see C-4 note above). */
@media(max-width:680px){
  .auth-screen{
    flex-direction:column;
    margin:1rem auto;
    min-height:0;
    max-width:100%;
  }
  .auth-brand-panel{
    flex:none;padding:1.6rem 1.4rem;
    flex-direction:row;align-items:center;flex-wrap:wrap;gap:var(--sp-3);
  }
  .auth-brand-panel::before,.auth-brand-panel::after{display:none;}
  .auth-logo{width:48px;height:48px;border-radius:var(--radius-md);margin-bottom:0;flex-shrink:0;}
  .auth-brand-title{font-size:var(--fs-3xl);margin-bottom:0;}
  .auth-brand-tagline{display:none;}
  .auth-feature-list{display:none;}
  .auth-login-panel{
    width:100%;flex:1;
    border-left:none;border-top:1px solid var(--bk3);
    padding:1.8rem 1.4rem;
    justify-content:flex-start;
  }
  .auth-login-inner{max-width:none;}
  .auth-login-heading{font-size:1.4rem;}
  .auth-login-sub{margin-bottom:1.4rem;}
  .auth-beta-disclosure{padding:.9rem 1rem;margin-bottom:1.1rem;}
  .auth-beta-copy{font-size:var(--fs-md);}
}
/* MIDATA badge */
.midata-badge{display:inline-flex;align-items:center;gap:var(--sp-1h);padding:.18rem .55rem;border-radius:var(--radius-xs);font-size:var(--fs-sm);font-weight:var(--fw-bold);}
.midata-badge.connected{background:var(--bg-permit-manual);color:var(--fg-permit-manual);}
.midata-badge.disconnected{background:var(--bk3);color:#b5b3aa;}

/* ADMIN PANEL */
.admin-section{margin-bottom:2.2rem;}
.admin-section-hd{display:flex;align-items:center;justify-content:space-between;margin-bottom:1rem;padding-bottom:.5rem;border-bottom:2px solid var(--y);}
.admin-section-hd h3{font-size:var(--fs-xl);}
.admin-role-badge{display:inline-flex;align-items:center;gap:var(--sp-1);padding:.18rem .55rem;border-radius:var(--radius-xs);font-size:var(--fs-sm);font-weight:var(--fw-bold);}
.admin-role-abteilung{background:var(--purple);color:var(--white);}


/* Guide §19 — inline-editable title pattern. Subtle hover affordance only;
   no permanent visual decoration so titles stay readable. The input takes
   over in-place when clicked; sized to fit the label. */
.inline-editable{cursor:text;border-radius:var(--radius-xs);padding:0 var(--sp-05);margin-left:calc(var(--sp-05) * -1);transition:background var(--dur-fast);}
.inline-editable:hover{background:rgb(var(--y-rgb) / 10%);}
.inline-edit-input{font:inherit;color:inherit;background:var(--wh);border:1px solid var(--y);border-radius:var(--radius-xs);padding:1px 4px;margin:-1px -4px;outline:none;box-shadow:0 0 0 3px rgb(var(--y-rgb) / 35%);}
.admin-tpl-editor{background:var(--wh);border:var(--hairline);border-radius:var(--radius-md);overflow:hidden;margin-bottom:.85rem;box-shadow:var(--shadow-sm);}
.admin-tpl-hd{display:flex;align-items:center;justify-content:space-between;padding:.6rem 1rem;background:var(--g1);}
.admin-tpl-hd-left{display:flex;align-items:center;gap:var(--sp-2h);flex:1;min-width:0;}
.admin-tpl-name{font-weight:var(--fw-semibold);font-size:var(--fs-md);}
.admin-tpl-body{padding:.75rem 1rem;font-size:var(--fs-md);color:var(--g4);}
.admin-tpl-mats{display:flex;gap:var(--sp-1);flex-wrap:wrap;padding:.4rem 1rem .7rem;border-top:1px solid var(--g1);}
.admin-tpl-mat{font-size:var(--fs-sm);background:var(--g2);padding:.12rem .4rem;border-radius:var(--radius-xs);color:var(--g4);}
.admin-access-denied{text-align:center;padding:3rem 1rem;}
.admin-access-denied .icon{font-size:2.8rem;margin-bottom:.8rem;}
.admin-access-denied h3{font-size:var(--fs-lg);margin-bottom:.4rem;}
.admin-access-denied p{font-size:var(--fs-md);color:var(--g4);line-height:var(--lh-relaxed);max-width:380px;margin:0 auto;}

/* IDENTITY MODAL TABS */

/* ── SIDEBAR COLLAPSE ──────────────────────────────────────── */
.sidebar.sb-collapsed{width:52px;min-width:52px;}
.sidebar.sb-collapsed .sb-logo-label{display:none;}
.sidebar.sb-collapsed .sb-new-camp{display:none;}
.sidebar.sb-collapsed .sb-section-label{display:none;}
.sidebar.sb-collapsed .sb-item{padding:.45rem;text-align:center;font-size:var(--fs-lg);}
.sidebar.sb-collapsed .sb-label{display:none;}
.sidebar.sb-collapsed .sb-camp-item{justify-content:center;padding:.4rem;}
.sidebar.sb-collapsed .camp-label{display:none;}
/* When collapsed, the "+N autres camps — voir tout" label wraps to 6 lines in
   the 52px column. Hide it; the user expands the sidebar (or visits Home) to
   see the full list. */
.sidebar.sb-collapsed .sb-more-camps{display:none;}
.sidebar.sb-collapsed .sb-user{padding:.5rem;flex-direction:column;gap:var(--sp-1);}
.sidebar.sb-collapsed .sb-user .btn{font-size:var(--fs-xs);padding:.15rem .3rem;}
.sidebar.sb-collapsed .sb-divider{margin:.25rem .35rem;}
.sidebar.sb-collapsed .sb-header{justify-content:center;padding:.55rem .4rem;overflow:hidden;}
.sidebar.sb-collapsed .sb-header img{display:none;}
.sidebar.sb-collapsed .sb-header-actions{gap:0;}
.sidebar.sb-collapsed #sbCollapseBtn{display:flex;}

/* ── TOPBAR BACK BUTTON ────────────────────────────────────── */
.topbar-back-btn{
  background:var(--wh);border:var(--hairline);color:var(--text);
  border-radius:var(--radius-sm);padding:.28rem .65rem;font-size:var(--fs-md);
  cursor:pointer;margin-right:.75rem;transition:all var(--dur-normal);flex-shrink:0;position:relative;z-index:1;
}
.topbar-back-btn:hover{background:var(--g1);border-color:var(--g3);}

/* ── MOBILE HAMBURGER ──────────────────────────────────────── */
.sb-mobile-btn{
  display:none;background:none;border:none;color:var(--text);
  font-size:var(--fs-lg);cursor:pointer;padding:.3rem .5rem;
  margin-right:.5rem;flex-shrink:0;position:relative;z-index:1;
}
.sb-overlay{
  display:none;position:fixed;inset:0;background:var(--bg-overlay-light);
  z-index:998;
}
.sb-overlay.show{display:block;}

/* ── MOBILE RESPONSIVE ─────────────────────────────────────── */
@media (max-width: 768px) {
  .sb-mobile-btn{display:block;}
  .sidebar{
    position:fixed;top:0;left:0;height:100vh;height:100dvh;z-index:999;
    transform:translateX(-100%);transition:transform var(--dur-normal) ease;
    box-shadow:4px 0 24px rgba(0,0,0,.35);
  }
  .sidebar.sb-mobile-open{transform:translateX(0);}
  .sidebar.sb-collapsed{transform:translateX(-100%);}
  .sidebar.sb-collapsed.sb-mobile-open{transform:translateX(0);width:220px;min-width:220px;}
  .sidebar.sb-collapsed.sb-mobile-open .sb-logo-label,
  .sidebar.sb-collapsed.sb-mobile-open .sb-new-camp,
  .sidebar.sb-collapsed.sb-mobile-open .sb-section-label,
  .sidebar.sb-collapsed.sb-mobile-open .sb-label,
  .sidebar.sb-collapsed.sb-mobile-open .camp-label{display:block;}
  .content{padding:1rem;}
  .topbar{padding:.8rem 1rem .7rem;}
  .topbar h1{font-size:var(--fs-xl);max-width:calc(100% - 110px);}
  .topbar-sub{max-width:calc(100% - 110px);}
  .camps-grid{grid-template-columns:1fr;}
  .ph{flex-direction:column;align-items:flex-start;gap:var(--sp-2);}
  .ph-right{width:100%;}
  .ph-right .tgl-btn,
  .ph-right .resp-filter-btn{flex:1;text-align:center;}
  /* Action buttons (+ Activité / Modèles / …) size to their content instead
     of each stretching to a full half-width block, which read as oversized. */
  .ph-right .btn{flex:0 1 auto;text-align:center;}
  table{font-size:var(--fs-md);}
  #sbCollapseBtn{display:none!important;}
  .topbar-back-btn{font-size:var(--fs-sm);padding:.22rem .45rem;}
}

@media (max-width: 480px) {
  .content{padding:.75rem;}
  .topbar{padding:.65rem .75rem .6rem;}
  .topbar h1{font-size:var(--fs-lg);}
  .camps-grid{gap:var(--sp-2h);}
  .camp-card{padding:.85rem;}
  .btn{font-size:var(--fs-md);}
  .online-count{display:none;}
  .sb-badge{font-size:max(.55rem,9px);padding:0 var(--sp-05);min-width:12px;line-height:12px;}
}

/* ── MIDATA IMPORT CARD NAME (flex for badges) ─────────────── */

/* PRESENCE TEXT + CONFLICT COMPARE */
.page-collab-banner{padding:var(--sp-1h) var(--sp-3);background:var(--bg-info);color:var(--fg-warn);font-size:var(--fs-sm);border-bottom:var(--hairline);text-align:center;word-break:break-word;transition:opacity var(--dur-slow);}
.undo-bar{position:fixed;bottom:20px;left:50%;transform:translateX(-50%);background:var(--bk);color:var(--white);padding:var(--sp-2h) var(--sp-3);border-radius:var(--radius-sm);box-shadow:var(--shadow-lg);z-index:var(--z-toast);display:flex;align-items:center;gap:var(--sp-3);font-size:var(--fs-md);max-width:90%;animation:slide-up var(--dur-slow) ease-out;}
@keyframes slide-up{from{transform:translateX(-50%) translateY(20px);opacity:0;}to{transform:translateX(-50%) translateY(0);opacity:1;}}
.scroll-to-top-btn{display:none;position:fixed;bottom:20px;right:20px;z-index:var(--z-dropdown);width:44px;height:44px;border-radius:var(--radius-pill);border:var(--hairline);background:var(--wh);color:var(--text);font-size:var(--fs-lg);cursor:pointer;box-shadow:var(--shadow-md);transition:opacity var(--dur-fast);}
@media(max-width:640px){
  .undo-bar{bottom:calc(75px + env(safe-area-inset-bottom,0));}
  .scroll-to-top-btn{bottom:calc(75px + env(safe-area-inset-bottom,0));width:40px;height:40px;}
}
.act-lock-banner{display:none;padding:var(--sp-2h) var(--sp-4);background:var(--bg-warn);border-bottom:var(--hairline);color:var(--fg-warn);font-size:var(--fs-md);line-height:var(--lh-normal);}
.act-lock-banner.show{display:block;}
@media (max-width: 900px){.compare-grid{grid-template-columns:1fr !important;}.presence-text{display:none;}}

/* ── Relation tooltip ─────────────────────────────────── */
.rel-info-btn{background:none;border:1px solid var(--border-strong);border-radius:50%;width:1.25rem;height:1.25rem;font-size:var(--fs-xs);font-weight:var(--fw-bold);cursor:pointer;color:var(--g4);line-height:1;display:inline-flex;align-items:center;justify-content:center;margin-left:.35rem;vertical-align:middle;flex-shrink:0;}
.rel-info-btn:hover{background:var(--bk);color:var(--white);}
.rel-tooltip{position:fixed;z-index:var(--z-skip);background:var(--bk);color:var(--white);border-radius:var(--radius-sm);padding:.75rem 1rem;font-size:var(--fs-sm);line-height:var(--lh-normal);max-width:300px;box-shadow:0 4px 20px rgba(0,0,0,.35);pointer-events:none;opacity:0;transition:opacity var(--dur-normal);}
.rel-tooltip.show{opacity:1;}

/* ── J+S section in aperçu ───────────────────────────── */
.js-section{margin-top:1rem;background:var(--wh);border-radius:var(--radius-md);padding:1rem 1.1rem;border:var(--hairline);}
.js-day-row{display:flex;align-items:center;gap:var(--sp-2);padding:.3rem 0;border-bottom:var(--hairline);font-size:var(--fs-md);color:var(--text);}
.js-day-row:last-child{border-bottom:none;}
.js-day-label{width:5rem;font-weight:var(--fw-semibold);flex-shrink:0;color:var(--text);}
.js-bar-wrap{flex:1;background:var(--g1);border-radius:var(--radius-xs);height:7px;overflow:hidden;}
.js-bar{height:100%;border-radius:var(--radius-xs);transition:width var(--dur-slow);}
.js-pill{font-size:var(--fs-xs);font-weight:var(--fw-bold);padding:.12rem .4rem;border-radius:var(--radius-xs);flex-shrink:0;}
.js-ok{background:var(--bg-success);color:var(--fg-success);}.js-warn{background:var(--bg-warn);color:var(--fg-warn);}.js-bad{background:var(--bg-error);color:var(--fg-error);}
.js-summary{display:flex;align-items:center;gap:var(--sp-2);margin-bottom:.5rem;font-size:var(--fs-md);font-weight:var(--fw-semibold);}

/* ── Validation badges ───────────────────────────────── */
.vld-section{margin-top:.8rem;background:var(--wh);border-radius:var(--radius-md);padding:1rem 1.1rem;border:var(--hairline);}
.vld-row{display:flex;align-items:center;gap:var(--sp-2);padding:.25rem 0;font-size:var(--fs-md);color:var(--text);}
.vld-icon{font-size:var(--fs-lg);flex-shrink:0;}

/* ── History section ────────────────────────────────── */
.hist-section{margin-top:.8rem;background:var(--wh);border-radius:var(--radius-md);padding:1rem 1.1rem;border:var(--hairline);}
/* Card-title accent underline. Faded to the Style Guide's accent value
   (rgba(255,206,0,.25)) — at full-strength var(--y) the rule repeated under
   every analysis card "striped" the zone with loud yellow lines. The brand
   bar stays full-strength only on the topbar. */
:is(.hist-section-title,.apercu-sec-title,.section-hd-accent){font-size:var(--fs-lg);font-weight:var(--fw-regular);color:var(--text);margin-bottom:var(--sp-3h);padding-bottom:var(--sp-1h);border-bottom:2px solid rgba(255,206,0,.25);}
.hist-entry{display:flex;gap:var(--sp-2);align-items:baseline;padding:.25rem 0;border-bottom:1px solid var(--g1);font-size:var(--fs-md);}
.hist-entry:last-child{border-bottom:none;}
.hist-ts{color:var(--g4);white-space:nowrap;flex-shrink:0;min-width:3.5rem;}
.hist-by{font-weight:var(--fw-semibold);flex-shrink:0;max-width:7rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text);}
.hist-action{color:var(--g4);flex-shrink:0;}
.hist-detail{color:var(--g4);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;}

/* Picasso cell text sizes consolidated in the .pcell rules below */

/* ── PICASSO: Chef de jour/nuit rows ──────────────────────── */
#picHead th{background:var(--bk);}
.pic-day-label{font-size:var(--fs-xs);font-weight:var(--fw-bold);text-align:center;padding:.35rem .2rem;color:var(--white);background:var(--bk);}
.pic-chef-row{display:flex;align-items:center;gap:var(--sp-1);padding:.25rem .4rem;font-size:var(--fs-xs);cursor:pointer;transition:background var(--dur-fast);white-space:nowrap;overflow:hidden;}
.pgrid th{padding:0;}

/* .apercu-layout deleted 2026-06-21 — no JS/HTML/test consumers; the v3
   three-section restructure 2026-05-16 uses `.apercu-section` instead. */
.apercu-col-side .apercu-bar-section{margin-top:0;}
.apercu-col-side .hist-section{margin-top:.8rem;}

/* ═════════════════════════════════════════════════════════════
   APERÇU v3  ·  three-section layout per Camp v2 Style Guide
   ═════════════════════════════════════════════════════════════ */

/* All three sections share the same spacing rhythm. Stacked
   vertically; sections never side-by-side. Bottom margin is the
   visual breath between sections. */
.apercu-section{margin-bottom:var(--sp-4);}
.apercu-section:last-child{margin-bottom:0;}

/* Section header (used by §2 and §3) — sans H2 next to a flush-right
   aside (pill in §2, button in §3). H2 itself follows the style-guide
   "Section H2" spec: DM Serif Display 24/400 line-height 1.15. */
.apercu-section-hd{
  display:flex;align-items:center;gap:var(--sp-2);
  margin-bottom:var(--sp-3);
}
.apercu-section-title{
  font-family:var(--serif);
  font-weight:400;
  font-size:var(--fs-2xl);line-height:1.15;letter-spacing:-.005em;
  color:var(--text);
  flex:1;min-width:0;
  margin:0;
}
.apercu-section-aside{display:inline-flex;align-items:center;gap:var(--sp-1h);flex-shrink:0;flex-wrap:wrap;}
/* At narrow widths (phones), the section header doesn't have room for
   "Statut du camp" + "15 points" badge + "Camp en cours · fin dans 6 j"
   pill on one line — the pill gets clipped or text wraps mid-word.
   Allow the row to wrap so the title sits on its own line. */
@media (max-width: 640px) {
  .apercu-section-hd { flex-wrap: wrap; row-gap: var(--sp-1); }
  .apercu-section-aside { width: 100%; justify-content: flex-start; }
}

/* ── §1  Camp en bref  ──────────────────────────────────────
   Hero-ish surface: serif H2 for the camp name, meta line beneath,
   then a 4-up stat grid. On mobile the stats collapse to 2x2. */
.apercu-glance{
  background:linear-gradient(180deg, var(--wh) 0%, var(--g1) 100%);
  border:var(--hairline);
  border-radius:var(--radius-lg, 20px);
  padding:var(--sp-4) var(--sp-4) var(--sp-3);
  box-shadow:var(--shadow-sm);
  position:relative;overflow:hidden;
}
/* Soft yellow accent — purely decorative, mirrors sg-hero. */
.apercu-glance::after{
  content:"";
  position:absolute;right:-60px;top:-60px;
  width:220px;height:220px;
  background:var(--y);
  border-radius:50%;
  opacity:.10;filter:blur(2px);
  pointer-events:none;
}
.apercu-glance-hd{position:relative;z-index:1;margin-bottom:var(--sp-3);}
.apercu-glance-eyebrow{
  font-size:var(--fs-xs);font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:var(--g4);margin-bottom:var(--sp-1);display:block;
}
.apercu-glance-title{
  font-family:var(--serif);
  font-weight:400;
  font-size:var(--fs-2xl);line-height:1.15;letter-spacing:-.015em;
  color:var(--text);
  margin:0 0 var(--sp-1h);
  text-wrap:balance;
}
.apercu-glance-meta{
  font-size:var(--fs-md);color:var(--g4);line-height:1.5;margin:0;
  display:flex;flex-wrap:wrap;gap:0 var(--sp-2h);
}
.apercu-glance-meta b{color:var(--text);font-weight:600;}
.apercu-glance-meta-sep{opacity:.4;}
/* Branches strip — colored chips for each branch present, in canonical
   order (Castors → Resp). Same --br-* tokens as the Picasso columns +
   the camp-card title strip so the visual stays consistent across the
   app. Aperçu glance item #1. */
.apercu-glance-branches{
  display:flex;flex-wrap:wrap;gap:var(--sp-1);
  margin-top:var(--sp-2);
  position:relative;z-index:1;
}
.apercu-branch{
  display:inline-flex;align-items:center;
  padding:3px 10px;
  border-radius:var(--radius-pill);
  font-size:var(--fs-xs);font-weight:600;
  letter-spacing:.02em;
  border:1px solid transparent;
  color:var(--text);
  background:var(--g1);
  white-space:nowrap;
}
.apercu-branch-castors{background:var(--br-castors);color:var(--bk);}
.apercu-branch-louveteaux{background:var(--br-louv);color:var(--white);}
.apercu-branch-eclais{background:var(--br-eclais);color:var(--white);}
.apercu-branch-picos{background:var(--br-picos);color:var(--white);}
.apercu-branch-responsables{background:var(--br-resps);color:var(--white);}
.apercu-glance-stats{
  display:grid;
  grid-template-columns:repeat(4, 1fr);
  gap:var(--sp-2);
  position:relative;z-index:1;
}
@media (max-width:768px){
  .apercu-glance{padding:var(--sp-3) var(--sp-2h);}
  .apercu-glance-title{font-size:var(--fs-xl);}
  .apercu-glance-stats{grid-template-columns:repeat(2,1fr);gap:var(--sp-1h);}
}

/* ── Unified .apercu-stat tile (style-guide stat spec) ──────
   Number: DM Serif Display 28-32/700. Label: DM Sans 10-11/700
   uppercase, .09em tracking, --g4 color. Replaces the older .stat
   rule with the v2-spec'd typography. */
.apercu-stat{
  background:var(--surface-card);
  border:var(--hairline);
  border-radius:var(--radius-md);
  padding:var(--sp-2h) var(--sp-2);
  text-align:center;
  position:relative;
  display:flex;flex-direction:column;gap:var(--sp-1);
  transition:background var(--dur-fast), transform var(--dur-fast),
    box-shadow var(--dur-fast);
}
.apercu-stat:hover{background:var(--g1);}
/* The "i" info bubble is appended as a child; pin it to the corner so it
   doesn't flow onto its own line under the label (left it looking detached). */
.apercu-stat .i-bubble{position:absolute;top:var(--sp-1h);right:var(--sp-1h);}
/* Activités mobile cards reuse the shared .m-card-actions, but that class is
   the swipe-to-reveal drawer (position:absolute; background:var(--bk)). These
   cards show their actions inline (force-flexed via u-display-flex), so the
   black drawer fill leaked behind the Modifier/📋/✕ buttons. Neutralise the
   drawer styling for the always-visible activités usage. */
.m-card.act-row .m-card-actions{position:static;inset:auto;background:transparent;color:inherit;justify-content:flex-end;align-items:center;margin-top:var(--sp-1);}
.apercu-stat-n{
  font-family:var(--serif);
  font-weight:700;
  font-size:var(--fs-stat-num);line-height:1;
  color:var(--text);
  display:block;
}
.apercu-stat-l{
  font-family:var(--sans);
  font-weight:700;
  font-size:var(--fs-xs);line-height:1.2;
  letter-spacing:.09em;text-transform:uppercase;
  color:var(--g4);
  display:block;
}
@media (max-width:768px){
  .apercu-stat-n{font-size:var(--fs-stat-num-sm);}
}

/* Relation tiles — left-bar accent in the relation's color, mirrors
   the style-guide `.sg-rel` pattern. The relation tile uses a left
   stripe rather than a fully colored bg so the number stays
   readable + the page stays calm. */
.apercu-stat--relation{
  position:relative;
  padding-left:var(--sp-3);
  text-align:left;
}
.apercu-stat--relation::before{
  content:"";
  position:absolute;
  left:var(--sp-1h);top:50%;transform:translateY(-50%);
  width:4px;height:60%;
  background:var(--g3);
  border-radius:2px;
}
.apercu-stat--rel-pers::before{background:var(--pers);}
.apercu-stat--rel-corps::before{background:var(--corps);}
.apercu-stat--rel-env::before{background:var(--env);}
.apercu-stat--rel-autres::before{background:var(--autres);}
.apercu-stat--rel-spirit::before{background:var(--spirit);}

/* ── §2  Statut du camp  ────────────────────────────────────
   Always-visible status surface. The progress bar + alerts + smart
   suggestions render into #apercuStatusBody. When the camp is fully
   ready, body becomes a single sg-banner-success line. */
.apercu-status{}
.apercu-status-body{
  display:flex;flex-direction:column;gap:var(--sp-2);
}
.apercu-status-progress{
  background:var(--surface-card);
  border:var(--hairline);
  border-radius:var(--radius-md);
  box-shadow:var(--shadow-sm);
  padding:var(--sp-3) var(--sp-3);
  display:flex;flex-direction:column;gap:var(--sp-2);
}
.apercu-status-progress-row{
  display:flex;align-items:center;gap:var(--sp-2h);
}
.apercu-status-progress-track{
  flex:1;min-width:0;
  height:8px;background:var(--g1);
  border-radius:var(--radius-pill);overflow:hidden;
}
.apercu-status-progress-fill{
  height:100%;
  border-radius:var(--radius-pill);
  transition:width var(--dur-slow);
}
.apercu-status-progress-pct{
  font-family:var(--serif);
  font-weight:700;
  font-size:var(--fs-xl);line-height:1;
  color:var(--text);
  min-width:3em;text-align:right;
}
.apercu-status-checks{
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(240px, 1fr));
  gap:var(--sp-1h) var(--sp-2);
  font-size:var(--fs-sm);line-height:1.5;
  color:var(--g4);
  margin:0;padding:0;list-style:none;
}
.apercu-status-checks li{
  display:flex;align-items:flex-start;gap:var(--sp-1);
}
.apercu-status-checks li.is-ok{color:var(--g4);}
.apercu-status-checks li.is-todo{color:var(--text);font-weight:500;}
.apercu-status-checks-icon{flex-shrink:0;}
/* Reset native <button> styling on the matos-overlap card so it reads
   as a banner while staying keyboard-activatable. Pairs with the
   sg-banner-warn class for color + spacing. */
.apercu-matos-overlap-card{
  text-align:left;width:100%;border:0;font:inherit;
}
/* Alerts — uses sg-banner pattern from the style guide. */
.apercu-status-alert{
  display:flex;gap:var(--sp-1h);padding:var(--sp-2) var(--sp-2h);
  border-radius:var(--radius-sm);
  align-items:flex-start;
  font-size:var(--fs-sm);line-height:1.5;
  border:1px solid transparent;
}
.apercu-status-alert-icon{font-size:var(--fs-lg);line-height:1;flex-shrink:0;}
.apercu-status-alert-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--sp-1h);}
.apercu-status-alert-body strong{
  display:block;font-weight:600;margin-bottom:2px;color:inherit;
}
/* Category kicker above the strong line — small uppercase tag that
   identifies which check fired (e.g. "Activités sans responsable").
   Lighter weight than the score line so the eye reads score-first,
   category-second. */
.apercu-status-alert-body .apercu-status-alert-kicker{
  display:block;
  font-size:var(--fs-xs);font-weight:700;
  letter-spacing:.09em;text-transform:uppercase;
  opacity:.75;
  margin-bottom:2px;
}
.apercu-status-alert-body .apercu-status-alert-sub{
  font-size:var(--fs-xs);opacity:.85;display:block;margin-top:2px;
}
.apercu-status-alert-cta{
  appearance:none;background:none;border:none;padding:0;
  color:inherit;text-decoration:underline;cursor:pointer;
  font-size:var(--fs-xs);font-weight:600;
}
/* Intentional divergence from .sg-banner-* (style guide §16). Why: the
   apercu status tile carries a richer layout the canonical banner doesn't
   model (kicker + score line + sub + inline CTA + a count badge in the
   §2 header), so it keeps its own class rather than composing. The warn /
   error / success swatches read from the SAME --bg-*/--fg-* tokens as the
   canonical banners, so a token change propagates to both automatically —
   no manual sync needed. The --info variant deliberately uses muted --g4
   body text (not --fg-info): the info tile is informational chrome, not a
   coloured alert, so it stays quiet. Keep these four mapped to the canonical
   token set; only the info text colour is an owned deviation. */
.apercu-status-alert--warn{background:var(--bg-warn);color:var(--fg-warn);}
.apercu-status-alert--error{background:var(--bg-error);color:var(--fg-error);}
.apercu-status-alert--success{background:var(--bg-success);color:var(--fg-success);}
.apercu-status-alert--info{background:var(--bg-info);color:var(--g4);}
/* Consistent severity marker on the surface: a colored left accent so every
   tier reads at a glance even when its fill is pale (--bg-warn #fff3cd is so
   light it otherwise looks unstyled next to the red --bg-error). Mirrors the
   relation/now-next left-bar motif used elsewhere on the page. */
.apercu-status-alert{border-left:3px solid transparent;}
.apercu-status-alert--error{border-left-color:var(--red);}
.apercu-status-alert--warn{border-left-color:var(--amber);}
.apercu-status-alert--success{border-left-color:var(--green);}
.apercu-status-alert--info{border-left-color:var(--blue);}
/* ── Count badge in the §2 header ────────────────────────────
   Dynamic at-a-glance summary of how many items are in the section.
   Shows the highest severity color (red/amber/neutral) so the volume
   is visible BEFORE you scroll into the section body. Hidden when
   the camp is all-green. */
.apercu-status-count{
  display:inline-flex;align-items:center;gap:.25rem;
  padding:3px 10px;
  border-radius:var(--radius-pill);
  font-size:var(--fs-xs);font-weight:700;
  letter-spacing:.02em;
  border:1px solid transparent;
  background:var(--g1);color:var(--g4);
}
.apercu-status-count--must{
  background:var(--bg-error);color:var(--fg-error);border-color:var(--red);
}
.apercu-status-count--warn{
  background:var(--bg-warn);color:var(--fg-warn);border-color:var(--amber);
}
.apercu-status-count--info{
  background:var(--bg-info);color:var(--g4);border-color:var(--g2);
}

/* ── "Voir tout" expander for overflow alerts + info one-liners ── */
.apercu-status-more{
  border:var(--hairline);
  border-radius:var(--radius-sm);
  background:var(--wh);
  overflow:hidden;
}
.apercu-status-more-toggle{
  display:flex;align-items:center;justify-content:space-between;
  padding:var(--sp-1h) var(--sp-2);
  font-size:var(--fs-sm);font-weight:600;color:var(--text);
  cursor:pointer;
  list-style:none;
}
.apercu-status-more-toggle::-webkit-details-marker{display:none;}
.apercu-status-more-toggle::marker{display:none;}
.apercu-status-more-toggle:hover{background:var(--g1);}
.apercu-status-more-toggle-icon{
  transition:transform var(--dur-normal);
  font-size:var(--fs-md);color:var(--g4);
}
.apercu-status-more[open] .apercu-status-more-toggle-icon{
  transform:rotate(180deg);
}
.apercu-status-more-body{
  display:flex;flex-direction:column;gap:var(--sp-2);
  padding:var(--sp-2);
  border-top:var(--hairline);
}
/* Info one-liners — dense list, single line per item, separator
   between title and score. The compact form means 5+ "info" alerts
   stay readable without dominating the section. */
.apercu-status-info-list{
  list-style:none;padding:0;margin:0;
  display:flex;flex-direction:column;gap:var(--sp-05);
  font-size:var(--fs-xs);color:var(--g4);
}
.apercu-status-info-list li{
  display:flex;align-items:baseline;gap:var(--sp-1);
}
.apercu-status-info-title{color:var(--text);font-weight:600;}
.apercu-status-info-score{font-style:italic;}

.apercu-status-suggestions{
  display:flex;flex-wrap:wrap;gap:var(--sp-1h);
  margin-top:var(--sp-2);
}
/* ── §3  Tableaux de bord  ──────────────────────────────────
   Configurable widget grid grouped into sub-zones. Each sub-zone
   carries an H3 + a tile grid. The widget framework reorders/hides
   tiles within their sub-zone via [data-widget-id]. */
.apercu-subzone{margin-top:var(--sp-3);}
.apercu-subzone:first-child{margin-top:0;}
.apercu-subzone-title{
  font-family:var(--sans);
  font-weight:700;
  font-size:var(--fs-xs);line-height:1.4;
  letter-spacing:.14em;text-transform:uppercase;
  color:var(--text);
  margin:0 0 var(--sp-2);
  padding-bottom:var(--sp-1);
  border-bottom:var(--hairline);
  display:flex;align-items:baseline;gap:var(--sp-1);
}
.apercu-subzone-title > [aria-hidden]{font-size:var(--fs-md);letter-spacing:0;}

/* Unified tile shape used by §3 widgets. The same shape works for
   stats / live widgets / charts via modifier classes. */
.apercu-tile{
  background:var(--surface-card);
  border:var(--hairline);
  border-radius:var(--radius-md);
  box-shadow:var(--shadow-sm);
  padding:var(--sp-2h);
  position:relative;
  overflow:hidden;
}
.apercu-tile:empty{display:none;}
.apercu-tile-hd{
  font-family:var(--sans);
  font-weight:600;
  font-size:var(--fs-md);line-height:1.3;
  color:var(--text);
  margin-bottom:var(--sp-2);
}
.apercu-tile--chart{min-height:120px;}
.apercu-tile--num{padding:0;background:transparent;border:none;box-shadow:none;}

/* Column-count masonry: tiles flow top-to-bottom in each column,
   filling the available vertical space without leaving awkward gaps
   between tiles of different heights. The previous `display:grid;
   align-items:start` layout treated each row's height as the tallest
   tile, leaving whitespace below shorter tiles. */
.apercu-tile-grid{
  column-width:280px;
  column-gap:var(--sp-2);
  column-fill:balance;
}
.apercu-tile-grid > *{
  break-inside:avoid;
  /* inline-block prevents column-break inside the tile and gives it
     a sensible default width inside the column flow. */
  display:inline-block;
  width:100%;
  margin-bottom:var(--sp-2);
}
.apercu-tile-grid > *:last-child{margin-bottom:0;}
/* Relations counters: 5 small numeric tiles, all same height — these
   want a real grid row, not masonry. Override back to grid. */
.apercu-tile-grid--num{
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(160px, 1fr));
  column-width:auto;
  column-fill:auto;
  gap:var(--sp-2);
}
.apercu-tile-grid--num > *{
  display:block;
  margin-bottom:0;
}

/* ── Picasso sparkline widget ─────────────────────────────────
   A dense day × hour heatmap that summarises the camp's program at
   a glance. Click anywhere to jump to the full Picasso. The whole
   tile is the click target, so the inner content is rendered into
   a <button> with reset chrome. */
.apercu-tile--pico{padding:0;}
.apercu-pico-shell{
  appearance:none;background:none;border:none;padding:var(--sp-2h);
  width:100%;display:block;cursor:pointer;text-align:left;
  border-radius:inherit;
  transition:background var(--dur-fast);
  --apercu-pico-label-w:48px;
}
.apercu-pico-shell:hover{background:var(--g1);}
.apercu-pico-shell:focus-visible{
  outline:3px solid var(--focus-ring);
  outline-offset:2px;
}
.apercu-pico-hd{
  display:flex;align-items:baseline;justify-content:space-between;
  margin-bottom:var(--sp-1h);
}
.apercu-pico-title{
  font-family:var(--sans);
  font-weight:600;font-size:var(--fs-md);line-height:1.3;color:var(--text);
}
.apercu-pico-hint{
  font-size:var(--fs-xs);color:var(--g4);font-weight:600;letter-spacing:.04em;
}
.apercu-pico-axis{
  position:relative;height:14px;
  font-size:var(--fs-xs);color:var(--g4);font-weight:600;letter-spacing:.04em;
  margin-bottom:4px;
}
.apercu-pico-hour{position:absolute;top:0;transform:translateX(-50%);}
.apercu-pico-grid{display:flex;flex-direction:column;gap:2px;}
.apercu-pico-row{
  display:flex;align-items:center;gap:var(--sp-1);
  font-size:var(--fs-xs);color:var(--g4);
}
.apercu-pico-day{
  width:48px;flex-shrink:0;
  font-weight:600;
  text-align:right;
  font-variant-numeric:tabular-nums;
}
.apercu-pico-row-cells{
  flex:1;display:grid;
  grid-template-columns:repeat(24, 1fr);
  gap:1px;
  height:18px;
  border-radius:var(--radius-xs);
  overflow:hidden;
}
.apercu-pico-cell{
  background:var(--g1);
  height:100%;
  transition:opacity var(--dur-fast);
}
/* Density tiers — empty / 1 / 2 / 3+. Color comes from the dominant
   type via inline `data-style-set="background:var(--type-...)"`; the
   intensity class only modulates opacity for non-empty cells. */
.apercu-pico-cell[data-pico-empty="1"]{background:var(--g1);opacity:1;}
.apercu-pico-cell.apercu-pico-lo{opacity:.35;}
.apercu-pico-cell.apercu-pico-md{opacity:.65;}
.apercu-pico-cell.apercu-pico-hi{opacity:1;}
/* Late-night band (0-5 + 23) — dim the empty cells slightly so the
   user reads the "core day" 6-22 band more easily. */
.apercu-pico-cell[data-pico-empty="1"][data-pico-night="1"]{
  background:var(--g2);
}
@media (max-width:768px){
  .apercu-pico-shell{--apercu-pico-label-w:36px;}
  .apercu-pico-day{width:36px;font-size:var(--fs-xs);}
  .apercu-pico-row-cells{height:14px;}
}

/* Live widgets inside the dashboard adopt the shared tile look at
   their outer surface. The internal `live-widget` styling that
   live-widgets.js targets is preserved. */
.apercu-subzone[data-subzone="live"] .live-widget{
  /* live-widget already has bg + radius + shadow + border. Margin
     becomes grid-gap responsibility. */
  margin-bottom:0;
}
/* The live zone is an ops strip, NOT 280px masonry: now/next is a
   full-width hero banner, the supporting tiles flow in responsive
   columns wide enough for their compact "m" layout. (Cramming the
   "bn" banner into a 280px masonry column caused the title/countdown
   overlap + pill overflow — see live-widgets.js LIVE_AUTO_SIZE.) */
.apercu-subzone[data-subzone="live"] .apercu-tile-grid{
  column-width:auto;
  column-fill:auto;
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(260px, 1fr));
  gap:var(--sp-2);
  align-items:start;
}
.apercu-subzone[data-subzone="live"] .apercu-tile-grid > *{
  display:block;
  width:auto;
  margin-bottom:0;
  break-inside:auto;
}
.apercu-subzone[data-subzone="live"] .live-widget[data-widget-id="live-now-next"]{
  grid-column:1 / -1;
}
/* Defensive: titles wrap inside their flex column instead of spilling
   over a sibling, no matter how narrow the slot gets. */
.live-widget .lw-title{min-width:0;overflow-wrap:anywhere;}
.live-widget .lw-col{min-width:0;}

/* Mobile single-column flow for all sections. */
@media (max-width:768px){
  .apercu-section{margin-bottom:var(--sp-3);}
  .apercu-section-title{font-size:var(--fs-xl);}
  .apercu-status-progress-pct{font-size:var(--fs-lg);min-width:3em;}
  .apercu-status-checks{grid-template-columns:1fr;}
  .apercu-tile-grid{column-width:auto;column-count:1;gap:var(--sp-1h);}
  .apercu-tile-grid--num{grid-template-columns:1fr;gap:var(--sp-1h);}
}
/* Mobile: force single column AND inline the side column's widgets
   beneath the main column's widgets, in priority order. The bar-chart
   (charge par responsable) and history are the only side widgets that
   stay visible by default below 720px; the rest collapse into the
   customise modal. Aperçu review 2026-05-16. */
@media (max-width: 720px) {
  .apercu-layout { grid-template-columns: 1fr; gap: var(--sp-2); }
  .apercu-col-side > .hist-section,
  .apercu-col-side > .apercu-bar-section { margin-top: 0; }
  /* Compact the stats-row tiles on narrow viewports — fewer columns,
     smaller numbers, less padding. Existing breakpoints at 1146/2141
     handle 3-up / 2-up; we just need to keep the numbers legible. */
  .stats-row .stat-n { font-size:var(--fs-2xl); }
  .stats-row .stat-l { font-size: var(--fs-xs); }
}

/* ── APERÇU empty state — getting-started CTAs ────────────── */
.apercu-empty-card {
  background: var(--wh);
  border: var(--hairline);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  padding: var(--sp-4) var(--sp-3);
  max-width: 720px;
  margin: 0 auto;
}
.apercu-empty-kicker {
  font-size: var(--fs-xs); font-weight: var(--fw-bold);
  text-transform: uppercase; letter-spacing: .08em;
  color: var(--g4); margin-bottom: var(--sp-1);
}
.apercu-empty-kicker.u-c-error { color: var(--fg-error); }
.apercu-empty-title {
  font-family: var(--serif); font-weight: 400;
  font-size:var(--fs-3xl); line-height: 1.2; color:var(--text);
  margin: 0 0 var(--sp-3);
}
.apercu-empty-grid {
  display: grid; gap: var(--sp-2);
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  margin-bottom: var(--sp-3);
}
.apercu-empty-step {
  appearance: none; background: var(--wh); border: var(--hairline);
  border-radius: var(--radius-md); padding: var(--sp-2h) var(--sp-2);
  display: flex; gap: var(--sp-2); align-items: flex-start; text-align: left;
  cursor: pointer; transition: background var(--dur-normal),
    border-color var(--dur-normal), transform var(--dur-fast),
    box-shadow var(--dur-fast);
  width: 100%; min-height: 88px;
}
.apercu-empty-step:hover { background: var(--g1); border-color: var(--bk3); transform: translateY(-1px); box-shadow: var(--shadow-md); }
.apercu-empty-step:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 2px; border-color: var(--y); }
.apercu-empty-step-icon { font-size:var(--fs-3xl); line-height: 1; flex-shrink: 0; }
.apercu-empty-step-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.apercu-empty-step-body strong { font-size: var(--fs-md); color:var(--text); font-weight: var(--fw-semibold); }
.apercu-empty-step-sub { font-size: var(--fs-xs); color: var(--g4); }
.apercu-empty-foot { font-size: var(--fs-sm); color: var(--g4); }
.apercu-empty-link {
  background: none; border: none; padding: 0; color: var(--blue);
  cursor: pointer; text-decoration: underline; font-size: inherit;
}
.apercu-empty-link:hover { color:var(--text); }
@media (max-width: 720px) {
  .apercu-empty-card { padding: var(--sp-3) var(--sp-2); }
  .apercu-empty-title { font-size: 1.3rem; }
  .apercu-empty-grid { grid-template-columns: 1fr; }
}

/* ── MATÉRIEL responsive layout ───────────────────────────── */
.mat-wide-grid{
  display:grid;
  gap:var(--sp-3h);
  grid-template-columns:repeat(auto-fit,minmax(min(100%, 420px),1fr));
}

/* ── BAR CHART (Aperçu responsables) ─────────────────────── */
.apercu-bar-section{margin-top:.8rem;background:var(--wh);border-radius:var(--radius-md);padding:1rem 1.1rem;border:var(--hairline);}
/* .apercu-sec-title unified with .hist-section-title above */
.bar-legend{display:flex;gap:var(--sp-3h);margin-bottom:.6rem;flex-wrap:wrap;}
.bar-leg-item{display:flex;align-items:center;gap:var(--sp-1);font-size:var(--fs-sm);color:var(--g4);}
.bar-leg-dot{width:10px;height:10px;border-radius:2px;flex-shrink:0;}
.bar-chart-wrap{display:flex;flex-direction:column;gap:var(--sp-1);}
.bar-row{display:flex;align-items:center;gap:var(--sp-2);}
.bar-label{width:5.5rem;font-size:var(--fs-sm);font-weight:var(--fw-semibold);color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex-shrink:0;}
.bar-track{flex:1;height:16px;background:var(--g1);border-radius:var(--radius-xs);overflow:hidden;display:flex;}
.bar-seg{height:100%;transition:width var(--dur-slow);min-width:0;}
.bar-acts{background:var(--type-sc);}
.bar-resps{background:var(--type-aa);}
.bar-chefs{background:var(--pers);}
.bar-gray{background:var(--g2);}
.bar-total{min-width:2rem;text-align:right;font-size:var(--fs-sm);color:var(--g4);font-weight:var(--fw-semibold);flex-shrink:0;display:flex;align-items:center;gap:var(--sp-1);justify-content:flex-end;}

/* ── RELECTURE ───────────────────────────────────────────── */
.rev-progress-bar-wrap{height:7px;background:var(--g2);border-radius:var(--radius-pill);overflow:hidden;margin-bottom:.4rem;}
.rev-progress-bar{height:100%;background:var(--green);border-radius:var(--radius-pill);transition:width var(--dur-slow);}
.rev-progress-summary{display:flex;align-items:center;gap:var(--sp-2);margin-bottom:.9rem;flex-wrap:wrap;}
.rev-prog-pill{border-radius:var(--radius-pill);padding:.15rem .55rem;font-size:var(--fs-sm);font-weight:var(--fw-semibold);}
.rev-prog-approved{background:var(--bg-success);color:var(--fg-success);}
.rev-prog-pending{background:var(--bg-info);color:var(--fg-warn);}
.rev-prog-rejected{background:#ffebee;color:var(--fg-error);}
.rev-issues{display:flex;flex-wrap:wrap;gap:var(--sp-1);padding:.5rem .9rem;background:var(--bg-info);border-bottom:var(--hairline);}
.rev-issue-chip{background:var(--bg-warn);color:var(--fg-warn);border-radius:var(--radius-pill);padding:.1rem .45rem;font-size:var(--fs-sm);}
.rev-card{border:var(--hairline);border-radius:var(--radius-md);margin-bottom:.85rem;overflow:hidden;transition:box-shadow var(--dur-normal);}
.rev-card:hover{box-shadow:var(--shadow-md);}
.rev-card-hd{display:flex;align-items:center;gap:var(--sp-2);padding:.7rem .9rem;background:var(--g1);flex-wrap:wrap;}
.rev-act-name{font-weight:var(--fw-semibold);font-size:var(--fs-lg);flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.rev-meta{font-size:var(--fs-sm);color:var(--g4);white-space:nowrap;}
.rev-meta-pill{display:inline-flex;align-items:center;gap:var(--sp-1);font-size:var(--fs-sm);font-weight:var(--fw-semibold);padding:.12rem .48rem;border-radius:var(--radius-pill);white-space:nowrap;}
.rev-meta-pill-warn{color:var(--fg-warn);background:var(--bg-info);border:1px solid #f3d8a0;}
.rev-meta-reviewer{font-size:var(--fs-sm);}
.rev-body{padding:.9rem 1rem;}
.rev-act-details{margin-bottom:.6rem;}
.rev-desc{font-size:var(--fs-md);line-height:var(--lh-normal);color:var(--g4);margin-bottom:.3rem;}
.rev-comment{width:100%;margin-bottom:.5rem;min-height:132px;}
.rev-btns{display:flex;gap:var(--sp-2);}
.rev-approved{border-color:var(--green);border-left:4px solid var(--green);}
.rev-approved .rev-card-hd{background:var(--bg-approved);}
.rev-rejected{border-left:4px solid var(--spirit);}
.rev-rejected .rev-card-hd{background:var(--bg-rejected);}
.rev-pending{border-color:var(--g2);}
.rev-collapsed .rev-body{display:none;}
.rev-raid-box{margin:.5rem 0 .8rem;padding:.6rem .7rem;background:var(--bg-raid);border:1px solid #bfdbfe;border-radius:var(--radius-sm);}
.rev-raid-title{font-size:var(--fs-sm);font-weight:var(--fw-bold);text-transform:uppercase;letter-spacing:.05em;color:#1d4ed8;margin-bottom:.5rem;}
.rev-raid-segment{margin-bottom:.7rem;}
.rev-raid-segment:last-child{margin-bottom:0;}
.rev-raid-segment-title{font-size:var(--fs-sm);font-weight:var(--fw-semibold);margin-bottom:.3rem;}
.rev-sec-concept-box{margin:.6rem 0;padding:.55rem .8rem;background:var(--bg-info);border:var(--hairline);border-radius:var(--radius-sm);font-size:var(--fs-md);}
.rev-sec-concept-title{font-weight:var(--fw-bold);margin-bottom:.3rem;color:var(--fg-warn);}
.rev-sec-concept-grid{display:grid;grid-template-columns:max-content 1fr;gap:.1rem .6rem;color:var(--g4);min-width:0;overflow:hidden;}
.rev-sec-concept-value{color:var(--text);}
.rev-sec-concept-key-top{align-self:start;}
.rev-sec-concept-multiline{word-break:break-word;overflow-wrap:anywhere;}
/* Linked acts in resp card */

/* ── RELECTURE v2 — sub-tabs + LED matrix ──────────────── */
.rel-tabs{display:flex;gap:.25rem;border-bottom:var(--hairline);margin:.6rem 0 .85rem;flex-wrap:wrap;}
.rel-tab{background:transparent;border:none;padding:.55rem 1rem;font:inherit;font-size:var(--fs-md);color:var(--g4);cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1px;transition:color var(--dur-normal),border-color var(--dur-normal);}
.rel-tab:hover{color:var(--text);}
.rel-tab.on{color:var(--text);border-bottom-color:var(--y);font-weight:var(--fw-semibold);}
.rel-pane{display:none;}
.rel-pane.on{display:block;}
/* In detailed-review (focus) mode the overview's Statut/Type filter toolbar is
   irrelevant — hide it while the focus pane is the active one. */
#page-relecture:has(#relectureFocus.rel-pane.on) .act-toolbar{display:none;}

.rel-matrix-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch;max-width:100%;}
/* Mobile relecture overview: the desktop matrix + wrapping filter rows don't
   fit a phone. Let the filter pills scroll horizontally (instead of wrapping
   into odd rows) and let the matrix shrink to the viewport (denser, no page
   overflow). A full card-layout redesign is the longer-term fix. */
@media (max-width:680px){
  #page-relecture .act-toolbar-grp .suite-tabs--pill{flex-wrap:nowrap;overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none;}
  #page-relecture .act-toolbar-grp .suite-tabs--pill::-webkit-scrollbar{display:none;}
  #page-relecture .act-toolbar-grp .suite-tab{flex:0 0 auto;}
  #page-relecture .rel-matrix{min-width:0;font-size:var(--fs-sm);}
}
.rel-matrix{width:100%;min-width:540px;border-collapse:separate;border-spacing:0;font-size:var(--fs-md);background:var(--wh);border:var(--hairline);border-radius:var(--radius-sm);overflow:hidden;}
.rel-matrix th{font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:.05em;color:var(--g4);text-align:center;padding:.5rem .25rem;border-bottom:var(--hairline);background:var(--g1);font-weight:var(--fw-semibold);}
.rel-matrix th.rel-mx-act{text-align:left;padding-left:.75rem;min-width:180px;}
.rel-matrix td{padding:.5rem .25rem;border-bottom:1px solid var(--g1);text-align:center;vertical-align:middle;}
.rel-matrix td.rel-mx-act{text-align:left;padding-left:.75rem;}
.rel-matrix td.rel-mx-act b{font-size:var(--fs-md);font-weight:var(--fw-semibold);display:block;}
.rel-matrix td.rel-mx-act .rel-mx-meta{font-size:var(--fs-sm);color:var(--g4);margin-top:.1rem;}
.rel-matrix tr.rel-mx-dh td{background:var(--g1);font-weight:var(--fw-bold);font-size:var(--fs-sm);color:var(--g4);text-transform:uppercase;letter-spacing:.04em;text-align:left;padding:.35rem .75rem;position:sticky;top:0;z-index:2;}
.rel-matrix tbody tr.rel-mx-row{cursor:pointer;}
.rel-matrix tbody tr.rel-mx-row:hover td{background:rgb(var(--y-rgb) / 8%);}
.rel-matrix tbody tr.rel-mx-row:focus-visible td{background:rgb(var(--y-rgb) / 18%);}
.rel-matrix .rel-mx-stat{display:inline-block;font-size:var(--fs-xs);font-weight:var(--fw-semibold);padding:.1rem .55rem;border-radius:var(--radius-pill);background:var(--g1);color:var(--g4);}
.rel-matrix .rel-mx-stat.rel-mx-stat-ok{background:var(--bg-success);color:var(--fg-success);}
.rel-matrix .rel-mx-stat.rel-mx-stat-pending{background:var(--bg-info);color:var(--fg-warn);}
.rel-matrix .rel-mx-stat.rel-mx-stat-rejected{background:var(--bg-rejected);color:var(--fg-error);}
.rel-mx-legend{display:flex;gap:.9rem;flex-wrap:wrap;font-size:var(--fs-sm);color:var(--g4);margin:.55rem .15rem 0;align-items:center;}
.rel-mx-legend .rel-led{margin-right:.25rem;}

/* LED — interactive 22×22 circle. */
/* flex:none + aspect-ratio:1 keep the LED a circle: in a flex/narrow matrix
   cell it was being stretched vertically into an ellipse. */
.rel-led{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;flex:none;aspect-ratio:1;border-radius:50%;border:1.5px solid var(--g2);background:var(--wh);vertical-align:middle;cursor:pointer;padding:0;font-size:var(--fs-sm);font-weight:var(--fw-bold);line-height:1;color:var(--g3);box-sizing:border-box;transition:transform var(--dur-fast),box-shadow var(--dur-normal);}
.rel-led:hover{transform:scale(1.08);}
.rel-led:focus-visible{outline:2px solid var(--bk);outline-offset:2px;}
/* Unrated LED: must read as a visible empty well. --wh would match the
   --wh matrix/row surface exactly (invisible); --g1 fill + --g3 border +
   --g4 dot make it distinct from the surface in both light and dark. */
.rel-led.rel-led-none{background:var(--g1);border-color:var(--g3);color:var(--g4);}
.rel-led.rel-led-ok{background:var(--green);border-color:var(--green);color:var(--white);}
.rel-led.rel-led-warn{background:var(--y);border-color:var(--y);color:var(--bk);}
.rel-led.rel-led-bad{background:var(--red);border-color:var(--red);color:var(--white);}
.rel-led.rel-led-active{border-color:var(--bk);}
.rel-led.rel-led-na{background:transparent;border:none;color:var(--g3);font-size:var(--fs-sm);width:auto;height:auto;cursor:default;}
.rel-led.rel-led-sm{width:14px;height:14px;}
.rel-led.rel-led-xs{width:10px;height:10px;border-width:1.5px;}

/* Focus prev/next nav strip */
.rel-focus-nav{display:flex;align-items:center;gap:var(--sp-2);margin:.4rem 0 .85rem;flex-wrap:wrap;}
.rel-focus-nav .rel-focus-pos{font-size:var(--fs-sm);color:var(--g4);}
.rel-focus-nav .rel-focus-spacer{flex:1;}
.rel-focus-nav .rel-focus-leds{display:inline-flex;gap:.35rem;align-items:center;font-size:var(--fs-sm);color:var(--g4);}
.rel-focus-nav .rel-focus-leds-label{font-weight:var(--fw-semibold);color:var(--text);margin-right:.25rem;}

.rel-empty{padding:1.5rem 1rem;text-align:center;color:var(--g4);font-size:var(--fs-md);}

/* v2 Focus mode — queue + main rel-card layout */
/* 2026-05-14 restructure: the 2-col `240px 1fr` grid (queue + main)
   was retired. Focus mode now renders a single rel-card spanning the
   full pane; the left-rail queue and its associated rules below are
   orphaned but kept inert (no callers, no markup uses them). */
.rel-focus{display:block;margin-top:.4rem;}
/* Back-to-overview link at the top of the focus card. Small, restrained;
   the primary affordance is the focus content, not the chrome. */
.rel-card-back{padding:8px 18px 0;}
.rel-card-back .btn{font-size:var(--fs-sm);}
.rel-queue{background:var(--wh);border:var(--hairline);border-radius:var(--radius-sm);padding:8px;display:flex;flex-direction:column;gap:2px;max-height:calc(100vh - 220px);overflow-y:auto;position:sticky;top:8px;}
.rel-queue-hd{font-size:10.5px;text-transform:uppercase;letter-spacing:.05em;color:var(--g4);padding:4px 6px;display:flex;justify-content:space-between;font-weight:var(--fw-semibold);}
.rel-q-item{display:grid;grid-template-columns:14px 1fr auto;gap:6px;align-items:center;padding:6px 8px;border-radius:var(--radius-sm);font-size:var(--fs-sm);cursor:pointer;background:transparent;border:none;width:100%;text-align:left;font:inherit;color:inherit;}
.rel-q-item:hover{background:var(--g1);}
.rel-q-item.on{background:var(--y);font-weight:600;}
.rel-q-item:focus-visible{outline:2px solid var(--bk);outline-offset:1px;}
.rel-q-item .rel-q-led{width:10px;height:10px;border-radius:50%;display:inline-block;}
.rel-q-item .rel-q-led-ok{background:var(--green);}
.rel-q-item .rel-q-led-warn{background:var(--y);border:1.5px solid var(--bk);}
.rel-q-item .rel-q-led-bad{background:var(--red);}
/* Empty LED: matches the surrounding surface so it reads as "hollow /
 * not yet rated" in both themes. Literal `#fff` stayed pure-white in
 * dark mode, which made the empty LED brighter than the active green/
 * yellow/red ones (inverted signal). */
.rel-q-item .rel-q-led-none{background:var(--wh);border:1.5px solid var(--g3);}
.rel-q-item .rel-q-nm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.rel-q-item .rel-q-when{font-size:10.5px;color:var(--g4);}
.rel-q-item.on .rel-q-when{color:var(--text);opacity:.7;}

.rel-card{background:var(--wh);border:var(--hairline);border-radius:var(--radius-md);overflow:hidden;}
/* Card header background — was `linear-gradient(180deg,#fff,var(--wh))`
   which broke in dark mode (the #fff stop stays white while --wh flips
   to near-black, producing a high-contrast gradient instead of the
   subtle white-on-off-white intended). Use --wh for both stops so the
   gradient stays subtle in both themes. */
.rel-card-hd{padding:14px 18px;border-bottom:var(--hairline);background:var(--wh);}
.rel-card-hd .rel-topline{display:flex;align-items:center;gap:8px;font-size:var(--fs-xs);color:var(--g4);margin-bottom:4px;flex-wrap:wrap;}
.rel-card-hd .rel-tp-pill{display:inline-block;font-size:10.5px;font-weight:700;padding:1px 7px;border-radius:99px;border:1px solid var(--bk);background:var(--g1);}
.rel-card-hd .rel-tp-pill.aa{background:#f3e8ff;}
.rel-card-hd .rel-tp-pill.ac{background:#ecfccb;}
.rel-card-hd .rel-tp-pill.sc{background:#dbeafe;}
.rel-card-hd .rel-block-flag{margin-left:auto;color:var(--red);font-weight:600;}
.rel-card-hd h3{font-family:var(--serif);font-size:var(--fs-2xl);line-height:1.1;margin:0 0 4px;color:var(--text);}
.rel-card-hd .rel-meta-row{font-size:var(--fs-sm);color:var(--g4);display:flex;flex-wrap:wrap;gap:14px;}
.rel-card-hd .rel-meta-row b{color:var(--text);}
.rel-card-hd .rel-meta-row .rel-danger{color:var(--red);font-weight:600;}
.rel-card-hd .rel-nav{display:flex;gap:6px;margin-top:10px;align-items:center;flex-wrap:wrap;}
.rel-card-hd .rel-nav .rel-kbd{font-family:ui-monospace,monospace;font-size:var(--fs-xs);border:var(--hairline);padding:1px 5px;border-radius:3px;background:var(--g1);}
.rel-card-hd .rel-nav .rel-pos{font-size:var(--fs-xs);color:var(--g4);margin:0 8px;}
.rel-card-hd .rel-approve-row{display:flex;gap:8px;margin-top:10px;align-items:center;flex-wrap:wrap;}
/* Approve button gated by red-LED criteria — visually dim + not-allowed
   cursor so users see why it's unclickable. Uses [disabled] attribute
   selector so the markup keeps its canonical class list (the existing
   regression test pins the exact class string). */
.rev-approve-btn[disabled]{opacity:.5;cursor:not-allowed;}
.rel-card-hd .rel-approve-row .rel-gate{font-size:var(--fs-xs);color:var(--red);font-weight:600;margin-left:auto;}

.rel-body{padding:14px 18px;display:grid;grid-template-columns:1.4fr 1fr;gap:18px;}
.rel-sec{margin-bottom:14px;}
.rel-sec:last-child{margin-bottom:0;}
.rel-sec h4{font-family:var(--serif);font-size:var(--fs-md);margin:0 0 8px;display:flex;align-items:center;gap:6px;color:var(--text);}
.rel-sec h4 .rel-count{font-family:var(--sans);font-size:var(--fs-xs);color:var(--g4);font-weight:400;}

.rel-list{display:flex;flex-direction:column;gap:6px;}
.rel-row{display:grid;grid-template-columns:8px 1fr auto;gap:12px;align-items:center;background:var(--wh);border:var(--hairline);border-radius:var(--radius-sm);padding:6px 12px;}
.rel-row.warn{background:#fff8e1;}
.rel-row.bad{background:#fee2e2;border-color:#fca5a5;}
.rel-row .rel-row-bar{width:8px;height:36px;border-radius:99px;background:var(--g3);border:none;cursor:pointer;padding:0;}
.rel-row .rel-row-bar.ok{background:var(--green);}
.rel-row .rel-row-bar.warn{background:var(--y);}
.rel-row .rel-row-bar.bad{background:var(--red);}
.rel-row .rel-row-bar:focus-visible{outline:2px solid var(--bk);outline-offset:2px;}
.rel-row .rel-row-body b{font-size:var(--fs-sm);color:var(--text);}
.rel-row .rel-row-body .rel-row-meta{font-size:var(--fs-xs);color:var(--g4);margin-top:2px;}
.rel-row .rel-row-checks{display:flex;gap:4px;}
/* 2026-05-17: ✓/⚠/✕ are now clickable buttons (bug #18). The legacy
   span selectors stay for any markup that hasn't been re-rendered yet. */
.rel-row .rel-row-checks span,.rel-row .rel-row-checks .rel-row-check{width:24px;height:24px;border-radius:50%;display:grid;place-items:center;font-size:var(--fs-xs);background:var(--g1);}
.rel-row .rel-row-checks .rel-row-check{appearance:none;border:1px solid transparent;color:inherit;cursor:pointer;padding:0;line-height:1;transition:background var(--dur-fast),border-color var(--dur-fast);}
.rel-row .rel-row-checks .rel-row-check:hover{border-color:var(--g3);}
.rel-row .rel-row-checks .rel-row-check:focus-visible{outline:3px solid var(--focus-ring);outline-offset:2px;}
.rel-row .rel-row-checks .ok,.rel-row .rel-row-checks .rel-row-check.ok{background:#e8f5e9;}
.rel-row .rel-row-checks .warn,.rel-row .rel-row-checks .rel-row-check.warn{background:#fff3cd;}
.rel-row .rel-row-checks .bad,.rel-row .rel-row-checks .rel-row-check.bad{background:#fee2e2;}
.rel-row .rel-row-checks .none{opacity:.4;}
.rel-row .rel-row-checks .rel-row-check.active{border-color:var(--bk);}

.rel-mat-list{display:flex;flex-direction:column;gap:3px;font-size:var(--fs-sm);}
.rel-mat-list .rel-mat-row{display:grid;grid-template-columns:1fr auto;gap:8px;padding:3px 0;border-bottom:1px dashed var(--g1);}
.rel-mat-list .rel-mat-row:last-child{border-bottom:none;}
.rel-mat-list .rel-mat-row .rel-mat-qty{color:var(--g4);font-size:var(--fs-xs);}

.rel-resp-list{display:flex;flex-wrap:wrap;gap:6px;}
/* .rel-resp-chip / .rel-resp-chip.empty retired 2026-07-09 — relecture now
   renders responsables via the canonical person-chip (js/shared/person-chip.js)
   and the missing state via renderRespEmpty (.badge-error). */

@media(max-width:1100px){
  .rel-focus{grid-template-columns:1fr;}
  .rel-queue{position:static;max-height:240px;}
  .rel-body{grid-template-columns:1fr;}
}

@media(max-width:640px){
  .rel-matrix th.rel-mx-act,.rel-matrix td.rel-mx-act{padding-left:.45rem;min-width:140px;}
}

.act-filter-block{margin:.55rem 0;}
.act-filter-label{font-size:var(--fs-sm);font-weight:var(--fw-bold);text-transform:uppercase;letter-spacing:var(--ls-wide);color:var(--g4);margin:.15rem 0 .35rem;}

.pcell-name{word-break:break-word;}

/* ── CHEF ROWS IN PICASSO TABLE ─────────────────────────── */
.pic-chef-row-jour td{background:#3a3200;color:var(--pers);font-size:var(--fs-sm);font-weight:var(--fw-semibold);border-top:2px solid rgba(252,190,9,.5);border-bottom:1px solid rgba(252,190,9,.15);}
.pic-chef-row-nuit td{background:#1a1a3a;color:#9ab0ff;font-size:var(--fs-sm);font-weight:var(--fw-semibold);border-top:2px solid rgba(154,176,255,.5);border-bottom:1px solid rgba(154,176,255,.15);}
.pic-chef-row-jour .pic-ext-label-cell,.pic-chef-row-nuit .pic-ext-label-cell{font-size:var(--fs-xs);font-weight:var(--fw-regular);}
.pic-chef-row-jour .pic-ext-clickable:hover{background:#4a4200;filter:none;}
.pic-chef-row-nuit .pic-ext-clickable:hover{background:#25254a;filter:none;}
.pic-ext-label-cell{font-size:var(--fs-xs);color:var(--g4);text-align:center;padding:.3rem 0;white-space:nowrap;width:36px;min-width:36px;overflow:visible;line-height:1;vertical-align:middle;}
.pic-ext-cell{padding:.45rem .55rem;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;border-left:1px solid rgba(255,255,255,.08);vertical-align:middle;max-width:0;min-height:2rem;}
.pic-ext-clickable{cursor:pointer;}
.pic-ext-clickable:hover{filter:brightness(1.25);}
.pic-ext-empty{opacity:.4;}

/* ── SETTINGS PERMIT GRID ────────────────────────────── */

/* ── FULL-SCREEN WIZARD ──────────────────────────────── */
/* Wizard steps (used inside modals) */
.wizard-step{margin-bottom:1.2rem;padding-bottom:1rem;border-bottom:var(--hairline);}
.wizard-step:last-child{border-bottom:none;}
.wizard-step-hd{font-size:var(--fs-lg);font-weight:var(--fw-bold);color:var(--text);margin-bottom:.7rem;display:flex;align-items:center;gap:var(--sp-2);}
.wizard-step-num{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border-radius:50%;background:var(--bk);color:var(--white);font-size:var(--fs-sm);font-weight:var(--fw-bold);flex-shrink:0;}

/* ── SIDEBAR TAB CONFIG ──────────────────────────────── */
.tab-config-grid{display:flex;flex-direction:column;gap:var(--sp-1h);margin-top:.5rem;}
/* tab-config-row — see further down */
.tab-config-row:hover{border-color:var(--y);}
.tab-config-row label{display:flex;align-items:center;gap:var(--sp-2);flex:1;cursor:pointer;font-size:var(--fs-md);}
/* tab-config-handle — see further down */

/* ── MENUS PAGE ──────────────────────────────────────── */
.menus-layout{display:grid;grid-template-columns:1fr 1fr;gap:1.5rem;align-items:start;}
@media(max-width:820px){.menus-layout{grid-template-columns:1fr;}}
/* min-width:0 lets the columns shrink below their grid children's min-content
   (the .menu-grid / .menus-grid minmax tracks), so nothing forces horizontal
   overflow on narrow phones. */
.menus-plan-col,.menus-lib-col{min-width:0;}
.menus-hint{font-size:var(--fs-md);color:var(--g4);line-height:var(--lh-normal);margin:0 0 var(--sp-2);}
#menuPhRight{display:flex;align-items:center;gap:var(--sp-2) .5rem;flex-wrap:wrap;}
#menuPhRight .btn{flex:0 0 auto;}
#menuCampPeople{width:88px;max-width:88px;min-width:88px;}
@media(max-width:768px){
  #menuPhRight{width:100%;}
  #menuPhRight .btn{flex:1 1 170px;justify-content:center;}
}
.section-label{font-size:var(--fs-xs);font-weight:var(--fw-bold);text-transform:uppercase;letter-spacing:.08em;color:var(--g4);margin-bottom:.6rem;}
.menus-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:var(--sp-3);margin-top:.5rem;}
/* .menu-card composes onto .suite-card; only adds the camp-cookbook
 * specifics (asymmetric padding, yellow border on hover). */
.menu-card{padding:.85rem 1rem;cursor:pointer;transition:all var(--dur-normal);position:relative;}
.menu-card:hover{border-color:var(--y);}
.menu-card h3{font-size:var(--fs-lg);margin-bottom:.25rem;padding-right:2rem;}
.menu-card-meta{font-size:var(--fs-sm);color:var(--g4);margin-top:.4rem;}
.menu-card-edit{position:absolute;top:.6rem;right:.6rem;background:none;border:none;cursor:pointer;font-size:var(--fs-md);opacity:.45;transition:opacity var(--dur-normal);padding:.2rem .35rem;}
.menu-card-edit:hover{opacity:1;}
.meal-slot{border:var(--hairline);border-radius:var(--radius-sm);padding:.55rem .8rem;background:var(--wh);display:flex;align-items:center;gap:var(--sp-3);margin-bottom:.35rem;}
.meal-slot-time{font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--g4);white-space:nowrap;min-width:5rem;}
.meal-slot-name{font-size:var(--fs-md);font-weight:var(--fw-medium);flex:1;}
.meal-day-hd{font-size:var(--fs-lg);padding:.3rem 0;border-bottom:2px solid var(--y);margin:.9rem 0 .4rem;}
.meal-divers-item{border:var(--hairline);border-radius:var(--radius-sm);padding:.45rem .8rem;background:var(--wh);display:flex;align-items:center;gap:var(--sp-3);margin-bottom:.35rem;font-size:var(--fs-md);}
.meal-pick-item{display:flex;align-items:center;gap:var(--sp-2h);padding:.55rem .7rem;border-radius:var(--radius-sm);cursor:pointer;transition:background var(--dur-fast);}
.meal-pick-item:hover{background:var(--g1);}
.meal-pick-badge{font-size:var(--fs-xs);font-weight:var(--fw-bold);padding:.1rem .38rem;border-radius:var(--radius-lg);white-space:nowrap;}
.meal-pick-badge-group{background:#faf4cc;color:#a07800;}
.meal-pick-badge-camp{background:var(--bg-success);color:#2e7d32;}
.shop-toolbar{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-2);margin-top:.4rem;margin-bottom:.5rem;}
.shop-count{font-size:var(--fs-sm);color:var(--g4);font-weight:var(--fw-semibold);}
.shop-list{display:flex;flex-direction:column;gap:var(--sp-3);}
.shop-aisle{display:flex;flex-direction:column;gap:var(--sp-1);}
.shop-aisle-hd{font-size:var(--fs-xs);font-weight:var(--fw-bold);text-transform:uppercase;letter-spacing:.06em;color:var(--g4);padding-bottom:.15rem;border-bottom:var(--hairline);margin-bottom:.1rem;}
.shop-row{border-radius:var(--radius-sm);padding:.4rem .6rem;background:var(--g1);border:var(--hairline);}
.shop-row:has(input:checked){opacity:.45;text-decoration:line-through;}
.shop-qty{font-weight:var(--fw-bold);font-size:var(--fs-md);color:var(--text);font-variant-numeric:tabular-nums;white-space:nowrap;}
.shop-label{font-size:var(--fs-md);font-weight:var(--fw-medium);}
.shop-sources{font-size:var(--fs-sm);color:var(--g4);margin-top:.15rem;line-height:1.4;display:block;}

/* ── Photo filter grid ────────────────────────────────────────── */
/* ── Photo gallery grid ───────────────────────────────────────── */
/* v2 hi-fi aliases (.photo-grid, .photo-tile, .photo-bar) — production uses .ph-gallery/.ph-gi */
.ph-gallery,.photo-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(130px,1fr));gap:6px;padding:.25rem 0;}
.ph-gi,.photo-tile{position:relative;aspect-ratio:1;border-radius:var(--radius-sm);overflow:hidden;cursor:pointer;background:var(--g2);}
.photo-bar{display:flex;gap:var(--sp-1);align-items:center;flex-wrap:wrap;margin-bottom:var(--sp-2);}
.ph-gi img{width:100%;height:100%;object-fit:cover;display:block;transition:opacity var(--dur-normal);}
.ph-gi:hover img{opacity:.85;}
.ph-gi-rej{opacity:.4;}
.ph-gi-rej img{filter:grayscale(1);}
.ph-gi-acc{outline:2px solid var(--green);outline-offset:-2px;}
.ph-gi-neu{outline:2px solid #f59e0b;outline-offset:-2px;opacity:.75;}
.ph-gi-badge{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:var(--fs-3xl);font-weight:var(--fw-extrabold);pointer-events:none;}
.ph-gi-badge-acc{color:var(--green);text-shadow:0 0 6px rgba(0,0,0,.6);}
.ph-gi-badge-rej{color:var(--fg-muted);}
.ph-gi-badge-neu{color:#f59e0b;font-size:var(--fs-xl);text-shadow:0 0 4px rgba(0,0,0,.5);}

/* ── Lightbox ─────────────────────────────────────────────────── */
.ph-lb{position:fixed;inset:0;z-index:1000;background:var(--bg-lightbox);display:none;flex-direction:column;}
.ph-lb.ph-lb-open{display:flex;}
.ph-lb-top{display:flex;align-items:center;gap:var(--sp-2h);padding:.6rem 1rem;background:#111;flex-shrink:0;min-height:52px;}
.ph-lb-person-bar{display:flex;align-items:center;gap:var(--sp-2);flex:1;overflow:hidden;}
.ph-lb-pface{width:36px;height:36px;border-radius:50%;object-fit:cover;border:2px solid #444;flex-shrink:0;}
.ph-lb-pname{color:var(--white);font-size:var(--fs-md);font-weight:var(--fw-semibold);cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:180px;}
.ph-lb-pname:hover{text-decoration:underline;}
.ph-lb-rename-input{background:#222;border:1px solid var(--border-dark);border-radius:var(--radius-xs);color:var(--white);font-size:var(--fs-md);padding:.2rem .4rem;width:160px;outline:none;}
.ph-lb-pbtn{font-size:var(--fs-sm);padding:.2rem .55rem;border:1px solid var(--border-dark);border-radius:var(--radius-lg);background:none;color:#ccc;cursor:pointer;white-space:nowrap;transition:all var(--dur-normal);}
.ph-lb-pbtn:hover{border-color:var(--white);color:var(--white);}
.ph-lb-pbtn.on{background:var(--purple);border-color:var(--purple);color:var(--white);}
.ph-lb-merge-pick{position:absolute;top:52px;left:0;right:0;background:#1a1a1a;border-bottom:1px solid #333;padding:.6rem 1rem;flex-wrap:wrap;gap:var(--sp-2);z-index:10;align-items:center;}
.ph-lb-merge-label{font-size:var(--fs-sm);color:var(--fg-muted);width:100%;}
.ph-lb-merge-opt{display:flex;align-items:center;gap:var(--sp-1h);background:#222;border:1px solid #444;border-radius:var(--radius-sm);color:var(--white);font-size:var(--fs-sm);padding:.3rem .5rem;cursor:pointer;}
.ph-lb-merge-opt img{width:28px;height:28px;border-radius:50%;object-fit:cover;}
.ph-lb-merge-opt:hover{border-color:var(--blue);background:#1e2d4a;}
.ph-lb-merge-cancel{font-size:var(--fs-sm);padding:.2rem .5rem;border:1px solid var(--border-dark);border-radius:var(--radius-lg);background:none;color:var(--fg-muted);cursor:pointer;}
.ph-lb-counter{color:var(--fg-muted);font-size:var(--fs-md);white-space:nowrap;margin-left:auto;}
.ph-lb-close{background:none;border:none;color:var(--g3);font-size:1.4rem;cursor:pointer;padding:.2rem .5rem;line-height:1;flex-shrink:0;}
.ph-lb-close:hover{color:var(--white);}
.ph-lb-body{flex:1;display:flex;align-items:center;overflow:hidden;position:relative;}
.ph-lb-img-wrap{flex:1;height:100%;display:flex;align-items:center;justify-content:center;position:relative;overflow:hidden;}
.ph-lb-img-wrap img{max-width:100%;max-height:100%;object-fit:contain;transition:opacity var(--dur-normal);}
.ph-lb-spinner{position:absolute;width:32px;height:32px;border:3px solid #333;border-top-color:var(--white);border-radius:50%;animation:spin .7s linear infinite;display:none;}
.ph-lb-nav{background:none;border:none;color:rgba(255,255,255,.5);font-size:3rem;cursor:pointer;padding:0 1rem;flex-shrink:0;transition:color var(--dur-normal);line-height:1;}
.ph-lb-nav:hover:not(:disabled){color:var(--white);}
.ph-lb-nav:disabled{opacity:.15;cursor:default;}
.ph-lb-foot{display:flex;align-items:center;gap:var(--sp-4);padding:.6rem 1.2rem;background:#111;flex-shrink:0;}
.ph-lb-dec{font-size:var(--fs-md);padding:.3rem .9rem;border:1px solid var(--border-dark);border-radius:var(--radius-lg);background:none;color:var(--g3);cursor:pointer;transition:all var(--dur-normal);}
.ph-lb-dec:hover{border-color:var(--white);color:var(--white);}
.ph-lb-dec.on-acc{background:#15803d;border-color:var(--green);color:var(--white);}
.ph-lb-dec.on-rej{background:#7f1d1d;border-color:var(--red);color:var(--white);}
.ph-lb-dec.on-neu{background:#333;border-color:#666;color:var(--g3);}
.ph-lb-hint{font-size:var(--fs-sm);color:var(--g4);}

/* ── People / blur grid ───────────────────────────────────────── */
.pp-grid{display:flex;flex-wrap:wrap;gap:12px;padding:.5rem 0;}
.pp-card{width:80px;text-align:center;transition:opacity var(--dur-normal);}
.pp-card.pp-merge-src{outline:2px solid var(--amber);border-radius:var(--radius-sm);padding:2px;}
.pp-face{position:relative;width:64px;height:64px;border-radius:50%;overflow:hidden;border:2px solid var(--g2);margin:0 auto .35rem;transition:border-color var(--dur-normal);}
.pp-card.pp-on .pp-face{border-color:var(--purple);}
.pp-face:hover{border-color:var(--g4);}
.pp-face img{width:100%;height:100%;object-fit:cover;display:block;}
.pp-blur-icon{position:absolute;bottom:-2px;right:-2px;font-size:var(--fs-md);background:var(--purple);border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;line-height:1;}
.pp-name-row{margin-bottom:.3rem;}
.pp-name{font-size:var(--fs-sm);font-weight:var(--fw-medium);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;}
.pp-unnamed{color:var(--g4);font-style:italic;}
.pp-rename-input{width:74px;font-size:var(--fs-xs);border:1px solid var(--border-strong);border-radius:var(--radius-xs);padding:.1rem .25rem;text-align:center;outline:none;}
.pp-actions{display:flex;flex-direction:column;gap:var(--sp-1);align-items:center;}
.pp-btn{font-size:var(--fs-xs);padding:.1rem .32rem;border:1px solid var(--border-strong);border-radius:var(--radius-lg);background:none;cursor:pointer;white-space:nowrap;transition:all var(--dur-normal);line-height:1.4;}
.pp-btn:hover{border-color:var(--purple);color:var(--purple);}
.pp-toggle.on{background:var(--purple);color:var(--white);border-color:var(--purple);}
.pp-merge-start{color:var(--g4);}
.pp-merge-into{border-color:var(--blue);color:var(--blue);font-size:var(--fs-xs);}
.pp-merge-into:hover{background:var(--blue);color:var(--white);}
.pp-merge-cancel{border-color:var(--amber);color:var(--amber);}
.pp-merge-cancel:hover{background:var(--amber);color:var(--white);}


/* ══════════════════════════════════════════════════════════════
   RESPONSIVE — TABLET / MOBILE  (≤ 640 px)
   ══════════════════════════════════════════════════════════════ */

/* Stats row: 5 columns → 3 on tablets */
@media(max-width:640px){
  .stats-row{grid-template-columns:repeat(3,1fr);}
  .ph-right .btn-sm{padding:var(--sp-1) var(--sp-1h);font-size:var(--fs-sm);}
}
/* Stats row: 3 → 2 on phones */
@media(max-width:420px){
  .stats-row{grid-template-columns:repeat(2,1fr);}
}

/* Two- and three-column form grids collapse to single column */
@media(max-width:640px){
  .grid2,.grid3{grid-template-columns:1fr !important;}
  .fm-row{grid-template-columns:1fr !important;}
  .mat-editor-wrap{grid-template-columns:1fr !important;}
  .cl-item{gap:var(--sp-2);padding:.38rem .15rem;}
  .cl-item input[type=checkbox]{margin-top:.14rem;}
  .cl-item-label{flex-basis:100%;}
  .cl-item-acts{flex-basis:100%;}
  .cl-add-row{flex-wrap:wrap;gap:var(--sp-1h);}
  .cl-add-row input{flex:1 1 100%;}
  .cl-add-row input.qty{flex:0 0 92px;}
  .cl-add-row .btn{flex:0 0 auto;}
  /* Admin group-settings two-column (Immich | WordPress) */
  .admin-settings-grid{grid-template-columns:1fr !important;}
  /* fm-input width unconstrained on mobile */
}

@media(max-width:375px){
  .cl-add-row input.qty{flex:0 0 84px;}
}

/* Activity type filter tabs: wrap on mobile so every chip is reachable
   without horizontal scroll. Earlier we used overflow-x:auto + a fade
   mask to hint at hidden chips, but users still missed "Aux autres" /
   "Spirituel" because the cue was easy to overlook. Wrapping makes the
   full set always visible. */
@media(max-width:640px){
  .act-ftabs{flex-wrap:wrap;row-gap:var(--sp-1);}
  .suite-tabs--pill .suite-tab,.home-time-filter .suite-tab{white-space:nowrap;}
}

/* Modals: use more screen space on small phones */
@media(max-width:480px){
  .modal{width:98%;padding:1rem;}
  .overlay{align-items:flex-end;}
  .modal{border-radius:var(--radius-md) var(--radius-md) 0 0;max-width:100%;max-height:calc(100vh - 8px);max-height:calc(100dvh - 8px);}
  .modal::before{content:'';display:block;width:36px;height:4px;background:var(--g3);border-radius:var(--radius-pill);margin:var(--sp-2) auto var(--sp-1);}
  .modal-acts{flex-wrap:wrap;justify-content:stretch;}
  .modal-acts .btn{flex:1 1 140px;justify-content:center;}
  /* The desktop sticky trick (bottom:-1.5rem cancels the centered modal's
     1.5rem padding) overshoots on mobile: the modal padding drops to 1rem
     and there's no safe-area inset, so the CTA row sank below the viewport
     into the home-indicator / gesture zone and taps were swallowed. Re-pin
     to the 1rem mobile padding and clear the gesture zone with safe-area. */
  .modal-acts{bottom:-1rem;margin-bottom:-1rem;padding-bottom:calc(1rem + env(safe-area-inset-bottom, 0px));}
  /* The toast lives at bottom-right by default. On mobile that collides with the
     bottom-sheet modal (which fills the bottom 90% of the screen) and covers
     the action buttons. Move the toast to the top-center of the viewport
     instead, where it never overlaps modal content. */
  .toast{bottom:auto;right:auto;top:1rem;left:50%;transform:translate(-50%, -48px);max-width:calc(100% - 1.6rem);}
  .toast.show{transform:translate(-50%, 0);}
}

/* Wizard: tighter padding on mobile */
/* Activity editor panel: tighter on mobile */
@media(max-width:640px){
  .panel-inner{padding:1rem .9rem 3rem;}
  .panel-top{padding:.7rem 1rem;}
  .type-tab{font-size:var(--fs-sm);padding:.45rem .3rem;}
  .panel-bottom{padding:.5rem .8rem;}
  .panel-bottom .panel-bottom-meta{display:none;}
}

/* Picasso: full-width horizontal scroll on mobile */
@media(max-width:640px){
  .pic-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch;}
  .pgrid{min-width:480px;}
}

/* Topbar: prevent presence bar from overlapping title on very small screens */
@media(max-width:380px){
  .presence-bar{display:none;}
}

/* Activity table: slightly smaller text on mobile */
@media(max-width:640px){
  .tbl{font-size:var(--fs-md);}
  .tbl th{font-size:var(--fs-xs);padding:.4rem .45rem;}
  .tbl td{padding:.45rem .45rem;}
}

/* Camp cards: single column already set at 768px; ensure full-width */
@media(max-width:640px){
  .camp-card{padding:.9rem;}
  .camps-grid{gap:var(--sp-3);}
}

/* Settings section: reduce padding */
@media(max-width:640px){
  .settings-sec{padding:.8rem .85rem;}
}
/* Admin: section header row may need to wrap */
@media(max-width:640px){
  .admin-section-hd{flex-wrap:wrap;gap:var(--sp-2);}
  .ph-right{flex-wrap:wrap;}
}

/* Menus layout: already single-column at 820px — also shrink grid cells */
@media(max-width:480px){
  .menus-grid{grid-template-columns:1fr;}
}

/* ══════════════════════════════════════════════════════════════
   RESPONSIVE — WIDE SCREENS  (≥ 1400 px)
   Growing side padding keeps lines readable on ultra-wide monitors.
   ══════════════════════════════════════════════════════════════ */
@media(min-width:1400px){
  .content{padding:1.6rem clamp(2rem, 6vw, 9rem);}
  .topbar{padding:.9rem clamp(2rem, 6vw, 9rem);}
  .conflict-banner{padding:.5rem clamp(2rem, 6vw, 9rem);}
  .session-expired-banner{padding:.65rem clamp(2rem, 6vw, 9rem);}
  .ro-banner{padding:.4rem clamp(2rem, 6vw, 9rem);}
}
/* Very wide: cap the readable content width for text-heavy pages */
@media(min-width:1800px){
  .content{max-width:1800px;margin-left:auto;margin-right:auto;}
  /* Raid 3D wants the full window width — the map is visual, not
   * text. js/main.js toggles `raid3d-active` on <body> while the
   * viewer is shown. */
  body.raid3d-active .content{max-width:none;}
}
/* The 3D raid viewer is a full-bleed map/canvas — drop the shared
 * .d-content padding (added in @suite/lib desktop/app-shell.css) so the
 * canvas reaches the topbar underline and the window edges. Applies at
 * all desktop widths, hence outside the 1800px block above. */
body.raid3d-active .d-content{padding:0;}
/* The 3D raid viewer (Cesium) is a desktop-only experience, so hide every
   "Voir en 3D" entry point below the 960px shell breakpoint: the editor
   totals + per-link buttons and the relecture header button. */
@media (max-width:959px){
  .raid-totals-3d,
  .raid-link-3d,
  .rel-raid3d-btn{display:none !important;}
}

/* ══════════════════════════════════════════════════════════════
   MULTI-USER: "last saved by" topbar indicator
   ══════════════════════════════════════════════════════════════ */
.topbar-sub{transition:color var(--dur-normal);}

/* ══════════════════════════════════════════════════════════════
   ACCESSIBILITY: respect reduce-motion preference
   ══════════════════════════════════════════════════════════════ */
@media(prefers-reduced-motion:reduce){
  *{animation-duration:.01ms !important;animation-iteration-count:1 !important;transition-duration:.01ms !important;}
  .ph-lb-img-wrap img{transition:none;}
  .sync-dot.syncing{animation:none;}
  .session-expired-banner{animation:none;}
}

/* ── GROUP RECIPE CARDS ──────────────────────────────────── */
/* .recipe-card composes onto @suite/lib/style/card.css `.suite-card`
 * (and is also stacked with `.kb-card` in markup which already provides
 * shadow + cursor). Only the recipe-specific sub-element rules below
 * remain; the duplicated base block was removed in the Tier H follow-up
 * migration (border / radius / background / padding / transition all
 * come from `.suite-card` + `.kb-card`). The yellow hover border is
 * kept because `.kb-card` only changes border on `:hover` to `var(--g3)`
 * — recipe cards want the brand accent instead. */
.recipe-card:hover{border-color:var(--y);}
.recipe-card-hd{display:flex;align-items:baseline;gap:var(--sp-2);margin-bottom:.3rem;flex-wrap:wrap;}
.recipe-card-name{font-weight:var(--fw-semibold);font-size:var(--fs-lg);}
.recipe-card-meta{font-size:var(--fs-sm);color:var(--g4);}
.recipe-card-tags{display:flex;gap:var(--sp-1);flex-wrap:wrap;margin-bottom:.35rem;}
.recipe-card-desc{font-size:var(--fs-md);color:var(--g4);line-height:var(--lh-normal);margin-bottom:.5rem;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
.recipe-card-acts,.kb-card-acts{display:flex;gap:var(--sp-1h);flex-wrap:wrap;margin-top:.5rem;}

/* ── GROUP RECIPE COMMENTS ───────────────────────────────── */
.gr-comment{padding:.4rem .5rem;border-radius:var(--radius-sm);background:var(--g1);margin-bottom:.35rem;font-size:var(--fs-md);}
.gr-comment-author{font-weight:var(--fw-semibold);margin-right:.4rem;}
.gr-comment-time{font-size:var(--fs-sm);color:var(--g4);}
.gr-comment-text{margin-top:.2rem;line-height:var(--lh-normal);}

/* ── PICASSO DAY VIEW BUTTONS ────────────────────────────── */

/* ── AUTH FEAT ICON ALIGNMENT ────────────────────────────── */
.auth-feat-icon{font-size:var(--fs-lg);flex-shrink:0;line-height:1;display:flex;align-items:center;}

@media(max-width:640px){
  .ph-lb-top,.ph-lb-foot{
    padding:.55rem .75rem;
    gap:var(--sp-2h);
    flex-wrap:wrap;
  }
  .ph-lb-pname{max-width:120px;}
  .ph-lb-rename-input{width:120px;}
  .ph-lb-nav{
    font-size:2.1rem;
    padding:0 .35rem;
  }
  .ph-lb-merge-pick{max-height:45vh;overflow-y:auto;-webkit-overflow-scrolling:touch;}
}

/* ══════════════════════════════════════════════════════════════
   MOBILE — ADDITIONAL PHONE FIXES
   ══════════════════════════════════════════════════════════════ */

/* Activity editor panel-top: wrap buttons on narrow screens.
   panel-top is flex-column (3 rows: breadcrumb, header-main, pill-row);
   the wrap behavior applies to .ae-header-main (the actions row) so its
   buttons stack rather than overflow. The .panel-top flex-wrap rule is
   harmless on a column-direction parent and kept for the existing
   tests/mobile-responsive.test.js literal-string check. */
@media(max-width:480px){
  .panel-top{flex-wrap:wrap;gap:var(--sp-2);padding:.6rem .75rem;}
  .panel-top h2{font-size:var(--fs-lg);order:-1;flex-basis:100%;}
  .ae-header-main{flex-wrap:wrap;gap:var(--sp-2);}
  .ae-breadcrumb{font-size:var(--fs-xs);}
}

/* Compare modal: single column on phones */
@media(max-width:640px){
  #modalCompare .modal-bd > div[style*="grid-template-columns"]{
    grid-template-columns:1fr !important;
  }
}

/* Inline 2-col grids that lack mobile collapse */
@media(max-width:640px){
  .u-inl-106{grid-template-columns:1fr !important;}
}

/* Security concept grid: prevent max-content overflow */
@media(max-width:480px){
  .rev-sec-concept-grid{grid-template-columns:1fr;gap:var(--sp-1h);}
}

/* Tooltip: constrain to viewport */
.rel-tooltip{max-width:min(300px, calc(100vw - 2rem));}

/* Tag suggestions: constrained to viewport via @media (max-width:960px) in
   shared/style/_components/chip-input.css — no local duplicate needed. */

/* Activity row actions: larger tap targets on touch */
@media(pointer:coarse){
  .tbl .btn-sm{min-height:32px;min-width:32px;padding:.3rem .5rem;}
  .tbl td div[style*="gap:var(--sp-1)"]{gap:6px !important;}
  /* RAID map enlarge button */
  .raid-map-enlarge{min-height:32px;padding:.3rem .7rem !important;font-size:var(--fs-sm) !important;}
}

/* Lightbox: tighter layout on very small screens */
@media(max-width:380px){
  .ph-lb-top,.ph-lb-foot{padding:.4rem .5rem;gap:var(--sp-1h);}
  .ph-lb-nav{font-size:var(--fs-3xl);padding:0 .2rem;}
  .ph-lb-pname{max-width:80px;}
  .ph-lb-dec{font-size:var(--fs-sm);padding:.25rem .45rem;}
}

/* ⌘K palette chrome moved to shared/style/desktop/cmdk.css (2026-06-22).
   Campscout-specific overrides (colorblind active row, sidebar kbd chip)
   remain in the sections below. */

/* ══════════════════════════════════════════════════════════════════════════
   Folded in from css/enhancements.css (2026-05-09 — v2 unification step).
   These rules previously lived in a separate file; merged here so the app
   ships a single stylesheet. Original comment groupings preserved.
   ══════════════════════════════════════════════════════════════════════════ */

/* typography unification */
body, input, textarea, select, button, .tbl, .panel, .wiki-card, .admin-section { font-family:var(--sans); }
.topbar h1, .ph h2, .settings-sec h3, .modal-hd h3, .admin-section-hd h3, .wiki-card h3,
.sb-header-title, .stat-n, .mat-section-hd h3, .panel-top h2, .camp-card h3, .confirm-box h3,
.act-day-head-inner strong, .kb-wizard-title, .tour-title { font-family:var(--serif); }

.pic-chef-row{align-items:flex-start;min-height:34px;white-space:normal;line-height:var(--lh-tight);}

/* .pcell z-index merged into main rule below */
/* Chip bg at .4 (was .18): the white ⋯ glyph needs a dark enough chip to
   stay legible on bright cell colours (AC lime, Pers amber, Spirituel red),
   not just on dark ones (SC blue, AA violet). */
/* The ⋯ glyph is white (var(--white)) and floats over arbitrary cell fills.
   The pill background MUST stay dark enough that white reads on the lightest
   cells (pcell-dim --g2 #e4e2db, bright t-ac #b6cc17 / r-pers #fcbe09) — at .4
   it washed out to ~3:1 ("white on white"). .62 keeps composite contrast >4.5:1
   on every cell while staying translucent; the text-shadow halo is a belt-and-
   suspenders guarantee for any future light fill. Don't drop the alpha below .5. */
.pcell-menu-toggle{border:none;background:rgba(0,0,0,.62);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);color:var(--white);text-shadow:0 1px 2px rgba(0,0,0,.6);border-radius:var(--radius-pill);width:28px;height:28px;min-width:28px;min-height:28px;cursor:pointer;font-size:var(--fs-lg);line-height:1;display:flex;align-items:center;justify-content:center;touch-action:manipulation;}
.pcell-menu{display:none;position:fixed;background:var(--wh);border:var(--hairline);border-radius:var(--radius-sm);box-shadow:var(--shadow-lg);min-width:190px;overflow:hidden;z-index:9999;}
.pcell-menu.open{display:block;}
/* An explicit colour is required — without it the button inherits the
   parent .pcell's white text (cells have dark fills), rendering "Modifier"
   white-on-white inside the white menu. The --bk fallback hardens this
   against a stale/older deployed shared bundle where the --text token may
   be undefined (which would otherwise let the inherited white win on the
   dark-filled cells). The delete item re-overrides below. */
.pcell-menu button{display:block;width:100%;border:none;background:var(--wh);color:var(--text,var(--bk));padding:.5rem .75rem;text-align:left;font-size:var(--fs-md);cursor:pointer;}
.pcell-menu button:hover{background:var(--g1);}
/* Destructive item: red label (2-class specificity beats the dark-mode
   `.pcell-menu button` colour override, so it stays red in both themes). */
.pcell-menu .pcell-menu-del{color:var(--red);}

.permit-mini{display:inline-flex;align-items:center;gap:.2rem;border-radius:var(--radius-pill);padding:.08rem .38rem;margin-left:.35rem;font-size:var(--fs-xs);vertical-align:middle;}
.permit-badge{display:inline-block;font-size:var(--fs-xs);font-weight:var(--fw-bold);padding:.05rem .35rem;border-radius:var(--radius-xs);margin-left:.3rem;vertical-align:middle;}
.permit-badge.permit-auto,.permit-mini.permit-auto{background:var(--bg-raid);color:var(--blue);}
.permit-badge.permit-manual,.permit-mini.permit-manual{background:var(--bg-success);color:var(--fg-success);}
.permit-badge.permit-none,.permit-mini.permit-none{background:var(--g2);color:var(--g4);}

/* .wiki-card is always co-applied with .kb-card in markup (see
 * js/components/wiki-admin.js renderWiki), so the .suite-card primitive
 * provides the border / radius / background / base transition and
 * .kb-card supplies padding / shadow / hover lift / cursor. Only the
 * wiki-specific extras remain: vertical rhythm between stacked cards
 * and the larger H3 heading scale. */
.wiki-card{margin-bottom:.85rem;}
.wiki-card h3{font-size:var(--fs-xl);margin:.15rem 0 .55rem;}
.wiki-meta{display:flex;justify-content:space-between;gap:var(--sp-2);font-size:var(--fs-sm);color:var(--g4);margin-bottom:.35rem;flex-wrap:wrap;}
.wiki-group{font-weight:var(--fw-bold);color:var(--text);background:var(--g1);padding:.18rem .4rem;border-radius:var(--radius-pill);}
.wiki-body{line-height:1.7;font-size:var(--fs-md);color:var(--text);}
.kb-wizard-shell{background:linear-gradient(180deg,#faf8f2,#fff);border:var(--hairline);border-radius:var(--radius-md);padding:1rem 1.1rem;box-shadow:var(--shadow-sm);}
.kb-wizard-head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--sp-3h);flex-wrap:wrap;margin-bottom:.9rem;padding-bottom:.75rem;border-bottom:var(--hairline);}
.kb-wizard-title{font-size:var(--fs-lg);line-height:1.15;color:var(--text);}
.kb-wizard-copy{font-size:var(--fs-md);color:var(--g4);line-height:var(--lh-normal);max-width:64ch;margin:.22rem 0 0;}
.kb-wizard-tools{display:flex;gap:var(--sp-2);flex-wrap:wrap;align-items:center;}
.kb-wizard-body{display:flex;flex-direction:column;gap:.85rem;}
.kb-wizard-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-3h);}
.kb-wizard-list{display:flex;flex-direction:column;gap:var(--sp-2h);}
.kb-wizard-row{display:grid;grid-template-columns:minmax(140px,1fr) minmax(140px,1.2fr) auto;gap:var(--sp-2h);align-items:start;padding:.7rem .75rem;border:var(--hairline);border-radius:var(--radius-md);background:var(--wh);}
.kb-wizard-row.kb-wizard-row-material{grid-template-columns:minmax(140px,1.3fr) 120px 100px auto;}
.kb-wizard-actions{display:flex;justify-content:flex-end;gap:var(--sp-2h);flex-wrap:wrap;margin-top:.15rem;padding-top:.8rem;border-top:var(--hairline);}
.kb-wizard-pill{display:inline-flex;align-items:center;gap:var(--sp-1);padding:.18rem .55rem;border-radius:var(--radius-pill);background:var(--wh);border:var(--hairline);font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--g4);}
.kb-wizard-section{padding:.8rem .9rem;border:var(--hairline);border-radius:var(--radius-md);background:var(--wh);}
.kb-wizard-section-title{font-size:var(--fs-sm);font-weight:var(--fw-bold);text-transform:uppercase;letter-spacing:var(--ls-wide);color:var(--g4);margin-bottom:.45rem;}
.kb-wizard-item-stack{display:flex;flex-direction:column;gap:var(--sp-1h);min-height:2rem;margin-bottom:.55rem;}
.kb-wizard-item{display:flex;align-items:center;gap:var(--sp-2);padding:.45rem .55rem;border:var(--hairline);border-radius:var(--radius-md);background:var(--wh);}
.kb-wizard-item-label{flex:1;font-size:var(--fs-md);}
.kb-wizard-item-meta{font-size:var(--fs-sm);color:var(--g4);}

.sidebar .sb-user .btn{min-width:unset;}

/* more forgiving click targets */
.pic-chef-row, .tag-chip, .btn, .sb-item{touch-action:manipulation;}
.branch-check-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:var(--sp-2) .8rem;font-size:var(--fs-md);}
.branch-check-grid label{display:flex;align-items:center;gap:var(--sp-2);padding:.35rem .5rem;border-radius:var(--radius-sm);background:var(--wh);border:var(--hairline);}
.pcell-menu-wrap{position:absolute;right:3px;top:3px;z-index:8;}
.wiki-toolbar{display:flex;gap:var(--sp-1h);flex-wrap:wrap;margin-bottom:.5rem;}
.wiki-toolbar button{border:var(--hairline);background:var(--wh);border-radius:var(--radius-sm);padding:.35rem .6rem;cursor:pointer;font-size:var(--fs-md);}
.wiki-body img,.wiki-rendered img{max-width:100%;height:auto;border-radius:var(--radius-md);margin:.6rem 0;display:block;box-shadow:0 4px 14px rgba(0,0,0,.08);}
.wiki-rendered h1,.wiki-rendered h2,.wiki-rendered h3{margin:.9rem 0 .45rem;}
.wiki-rendered ul{padding-left:1.2rem;}
.obj-card .obj-sp{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-2h);}
@media print{
  body{background:var(--wh) !important;}
  .topbar,.sidebar,.btn,.pcell-menu-wrap{display:none !important;}
  .page{display:block !important;}
}
.pic-drag-preview{position:absolute;left:1px;right:1px;border:2px dashed rgba(34,133,208,.9);background:rgba(34,133,208,.14);border-radius:var(--radius-md);pointer-events:none;z-index:4;padding:.3rem .4rem;display:flex;align-items:flex-start;justify-content:flex-start;box-sizing:border-box;}
.pic-drag-preview-time{font-size:var(--fs-sm);font-weight:var(--fw-bold);color:#165a8d;background:rgba(255,255,255,.9);padding:.12rem .35rem;border-radius:var(--radius-pill);}
/* readability on dark surfaces */
#pAllowedUsersSecurity{color:var(--white);}
#pAllowedUsersSecurity .badge--event-status{background:rgba(255,255,255,.1);color:var(--white);}
.midata-badge.disconnected{color:#b5b3aa !important;}
.auth-footer a,.auth-oauth-status{color:var(--g3);}

/* .pic-day-cell overflow set below */
.pic-branch-guide{position:absolute;top:0;bottom:0;border-left:1px dashed rgba(0,0,0,.08);pointer-events:none;z-index:0;}
.pic-branch-guide:first-of-type{border-left:none;}
.vld-suggestions{margin-top:.55rem;padding:.55rem .7rem;border-radius:var(--radius-md);background:var(--g1);font-size:var(--fs-md);line-height:var(--lh-normal);}
.act-day-head td{background:var(--g1);padding:0;border-top:2px solid var(--g2);position:sticky;top:0;z-index:2;}
.act-day-head td:first-child{border-left:3px solid var(--y);}
.act-day-head-inner{display:flex;justify-content:space-between;align-items:center;gap:var(--sp-3);padding:.65rem .75rem;}
.act-day-head-inner strong{font-size:var(--fs-lg);}
.act-row td{padding:var(--act-row-pad,9px) .65rem;}

.wizard-block{background:var(--wh);border:var(--hairline);border-radius:var(--radius-md);padding:1rem 1.1rem;margin-top:.8rem;}
.wizard-block-hd{font-weight:var(--fw-bold);margin-bottom:.6rem;}
.wizard-grid-2,.settings-grid-2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-3h);}
.fm-inline{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-2);}
.wizard-help{font-size:var(--fs-sm);color:var(--g4);margin-top:.45rem;line-height:var(--lh-normal);}
.pic-day-cell{overflow:visible;} /* menus need to overflow for positioning */
.pcell{display:flex;flex-direction:column;gap:.18rem;padding:5px 32px 6px 7px;overflow:hidden;border-radius:var(--radius-sm);z-index:2;cursor:grab;}
.pcell:active{cursor:grabbing;}
.pcell > *{flex-shrink:0;}
.pcell .pcell-unit-bar{order:-1;}
.pcell .pcell-name{order:0;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;overflow:hidden;line-height:1.15;font-size:var(--fs-sm);font-weight:var(--fw-bold);letter-spacing:.01em;text-shadow:0 1px 1px rgba(0,0,0,.18);}
.pcell .pcell-resp{order:1;font-size:var(--fs-xs);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;opacity:.9;line-height:1.15;text-shadow:0 1px 1px rgba(0,0,0,.15);}
.pcell .pcell-sec{font-size:var(--fs-xs);opacity:.8;vertical-align:middle;}
.pcell .pcell-top{order:2;font-size:var(--fs-xs);font-weight:var(--fw-bold);display:flex;justify-content:space-between;gap:var(--sp-1);opacity:.92;line-height:1.1;text-shadow:0 1px 1px rgba(0,0,0,.15);}
.pcell .pcell-loc{order:3;font-size:var(--fs-xs);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;opacity:.78;text-shadow:0 1px 1px rgba(0,0,0,.15);}
.pcell-compact .pcell-name{-webkit-line-clamp:2;font-size:var(--fs-sm);}
.pcell-tiny .pcell-name{-webkit-line-clamp:1;font-size:var(--fs-sm);}
.pcell-tiny .pcell-resp{display:none;}
.pcell.t-ac .pcell-name,.pcell.t-ac .pcell-resp,.pcell.t-ac .pcell-top,.pcell.t-ac .pcell-loc,
.pcell.r-pers .pcell-name,.pcell.r-pers .pcell-resp,.pcell.r-pers .pcell-top,.pcell.r-pers .pcell-loc{
  text-shadow:none;
  color:var(--bk);
}

/* pcell drag-resize handles */
.pcell-resize-top,.pcell-resize-bot{position:absolute;left:0;right:0;height:12px;cursor:ns-resize;z-index:5;background:transparent;touch-action:none;}
.pcell-resize-top{top:0;}
.pcell-resize-bot{bottom:0;}
.pcell-resize-top:hover,.pcell-resize-bot:hover{background:rgba(0,0,0,.12);}
/* Top-right menu-safe interaction area */
.pcell-resize-top{right:var(--pic-menu-safe-zone);}
.pcell.pcell-narrow .pcell-resize-top{right:24px;}
/* §19 touch-target: 12px desktop → 24px on coarse pointer (finger) */
@media (pointer: coarse) {
  .pcell-resize-top,.pcell-resize-bot{height:24px;}
}
/* pcell-menu-toggle size merged into base rule above */
.pcell-menu-toggle:focus-visible{
  outline:2px solid #fff;
  outline-offset:1px;
  box-shadow:0 0 0 2px rgba(20,20,20,.35);
}

/* pages mode: suppress horizontal scroll */

/* Picasso page: full viewport height, no page-level scroll */
#page-picasso{overflow:hidden !important;padding:0 !important;flex-direction:column !important;}
#page-picasso.active{display:flex !important;}
#page-picasso .ph{flex-shrink:0;padding:.45rem 1rem .35rem;margin-bottom:.8rem;padding-bottom:.6rem;}
#page-picasso .ph-right{
  display:flex;
  align-items:center;
  gap:.65rem 1rem;
  flex-wrap:nowrap;
  min-width:0;
  overflow-x:auto;
  scrollbar-width:thin;
}
#page-picasso .ph-right::-webkit-scrollbar{height:6px;}
#page-picasso .ph-right::-webkit-scrollbar-thumb{background:rgba(20,20,20,.18);border-radius:var(--radius-pill);}
#page-picasso .pic-legend,#picPagesNav,#picChefAbove,#picChefBelow{flex-shrink:0;}
#picWrap{flex:1;min-height:0;}

/* Day picker — mobile 1-day view chip strip */
.pic-day-picker{flex-shrink:0;padding:var(--sp-1) var(--sp-2) var(--sp-1);}
.pic-day-picker .chip{font-size:var(--fs-sm);padding:var(--sp-05) var(--sp-2);border-radius:var(--radius-pill);border:var(--hairline);background:var(--wh);cursor:pointer;white-space:nowrap;transition:background var(--dur-chip),color var(--dur-chip);}
/* --white (always light), NOT --wh (a surface token that flips to dark): on
   the dark --bk pill the flipping --wh made the active day label dark-on-dark. */
.pic-day-picker .chip.active{background:var(--bk);color:var(--white);border-color:var(--bk);}
.pic-day-picker .chip:hover:not(.active){background:var(--g1);}

.pic-filter-block{margin:.35rem 0 .55rem;}
.pic-inline-tabs{margin-bottom:0;}
.pic-subfilters{
  display:flex;
  align-items:center;
  gap:var(--sp-3h) 1rem;
  flex-wrap:wrap;
}
.pic-subfilter{
  display:flex;
  align-items:center;
  gap:var(--sp-2);
  flex-wrap:nowrap;
  min-width:0;
}
.pic-subfilter-label{
  font-size:var(--fs-sm);
  font-weight:var(--fw-bold);
  color:var(--g4);
  white-space:nowrap;
}
#page-picasso .act-filter-block{min-width:0;}
#page-picasso .pic-filter-block{
  display:flex;
  align-items:center;
  gap:var(--sp-2);
  flex:0 0 auto;
  margin:0;
  overflow:visible;
}
#page-picasso .act-ftabs,
#page-picasso .pic-inline-tabs,
#page-picasso .pic-dayview-wrap,
#page-picasso .tgl-group{
  display:inline-flex;
  flex-wrap:nowrap;
  min-width:0;
}
#page-picasso .act-filter-label,
#page-picasso .pic-subfilter-label,
#page-picasso .tgl-btn{
  white-space:nowrap;
}
#page-picasso .tgl-btn{
  font-size:var(--fs-sm);
  padding:.36rem .72rem;
}
#page-picasso .pic-inline-tabs,
#page-picasso .pic-subfilters,
#page-picasso .pic-subfilter{
  gap:var(--sp-2);
  flex-wrap:nowrap;
}
#page-picasso .act-filter-label{
  margin:0;
  flex:0 0 auto;
}
.pic-conflict-strip{
  display:flex;
  flex-wrap:wrap;
  gap:var(--sp-1h);
  margin:0 0 .55rem;
}
.pic-conflict-pill{
  display:inline-flex;
  align-items:center;
  gap:.28rem;
  padding:.24rem .6rem;
  border-radius:var(--radius-pill);
  background:var(--bg-rejected);
  border:1px solid var(--bg-error);
  color:var(--fg-error);
  font-size:var(--fs-sm);
  font-weight:var(--fw-bold);
}
#page-picasso .pic-dayview-wrap{
  display:flex;
  align-items:center;
  gap:var(--sp-1);
}
#page-picasso .tgl-btn,#page-picasso .resp-filter-btn,#page-picasso .btn{min-height:30px;}
#page-picasso #picTouchBtn.active{
  background:var(--bk);
  color:var(--white);
}

/* Sticky orientation helpers for long schedule scroll */
#page-picasso .pgrid thead th{
  position:sticky;
  top:0;
  z-index:6;
}
#page-picasso .pgrid thead th:first-child{
  left:0;
  z-index:8;
}
#page-picasso .pgrid td.tc{
  position:sticky;
  left:0;
  z-index:5;
  background:var(--g1);
}
#page-picasso .pic-ext-label-cell{
  position:sticky;
  left:0;
  z-index:6;
}
#page-picasso .pic-chef-row-jour .pic-ext-label-cell{background:#3a3200;color:var(--pers);}
#page-picasso .pic-chef-row-nuit .pic-ext-label-cell{background:#1a1a3a;color:#9ab0ff;}
.pic-day-drop-target{
  background:linear-gradient(180deg, rgb(var(--y-rgb) / 10%), rgb(var(--y-rgb) / 3%));
  box-shadow:inset 0 0 0 2px rgb(var(--y-rgb) / 90%);
}
.pic-sunset-mark{
  position:absolute;right:2px;font-size:var(--fs-xs);line-height:1;
  color:#5a4080;
}
.pic-empty-cell-hint{
  position:absolute;
  inset:10px 8px;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:.15rem;
  text-align:center;
  padding:.6rem;
  border:1px dashed rgba(20,20,20,.12);
  border-radius:var(--radius-md);
  background:linear-gradient(180deg, rgba(252,250,245,.96), rgba(245,240,231,.88));
  color:var(--g4);
  font-size:var(--fs-sm);
  line-height:var(--lh-normal);
  pointer-events:none;
}
.pic-empty-cell-hint span{font-size:var(--fs-sm);opacity:.85;}
.pcell-conflict{
  box-shadow:inset 0 0 0 2px var(--red), 0 0 0 1px rgba(0,0,0,.05);
}
/* Guide §08 — 2-letter type code in every Picasso cell so colour is not the only
   signal (color-blind a11y). Tiny tile in top-left, translucent background so it
   reads on every type/relation hue. pointer-events:none so it doesn't block
   the resize handle that sits on the same line. Hidden in compact / tiny /
   narrow cells — those are too cramped for an extra glyph. */
.pcell-type-code{
  position:absolute;
  top:3px;
  left:3px;
  z-index:3;
  font-size:var(--fs-xs);
  font-weight:var(--fw-bold);
  letter-spacing:.04em;
  padding:1px 4px;
  border-radius:var(--radius-xs);
  background:rgba(255,255,255,.92);
  color:var(--text);
  line-height:1.2;
  pointer-events:none;
  text-shadow:none;
}
.pcell-compact-mode .pcell-type-code,
.pcell-tiny .pcell-type-code,
.pcell-narrow .pcell-type-code{display:none;}
/* Guide §16 Status visibility — "warning dot if responsable missing" on the
   Picasso cell. Top-right corner, behind the menu toggle but visually
   distinct (red glyph on white tile). pointer-events:none so it doesn't
   block menu clicks. */
.pcell-warn-resp{
  position:absolute;
  top:3px;
  right:35px;
  z-index:3;
  font-size:var(--fs-xs);
  font-weight:var(--fw-bold);
  padding:1px 4px;
  border-radius:var(--radius-xs);
  background:rgba(255,255,255,.92);
  color:var(--red);
  line-height:1.2;
  pointer-events:none;
  text-shadow:none;
}
.pcell-tiny .pcell-warn-resp,
.pcell-narrow .pcell-warn-resp{display:none;}
.pcell-conflict-badge{
  display:inline-flex;
  align-items:center;
  align-self:flex-start;
  gap:.2rem;
  margin-top:1px;
  padding:1px 5px;
  border-radius:var(--radius-pill);
  background:var(--bg-glass);
  color:var(--fg-error);
  font-size:var(--fs-xs);
  font-weight:var(--fw-bold);
}
.pcell.pcell-dragging{
  opacity:.6;
  transform:none;
  filter:none;
}

/* Touch mode: larger interactive targets + calmer card density */
#page-picasso.pic-touch-mode .pcell{
  padding:6px 36px 7px 8px !important;
  gap:.26rem;
}
#page-picasso.pic-touch-mode .pcell .pcell-name{-webkit-line-clamp:2;font-size:var(--fs-md);}
#page-picasso.pic-touch-mode .pcell .pcell-resp{font-size:var(--fs-sm);}
#page-picasso.pic-touch-mode .pcell .pcell-loc{display:none;}
#page-picasso.pic-touch-mode .pcell-resize-top,
#page-picasso.pic-touch-mode .pcell-resize-bot{height:18px;}
#page-picasso.pic-touch-mode .pcell-menu-toggle{width:32px;height:32px;min-width:32px;min-height:32px;}
#page-picasso.pic-touch-mode .tgl-btn,
#page-picasso.pic-touch-mode .resp-filter-btn{min-height:34px;}


@media (max-width: 900px){
  .wizard-grid-2,.settings-grid-2{grid-template-columns:1fr;}
  .kb-wizard-grid,.kb-wizard-row,.kb-wizard-row.kb-wizard-row-material{grid-template-columns:1fr;}
  .pic-subfilters{align-items:stretch;}
  .pic-subfilter{width:100%;flex-wrap:wrap;}
}
@media (max-width: 640px){
  .rev-criterion,.rev-check-row{align-items:flex-start;flex-wrap:wrap;}
  .rev-crit-help,.rev-check-help{margin-left:0;max-width:none;white-space:normal;text-align:left;width:100%;}
  .pcell-resize-top{right:var(--pic-menu-safe-zone-mobile);}
  .pcell.pcell-narrow .pcell-resize-top{right:26px;}
  .pcell-menu-toggle{width:30px;height:30px;min-width:30px;min-height:30px;}
  .pic-subfilters{gap:var(--sp-2h);}
  .pic-subfilter{gap:var(--sp-1h);}
}
/* ══════════════════════════════════════════════════════════════
   MOBILE — PHONE-SPECIFIC FIXES  (≤ 480 px)
   ══════════════════════════════════════════════════════════════ */

/* Export page: tighter on phones */
@media(max-width:480px){
  .export-page-grid,.exp-grid{gap:var(--sp-3h);padding:.5rem;}
  .export-card,.exp-card{padding:1rem;}
}

/* Picasso toolbar: scroll horizontally instead of overflowing */
@media(max-width:640px){
  #page-picasso .ph-right{
    overflow-x:auto;-webkit-overflow-scrolling:touch;
    flex-wrap:nowrap;gap:var(--sp-1h);padding-bottom:.15rem;
    scrollbar-width:none;
  }
  #page-picasso .ph-right::-webkit-scrollbar{display:none;}
  #page-picasso .ph-right .btn,
  #page-picasso .ph-right .resp-filter-btn{flex-shrink:0;white-space:nowrap;}
  /* Filter blocks: stack labels above controls */
  #page-picasso .pic-filter-block{flex-wrap:wrap;gap:var(--sp-1) .45rem;}
}

/* Minimum tap targets on touch devices */
@media(pointer:coarse){
  .sb-icon-btn{width:36px;height:36px;font-size:var(--fs-xl);}
  .modal-x{width:36px;height:36px;font-size:var(--fs-lg);}
  /* Guide §18: topbar 30px icons reach 44×44 on touch via invisible padding */
  .topbar .tour-help-btn,.topbar #changeFeedToggle{width:44px;height:44px;}
  .tag-chip button{min-width:28px;min-height:28px;font-size:var(--fs-md);}
  .tgl-btn{min-height:36px;}
  .resp-filter-btn{min-height:36px;}
  .rel-info-btn{width:1.6rem;height:1.6rem;font-size:var(--fs-sm);}
  .rev-crit-btn{width:32px;height:32px;}
  /* Date/time sub-inputs: wider on touch */
  .ae-sub{width:2.4rem;font-size:var(--fs-lg);padding:.25rem .2rem;}
  .ae-sub.ae-sub-yr{width:3.4rem;}
  .ae-sub.ae-sub-t{width:2.2rem;}
  /* Presence avatar tooltip: no hover on touch */
  .presence-avatar[title]:hover::after{display:none;}
}

/* Tab config drag-and-drop */
.tab-config-row { display:flex; align-items:center; gap:var(--sp-2); padding:.35rem .4rem; border-radius:var(--radius-sm); border:1px solid transparent; transition:background var(--dur-fast), border-color var(--dur-fast); cursor:default; }
.tab-config-row:hover { background:var(--g1); }
.tab-config-row.dragging { opacity:.45; border:1px dashed var(--g3); }
.tab-config-row.drag-over { background:#f5f9db; border-color:var(--y); }
.tab-config-handle { cursor:grab; touch-action:none; }
@media(pointer:coarse){ .tab-config-handle{display:none;} }

/* Review criteria checkboxes */
.rev-criteria-block { border: var(--hairline); border-radius: var(--radius-sm); overflow: hidden; margin: .5rem 0; }
.rev-criterion { display: flex; align-items: center; gap:var(--sp-2); padding: .35rem .6rem; border-bottom: var(--hairline); font-size: var(--fs-md); }
.rev-criterion:last-child { border-bottom: none; }
.rev-check-row{
  display:flex;
  align-items:center;
  gap:var(--sp-2);
  padding:.4rem .6rem;
  border:var(--hairline);
  border-radius:var(--radius-sm);
  background:var(--wh);
  font-size:var(--fs-md);
  cursor:pointer;
  flex-wrap:wrap;
  word-break:break-word;
  line-height:var(--lh-tight);
}
.rev-check-row input[type=checkbox]{margin-top:.05rem;}
.rev-check-icon{font-size:var(--fs-lg);flex-shrink:0;}
.rev-check-label{font-weight:var(--fw-medium);flex-shrink:0;}
.rev-check-help{color:var(--g4);font-size:var(--fs-sm);margin-left:auto;text-align:right;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.rev-check-row-warn{color:var(--fg-warn);background:var(--bg-info);border-color:var(--amber);}
.rev-crit-btn { width: 24px; height: 24px; border-radius: 50%; border: 1.5px solid currentColor; font-size: var(--fs-sm); font-weight: 700; display: flex; align-items: center; justify-content: center; cursor: pointer; flex-shrink: 0; transition: all var(--dur-fast); padding: 0; }
.rev-crit-null { color: var(--g4); background: transparent; }
.rev-crit-ok   { color: var(--green); background: var(--bg-success); border-color: var(--green); }
.rev-crit-no   { color: var(--red); background: var(--bg-error); border-color: var(--red); }
.rev-crit-icon { font-size: var(--fs-lg); flex-shrink: 0; }
.rev-crit-label { font-weight: 500; flex-shrink: 0; }
.rev-crit-help  { color: var(--g4); font-size: var(--fs-sm); margin-left: auto; text-align: right; max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── SPOTLIGHT TOUR ───────────────────────────────────────── */
#tourOverlay {
  position: fixed; inset: 0; z-index: 10000;
  /* pointer-events:none lets clicks pass through the dimmed overlay
     to the highlighted element below — the user CAN interact with the
     feature being explained. The tour tooltip + buttons sit in a
     separate stacking layer (#tourTooltip) that catches its own clicks. */
  pointer-events: none;
  opacity: 0; transition: opacity var(--dur-slow);
}
#tourOverlay.visible { opacity: 1; }

#tourSpotlight {
  position: fixed; z-index: 10001; pointer-events: none;
  border-radius: var(--radius-md);
  box-shadow: 0 0 0 9999px rgba(0,0,0,.62);
  opacity: 0; transition: opacity var(--dur-slow);
}
#tourSpotlight.visible { opacity: 1; }

#tourTooltip {
  position: fixed; z-index: 10002; width: min(320px, calc(100vw - 24px));
  max-width: calc(100vw - 24px);
  background: var(--wh); border-radius: var(--radius-md);
  padding: 1.2rem 1.3rem 1rem;
  box-shadow: var(--shadow-overlay);
  opacity: 0; transform: translateY(6px);
  transition: opacity var(--dur-slow), transform var(--dur-slow);
  pointer-events: all;
}
#tourTooltip.visible { opacity: 1; transform: translateY(0); }
#tourTooltip.tour-centered { transform: translate(-50%, -50%); }
#tourTooltip.tour-centered.visible { transform: translate(-50%, -50%); }
#tourTooltip.tour-mobile { width: auto; max-width: none; }
.tour-progress { font-size: var(--fs-sm); color: var(--g4); margin-bottom: .4rem; font-weight: var(--fw-semibold); letter-spacing: .04em; text-transform: uppercase; }
.tour-title { font-family: var(--serif); font-weight: 400; font-size: var(--fs-xl); line-height:1.15; margin-bottom: .45rem; color:var(--text); }
.tour-body { font-size: var(--fs-md); color: var(--g4); line-height: 1.55; margin-bottom: 1rem; }
.tour-actions { display: flex; justify-content: space-between; align-items: center; gap:var(--sp-2); }
.tour-nav-btns { display: flex; gap: .45rem; }
.tour-skip { background: none; border: var(--hairline); border-radius: var(--radius-sm); color: var(--g4); font-size: var(--fs-md); cursor: pointer; padding: .38rem .65rem; }
.tour-skip:hover { background: var(--g1); color:var(--text); }
.tour-nav { background: none; border: var(--hairline); border-radius: var(--radius-sm); padding: .38rem .75rem; font-size: var(--fs-md); cursor: pointer; color: var(--g4); }
.tour-nav:hover { background: var(--g1); }
.tour-next { background: var(--y); border: none; border-radius: var(--radius-sm); padding: .38rem .9rem; font-size: var(--fs-md); font-weight: 700; cursor: pointer; color: var(--bk); }
.tour-next:hover { opacity: .88; }
.tour-help-btn {
  background: none; border: 1px solid rgba(255,255,255,.25); border-radius: 50%;
  color: rgba(255,255,255,.7); width: 28px; height: 28px; font-size: var(--fs-sm);
  font-weight: 700; cursor: pointer; line-height: 1; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
}
@media (pointer: coarse) {
  /* WCAG 2.5.5 — touch targets must be at least 44×44. Bump topbar icons on
     touch devices without enlarging them on desktops where mouse precision
     makes 28px fine. */
  .tour-help-btn { width: 44px; height: 44px; }
}
.tour-help-btn:hover { background: rgba(255,255,255,.12); color:var(--white); }

@media (max-width: 480px){
  #tourTooltip {
    width: calc(100vw - 16px);
    max-width: calc(100vw - 16px);
    padding: .95rem 1rem .85rem;
    border-radius: var(--radius-md);
  }
  #tourTooltip.tour-mobile{
    left:8px !important;
    right:8px !important;
    top:auto !important;
    bottom:8px !important;
  }
  .tour-actions {
    flex-direction: column;
    align-items: stretch;
  }
  .tour-nav-btns {
    display: grid;
    grid-template-columns: 1fr 1fr;
  }
  .tour-nav, .tour-next {
    width: 100%;
    text-align: center;
  }
}

.sp-sugg-item:hover { background: var(--g1); }

/* ── Export page ───────────────────────────────────────── */
/* v2 hi-fi class names (.exp-grid, .exp-card, .exp-icon) — match Hi-Fi rhythm */
.exp-intro{margin:0 0 1.25rem;color:var(--g4);font-size:var(--fs-md);line-height:var(--lh-normal);}
.export-page-grid,.exp-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1rem;padding:0;}
@media(max-width:1024px){.export-page-grid,.exp-grid{grid-template-columns:repeat(2,1fr);}}
@media(max-width:600px){.export-page-grid,.exp-grid{grid-template-columns:1fr;}}
.export-card,.exp-card{background:var(--wh);border:var(--hairline);border-radius:var(--radius-md);padding:1.25rem 1.1rem;box-shadow:var(--shadow-sm);display:flex;flex-direction:column;gap:.4rem;}
.export-card-icon,.exp-icon{font-size:1.75rem;margin-bottom:.15rem;line-height:1;}
.export-card h3,.exp-card h3{margin:0;font-family:var(--serif);font-size:1.1rem;font-weight:400;line-height:1.2;}
.export-card p,.exp-card p{color:var(--g4);font-size:var(--fs-sm);margin:0 0 .5rem;line-height:var(--lh-normal);flex:1;}
.export-card .export-check-list,.exp-card .export-check-list{margin-bottom:.75rem;}
.export-card>.btn,.exp-card>.btn{align-self:flex-start;}
.export-card button:disabled,.exp-card button:disabled{opacity:.4;cursor:not-allowed;}
#expCardCSV>.btn{align-self:auto;}

/* ── Picasso compact mode cells ────────────────────────── */
.pcell.pcell-compact-mode{padding:2px 3px;}
.pcell-compact-mode .pcell-name{font-size:var(--fs-xs);line-height:1.15;word-break:break-word;overflow-wrap:break-word;hyphens:auto;}
.pcell-compact-mode .pcell-resp,
.pcell-compact-mode .pcell-top,
.pcell-compact-mode .pcell-menu-wrap,
.pcell-compact-mode .pcell-resize-top,
.pcell.pcell-compact-mode .pcell-resize-bot{display:none;}

/* ─────────────────────────────────────────────────────────
   v2 visual restyle: low-fi page layout grids/cards
   (kb / prof / admin / obj / fil / menu)
   Tokens reused: --wh, --g1..g4, --y, --pers/corps/env/autres/spirit, --radius-md, --shadow-sm.
───────────────────────────────────────────────────────── */

/* Wiki / KB grid (guides + group recipes) */
.kb-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-3);}
/* .kb-card composes onto @suite/lib/style/card.css `.suite-card`
 * (border, radius, background, base transition). Only the KB-specific
 * extras live here: denser asymmetric padding, persistent soft shadow,
 * translateY hover lift, cursor:pointer, plus a faster transition
 * profile (uses `--dur-fast`) to feel snappier on dense grids. */
.kb-card{padding:.9rem 1rem;box-shadow:var(--shadow-sm);transition:transform var(--dur-fast),box-shadow var(--dur-fast),border-color var(--dur-fast);cursor:pointer;}
.kb-card:hover{transform:translateY(-2px);box-shadow:var(--shadow-md);border-color:var(--g3);}
.kb-card h3{font-family:var(--serif);font-size:var(--fs-xl);margin:.3rem 0 .35rem;line-height:1.2;}
.kb-card p{font-size:var(--fs-md);color:var(--g4);margin:0;line-height:var(--lh-normal);}
.kb-meta{display:flex;justify-content:space-between;gap:var(--sp-2);font-size:var(--fs-xs);color:var(--g4);align-items:center;flex-wrap:wrap;}
@media(max-width:680px){.kb-grid{grid-template-columns:1fr;}}
/* KB has 6 tabs — on the mobile shell they can't fit in one row without
 * wrapping to 2–3 lines / clipping the last tab. Below the 960 shell flip,
 * turn the tab strip into a single horizontal-scroll row (matches the
 * relecture toolbar pattern; scrollbar hidden, labels stay on one line). */
@media(max-width:959px){
  /* Right-edge fade hints there are more tabs to scroll to. */
  #page-wiki .suite-tabs{flex-wrap:nowrap;overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none;gap:var(--sp-2);-webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 22px),transparent);mask-image:linear-gradient(90deg,#000 calc(100% - 22px),transparent);}
  #page-wiki .suite-tabs::-webkit-scrollbar{display:none;}
  #page-wiki .suite-tabs .suite-tab{white-space:nowrap;flex:0 0 auto;}
}

/* ── KB: search, category chips, read view, rich empty state ─────────── */
.kb-search{margin-bottom:var(--sp-3);}
.kb-search .fm-input{width:100%;}
/* Card body is the read affordance; actions sit outside it. */
.wiki-card-main{cursor:pointer;}
.wiki-card-main h3{transition:color var(--dur-fast);}
.wiki-card-main:hover h3{color:var(--link,var(--corps));}
.wiki-meta-date{margin-left:auto;}
.wiki-cat{font-weight:var(--fw-semibold);font-size:var(--fs-xs);padding:.05rem .45rem;border-radius:var(--radius-pill);background:var(--g1);color:var(--g4);white-space:nowrap;}
.wiki-cat-cuisine{background:var(--bg-warn);color:var(--fg-warn);}
.wiki-cat-securite{background:var(--bg-error);color:var(--fg-error);}
.wiki-cat-sante{background:var(--bg-success);color:var(--fg-success);}
.wiki-cat-logistique{background:var(--bg-info);color:var(--corps);}
.wiki-cat-pedagogie{background:var(--g1);color:var(--purple);}
/* Read modal */
.wiki-read-meta{font-size:var(--fs-sm);color:var(--g4);padding:0 var(--sp-1) var(--sp-2);border-bottom:var(--hairline);margin-bottom:var(--sp-3);}
.wiki-read-body{max-height:min(64vh,560px);overflow-y:auto;font-size:var(--fs-md);}
.wiki-read-body h1,.wiki-read-body h2,.wiki-read-body h3{font-family:var(--serif);font-weight:400;margin:1rem 0 .4rem;line-height:1.2;}
.wiki-read-body h2{font-size:var(--fs-lg);}
.wiki-read-body h3{font-size:var(--fs-md);}
.wiki-read-body p{margin:0 0 .7rem;}
.wiki-read-body ul{margin:0 0 .7rem;padding-left:1.3rem;}
.wiki-read-body img{max-width:100%;height:auto;border-radius:var(--radius-sm);}
/* Rich empty state */
.wiki-empty{text-align:center;padding:2.4rem 1.2rem;border:1px dashed var(--g2);border-radius:var(--radius-md);background:linear-gradient(180deg,#fffaea,var(--wh));}
.wiki-empty-icon{font-size:2.4rem;line-height:1;margin-bottom:.4rem;}
.wiki-empty h3{font-family:var(--serif);font-weight:400;font-size:var(--fs-xl);margin:0 0 .35rem;}
.wiki-empty p{font-size:var(--fs-md);color:var(--g4);max-width:46ch;margin:0 auto 1rem;line-height:var(--lh-normal);}
.wiki-empty-starters{display:flex;flex-wrap:wrap;gap:var(--sp-1h);justify-content:center;}

/* Profil 2-col grid of prof-card blocks */
.prof-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-3);margin-bottom:var(--sp-3);}
.prof-card{background:var(--wh);border:var(--hairline);border-radius:var(--radius-md);padding:1rem 1.1rem;box-shadow:var(--shadow-sm);transition:transform var(--dur-fast),box-shadow var(--dur-fast);}
.prof-card:hover{transform:translateY(-1px);box-shadow:var(--shadow-md);}
.prof-card > h3{font-family:var(--serif);font-size:var(--fs-lg);margin:0 0 var(--sp-2);}
@media(max-width:680px){.prof-grid{grid-template-columns:1fr;}}

/* Admin grid (wraps existing .admin-section blocks) */
.admin-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-3);align-items:start;}
.admin-grid .admin-section{margin-bottom:0;}
.admin-grid .admin-section.admin-section-full{grid-column:1 / -1;}
@media(max-width:680px){.admin-grid{grid-template-columns:1fr;}}

/* Objectifs v2: relation dot, level pill, linked-activity-count stat */
/* slightly tighter vertical padding than .suite-card's --sp-4; fill comes
   from .suite-card's --surface-card (dark-mode aware) — the old
   background:var(--wh) made the card melt into the page surface in dark mode. */
.obj-card-v2{padding:.9rem 1rem;}
.obj-stat{font-size:var(--fs-xs);background:var(--g1);border:var(--hairline);padding:.18rem .55rem;border-radius:var(--radius-pill);color:var(--g4);font-weight:var(--fw-semibold);white-space:nowrap;}
.obj-stat.ok{background:var(--bg-success);color:var(--fg-success);border-color:transparent;}
.obj-stat.warn{background:var(--bg-warn);color:var(--fg-warn);border-color:transparent;}
.obj-rel-dot{display:inline-block;width:10px;height:10px;border-radius:50%;flex-shrink:0;vertical-align:middle;margin-right:var(--sp-1);}
.obj-rel-dot.pers{background:var(--pers);}
.obj-rel-dot.corps{background:var(--corps);}
.obj-rel-dot.env{background:var(--env);}
.obj-rel-dot.autres{background:var(--autres);}
.obj-rel-dot.spirit{background:var(--spirit);}
.obj-level-pill{display:inline-flex;align-items:center;font-size:var(--fs-xs);font-weight:var(--fw-bold);background:var(--bk);color:var(--y);border-radius:var(--radius-pill);padding:.1rem .55rem;letter-spacing:.04em;}

/* Fil rouge presentation card */
.fil-card{background:var(--wh);border:var(--hairline);border-radius:var(--radius-md);padding:1.4rem 1.6rem;background-image:linear-gradient(180deg,#fffaea,var(--wh));box-shadow:var(--shadow-sm);}
.fil-card-tag{font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:.08em;color:var(--g4);font-weight:var(--fw-bold);}
.fil-card-empty{font-size:var(--fs-md);color:var(--g4);font-style:italic;}
.fil-card-body{font-size:var(--fs-md);line-height:var(--lh-body);color:var(--text);}
.fil-card-body p{margin:0 0 .8rem;max-width:65ch;}
.fil-card-body img{max-width:100%;height:auto;border-radius:var(--radius-sm);}

/* v2 hi-fi shared utility — vacant/missing-data marker (used in resp table, etc.) */
.warn-txt{color:var(--red);font-weight:var(--fw-medium);}

/* Menus chip-filter bar above grid */
.menu-bar{display:flex;gap:var(--sp-1h);flex-wrap:wrap;margin:0 0 var(--sp-3);align-items:center;}
/* v2 menus grid: 3-col cards with black DM Serif day header per hi-fi */
.menu-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:var(--sp-3);}
.menu-day{background:var(--wh);border:var(--hairline);border-radius:var(--radius-md);overflow:hidden;box-shadow:var(--shadow-sm);}
/* Day heading reads like a menu-board line, not a heavy black bar: a warm
 * cream tint (shared with .fil-card / .kb-wizard-shell) + serif date, with a
 * hairline carrying the day/meal separation instead of a full ink block. */
.menu-day-hd{background:linear-gradient(180deg,#fffaea,var(--wh));color:var(--text);font-family:var(--serif);font-weight:400;font-size:var(--fs-lg);padding:.5rem .75rem;line-height:1.2;border-bottom:1px solid var(--g2);}
.menu-meal{display:flex;gap:10px;padding:10px 12px;border-top:var(--hairline);align-items:flex-start;cursor:pointer;transition:background var(--dur-fast);}
.menu-meal:first-of-type{border-top:none;}
.menu-meal:hover{background:var(--g1);}
.menu-time{font-family:var(--serif);font-size:var(--fs-sm);color:var(--g4);min-width:42px;flex-shrink:0;}
.menu-body{flex:1;min-width:0;}
.menu-body b{font-size:var(--fs-sm);color:var(--text);font-weight:var(--fw-semibold);}
.menu-meta{font-size:var(--fs-xs);color:var(--g4);margin-top:3px;line-height:1.4;}
/* Coverage summary + view toggle above the meal plan */
.menu-topbar{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--sp-3);flex-wrap:wrap;margin-bottom:var(--sp-3);}
.menu-cover{flex:1 1 220px;min-width:0;}
.menu-cover-line{font-size:var(--fs-sm);color:var(--text);}
.menu-cover-todo{color:var(--fg-warn);font-weight:var(--fw-semibold);}
.menu-cover-bar{height:6px;border-radius:var(--radius-pill);background:var(--g2);overflow:hidden;margin-top:.4rem;max-width:280px;}
.menu-cover-bar span{display:block;height:100%;background:var(--green);border-radius:inherit;transition:width var(--dur-slow) ease;}
.menu-diet-legend{font-size:var(--fs-xs);color:var(--g4);margin-top:.45rem;display:flex;flex-wrap:wrap;gap:var(--sp-1);align-items:center;}
.menu-diet-chip{display:inline-block;font-size:var(--fs-xs);font-weight:var(--fw-semibold);background:var(--bg-success);color:var(--fg-success);border-radius:var(--radius-pill);padding:.05rem .5rem;}
.menu-view-toggle{flex:0 0 auto;margin-bottom:0;border-bottom:none;}
.menu-meal-diet{display:flex;flex-wrap:wrap;gap:var(--sp-1);margin-top:4px;}
.menu-meal-todo{border-left:3px solid var(--amber);}
/* Grid / menu-board view: days × meal-slots */
.menu-board-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch;}
.menu-board{width:100%;border-collapse:separate;border-spacing:0;font-size:var(--fs-sm);}
.menu-board th{font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:.05em;color:var(--g4);font-weight:var(--fw-bold);padding:.4rem .5rem;text-align:left;white-space:nowrap;}
.menu-board .menu-row-hd{font-family:var(--serif);font-weight:400;font-size:var(--fs-md);color:var(--text);text-transform:none;letter-spacing:0;vertical-align:top;padding-top:.6rem;white-space:nowrap;}
.menu-cell{border-top:var(--hairline);padding:.35rem;vertical-align:top;min-width:120px;}
.menu-cell-empty{color:var(--g3);text-align:center;}
.menu-cell-meal{display:flex;flex-direction:column;gap:2px;width:100%;text-align:left;background:var(--wh);border:var(--hairline);border-radius:var(--radius-sm);padding:.4rem .55rem;cursor:pointer;transition:border-color var(--dur-fast),background var(--dur-fast);margin-bottom:.3rem;}
.menu-cell-meal:last-child{margin-bottom:0;}
.menu-cell-meal:hover{border-color:var(--y);}
.menu-cell-todo{border-style:dashed;}
.menu-cell-name{font-weight:var(--fw-semibold);color:var(--text);}
.menu-cell-recipe{font-size:var(--fs-xs);color:var(--g4);}
.menu-cell-add{font-size:var(--fs-xs);color:var(--fg-warn);font-weight:var(--fw-semibold);}
/* v2 stats-row — 4-up at-a-glance numbers (used by Admin and Profil hero) */
.stats-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:var(--sp-2);margin-bottom:var(--sp-3);}
.stats-row .stat{background:var(--wh);border:var(--hairline);border-radius:var(--radius-md);padding:14px 12px;text-align:center;box-shadow:var(--shadow-sm);}
.stats-row .stat-n{font-family:var(--serif);font-weight:400;font-size:1.875rem;line-height:1;color:var(--text);margin-bottom:4px;}
.menu-bar-label{font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:var(--ls-wide);color:var(--g4);font-weight:var(--fw-bold);margin-right:var(--sp-1);}

/* v2 hi-fi: flat underline sub-tabs for Aperçu (overrides pill style in style.css) */
.apercu-subtabs{background:transparent !important;border-radius:0 !important;padding:0 !important;gap:1.125rem !important;border-bottom:var(--hairline);width:100%;}
.apercu-subtab{padding:.45rem 0 !important;border-radius:0 !important;border-bottom:2px solid transparent !important;background:transparent !important;box-shadow:none !important;font-weight:var(--fw-semibold) !important;color:var(--g4) !important;}
.apercu-subtab.active{background:transparent !important;color:var(--text) !important;border-bottom-color:var(--y) !important;box-shadow:none !important;}
.apercu-subtab:hover{color:var(--text) !important;}

/* v2 hi-fi: small uppercase section labels (used inside Aperçu Statistiques) */
.section-title-v2{font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:var(--ls-wide);color:var(--g4);font-weight:var(--fw-bold);margin:1.125rem 0 .5rem;}

/* v2 hi-fi: page intro paragraph (muted, sits below the page header) */
.page-intro{margin:.15rem 0 1rem;color:var(--g4);font-size:var(--fs-md);line-height:var(--lh-normal);max-width:64ch;}

/* v2 hi-fi: hide the per-section "Dernière modification" line — cleaner pages */
.section-modified-label{display:none !important;}

/* v2 hi-fi: profil 2-col layout. align-items:start keeps the left hero card
   at its natural content height — without it the card stretches to match
   the right column's full height (which has 5+ sections stacked). Mirrors
   the home-grid pattern. */
.prof-grid{display:grid;grid-template-columns:280px 1fr;gap:var(--sp-3);align-items:start;}
@media(max-width:760px){.prof-grid{grid-template-columns:1fr;}}
.prof-card{background:var(--wh);border:var(--hairline);border-radius:var(--radius-md);padding:1.25rem;text-align:center;box-shadow:var(--shadow-sm);}
.prof-av{width:80px;height:80px;border-radius:50%;background:var(--prof-av-c, var(--y));color:var(--wh);font-weight:var(--fw-bold);font-size:1.75rem;display:grid;place-items:center;margin:0 auto .75rem;}
/* Photo variant — img element fills the circle; no background tint or padding. */
img.prof-av{background:none;padding:0;overflow:hidden;object-fit:cover;}
.prof-card h3{font-family:var(--serif);font-weight:400;margin:0 0 .25rem;font-size:var(--fs-xl);}
.prof-meta{font-size:var(--fs-sm);color:var(--g4);margin-bottom:.15rem;}
.prof-section{background:var(--wh);border:var(--hairline);border-radius:var(--radius-md);padding:.9rem 1rem;margin-bottom:.75rem;box-shadow:var(--shadow-sm);}
.prof-section:last-child{margin-bottom:0;}
.prof-section h3{font-family:var(--serif);font-weight:400;font-size:var(--fs-lg);margin:0 0 .65rem;border-bottom:none;padding-bottom:0;}
.prof-section .set-row{display:flex;align-items:center;gap:var(--sp-2);padding:.5rem 0;border-top:var(--hairline);font-size:var(--fs-md);}
.prof-section .set-row:first-of-type{border-top:none;}
.prof-section .set-row > div:first-child{flex:1;min-width:0;}
.prof-section .set-meta{font-size:var(--fs-xs);color:var(--g4);margin-top:.05rem;}

/* v2 hi-fi: matériel section card rhythm — tighter padding to match hi-fi cards */
.mat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,360px),1fr));gap:var(--sp-3);}
.mat-section{background:var(--wh);border:var(--hairline);border-radius:var(--radius-md);padding:1rem 1.1rem;margin-bottom:0;box-shadow:var(--shadow-sm);}
.mat-section-hd h3,.mat-hd h3{font-family:var(--serif);font-weight:400;font-size:var(--fs-lg);margin:0;}

/* v2 hi-fi: paramètres 2-col grid (overrides single-col fallback). Drops bottom-margin on inner sections so grid gap is the only spacing. */
#page-parametres .set-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-3);align-items:start;}
@media(max-width:900px){#page-parametres .set-grid{grid-template-columns:1fr;}}
#page-parametres .set-grid > .settings-sec,#page-parametres .set-grid > .set-section{margin-bottom:0;}
#page-parametres .set-section.danger{display:flex;flex-direction:column;gap:.55rem;align-items:flex-start;}
#page-parametres .set-section.danger > h3{align-self:stretch;}

/* Dark-mode component overrides — placed at end of file so they win the
   cascade against the original component rules above. The :root token
   overrides live in the earlier @media block.

   Root cause: dark mode flips `--wh` from off-white (#FAFAF8) to near-black
   (#1a1a1a) so it can serve as the page background. Anywhere the original
   stylesheet uses `color: var(--white)` as foreground breaks; the worst case
   is `bg:var(--bk) + color:var(--white)` (both ~#1a) — totally unreadable.
   The fix is to re-point those callsites to a bright foreground in dark
   mode. */
@media(prefers-color-scheme:dark){
  /* Auth screen */
  .auth-login-heading,.auth-beta-copy{color:#f0f0f0;}
  .auth-login-sub,.auth-remember-me span,.auth-footer{color:#bdbdbd;}
  .auth-remember-hint{color:#9c9c9c;}
  .auth-error{background:#4a1818;color:#ff9c9c;}
  .auth-beta-disclosure{
    border-color:rgb(var(--y-rgb) / 32%);
    background:linear-gradient(180deg,rgb(var(--y-rgb) / 14%),rgb(var(--y-rgb) / 5%));
  }

  /* Surfaces with bg:var(--bk) + color:var(--white) — bright foreground so
     text doesn't disappear into the matching dark background. */
  .btn-gh.active,
  .tag-chip,
  .tgl-btn.on, .tgl-group .tgl-btn.on,
  .resp-filter-btn.active,
  .pgrid th,
  .suite-tabs--pill .suite-tab.is-active[data-type="all"],
  .suite-tabs--pill .suite-tab.is-active[data-rel="all"],
  .suite-tabs--pill .suite-tab.is-active[data-rev-filter="all"],
  .suite-tabs--pill .suite-tab.is-active[data-groupby],
  .rel-info-btn:hover, .rel-tooltip,
  .pic-day-label,
  .wizard-step-num { color:#f0f0f0; }
  /* Day heading: the light cream tint would glare in dark mode — flip to the
     elevated card surface with a hairline, keeping the serif date legible. */
  .menu-day-hd { background:var(--g1); color:var(--text); border-bottom-color:var(--g2); }
  /* Same cream-glare fix for the KB empty state. */
  .wiki-empty { background:var(--g1); }

  /* Sidebar items use `color: var(--white)` over the sidebar's own dark
     background — already legible in dark mode but reinforce so the
     "active" state stays high-contrast. */
  .sb-header-title, .sb-item, .sb-item:hover,
  .sb-camp-item.active, .sb-camp-item.active .camp-label,
  .sb-more-camps:hover { color:#f0f0f0; }
  .u-name { color:#d0d0d0; }

  /* Generic color flips happen automatically via --text / --surface-card
     (defined in shared/style/_base/tokens.css). Body color flips to --g4
     in dark mode so plain text inherits a legible bright fg already, and
     light-mode rules that opt into var(--text) / var(--g3) / var(--g4)
     auto-flip too — those selectors are NOT listed here.

     What stays in this block:
       1. Selectors whose light-mode `color:var(--bk)` doesn't flip and that
          don't already pick up var(--text) via a more specific rule
          (migrating the shared/style sources is out of scope).
       2. Surfaces that the shared --surface-card token doesn't cover
          (sidebar app-menu drop-down, home-mode chip strip).
       3. Elements that sit on a COLOURED bg (yellow auth panel) where
          var(--text)'s dark→bright flip would kill contrast — force --bk
          so dark text survives.
       4. Theme-specific accent overrides. */
  .btn-gh,
  .fil-editor.longtext-surface { color:var(--text); }

  /* Sidebar app-menu drops down over a hard-coded `var(--white)` (#fff) bg
     that doesn't flip in dark mode — flip both the bg and its descendants'
     colors so the menu doesn't render as a blinding white panel. */
  .sb-app-menu, .sb-app-tile.on { background:#252525; color:#e8e8e8; border-color:#3a3a3a; }
  .sb-app-menu-hd { color:#9c9c9c; }
  .sb-app-menu-ft { color:#9c9c9c; }
  .sb-app-tile { background:#2a2a2a; color:#e8e8e8; border-color:transparent; }
  .sb-app-tile:hover { background:#333; }
  .sb-app-tile.add { color:#bdbdbd; border-color:#555; background:transparent; }
  .sb-app-tile .m, .sb-app-tile .ic { color:#bdbdbd; }
  .sb-icon-btn, .sb-icon-btn.sb-logo-label,
  .sb-badge { color:#e8e8e8; }
  .home-mode { background:#252525; border-color:#3a3a3a; }

  /* Yellow auth-brand panel — bg:var(--y) doesn't flip, so var(--text)'s
     light→dark flip in dark mode would put #c8c8c8 light text on yellow.
     Force --bk so dark text survives. */
  .auth-brand-title { color:var(--bk); }

  /* Generic body inline emphasis + anchors — inherit body's bright color
     when nothing more specific applies. */
  strong, b, a.on { color:#e8e8e8 !important; }

  /* Spans inside warn/error/success-tinted boxes — keep the colored fg
     that was paired with the tinted backdrop. Scoped to text-bearing
     descendants only (span/strong/b/em) so we don't accidentally repaint
     buttons or icons inside these boxes. */
  .badge--permission-owner, .badge--permission-unlinked, .conflict-banner,
  .suite-tabs--pill .suite-tab.is-active[data-rev-filter="issues"],
  .badge--event-status-countdown,
  .badge--permission-owner :is(span, strong, b, em),
  .badge--permission-unlinked :is(span, strong, b, em),
  .conflict-banner :is(span, strong, b, em),
  .suite-tabs--pill .suite-tab.is-active[data-rev-filter="issues"] :is(span, strong, b, em),
  .att-item.warn :is(.icon, span, strong, b, em) { color:var(--fg-warn) !important; }

  /* Read-only banner / chip use --bg-badge-blue which is intentionally a
     light-blue surface in both modes — keep dark text on it (the strong
     override above would otherwise flip it bright and kill contrast). */
  .ro-banner, .ro-banner :is(span, strong, b, em),
  .camp-card-ro, .camp-card-ro :is(span, strong, b, em) {
    color:var(--fg-badge-blue) !important;
  }

  /* Anchor links inside body text — bright with a hint of blue. */
  a:not(.btn):not([class*="suite-tab"]):not(.sb-item):not([href^="javascript"]) {
    color:#a8c8ff;
  }

  /* ── 2026-05-14 contrast sweep ────────────────────────────────
     Static audit pass — 24 sites where the existing override block
     missed coverage. Grouped by failure mode. */

  /* Light-coloured surfaces using literal hex (don't flip) — repaint
     the surface dark so inherited light text becomes readable. */
  .home-attention-panel { background:var(--g1); color:#e8e8e8; }
  .kb-wizard-shell { background:linear-gradient(180deg,#252525,#1e1e1e); color:#e8e8e8; }
  .fil-card { background-image:none; background:var(--g1); }

  /* `background:var(--wh)` (flips dark) + dark text via var(--bk) or
     inherited from elsewhere — flip the text bright. */
  .scroll-to-top-btn, .mbn-sheet-item,
  .ae-toc a:hover, .ae-toc a.on,
  .ae-sub, .type-tab:hover:not(.active),
  .cmdk-input, .cmdk-result,
  .tour-title,
  .topbar-search:hover,
  .fil-card-body { color:#e8e8e8 !important; }
  .cmdk-input::placeholder { color:#888 !important; }

  /* Pastel-tinted pills that stayed light in dark mode — force dark
     text so the blanket `b{color:#e8e8e8}` doesn't kill contrast. */
  .rel-card-hd .rel-tp-pill.aa,
  .rel-card-hd .rel-tp-pill.ac,
  .rel-card-hd .rel-tp-pill.sc,
  .mbn-sheet-item.active { color:var(--bk) !important; }

  /* Picasso right-pane scrollbar — 18% black thumb is invisible on
     dark surfaces; swap to 18% white so the thumb stays distinct
     against the dark page. */
  #page-picasso .ph-right::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.18);
  }

  /* Toggle button "on" state was a black pill (--bk on light page →
     high contrast). In dark mode --bk #141414 sits on --wh #1a1a1a —
     near-zero contrast. Swap the pill to a bright surface in dark
     mode; the white text stays. */
  .tgl-btn.on,
  .tgl-group .tgl-btn.on {
    background: var(--g4);
    color: var(--bk);
    border-color: var(--g4);
  }

  /* Dark-on-dark badges + glass surfaces. */
  .cl-item-qty-total { background:#3a3a3a; color:#e8e8e8; }

  /* `.rel-row.warn` / `.rel-row.bad` have literal pastel backgrounds
     (#fff8e1, #fee2e2) that DON'T flip — so the blanket `b{color:
     #e8e8e8}` makes their text invisible on the light pastel. Restore
     dark text inside these rows. User-reported regression: "accepting
     securité" toggles to .warn/.bad and the row becomes unreadable. */
  .rel-row.warn, .rel-row.bad,
  .rel-row.warn :is(b, strong, span),
  .rel-row.bad :is(b, strong, span) { color:var(--bk) !important; }

  /* Yellow-on-light-text — make the active queue item legible. */
  .rel-q-item.on, .rel-q-item.on .rel-q-nm { color:var(--bk) !important; }

  /* Picasso cell-menu portal lives outside .content so it doesn't
     inherit the bright body text. Give it its own surface treatment. */
  .pcell-menu, .pcell-menu button { background:#252525; color:#e8e8e8; border-color:#3a3a3a; }
  .pcell-menu button:hover { background:#333; }

  /* 2026-05-14 follow-up — additional sites the user spotted:
     The `.longtext-surface` (Fil rouge & thème editor + the activity
     editor's descriptif textarea + the objectifs editor) had a
     `linear-gradient(#fcfbf8, #f4f2eb)` cream background that doesn't
     flip in dark mode while paragraphs inside it flip light via the
     blanket — light text on cream = unreadable. Repaint dark. */
  .longtext-surface,
  .longtext-input { background:var(--g1); background-image:none; color:#e8e8e8; }
  .longtext-surface[data-placeholder]:empty::before,
  .longtext-input::placeholder { color:#888 !important; }
  .longtext-input:focus,
  .longtext-surface:focus,
  .longtext-surface.editable { background:#1e1e1e; border-color:var(--y); }

  /* Picasso empty-day placeholder ("Jour libre / Glisse ici…") uses a
     literal cream gradient + dark dashed border that doesn't flip. In
     dark mode the cell becomes a bright cream rectangle on a dark
     timeline — repaint to a dim charcoal with a lighter dashed border. */
  .pic-empty-cell-hint {
    background:linear-gradient(180deg, rgba(40,40,40,.55), rgba(28,28,28,.45));
    border-color:rgba(232,232,232,.18);
    color:#9c9c9c;
  }

  /* Descriptif body inside rel-card focus mode. Used `var(--bk)` which
     doesn't flip — black on `var(--wh)`-dark = 1.06:1 (invisible).
     `!important` because the source rule lives after this @media block
     in the CSP wave 3 section and otherwise wins on cascade order. */
  .u-inl-ea72a59f { color:#e8e8e8 !important; }

  /* Health-card score colors: the light-mode darks (good/warn/must)
     stay readable on the light card tint but become unreadable on
     dark-mode card surfaces. Brighten in dark mode. */
  .health-card.is-good .hc-score { color:#5dba5d; }
  .health-card.is-warn .hc-score { color:#e6c56a; }
  .health-card.is-must .hc-score { color:#ff7373; }

  /* Sunset time label sits on Picasso's first day column (dark in dark
     mode). The literal purple worked on light cream but vanished on
     dark — brighten to a readable lavender. */
  .pic-sunset-mark { color:#b8a8e0; }

  /* `color:var(--bk)` on `background:var(--g1)` patterns — both tokens
     flip dark, so the text becomes invisible (~1:1) in dark mode. These
     three sit on pages the screenshot tour didn't exercise (wiki/KB,
     menus, profile-tabs config). */
  .wiki-group { color:#e8e8e8; }

  /* Utility text-color classes used widely: their light-mode values are
     darkened for AA, so they vanish on dark surfaces. Flip to bright. */
  .u-c-amber { color:#e6c56a; }
  .u-c-error { color:#ff7373; }
  .u-c-success { color:#5dba5d; }
  .u-inl-046 { color:#b8b5ab; }
  .badge--event-status { color:#d0cec5; }

  /* ── APERÇU v3 dark-mode rescue (2026-05-16) ──────────────
     The v3 restructure introduced surfaces that hadn't been audited
     for dark mode. Fixes:
       • H2/H3 titles colored `--bk` — sit on the page bg (which
         becomes `--wh`=near-black in dark) → flip to bright.
       • `.apercu-glance` gradient looks fine in dark, but the inner
         title + meta `<b>` are `--bk` → flip.
       • Tiles using `var(--white)` (constant #fff) stay jarring-white
         on dark page → flip to `--g1` per the codebase convention
         (see `.modal { background: var(--g1); }` above).
       • Empty-state card uses `var(--wh)` for its bg (flips dark);
         inner text in `--bk` → flip text.
       • Phase pills + status alerts keep their semantic --bg-*/--fg-*
         colors (already dark-mode-aware via the token flip block
         at line 105+). */
  .apercu-section-title,
  .apercu-subzone-title,
  .apercu-glance-title,
  .apercu-glance-meta b,
  .apercu-stat-n,
  .apercu-tile-hd,
  .apercu-status-progress-pct {
    color:#f0f0f0;
  }
  .apercu-glance {
    /* Same gradient, but skewed slightly lighter so the eyebrow + title
       have visible contrast against the rest of the page. */
    background:linear-gradient(180deg, var(--g1) 0%, var(--bk2) 100%);
    border-color:var(--bk3);
  }
  /* Keep the accent a calm hint on dark surfaces. A higher opacity (.22)
     read as a heavy olive smudge over the dark gradient; .08 + extra blur
     tracks the subtle light-mode weight without disappearing. */
  .apercu-glance::after { opacity:.08; filter:blur(6px); }
  .apercu-stat,
  .apercu-tile,
  .apercu-status-progress,
  .widget-customise-preset {
    background:var(--g1);
    border-color:var(--bk3);
    color:#f0f0f0;
  }
  .apercu-stat:hover { background:var(--bk2); }
  .widget-customise-preset:hover {
    background:var(--bk2);
    border-color:#666;
  }
  .widget-customise-preset.is-active {
    background:var(--bg-info); /* token already flips for dark */
    border-color:var(--y);
  }
  .widget-customise-preset-label { color:#f0f0f0; }
  /* Mobile hamburger menu — `.sb-mobile-btn { color: var(--bk) }` left
     the ☰ glyph rendering black-on-dark, fully invisible on phones in
     dark mode. Flip the icon color so the menu is reachable. */
  .sb-mobile-btn { color:#f0f0f0; }
  /* Objectif activity-count pill (.u-inl-91a463fa) hard-codes
     `background:var(--bk); color:var(--white)`. --wh flips to #1a1a1a in
     dark, leaving black bg + near-black text → invisible. Swap to a
     legible pairing on dark. */
  .u-inl-91a463fa { background:#3a3a3a; color:#f0f0f0; }
  /* §2 status expander "Voir les X autres points" toggle text was
     `color:var(--bk)` — pitch-black on dark surface. Flip to bright
     so the disclosure stays discoverable. */
  .apercu-status-more-toggle { color:#f0f0f0; }
  .apercu-status-more { background:var(--g1); border-color:var(--bk3); }
  /* Mobile-style picker — flip card + preview surfaces. */
  .widget-card { background:var(--g1); border-color:var(--bk3); color:#ddd; }
  .widget-card:hover { border-color:#666; }
  .widget-card-title { color:#f0f0f0; }
  .widget-card-desc { color:#bbb; }
  .widget-card-preview { background:var(--bk2); border-color:var(--bk3); }
  .widget-card-btn { background:var(--bk2); border-color:var(--bk3); color:#f0f0f0; }
  .widget-card-btn:hover { background:#3a3a3a; }
  .widget-card-add { background:var(--bk2); border-color:var(--bk3); color:#f0f0f0; }
  .widget-card-add:hover { background:#3a3a3a; border-color:#666; }
  .widget-card-size { background:var(--bk2); border-color:var(--bk3); color:#f0f0f0; }
  .widget-picker-section-count { background:var(--bk2); border-color:var(--bk3); color:#f0f0f0; }
  .widget-picker-empty { background:var(--bk2); border-color:var(--bk3); color:#bbb; }
  .widget-picker-category-hd { color:#bbb; }
  /* Preview vignettes — adjust on-bk surfaces for legibility. */
  .wp-js-bar, .wp-bar-track, .wp-mat-track, .wp-live-progress,
  .wp-pico-cells i, .wp-objgrid-row i { background:#2a2a2a; }
  .wp-stat[data-rel=pers], .wp-stat[data-rel=env] { color:var(--bk); }
  .wp-stat b { color:inherit; }
  .wp-hist-row b, .wp-mat-row b, .wp-live b, .wp-live-temp { color:#f0f0f0; }
  .apercu-subzone-title {
    border-bottom-color:var(--bk3);
  }
  /* Status surface — progress track + check-list rows + alert bodies
     inherit colors via the dark-mode flip below. */
  .apercu-status-progress-track { background:var(--bk3); }
  .apercu-status-checks li.is-todo { color:#f0f0f0; }
  .apercu-status-checks li.is-ok { color:#aaa; }
  /* Empty-state — card flips bg + text. */
  .apercu-empty-card {
    background:var(--g1);
    border-color:var(--bk3);
  }
  .apercu-empty-title { color:#f0f0f0; }
  .apercu-empty-step {
    background:var(--g1);
    border-color:var(--bk3);
  }
  .apercu-empty-step:hover {
    background:var(--bk2);
    border-color:#666;
  }
  .apercu-empty-step-body strong { color:#f0f0f0; }
  .apercu-empty-foot,
  .apercu-empty-step-sub { color:#bdbdbd; }
  /* The "🪄 auto" badge stays yellow — token color, dark-mode-safe. */

  /* ── 2026-06-01 contrast audit ──────────────────────────────
     Cross-suite sweep (matos 9cc2696 + secretariat 6f5f0b3 landed
     same day). campscout's pre-existing override block already
     caught most callsites; these eight slipped through because
     they're either (a) <span>/<div> elements not in the h-tag/
     <b> blanket at line 4236/4298, (b) raid-map Leaflet labels
     rendered in a portal outside the .content tree, or (c) inline
     draft-preview chips whose --bg-draft surface flips dark while
     the explicit color:var(--bk) doesn't follow.
     Strategy A from the audit: surgical color: var(--g4) override
     so the text gets the same near-white the body-level fix sets
     for inherited copy. */
  /* Home page empty-camp call-to-action title (<div>, not h*). */
  .empty-camp-title { color: var(--g4); }
  /* Raid-3D / relecture map endpoint labels (Leaflet portal). */
  .leaflet-tooltip.raid-endpoint-label { color: var(--g4); }
  /* Aperçu §2 status info list — <span class="...">. */
  .apercu-status-info-title { color: var(--g4); }
  /* Aperçu empty-state inline button hover. */
  .apercu-empty-link:hover { color: var(--g4); }
  /* Auto-save draft preview chips (editor, wiki-admin, objectifs)
     — --bg-draft flips dark (#1e1e2e) but the text stayed --bk. */
  .u-inl-fecfbf9c,
  .u-inl-f1953529 { color: var(--g4); }
  /* Topbar group switcher <select> (--g1 chip surface, flips). */
  .topbar-group-switcher .g-switcher { color: var(--g4); }
}
/* CSP wave 3 — generated scoped classes for long-tail static inline styles. */
.u-inl-246a17f9{padding:.4rem .6rem;background:var(--wh);border-top:1px solid var(--g1);max-height:160px;overflow-y:auto;}
.u-inl-2c9c50cd{min-height:.9rem;margin-top:-.2rem;}
.u-inl-fe47a7a9{max-height:70vh;overflow-y:auto;padding:.5rem 1rem;}
.u-inl-e69efb94{justify-content:space-between;gap:.5rem;margin-bottom:.6rem;}
.u-inl-5c2e5617{margin-top:.8rem;}
.u-inl-850e442e{min-height:44px;}
.u-inl-a70663c6{display:grid;grid-template-columns:1fr 1fr;gap:.75rem;}
.u-inl-eeee85e0{background:var(--g1);border:var(--hairline);border-radius:var(--radius-sm);padding:var(--sp-2h);min-height:4rem;max-height:14rem;overflow-y:auto;}
.u-inl-d02d845f{min-height:120px;}
.u-inl-b2f3ed89{height:1.2rem;width:60%;}
.u-inl-8c9b2c55{height:.8rem;width:80%;}
.u-inl-8ee33ce3{height:.8rem;width:40%;}
.u-inl-1d2bd66f{color:var(--pers,#fcbe09);}
.u-inl-c71053c4{color:var(--corps,#2285d0);}
.u-inl-61ae5f35{color:var(--env,#20bb45);}
.u-inl-465d04c2{color:var(--autres,#e13998);}
.u-inl-3210558b{color:var(--spirit,#dc2728);}
.u-inl-55db2416{justify-content:space-between;}
.u-inl-8bb8a3b7{font-size:var(--fs-xl);color:var(--g3);padding:0 .4rem;user-select:none;touch-action:none;}
.u-inl-59a42f8d{padding:var(--sp-3h) .9rem;}
.u-inl-bd6aa619{gap:var(--sp-2h);}
.u-inl-0807bf71{padding-top:.5rem;}
.u-inl-0a53794f{margin-bottom:var(--sp-3h);}
.u-inl-529e1abd{margin:0 0 var(--sp-2);}
.u-inl-f8c84284{margin:0 0 var(--sp-2h);}
.u-inl-a83ce3a2{word-break:break-all;}
.u-inl-b7aa1ec0{width:100%;}
.u-inl-09046c59{color:var(--g3);}
.u-inl-f59ad2ac{padding:var(--sp-05) 0;border-bottom:1px solid var(--g1);}
.u-inl-3861c90e{opacity:.8;}
.u-inl-59e62972{padding:var(--sp-1h) var(--sp-2);}
.u-inl-372ef83e{width:8px;height:8px;border-radius:50%;background:var(--green);}
.u-inl-9f407bcc{text-overflow:ellipsis;}
.u-inl-bdfcd783{margin-bottom:var(--sp-2h);}
.u-inl-145c31c1{position:absolute;top:100%;left:0;right:0;z-index:var(--z-dropdown);background:var(--wh);border:1px solid var(--border-strong);border-radius:0 0 var(--radius-sm) var(--radius-sm);max-height:160px;overflow-y:auto;box-shadow:var(--shadow-md);}
.u-inl-48145853{padding:var(--sp-1h) .5rem;}
.u-inl-21f17cde{gap:var(--sp-4);margin-bottom:var(--sp-1h);}
.u-inl-8c356f19{flex-direction:column;gap:var(--sp-05);margin-right:var(--sp-05);}
/* "Draft hint" — pinned draft text under an editable field. The two
   class names (.u-inl-fecfbf9c and .u-inl-f1953529 below) are
   auto-generated from a per-callsite hash and pre-date the v2 utility
   rename. They share the same intent; the second has slightly tighter
   padding for objectifs/relecture rows. Future cleanup: rename both
   to .u-c-draft-hint and update editor.js + enhancements.js +
   objectifs.js + relecture.js + 2 sibling tests. */
.u-inl-fecfbf9c{padding:var(--sp-2h) .7rem;background:var(--bg-draft);border-radius:var(--radius-sm);color:var(--text);white-space:pre-wrap;}
.u-inl-0a3b69fe{text-transform:uppercase;letter-spacing:.04em;margin:var(--sp-2h) 0 .3rem;}
.u-inl-80972d09{margin:var(--sp-1) 0 0;}
.u-inl-d7453a1c{color:var(--red,#c00);}
.u-inl-e1863aa3{position:absolute;bottom:6px;left:50%;transform:translateX(-50%);z-index:var(--z-overlay);background:var(--bg-glass);padding:var(--sp-05) .5rem;}
.u-inl-2d424819{flex:2;}
.u-inl-f4093dae{width:100%;border-collapse:collapse;table-layout:auto;}
.u-inl-57bae4cd{padding:var(--sp-1) var(--sp-2);font-family:monospace;}
.u-inl-c568e1c8{background:var(--g1);padding:var(--sp-05) var(--sp-1);border-radius:var(--radius-xs);border:var(--hairline);}
.u-inl-4b8ee2d6{padding:var(--sp-1) var(--sp-2);}
.u-inl-2ad84165{padding:var(--sp-2);}
.u-inl-d1caead4{width:44px;}
.u-inl-6bce913b{background:var(--g1);border:var(--hairline);}
.u-inl-4a10f9aa{padding-bottom:.3rem;}
.u-inl-139935f1{align-items:flex-start;}
.u-inl-092af903{white-space:pre-wrap;}
.u-inl-0bb399fb{padding:var(--sp-5) 1rem;}
.u-inl-0716f2f1{display:grid;}
.u-inl-e2231d55{display:grid;grid-template-columns:minmax(0,1.4fr) minmax(0,1fr) auto;gap:var(--sp-3);padding:var(--sp-2h) .8rem;border:var(--hairline);border-radius:var(--radius-sm);background:var(--g1);}
.u-inl-55388107{display:inline-block;background:var(--bg);border:var(--hairline);border-radius:var(--radius-pill);padding:var(--sp-05) .55rem;max-width:100%;text-overflow:ellipsis;}
.u-inl-f8c392a2{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(280px,100%),1fr));gap:var(--sp-4);}
.u-inl-3b7d9fb2{background:var(--bg-info);border-radius:var(--radius-xs);border-left:2px solid var(--amber);}
.u-inl-2580ea5d{margin:var(--sp-2) 0;max-width:400px;}
.u-inl-e04167ec{margin-left:var(--sp-3);}
.u-inl-487ea625{padding:var(--sp-5);}
.u-inl-ebb13c75{max-width:120px;}
.u-inl-a71c8bfb{background:var(--bg-permit-manual);color:var(--fg-permit-manual);padding:.18rem .5rem;border-radius:var(--radius-xs);}
.u-inl-d7223ef8{background:var(--bg-permit-auto);color:var(--fg-permit-auto);padding:.18rem .5rem;border-radius:var(--radius-xs);}
.u-inl-ed642c16{margin-top:var(--sp-3h);}
.u-inl-eaf5b8bc{background:var(--type-sc);}
.u-inl-47d68ada{background:var(--type-aa);}
.u-inl-e3ad3ba6{background:var(--pers);}
.u-inl-24773229{background:var(--bg-raid);border:1px solid var(--corps);display:inline-block;width:8px;height:8px;border-radius:50%;}
.u-inl-c7aecb39{height:12px;background:var(--g1);border-radius:var(--radius-sm);}
.u-inl-9fa83626{width:35px;text-align:right;}
.u-inl-4b9d4c9a{position:absolute;bottom:4px;left:0;right:0;color:var(--white);text-shadow:0 1px 2px rgba(0,0,0,.4);}
.u-inl-fcc2c791{flex-direction:column;gap:var(--sp-05);min-width:36px;}
.u-inl-a8276ab1{align-items:flex-end;height:100px;padding:0 .1rem;overflow-x:auto;}
.u-inl-e6c75ba5{gap:var(--sp-4);}
.u-inl-0b936917{flex-direction:column;}
.u-inl-13c4f114{flex-direction:column;gap:var(--sp-05);min-width:24px;}
.u-inl-9939c088{height:14px;line-height:14px;}
.u-inl-6787fa9b{align-items:flex-end;gap:var(--sp-05);overflow-x:auto;}
.u-inl-a78283d4{margin-left:120px;}
.u-inl-99c58a15{width:28px;}
.u-inl-ac206114{flex-direction:column;gap:var(--sp-05);overflow-x:auto;}
.u-inl-7608acb2{color:var(--green);}
.u-inl-18ab3ea7{border-top:1px solid var(--g1);padding-top:var(--sp-1h);}
.u-inl-cc0cb97c{line-height:var(--lh-body);}
.u-inl-59526fcb{font-size:7.5pt;font-family:Arial,sans-serif;color:#999;width:100%;padding:5mm 14mm 0;justify-content:space-between;}
.u-inl-d15bdf8e{font-size:7.5pt;font-family:Arial,sans-serif;color:#999;width:100%;padding:0 14mm 4mm;justify-content:space-between;border-top:0.5pt solid #ddd;}
.u-inl-e5529f3c{color:#555;}
.u-inl-2a0af331{font-size:8pt;color:#666;}
.u-inl-728fd8a2{color:#664d03;background:#fff3cd;padding:1px 6px;border-radius:var(--radius-xs);font-size:8pt;}
.u-inl-c090f7dd{font-size:7.5pt;color:#555;margin-bottom:2px;}
.u-inl-4d673db9{font-size:8pt;border-bottom:1px solid #f0f0f0;padding:1px 0;}
.u-inl-4d7258c2{color:#aaa;}
.u-inl-db3ef811{font-size:11pt;color:#555;margin-bottom:6mm;}
.u-inl-b56987db{margin-bottom:12px;}
.u-inl-eb44f287{margin-bottom:4px;font-size:8.5pt;color:#555;}
.u-inl-dd1173f4{gap:10px;margin-bottom:10px;}
.u-inl-2adf519e{font-size:8pt;}
.u-inl-d4a16cdd{margin-top:10px;margin-bottom:6px;}
.u-inl-700ab13d{margin-bottom:10px;border:1px solid #ddd;border-radius:var(--radius-xs);page-break-inside:avoid;}
.u-inl-16c4713b{background:#1a1a1a;color: var(--white);padding:5px 10px;font-size:10pt;}
.u-inl-d4ebbe75{padding:4px 10px 4px 20px;border-top:1px solid #eee;font-size:9pt;}
.u-inl-d5130a7c{background:#f8f8f8;padding:10px 12px;border-radius:var(--radius-xs);border:1px solid #ddd;font-size:10pt;line-height:1.65;}
.u-inl-86209dc9{color:#999;}
.u-inl-24914820{font-size:8.5pt;color:#555;margin-top:2px;}
.u-inl-81527b8e{font-size:8.5pt;}
.u-inl-15556f4b{margin-bottom:10px;width:auto;}
.u-inl-a4eb7007{color:#155724;}
.u-inl-ebc68ca2{color:#721c24;}
.u-inl-606dd2be{color:#856404;}
.u-inl-02a221af{margin-top:8px;margin-bottom:6px;}
.u-inl-b922c89f{margin-bottom:10px;}
.u-inl-048fd4f9{font-size:9pt;}
.u-inl-a84cf9ae{font-size:10pt;}
.u-inl-411fb309{font-size:8.5pt;color:#555;}
.u-inl-25b791ef{width:100%;border-collapse:collapse;font-size:9pt;}
.u-inl-a2f3eba7{background:#f5f5f5;}
.u-inl-82e31340{text-align:left;padding:4px 8px;border-bottom:1px solid #ddd;}
.u-inl-9d095716{text-align:right;padding:4px 8px;border-bottom:1px solid #ddd;}
.u-inl-adde56aa{padding:3px 8px;border-bottom:1px solid #eee;}
.u-inl-10cafc50{text-align:right;padding:3px 8px;border-bottom:1px solid #eee;}
.u-inl-d2e3552d{margin-top:14px;margin-bottom:6px;}
.u-inl-702e3714{font-size:8pt;color:#555;margin-top:3px;}
.u-inl-301647f5{margin-top:6px;}
.u-inl-376f1c4d{margin:3px 0 0 16px;padding:0;font-size:8.5pt;line-height:1.6;}
.u-inl-df928149{margin-top:10px;}
.u-inl-a19afe15{page-break-before:always;padding-top:10mm;}
.u-inl-67dd12ec{margin-top:4pt;font-size:8pt;color:#a16207;}
.u-inl-efdac662{margin-top:5pt;font-size:8.5pt;line-height:1.45;color:#333;}
.u-inl-78651ab9{margin-top:6pt;}
.u-inl-1773a950{font-size:8.5pt;margin-bottom:3pt;}
.u-inl-51377a91{grid-column:1/-1;}
.u-inl-5225e5b7{width:0%;}
.u-inl-7f003c93{background:var(--bg-warn);color:var(--fg-warn);padding:var(--sp-2h) .7rem;border-radius:var(--radius-sm);}
.u-inl-73db66b1{padding:var(--sp-2) .7rem;}
.u-inl-c6a44605{padding:var(--sp-6);}
.u-inl-1dac370f{line-height:1.5;}
.u-inl-f0b1c68f{margin-left:var(--sp-1);}
.u-inl-25b88bdc{padding:var(--sp-3);border:var(--hairline);border-radius:var(--radius-sm);}
.u-inl-a2bbcca7{flex-wrap:nowrap;}
.u-inl-91a463fa{margin-left:var(--sp-1h);background:var(--bk);color:var(--white);border-radius:var(--radius-xs);padding:var(--sp-05) .35rem;}
.u-inl-f1953529{padding:var(--sp-2) .6rem;background:var(--bg-draft);border-radius:var(--radius-sm);color:var(--text);white-space:pre-wrap;}
.u-inl-89083200{background:var(--g2);border-radius:var(--radius-xs);height:6px;}
.u-inl-dfa12b87{background:var(--y);height:100%;width:0%;transition:width var(--dur-normal) ease;}
.u-inl-8cbbd088{margin-top:var(--sp-6);}
.u-inl-7748c273{margin-top:var(--sp-6);padding-bottom:var(--sp-6);}
.u-inl-1f9d922c{font-weight:var(--fw-regular);margin-left:var(--sp-2h);}
.u-inl-c23f4189{margin-bottom:var(--sp-1h);}
.u-inl-3a558831{width:100%;height:660px;}
.u-inl-39e5aef6{padding:var(--sp-2) .75rem;}
.u-inl-94c207c0{height:4px;width:100%;margin-bottom:1px;border-radius:var(--radius-xs);}
.u-inl-0eaeb02f{color:var(--bg-rejected);}
.u-inl-f5550bab{padding:var(--sp-3);}
.u-inl-00b5f64c{padding:var(--sp-1) var(--sp-2);background:var(--bg-info);border-radius:var(--radius-xs);}
.u-inl-bf595a3c{text-transform:uppercase;letter-spacing:.04em;}
.u-inl-c098eec6{margin:var(--sp-2h) 0;}
.u-inl-da12b03f{text-transform:uppercase;letter-spacing:.05em;}
.u-inl-3f4d1d9a{border-bottom:var(--hairline);}
.u-inl-4de37e09{margin:var(--sp-2) 0;}
.u-inl-d895d259{border-top:1px solid var(--g1);padding-top:var(--sp-1);}
.u-inl-6be45995{padding:.6rem;font-size:var(--fs-xs);}
.u-inl-da7f6ceb{font-weight:var(--fw-regular);margin-left:var(--sp-2);}
.u-inl-22df6faf{margin:var(--sp-2) 0 var(--sp-1);padding:var(--sp-1) var(--sp-2);background:var(--bk2,#f5f5f5);border-radius:var(--radius-xs);}
.u-inl-eef252b7{font-weight:var(--fw-regular);text-transform:none;letter-spacing:normal;margin-top:.1rem;}
.u-inl-ca6fc035{margin-left:auto;}
.u-inl-7e6609e5{font-size:var(--fs-sm);}
.u-inl-ea72a59f{font-size:var(--fs-sm);line-height:1.5;color:var(--text);}
.u-inl-f4eebea0{height:var(--sp-3);background:var(--g1);border-radius:var(--radius-sm);}

/* ── Live widgets (during-camp dashboard) ─────────────────────
   Imported from design_handoff_camp_live_widgets. Sizes vary by
   viewport: S compact, M wide, L large, BN banner. Render layer
   picks the variant from window.innerWidth. */
.live-widget{background:var(--surface-card);border:var(--hairline);border-radius:var(--radius-md);padding:var(--sp-4);box-shadow:var(--shadow-sm);position:relative;overflow:hidden;margin-bottom:var(--sp-3);}
/* Hide containers that haven't been populated yet — avoids a brief
   empty-rectangle flash on first paint before renderLiveWidgets() runs. */
.live-widget:empty{display:none;}
/* Size scale: S (compact widget, fits 3-up on desktop), M (single
   column desktop), L (1.5-up — fills more than M but still leaves room
   for a sibling), BN (banner, full width). Was: M and L identical at
   380px — the customise modal exposed both as choices but they rendered
   the same, confusing users. Aperçu review 2026-05-16. */
.live-widget[data-size="s"]{max-width:240px;}
.live-widget[data-size="m"]{max-width:380px;}
.live-widget[data-size="l"]{max-width:560px;}
.live-widget[data-size="bn"]{max-width:none;}

/* Freshness indicator — a small dot in the top-right corner. Green
   when the widget has been re-rendered within the last 2 minutes;
   amber when stale (page in background tab, network blip, etc). The
   class is toggled by the staleness sweep in live-widgets.js. */
.live-widget.is-fresh::after,
.live-widget.is-stale::after {
  content: "";
  position: absolute;
  top: 10px; right: 10px;
  width: 8px; height: 8px;
  border-radius: 50%;
  border: 1px solid rgba(0,0,0,.06);
  pointer-events: none;
}
.live-widget.is-fresh::after { background: var(--green); }
.live-widget.is-stale::after { background: var(--amber); }
.live-widget.is-empty{padding:var(--sp-3) var(--sp-2h);color:var(--g4);font-size:var(--fs-sm);font-style:italic;}

/* Emphasis variants (now/next, progress, brief). Per Style Guide §03
   "one yellow per screen", the focus is marked with a yellow accent trim
   on a calm --surface-card tile — NOT a full yellow/black surface fill.
   The old fills competed with the page CTA and rendered low-contrast text
   (the yellow card had no on-yellow text colour); the trim keeps the
   live widgets in the same family as every other dashboard tile. */
.live-widget.is-feature,
.live-widget.is-accent{border-left:3px solid var(--y);}

/* Atoms */
.lw-live-dot{display:inline-flex;align-items:center;gap:5px;font-size:var(--fs-xs);font-weight:var(--fw-semibold);text-transform:uppercase;letter-spacing:var(--ls-wide);color:var(--g4);}
.lw-live-dot::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--red);animation:lw-pulse 1.6s ease-in-out infinite;display:inline-block;}
.lw-live-dot.is-next::before{background:var(--amber);animation:none;}
.lw-live-dot.is-up::before{background:var(--g3);animation:none;}
@keyframes lw-pulse{0%,100%{opacity:1;transform:scale(1);}50%{opacity:.5;transform:scale(1.4);}}

.lw-title{font-family:var(--serif);font-weight:400;line-height:1.05;margin:6px 0 4px;}
.live-widget[data-size="s"] .lw-title{font-size:var(--fs-lg);}
.live-widget[data-size="m"] .lw-title{font-size:var(--fs-xl);}
.live-widget[data-size="l"] .lw-title{font-size:var(--fs-2xl);}
.live-widget[data-size="bn"] .lw-title{font-size:var(--fs-xl);}

.lw-meta{font-size:var(--fs-xs);color:var(--g4);}
.lw-sub{font-size:var(--fs-xs);color:var(--g4);margin-top:2px;}
.lw-lbl{font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:var(--ls-wide);color:var(--g4);font-weight:var(--fw-semibold);}
.lw-num{font-family:var(--serif);line-height:1;}
.lw-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-weight:var(--fw-semibold);}

.lw-pill{display:inline-block;font-size:9.5px;font-weight:var(--fw-bold);letter-spacing:.05em;border-radius:3px;padding:1px 6px;color: var(--white);}
.lw-pill.sc{background:var(--type-sc);}
.lw-pill.ac{background:var(--type-ac);color: var(--bk);}
.lw-pill.aa{background:var(--type-aa);}
.lw-pill.d{background:var(--type-d);}
.lw-rel{display:inline-block;font-size:var(--fs-xs);font-weight:var(--fw-semibold);border-radius:99px;padding:1px 7px;color: var(--white);}
.lw-rel.pers{background:var(--pers);color: var(--bk);}
.lw-rel.corps{background:var(--corps);}
.lw-rel.env{background:var(--env);}
.lw-rel.autres{background:var(--autres);}
.lw-rel.spirit{background:var(--spirit);}

.lw-av{display:inline-flex;width:22px;height:22px;border-radius:50%;background:var(--y);font-size:var(--fs-xs);font-weight:var(--fw-bold);color: var(--bk);align-items:center;justify-content:center;flex-shrink:0;}
.lw-av.lg{width:30px;height:30px;font-size:var(--fs-xs);}
.lw-av.sm{width:16px;height:16px;font-size:8px;}
.lw-av-stack{display:inline-flex;}
.lw-av-stack .lw-av{border:2px solid var(--wh);margin-left:-6px;}
.lw-av-stack .lw-av:first-child{margin-left:0;}

.lw-prog{height:5px;background:var(--g1);border-radius:99px;overflow:hidden;}
.lw-prog span{display:block;height:100%;background:var(--bk);border-radius:99px;}

.lw-divider{height:1px;background:var(--g2);margin:8px 0;}
.lw-row{display:flex;align-items:center;gap:8px;}
.lw-col{display:flex;flex-direction:column;}
.lw-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:8px;}
.lw-grid-4{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;}

.lw-icon-circ{width:32px;height:32px;border-radius:8px;background:var(--g1);display:grid;place-items:center;font-size:var(--fs-lg);flex-shrink:0;}
.lw-cd{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-weight:var(--fw-semibold);}

/* Section divider hint inside the widgets */
.lw-vrule{width:1px;align-self:stretch;background:var(--g2);}

@media (prefers-color-scheme: dark) {
  /* Base .live-widget flips automatically via --surface-card / --hairline
     (→ --g1 / --border in dark), matching .apercu-tile — no per-widget dark
     surface override needed. Only the inner atom plates take a tuned
     mid-step tone (#2a2a2a sits between the --g1/--g2 token steps). */
  .lw-icon-circ { background:#2a2a2a; }
  .lw-prog { background:#2a2a2a; }
  .lw-prog span { background:var(--y); }
  /* Activity-count badge (.u-inl-91a463fa) — base rule at line ~4470
     hardcodes bg:var(--bk); color:var(--white). In dark mode that's
     black-on-near-black = invisible. This block lives AFTER the base
     rule so it wins source-order. Same pattern for any other late-
     defined utility classes that rely on `--bk`/`--wh` semantics. */
  .u-inl-91a463fa { background:#3a3a3a; color:var(--g4); }
}

/* ────────────────────────────────────────────────────────────────
   GP-AUDIT-2026-06-14 round 3 — photo pages CSS.
   The gallery pipeline (GP-11/12/13) shipped without styling rules
   for any of the .ph-* / .phpub-* / .pcr-* classes the new pages
   emit; the pages rendered as unstyled HTML. This section adds
   layout + dark-mode + mobile-responsive rules using the existing
   design tokens.

   Conventions followed: design-token vars only (no hardcoded color);
   one yellow CTA per screen (.btn-g elsewhere); cards 12px radius +
   shadow-sm; mobile (≤768px) breakpoint matches the rest of the app.
   ──────────────────────────────────────────────────────────────── */

/* Photos triage page (js/pages/photos.js) ────────────────────── */

.ph-toolbar {
  display:flex; align-items:center; gap:var(--sp-2h);
  flex-wrap:wrap;
  padding:var(--sp-2) 0 var(--sp-2h);
  border-bottom:var(--hairline);
  margin-bottom:var(--sp-3);
}
.ph-camp-label { font-weight:var(--fw-semibold); color:var(--g4); font-size:var(--fs-sm); }
.ph-camp-name {
  font-weight:var(--fw-semibold);
  color:var(--text);
  font-size:var(--fs-md);
  margin-right:var(--sp-1h);
}
.ph-filter-chips { display:flex; gap:var(--sp-1h); flex-wrap:wrap; }

.ph-grid {
  display:grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap:var(--sp-3);
  padding:var(--sp-2) 0;
}

.ph-card {
  position:relative;
  border:var(--hairline);
  border-radius:var(--radius-md);
  background:var(--wh);
  box-shadow:var(--shadow-sm);
  overflow:hidden;
  transition: border-color var(--dur-fast), box-shadow var(--dur-fast), transform var(--dur-fast);
  display:flex; flex-direction:column;
}
.ph-card:hover { border-color:var(--g3); box-shadow:var(--shadow-md); }
.ph-card.is-selected { border-color:var(--y); box-shadow:0 0 0 2px var(--y); }
.ph-card[aria-pressed="true"] { border-color:var(--green); }

.ph-card-thumb {
  position:relative;
  width:100%;
  aspect-ratio: 4 / 3;
  background:var(--g2);
  overflow:hidden;
}
.ph-card-thumb img {
  width:100%; height:100%; object-fit:cover; display:block;
}
.ph-card-thumb.is-stale::after {
  content:"⚠ consentement obsolète";
  position:absolute; inset:auto 0 0 0;
  background:var(--bg-warn);
  color:var(--text);
  font-size:var(--fs-xs);
  padding:.2rem .5rem;
  text-align:center;
}

.ph-card-body {
  padding:var(--sp-2);
  display:flex; flex-direction:column;
  gap:var(--sp-1h);
  flex:1;
}
.ph-caption {
  font-size:var(--fs-sm);
  color:var(--text);
  line-height:var(--lh-tight);
  word-break:break-word;
}
.ph-caption-edit {
  width:100%;
  font-size:var(--fs-sm);
  padding:.25rem .35rem;
  border:var(--hairline);
  border-radius:var(--radius-xs);
  background:var(--wh);
  color:var(--text);
}
.ph-card-actions {
  display:flex; gap:var(--sp-1h); flex-wrap:wrap; align-items:center;
}
.ph-state-badge {
  display:inline-flex; align-items:center; gap:.25rem;
  padding:.15rem .55rem;
  border-radius:var(--radius-pill);
  font-size:var(--fs-xs);
  font-weight:var(--fw-semibold);
  background:var(--g2);
  color:var(--text);
}
.ph-state-badge.is-accepted { background:var(--bg-success); color:var(--fg-success); }
.ph-state-badge.is-rejected { background:var(--bg-error); color:var(--fg-error); }
.ph-state-badge.is-published { background:var(--bg-approved); color:var(--green); }

.ph-select-mark {
  position:absolute; top:.45rem; left:.45rem;
  width:1.4rem; height:1.4rem;
  border-radius:50%;
  background:var(--bg-overlay);
  color:#fff;
  display:flex; align-items:center; justify-content:center;
  font-size:var(--fs-sm);
  font-weight:var(--fw-bold);
  cursor:pointer;
}
/* The checkbox sits inside the label .ph-select-mark. Visually
   hidden via appearance:none + zero-size styling, but kept
   click-targetable for Playwright + assistive tech. The .ph-select-mark
   provides the visual ✓ on .is-selected via ::after. */
.ph-select-mark .ph-select-cb {
  position:absolute;
  inset:0;
  margin:0;
  appearance:none;
  -webkit-appearance:none;
  background:transparent;
  border:none;
  cursor:pointer;
  width:100%;
  height:100%;
}
.ph-card.is-selected .ph-select-mark::after { content:"✓"; }

.ph-accept, .ph-reject, .ph-blur-toggle {
  padding:.25rem .6rem;
  font-size:var(--fs-sm);
  border-radius:var(--radius-sm);
  border:var(--hairline);
  background:var(--wh);
  cursor:pointer;
}
.ph-accept:hover { background:var(--bg-success); color:var(--fg-success); }
.ph-reject:hover { background:var(--bg-error); color:var(--fg-error); }

.ph-face-row {
  display:flex; gap:var(--sp-1); flex-wrap:wrap; align-items:center;
  padding:var(--sp-1) var(--sp-2) var(--sp-2);
}
.ph-face-thumb {
  width:36px; height:36px;
  object-fit:cover;
  border-radius:var(--radius-md);
  border:1px solid var(--border-strong);
  background:var(--g2);
  flex:0 0 auto;
}
.ph-face-chip {
  display:inline-flex; align-items:center; gap:.3rem;
  padding:.15rem .5rem;
  font-size:var(--fs-xs);
  border-radius:var(--radius-pill);
  background:var(--g2);
  border:1px solid var(--border-strong);
  color:var(--text);
  cursor:pointer;
}
.ph-face-chip[data-decision="blur"] { background:var(--bg-warn); color:var(--text); }
.ph-face-chip[data-decision="publish"] { background:var(--bg-success); color:var(--fg-success); }

.ph-consent-dot {
  display:inline-block;
  width:.55rem; height:.55rem;
  border-radius:50%;
  margin-right:.3rem;
  background:var(--g3);
  vertical-align:middle;
}
.ph-consent-dot.is-yes { background:var(--green); }
.ph-consent-dot.is-no  { background:var(--red); }

.ph-bulk-bar {
  position:sticky; bottom:0;
  z-index: var(--z-banner);
  margin:var(--sp-3) calc(-1 * var(--sp-3)) 0;
  padding:var(--sp-2h) var(--sp-3);
  background:var(--wh);
  border-top:var(--hairline);
  box-shadow:0 -4px 16px rgba(0,0,0,.08);
  display:flex; align-items:center; gap:var(--sp-2h);
  flex-wrap:wrap;
}
.ph-bulk-count { font-weight:var(--fw-bold); color:var(--text); }

.ph-loading, .ph-empty {
  padding:var(--sp-5) var(--sp-3);
  text-align:center;
  color:var(--g4);
  font-size:var(--fs-md);
}
.ph-empty .btn { margin-top:var(--sp-2); }

/* Upload zone (drag + drop) */
.ph-upload-zone {
  padding:var(--sp-3);
  border:2px dashed var(--g3);
  border-radius:var(--radius-md);
  text-align:center;
  background:var(--bg-draft);
  cursor:pointer;
  color:var(--g4);
  font-size:var(--fs-sm);
  transition: background var(--dur-fast), border-color var(--dur-fast);
}
.ph-upload-zone.dragover {
  background:var(--bg-warn);
  border-color:var(--y);
  color:var(--text);
}

/* Upload-queue card */
.ph-queue-card {
  border:var(--hairline);
  border-radius:var(--radius-md);
  background:var(--wh);
  padding:var(--sp-2);
  margin-bottom:var(--sp-2);
}
.ph-queue-list { display:flex; flex-direction:column; gap:var(--sp-1h); margin-top:var(--sp-1h); }
.ph-queue-row {
  display:flex; align-items:center; gap:var(--sp-2);
  padding:var(--sp-1h);
  border:var(--hairline);
  border-radius:var(--radius-sm);
  background:var(--bg-draft);
  font-size:var(--fs-sm);
}
.ph-queue-row[data-state="failed"] { background:var(--bg-error); color:var(--fg-error); }
.ph-queue-row[data-state="complete"] { background:var(--bg-success); color:var(--fg-success); }
.ph-queue-bar {
  flex:1; height:.45rem;
  background:var(--g2);
  border-radius:var(--radius-xs);
  overflow:hidden;
}
.ph-queue-progress {
  display:block; height:100%; background:var(--y);
  transition: width var(--dur-normal);
}
.ph-queue-actions { display:flex; gap:var(--sp-1); }

/* Triage overlay (full-screen keyboard mode) */
.ph-triage-overlay {
  position:fixed; inset:0;
  z-index: var(--z-overlay);
  background:var(--bg-lightbox);
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  padding:var(--sp-3);
}
.ph-triage-overlay[aria-hidden="true"] { display:none; }
.ph-triage-overlay img { max-width:90vw; max-height:80vh; object-fit:contain; }
.ph-triage-overlay .ph-triage-hint {
  margin-top:var(--sp-3);
  color:#e8e8e8;
  font-size:var(--fs-sm);
  text-align:center;
}
.ph-triage-overlay .ph-triage-hint kbd {
  background:#2a2a2a; color:#f0f0f0;
  padding:.15rem .45rem;
  border-radius:var(--radius-xs);
  font-family: ui-monospace, "SF Mono", monospace;
  font-size:.7rem;
}

/* Slide-over drawer (face details) */
.ph-drawer {
  position:fixed; top:0; right:0; bottom:0;
  width:min(420px, 90vw);
  z-index: var(--z-modal);
  background:var(--wh);
  border-left:var(--hairline);
  box-shadow: var(--shadow-overlay);
  overflow:auto;
  padding:var(--sp-3);
  transform: translateX(100%);
  transition: transform var(--dur-normal);
}
/* photos.js toggles .open (not .is-open) — match both for safety. */
.ph-drawer.is-open, .ph-drawer.open { transform: translateX(0); }
.ph-drawer img { max-width:100%; border-radius:var(--radius-sm); }
.ph-drawer .ph-drawer-close {
  position:absolute; top:.6rem; right:.6rem;
  background:transparent; border:none;
  font-size:1.4rem; cursor:pointer; color:var(--g4);
}

/* Publish wizard (js/pages/photos-publish.js) ────────────────── */

.phpub-wizard {
  max-width: 760px;
  margin: 0 auto;
  padding: var(--sp-3);
}
.phpub-progress {
  display:flex; gap:var(--sp-1); margin-bottom:var(--sp-3);
  list-style:none; padding:0;
}
.phpub-step {
  flex:1;
  display:flex; flex-direction:column; align-items:center; gap:.3rem;
  padding:.4rem .5rem;
  border-radius:var(--radius-sm);
  background:var(--bg-draft);
  color:var(--g4);
  font-size:var(--fs-xs);
  font-weight:var(--fw-semibold);
  text-align:center;
  position:relative;
}
.phpub-step[aria-current="step"] {
  background:var(--y);
  color:var(--bk);
}
.phpub-step.is-done { background:var(--bg-success); color:var(--fg-success); }
.phpub-step::before {
  content: attr(data-step-num);
  display:inline-flex; align-items:center; justify-content:center;
  width:1.4rem; height:1.4rem; border-radius:50%;
  background:var(--wh);
  border:1px solid currentColor;
  font-size:var(--fs-xs);
}
.phpub-step.is-done::before { content:"✓"; background:currentColor; color:#fff; border-color:currentColor; }

.phpub-step-body {
  padding: var(--sp-3);
  border:var(--hairline);
  border-radius:var(--radius-md);
  background:var(--wh);
  box-shadow:var(--shadow-sm);
  min-height: 240px;
}
.phpub-step-body h3 {
  font-family: var(--serif);
  font-weight:400;
  font-size:var(--fs-xl);
  margin-bottom:var(--sp-2);
  color:var(--text);
}
.phpub-summary {
  display:grid;
  grid-template-columns: auto 1fr;
  gap:.5rem var(--sp-2);
  font-size:var(--fs-sm);
  color:var(--text);
}
.phpub-summary dt { color:var(--g4); }
.phpub-missing {
  margin-top:var(--sp-2);
  padding:var(--sp-2);
  background:var(--bg-error);
  color:var(--fg-error);
  border-radius:var(--radius-sm);
  font-size:var(--fs-sm);
}
.phpub-footer {
  display:flex; justify-content:space-between; gap:var(--sp-2);
  margin-top:var(--sp-3);
  padding-top:var(--sp-2h);
  padding-bottom: env(safe-area-inset-bottom, 0);
  border-top:var(--hairline);
}

/* Consent admin (js/pages/photos-consent.js) ──────────────────── */

.pcr-filters {
  display:flex; gap:var(--sp-1h); flex-wrap:wrap; margin-bottom:var(--sp-2h);
}
.pcr-search {
  flex:1; min-width:220px;
  padding:.4rem .7rem;
  border:var(--hairline);
  border-radius:var(--radius-sm);
  background:var(--wh);
  color:var(--text);
  font-size:var(--fs-md);
}
.pcr-table-wrap { overflow-x:auto; border:var(--hairline); border-radius:var(--radius-md); background:var(--wh); }
.pcr-table {
  width:100%;
  border-collapse:collapse;
  font-size:var(--fs-sm);
}
.pcr-table th, .pcr-table td {
  padding:var(--sp-1h) var(--sp-2);
  text-align:left;
  border-bottom:var(--hairline);
  color:var(--text);
}
.pcr-table th {
  background:var(--bg-draft);
  font-weight:var(--fw-semibold);
  font-size:var(--fs-xs);
  text-transform:uppercase;
  letter-spacing:.04em;
  color:var(--g4);
}
.pcr-row:hover { background:var(--bg-draft); }
.pcr-row.pcr-expiring td { background:rgba(255,193,7,.08); }
.pcr-row.pcr-expiring td:first-child::before {
  content:"⏳ "; color:var(--amber);
}
.pcr-row.pcr-expired td { background:rgba(120,120,120,.08); color:var(--g4); text-decoration: line-through; }
.pcr-row.pcr-expired td:first-child::before {
  content:"⛔ "; color:var(--red); text-decoration:none; display:inline-block;
}
.pcr-name { font-weight:var(--fw-semibold); }
.pcr-mid { color:var(--g4); font-size:var(--fs-xs); font-family: ui-monospace, "SF Mono", monospace; }
.pcr-notes { color:var(--g4); max-width:24ch; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

.pcr-edit-row td { background:var(--bg-warn); }
.pcr-edit-grid {
  display:grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap:var(--sp-2);
}
.pcr-edit-grid .pcr-notes-field { grid-column: 1 / -1; }
.pcr-edit-actions {
  display:flex; gap:var(--sp-2); margin-top:var(--sp-2); justify-content:flex-end;
}
.pcr-radio-row { display:flex; gap:var(--sp-2h); }
.pcr-radio { display:inline-flex; align-items:center; gap:.3rem; cursor:pointer; }
.pcr-radio input { margin:0; }

.pcr-user-list { list-style:none; padding:0; margin:.3rem 0 0; max-height:200px; overflow:auto; border:var(--hairline); border-radius:var(--radius-sm); }
.pcr-user-pick { padding:.35rem .6rem; cursor:pointer; }
.pcr-user-pick:hover { background:var(--bg-draft); }

/* Mobile responsiveness for all photo pages ───────────────────── */

@media (max-width: 768px) {
  .ph-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--sp-2); }
  .ph-toolbar { gap:var(--sp-2); }
  .ph-bulk-bar { padding:var(--sp-2); padding-bottom: calc(var(--sp-2) + env(safe-area-inset-bottom, 0)); }
  .phpub-wizard { padding: var(--sp-2); }
  .phpub-progress { overflow-x:auto; }
  .phpub-step { font-size:var(--fs-xs); min-width:64px; }
  .pcr-table { font-size:var(--fs-xs); }
  .pcr-table th:nth-child(n+5), .pcr-table td:nth-child(n+5) { display:none; }
  .ph-drawer { width:100vw; border-left:none; border-top:var(--hairline); }
}

/* Dark-mode overrides ─────────────────────────────────────────── */
/* Text colours map to the shared dark-mode body/muted tokens
   (--g4 = #c8c8c8 body, --g3 = #9c9c9c muted) per the 2026-06-13 sweep.
   Surface plates use --g1 (#25 card) / --g2 (#33 border / inset), with
   --wh (#1a page bg) for the deepest row stripe and a single raw #2a
   for the row hover (one step between --wh and --g1). */

@media (prefers-color-scheme: dark) {
  .ph-card { background: var(--g1); border-color: var(--g2); }
  .ph-card-thumb { background: var(--g2); }
  .ph-caption-edit { background: var(--g1); color: var(--g4); border-color: var(--g2); }
  .ph-state-badge { background: var(--g2); color: var(--g4); }
  .ph-bulk-bar { background: var(--g1); border-top-color: var(--g2); box-shadow: 0 -4px 16px rgba(0,0,0,.4); }
  .ph-upload-zone { background: var(--g1); border-color: var(--g2); color: var(--g3); }
  .ph-queue-card { background: var(--g1); border-color: var(--g2); }
  .ph-queue-row { background: var(--wh); border-color: var(--g2); color: var(--g4); }
  .ph-queue-bar { background: var(--g2); }
  .ph-drawer { background: var(--g1); border-left-color: var(--g2); }
  .phpub-step-body { background: var(--g1); border-color: var(--g2); }
  .phpub-step { background: var(--g2); color: var(--g3); }
  .pcr-table-wrap { background: var(--g1); border-color: var(--g2); }
  .pcr-table th { background: var(--g2); color: var(--g3); }
  .pcr-table td { color: var(--g4); }
  .pcr-row:hover { background: #2a2a2a; }
  .pcr-search { background: var(--g1); color: var(--g4); border-color: var(--g2); }
}

/* High-contrast — keep colorblind-distinguishable shapes ──────── */
[data-cb="on"] .ph-state-badge.is-accepted::before { content:"✓ "; }
[data-cb="on"] .ph-state-badge.is-rejected::before { content:"✕ "; }
[data-cb="on"] .ph-state-badge.is-published::before { content:"✓✓ "; }
[data-cb="on"] .ph-consent-dot.is-yes::before { content:"✓"; font-size:.5rem; color:#fff; line-height:1; }
[data-cb="on"] .ph-consent-dot.is-no::before  { content:"✕"; font-size:.5rem; color:#fff; line-height:1; }

/* ── Pattern B: new-camp wizard mobile fullscreen (Task 13) ─────────────────
 * On mobile, openNewCamp() adds .nc-mobile-fullscreen to the .overlay and
 * .nc-mobile-fullscreen-inner to the .modal. The .nc-m-topbar (BLACK editor
 * variant per §19) is prepended to the overlay; the modal becomes the
 * scrollable body and the existing .modal-acts "Créer" button stays as CTA.
 */
.nc-mobile-fullscreen {
  /* Intentionally NO forced display here. closeModal only removes the open
     state class, and hiding depends on the base overlay rule. Forcing the
     overlay visible would trap the wizard open on mobile (back / close /
     cancel / post-create dismiss all looked dead). The open-state rule
     already reveals it; flex-direction below makes it a column. */
  flex-direction: column;
  background: var(--surface-card);
  inset: 0;
  padding: 0;
  align-items: stretch !important;
}
.nc-mobile-fullscreen .nc-m-topbar {
  flex-shrink: 0;
}
.nc-mobile-fullscreen-inner {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  max-height: none;
  border-radius: 0;
  width: 100%;
  max-width: 100%;
  margin: 0;
}
.nc-mobile-fullscreen-inner::before { display: none; }
/* The black .nc-m-topbar (← Nouveau camp) is prepended to the overlay on
   mobile; hide the centered desktop .modal-hd so its title + ✕ don't render as
   a second stacked header. */
.nc-mobile-fullscreen-inner .modal-hd { display: none; }
/* Lift the centered-modal 70vh scroll cap: the overlay is already fullscreen
   and scrolls at the .modal level, so the inner wrapper must not cap height or
   nest a second scroller (which floated the action row mid-screen). */
.nc-mobile-fullscreen-inner .modal-scroll {
  max-height: none;
  overflow: visible;
}
/* The fullscreen morph applies across the whole mobile shell (<960px), not
   just ≤480px, so the CTA-pinning fix must hang off the fullscreen class —
   the @media(max-width:480px) .modal-acts override above doesn't reach
   481–959px phones. Pin "Créer le camp" / "Annuler" flush to the scroll
   container bottom and clear the gesture zone with a safe-area inset. The
   higher specificity (.nc-mobile-fullscreen-inner .modal-acts) also wins
   over the 480px media-query rule, keeping behaviour consistent. */
.nc-mobile-fullscreen-inner .modal-acts {
  bottom: 0;
  margin-bottom: 0;
  padding-bottom: calc(0.9rem + env(safe-area-inset-bottom, 0px));
}

/* Paramètres tabbed layout */
.param-tabs {
  display: flex;
  gap: var(--sp-2);
  flex-wrap: wrap;
  margin-bottom: var(--sp-3);
  border-bottom: var(--hairline);
  padding-bottom: var(--sp-2);
}
.param-panel {
  animation: none;
}
.param-footer {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-top: var(--sp-4);
}
.param-more {
  position: relative;
  margin-left: auto;
}
.param-more-menu {
  position: absolute;
  right: 0;
  bottom: calc(100% + var(--sp-1));
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  background: var(--surface-card);
  border: 1px solid var(--g2);
  border-radius: 12px;
  padding: var(--sp-2);
  box-shadow: var(--shadow-md);
  z-index: 5;
  min-width: 240px;
}
.param-check {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) 0;
}
.param-coverage {
  margin-top: var(--sp-3);
}
.param-coverage-sum {
  font-size: var(--fs-md);
  color: var(--text);
  margin-bottom: var(--sp-2);
}
.settings-danger h3 {
  color: var(--red);
}

/* ── Lieux de camp ── */
.venue-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  align-items: center;
  margin-bottom: var(--sp-3);
}
.venue-subtabs {
  display: flex;
  gap: var(--sp-1);
}
.venue-cards {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}
.venue-card {
  border: var(--hairline);
  border-radius: var(--radius-sm);
  padding: var(--sp-2) var(--sp-2h);
  background: var(--wh);
}
.venue-card-head {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}
.venue-card-meta {
  font-size: var(--fs-sm);
  color: var(--g4);
  margin-top: var(--sp-1);
}
.venue-detail {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}
.venue-detail-head {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}
.venue-detail-meta {
  font-size: var(--fs-sm);
  color: var(--g4);
}
.venue-gallery {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}
.venue-photo {
  max-width: 120px;
  height: auto;
  border-radius: var(--radius-sm);
}
.venue-map {
  border-radius: var(--radius-sm);
  overflow: hidden;
  border: var(--hairline);
}
.venue-pois {
  padding: var(--sp-2) 0;
}
.venue-pois h3 {
  margin: 0 0 var(--sp-1);
  font-size: var(--fs-md);
}
.venue-checklist {
  display: flex;
  flex-direction: column;
  gap: 0;
}
.venue-crit-row {
  display: grid;
  grid-template-columns: 22px 1fr auto;
  gap: var(--sp-2);
  align-items: center;
  padding: var(--sp-1) 0;
  border-bottom: var(--hairline);
}
.venue-crit-row:last-child {
  border-bottom: none;
}
.venue-crit-label {
  font-weight: 500;
}
.venue-crit-remarque {
  color: var(--g4);
  font-size: var(--fs-sm, 0.85rem);
}
.venue-contact {
  padding: var(--sp-2) 0;
  font-size: var(--fs-sm);
  color: var(--g4);
}
.venue-contact h3 {
  margin: 0 0 var(--sp-1);
  font-size: var(--fs-md);
  color: var(--text);
}
.venue-notes {
  padding: var(--sp-2) 0;
  font-size: var(--fs-sm);
}
.venue-notes h3 {
  margin: 0 0 var(--sp-1);
  font-size: var(--fs-md);
}
.venue-form-crit {
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: var(--sp-2);
  align-items: center;
  padding: var(--sp-1) 0;
  border-bottom: var(--hairline);
}
.venue-form-crit:last-child {
  border-bottom: none;
}
.venue-form-map {
  border-radius: var(--radius-sm);
  overflow: hidden;
  border: var(--hairline);
  margin-bottom: var(--sp-2);
}

