/* Copie de : aesop_arena_tactical/app_home/static/app_home/css/main.css @ 55e5aad1, 2026-10-24
   Adaptée pour aesop_arena_plan : la teinte du plan est le CYAN (spec §10.2) — --accent #22d3ee, --accent-highlight,
   --accent-soft, --row-highlight ; --info passe au bleu ciel, puisque le cyan est pris. Le reste est celui du jeu, et
   les ajouts du plan sont en fin de fichier (« les ajouts du plan »). */
/* Diodote · Plan COPD — dark design system (standalone, no aesop_ui dependency).
   Same tokens as the Diodote family (aesop_arena, aesop_wargame), cyan-keyed:
   the arena is blue because it builds, the game amber because it fights, the plan cyan because it designs.

   THE TOKENS — every stylesheet of this service (ops.css, plan.css, lobby.css, a page's own) reads these;
   a colour or a font size written as a literal is a defect waiting to drift.
     surfaces   --bg                the page
                --bg-secondary      cards, panels, the rows of a list
                --bg-elevated       what sits on a card: inputs' fill, chips, the explainer, a raised button
                --surface-tooltip   floating things: the (i) bubble, toasts, the map's tooltips
                --map-bg            behind a map while its cells draw
     lines      --border            hairlines between everything
                --border-strong     a bubble's or a key cap's outline
                --border-input      the edge of a field, a select or a switch's track: 3:1 against the page and a card
     text       --text-bright       titles and values · --text-primary  body · --text-secondary  labels, table heads
                --text-muted        meta and hints (4.5:1 on every surface, the amber-tinted cards included)
                --on-accent  text drawn on the amber fill
     accent     --accent · --accent-highlight · --accent-soft   selection, the primary action, the focus ring
     states     --success · --warning · --danger · --danger-text (red that reads as text on the dark surfaces)
                --info              the sensor cyan (a band, a sensor envelope)
                --path              a planned route (lime)
     energy     --energy-nuclear · --energy-coal · --energy-hydro · --energy-solar · --energy-wind
                the source a power station is drawn with (lens « Economy › Power plants »); nuclear's violet is the
                only violet of the map, so nothing else reads like it
     digital    --digital           a cable landing, a data centre (magenta — no other layer uses it)
     rows       --row-highlight     the row that matters (the weakest link, the relevant track)
                --row-good          the best row (the recommended COA)
     type       --font (the page, and every control) · --mono (code, key caps, seat codes)
                --fs-2xs .7rem · --fs-xs .72rem · --fs-sm .76rem · --fs-md .85rem · --fs-lg 1rem   the body is 14px; nothing in px;
                nothing is written under .7rem, the floor of a text that carries information (ui-static-33)
     shape      --radius (cards) · --radius-sm (buttons, inputs, alerts) · --focus (the keyboard ring)
     layout     --navbar-height     zero when the top line is folded away; every layout reads it

   THE SHARED COMPONENTS (defined below, for every page — do not redefine them in a page's stylesheet):
     .btn (-primary, -ghost, -lg, [disabled])   .badge (-ok, -warn, -no, -level) — a status word, never a button
     .alert (-danger, -warn, -ok) — .refuse-card and .warn-card are its two historical names
     .messages / .message-{success,info,warning,error}   Django's messages, announced and dismissable
     .section-title (an h2 that opens a section) · .block-title (an h3 that heads a panel or a block)
     .data-table (every table of figures) · .kv (a key/value table) · .table-wrap (a wide table scrolls in it)
     .card · .panel (folds) · .explainer · .field / .field-row / .segmented / .switch · progress
     .ux-ico (-add, -danger) — an icon-only button or summary (aria-hidden glyph + .sr-only name + a tooltip)
     .ux-tiles › .ux-tile (.ux-tile-k the label, .ux-tile-v the value) — a panel's state at a glance
     utilities: .inline · .mt-s · .mt-1 · .sr-only — a field's width is its page's (gm.css: .w-5, .w-6, .w-full)  */
:root {
  color-scheme: dark;                 /* the browser's own controls (spinners, pickers, scrollbars) are dark too */
  --bg: #0f1117;
  --bg-secondary: #171a23;
  --bg-elevated: #1e222d;
  --surface-tooltip: #262b38;
  --map-bg: #0b0e14;
  --border: #2a2f3d;
  --border-strong: #3a4152;
  --border-input: #636a7d;            /* 3.5:1 on --bg, 3.2:1 on --bg-secondary (browser_admin-15) */
  --text-primary: #e6e8ef;
  --text-secondary: #b8bccb;
  --text-muted: #979daf;              /* ≥ 4.5:1 on --bg-elevated, --surface-tooltip and an --accent-soft card */
  --text-bright: #ffffff;
  --on-accent: #101010;
  --accent: #22d3ee;
  --accent-highlight: #67e8f9;
  --accent-soft: rgba(34, 211, 238, 0.14);
  --success: #22c55e;
  --warning: #f59e0b;
  --danger: #ef4444;
  --danger-text: #fca5a5;
  --info: #38bdf8;
  --path: #a3e635;
  --energy-nuclear: #a78bfa;
  --energy-coal: #94a3b8;
  --energy-hydro: #38bdf8;
  --energy-solar: #fde047;
  --energy-wind: #4ade80;
  --digital: #e879f9;
  --row-highlight: #0f2a2e;
  --row-good: #14211a;
  --fs-2xs: .7rem;
  --fs-xs: .72rem;
  --fs-sm: .76rem;
  --fs-md: .85rem;
  --fs-lg: 1rem;
  --navbar-height: 52px;
  --radius: 8px;
  --radius-sm: 6px;
  --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  /* Q33 (spec §40.6) — le schéma du processus, d'après PROMPT_STYLE_SVG_JS_HTMX : une couleur par phase (1–2 l'appréciation,
     3a–3b l'estimation, 4a–4b le plan, 5–6 réservées), les deux sens de flèche, la provenance ; et le serif des fiches. */
  --band-1: #D63A9B; --band-2: #D63A9B; --band-3a: #2F86E0; --band-3b: #2F86E0; --band-4a: #00A898; --band-4b: #00A898;
  --band-res: #8C9AA3; --flow-down: #2AA3B5; --flow-up: #E56B36;
  --prov-measured: #4CAF76; --prov-estimated: #8B96E0; --prov-illustrative: #E0A043; --prov-empty: #8B9AA3;
  --serif: Charter, "Bitstream Charter", "Sitka Text", Cambria, "Liberation Serif", Georgia, serif;
  accent-color: var(--accent);        /* checkboxes, radios and range thumbs the page does not draw itself */
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body { background: var(--bg); color: var(--text-primary); font-family: var(--font); font-size: 14px; line-height: 1.55; }
/* The browser draws controls in its own font (Arial) unless told otherwise: one typeface for a <button class="btn">
   and an <a class="btn"> side by side. */
button, input, select, textarea { font: inherit; color: inherit; }
a { color: var(--accent-highlight); text-decoration: none; }
a:hover { text-decoration: underline; }
h1, h2, h3 { color: var(--text-bright); margin: 0 0 .6rem; line-height: 1.25; }
h1 { font-size: 1.75rem; } h2 { font-size: 1.15rem; } h3 { font-size: 1rem; }
p { margin: 0 0 .8rem; }
code { font-family: var(--mono); font-size: .85em; color: var(--text-secondary); }
em { color: var(--text-bright); font-style: italic; }
.muted { color: var(--text-muted); }
.small { font-size: var(--fs-md); }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.inline { display: inline; }
/* — Q16 — « Derived from (conclusions) » : un choix multiple dans les formulaires de quatre applications ; ses options
   sont des conclusions entières, il ne dépasse jamais la largeur de son formulaire (390 px) */
select[data-derived-from] { width: 100%; max-width: 100%; box-sizing: border-box; }
.mt-s { margin-top: .4rem; } .mt-1 { margin-top: 1rem; }

/* Navbar — one line on a wide screen; below 760px the links, the user and Sign out fold into a menu (ui.js). */
.navbar { position: fixed; top: 0; left: 0; right: 0; height: var(--navbar-height); z-index: 1000;
  background: linear-gradient(180deg, var(--bg-secondary), var(--bg)); border-bottom: 1px solid var(--border); }
.navbar-container { height: 100%; display: flex; align-items: center; gap: 1rem; padding: 0 1.1rem; min-width: 0; }
.navbar-brand { display: flex; align-items: center; gap: .5rem; color: var(--text-bright); white-space: nowrap;
  font-size: .95rem; letter-spacing: .05em; flex: none; }
.navbar-brand:hover { text-decoration: none; }
.brand-icon { color: var(--accent-highlight); font-size: 1.15rem; }
.navbar-sub { color: var(--text-muted); font-size: .78rem; letter-spacing: .02em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.navbar-spacer { flex: 1; }
.navbar-menu { display: flex; align-items: center; gap: 1rem; min-width: 0; }
.navbar-link { color: var(--text-secondary); font-size: .88rem; white-space: nowrap; }
.navbar-user { color: var(--text-muted); font-size: .82rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 16rem; }
.navbar-form { margin: 0; }
.navbar-form .btn { white-space: nowrap; }
.navbar-menu-toggle { display: none; width: 2.2rem; height: 2rem; flex: none; place-items: center; padding: 0;
  border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg-elevated); color: var(--text-secondary);
  cursor: pointer; font-size: 1.05rem; line-height: 1; }
.navbar-menu-toggle:hover, .navbar.is-open .navbar-menu-toggle { color: var(--accent-highlight); border-color: var(--accent-highlight); }

/* Layout */
.main-content { max-width: 1040px; margin: 0 auto; padding: calc(var(--navbar-height) + 2rem) 1.25rem 4rem; }
.section-title { margin-top: 2rem; }
.block-title { color: var(--text-bright); font-size: .95rem; font-weight: 600; margin: 0 0 .4rem; }

/* Hero */
.hero { margin-bottom: 1.8rem; }
.kicker { color: var(--accent); font-size: .78rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; }
.kicker a { color: inherit; }       /* the way back ("← Games", "← Studies") reads as the page's kicker, everywhere */
.hero h1 { font-size: 2rem; line-height: 1.22; margin: .3rem 0 .9rem; }
.lede { color: var(--text-secondary); font-size: 1.02rem; max-width: 74ch; }

/* The six steps — three by two, every blurb in the same place */
.steps { list-style: none; margin: 0; padding: 0; display: grid; gap: .6rem;
  grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 860px) { .steps { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .steps { grid-template-columns: minmax(0, 1fr); } }
.step { background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius);
  padding: .8rem .9rem; display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-rows: auto 1fr;
  gap: .15rem .7rem; align-items: start; }
.step-n { grid-row: 1 / span 2; color: var(--bg); background: var(--accent); font-weight: 700;
  width: 1.7rem; height: 1.7rem; border-radius: 50%; display: grid; place-items: center; font-size: .85rem; }
.step-name { grid-column: 2; color: var(--text-bright); font-size: .95rem; }
.step-blurb { grid-column: 2; color: var(--text-muted); font-size: .84rem; }
.steps-caps .step { grid-template-columns: minmax(0, 1fr); border-top: 2px solid var(--accent); }   /* capabilities: no number, the text takes the row */
.steps-caps .step-name, .steps-caps .step-blurb { grid-column: 1; }

/* Tiles — honest empty states */
.tiles { display: grid; gap: .7rem; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); margin: 1rem 0 0; }
.tile { background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius); padding: .9rem 1rem; }
.tile-label { color: var(--text-secondary); font-size: .8rem; text-transform: uppercase; letter-spacing: .07em; }
.tile-label .info { text-transform: none; letter-spacing: 0; }
.tile-value { color: var(--text-bright); font-size: 1.9rem; font-weight: 700; margin-top: .25rem; }
.tile-empty { color: var(--text-muted); font-size: .85rem; margin-top: .45rem; font-style: italic; }

/* Tables — one system: .data-table for figures, .kv for a key and its value; both from the tokens */
.data-table, .kv { width: 100%; border-collapse: collapse; }
.data-table { font-size: .82rem; margin: .4rem 0 1.1rem; }
.data-table th, .data-table td, .kv th, .kv td { text-align: left; border-bottom: 1px solid var(--border); vertical-align: top; }
.data-table th, .data-table td { padding: .35rem .55rem; }
.data-table thead th { color: var(--text-secondary); font-weight: 600; font-size: var(--fs-xs); text-transform: uppercase;
  letter-spacing: .05em; vertical-align: bottom; }
.data-table tbody tr:hover td { background: var(--bg-secondary); }
.data-table .badge { vertical-align: baseline; }
.data-table .small { font-size: .92em; }
.table-wrap { overflow-x: auto; max-width: 100%; }
.kv { margin-top: .6rem; }
.kv th, .kv td { padding: .5rem .6rem; font-weight: 400; }
.kv th { color: var(--text-secondary); width: 16rem; }

/* The explainer (house rule 10) — dismissed once, it folds into "About this page" and opens again on a click */
.explainer { background: var(--bg-elevated); border: 1px solid var(--border); border-left: 3px solid var(--accent);
  border-radius: var(--radius); padding: .85rem 1rem; margin: 1.2rem 0; }
.explainer-head { display: flex; align-items: center; gap: .6rem; }
.explainer-title { color: var(--text-bright); font-size: .95rem; }
.explainer-dismiss { margin-left: auto; background: none; border: none; color: var(--text-muted);
  font-size: 1.25rem; line-height: 1; cursor: pointer; padding: 0 .25rem; border-radius: 4px; }
.explainer-dismiss:hover { color: var(--text-bright); }
.explainer-purpose { color: var(--text-secondary); margin: .45rem 0 0; }
.explainer-todo { color: var(--text-secondary); margin: .5rem 0 0; padding-left: 1.1rem; }
.explainer-reveal-row { margin: .5rem 0 1rem; }
.explainer-reveal { display: inline-flex; align-items: center; gap: .4rem; padding: .15rem .1rem; background: none; border: 0;
  border-radius: 4px; color: var(--text-muted); font-size: .8rem; cursor: pointer; }
.explainer-reveal:hover { color: var(--accent-highlight); }
.explainer-reveal-i { display: inline-grid; place-items: center; width: 1.05rem; height: 1.05rem; border-radius: 50%;
  border: 1px solid currentColor; font: italic 700 var(--fs-xs)/1 Georgia, serif; }

/* Forms and buttons */
.btn { display: inline-block; border-radius: var(--radius-sm); padding: .4rem .8rem; font-size: .88rem;
  border: 1px solid var(--border); background: var(--bg-elevated); color: var(--text-primary); cursor: pointer; }
.btn:hover { text-decoration: none; border-color: var(--accent); }
.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); font-weight: 600; }
.btn-ghost { background: none; }
.auth-card { max-width: 25rem; margin: 2rem auto; background: var(--bg-secondary);
  border: 1px solid var(--border); border-radius: var(--radius); padding: 1.6rem; }
.auth-card label { display: block; color: var(--text-secondary); font-size: .85rem; margin: .7rem 0 .25rem; }
.auth-card input { width: 100%; padding: .5rem .6rem; background: var(--bg); color: var(--text-primary);
  border: 1px solid var(--border-input); border-radius: var(--radius-sm); font-size: .92rem; }
.auth-card input:hover { border-color: var(--text-muted); }
.auth-card input:focus { border-color: var(--accent); outline: none; box-shadow: 0 0 0 3px var(--accent-soft); }
.auth-card .btn { width: 100%; margin-top: 1.1rem; }
.auth-card .explainer { margin: .8rem 0 .4rem; }
.errorlist { color: var(--danger-text); list-style: none; padding: 0; margin: .5rem 0; font-size: .85rem; }
.helptext { color: var(--text-muted); font-size: .78rem; }

/* Django's messages: the colour says what kind, the container is announced, the × takes one away (ui.js) */
.messages { display: grid; gap: .4rem; margin-bottom: 1rem; }
.message { display: flex; align-items: flex-start; gap: .6rem; padding: .5rem .6rem .5rem .8rem; border-radius: var(--radius-sm);
  background: var(--bg-elevated); border: 1px solid var(--border); border-left-width: 3px; }
.message-text { flex: 1; min-width: 0; }
.message-close { flex: none; background: none; border: 0; padding: 0 .2rem; color: var(--text-muted); font-size: 1.15rem;
  line-height: 1.2; cursor: pointer; border-radius: 4px; }
.message-close:hover { color: var(--text-bright); }
.message-success { border-color: rgba(34, 197, 94, .5); border-left-color: var(--success); color: var(--success); }
.message-info { border-left-color: var(--info); }
.message-warning { border-color: rgba(245, 158, 11, .5); border-left-color: var(--warning); color: var(--accent-highlight); }
.message-error { border-color: rgba(239, 68, 68, .5); border-left-color: var(--danger); color: var(--danger-text); }

/* Alerts — a refusal (red), a warning (amber), a confirmation (green); in the page, not a toast */
.alert, .refuse-card, .warn-card { background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius);
  padding: .6rem .8rem; margin: .8rem 0; font-size: .88rem; }
.alert-danger, .refuse-card { border-color: var(--danger); }
.alert-warn, .warn-card { border-color: var(--warning); }
.alert-ok { border-color: var(--success); }

/* A bar that fills — the study's progress; the value is also written beside it (.progress-row) */
progress { -webkit-appearance: none; appearance: none; display: block; width: 100%; height: .55rem; border: 0;
  border-radius: 999px; background: var(--bg-elevated); color: var(--accent); overflow: hidden; }
progress::-webkit-progress-bar { background: var(--bg-elevated); border-radius: 999px; }
progress::-webkit-progress-value { background: var(--accent); border-radius: 999px; transition: width .3s; }
progress::-moz-progress-bar { background: var(--accent); border-radius: 999px; }
.progress-row { display: flex; align-items: center; gap: .7rem; }
.progress-row progress { flex: 1; }
.progress-pct { flex: none; min-width: 3.2rem; text-align: right; color: var(--text-bright); font-variant-numeric: tabular-nums; font-size: .85rem; }

/* ---------------------------------------------------------------------------------------------
   Shared interface pieces (ui.js): the (i) bubble, folding panels, splitters, dialogs, forms.
   --------------------------------------------------------------------------------------------- */
:root { --focus: 0 0 0 2px var(--bg), 0 0 0 4px var(--accent-highlight); }
/* The ring follows each control's own corners (a button keeps its 6px); only a bare link is given soft ones. */
:focus-visible { outline: none; box-shadow: var(--focus); }
a:not([class]):focus-visible { border-radius: 3px; }

/* the (i) */
.info { display: inline-grid; place-items: center; width: 1.05rem; height: 1.05rem; flex: none;
  margin: 0 .15rem; padding: 0; border-radius: 50%; border: 1px solid var(--text-muted);
  background: transparent; color: var(--text-muted); font: italic 700 var(--fs-xs)/1 Georgia, serif;
  cursor: help; vertical-align: middle; transition: color .12s, border-color .12s, background .12s; }
.info:hover, .info:focus-visible { color: var(--bg); background: var(--accent-highlight); border-color: var(--accent-highlight); }
.ui-tip { position: fixed; z-index: 3000; max-width: 22rem; padding: .5rem .65rem; pointer-events: none;
  background: var(--surface-tooltip); color: var(--text-primary); border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  box-shadow: 0 8px 24px rgba(0,0,0,.45); font-size: .8rem; line-height: 1.45; white-space: pre-line; }

/* folding panels */
.panel { background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius);
  display: flex; flex-direction: column; min-height: 0; }
.panel-head { display: flex; align-items: center; gap: .35rem; padding: .35rem .5rem; min-height: 2rem;
  border-bottom: 1px solid var(--border); flex: none; }
.panel-title { color: var(--accent); font-size: var(--fs-xs); font-weight: 700; letter-spacing: .12em; text-transform: uppercase; }
.panel-head .panel-extra { margin-left: auto; display: flex; align-items: center; gap: .35rem; }
.panel-toggle { margin-left: auto; background: none; border: 0; color: var(--text-muted); cursor: pointer;
  width: 1.5rem; height: 1.5rem; border-radius: 4px; display: grid; place-items: center; font-size: .8rem; }
.panel-head .panel-extra + .panel-toggle { margin-left: .2rem; }
.panel-toggle:hover { color: var(--text-bright); background: var(--bg-elevated); }
.panel-toggle::before { content: "▾"; transition: transform .15s; }
.panel.is-collapsed > .panel-head .panel-toggle::before { transform: rotate(-90deg); }
.panel-body { padding: .5rem; overflow: auto; min-height: 0; flex: 1; }
.panel.is-collapsed { flex: none !important; }
.panel.is-collapsed > .panel-body { display: none; }
.panel.is-collapsed > .panel-head { border-bottom: 0; }

/* splitters */
.splitter { flex: none; position: relative; cursor: col-resize; touch-action: none; }
.splitter::after { content: ""; position: absolute; inset: 0 2px; border-radius: 2px; transition: background .12s; }
.splitter:hover::after, .splitter.is-dragging::after, .splitter:focus-visible::after { background: var(--accent); opacity: .6; }
.splitter[data-axis="y"] { cursor: row-resize; }
body.is-resizing { user-select: none; cursor: col-resize; }

/* dialogs */
dialog.ui-dialog { background: var(--bg-secondary); color: var(--text-primary); border: 1px solid var(--border);
  border-radius: 12px; padding: 0; width: min(46rem, calc(100vw - 2rem)); max-height: calc(100vh - 4rem);
  box-shadow: 0 24px 64px rgba(0,0,0,.6); }
dialog.ui-dialog::backdrop { background: rgba(5, 7, 12, .65); backdrop-filter: blur(2px); }
.dialog-head { display: flex; align-items: center; gap: .6rem; padding: 1rem 1.2rem .6rem; border-bottom: 1px solid var(--border); }
.dialog-head h2 { margin: 0; font-size: 1.1rem; }
.dialog-close { margin-left: auto; background: none; border: 0; color: var(--text-muted); font-size: 1.4rem; cursor: pointer; line-height: 1; }
.dialog-close:hover { color: var(--text-bright); }
.dialog-body { padding: 1rem 1.2rem 1.2rem; overflow: auto; }
.dialog-body h3 { color: var(--accent-highlight); font-size: .78rem; letter-spacing: .1em; text-transform: uppercase; margin: 1.1rem 0 .4rem; }
.dialog-body h3:first-child { margin-top: 0; }
.how-steps { margin: 0; padding: 0; list-style: none; display: grid; gap: .5rem; counter-reset: s; }
.how-steps li { counter-increment: s; display: grid; grid-template-columns: 1.7rem 1fr; gap: .6rem; align-items: start; }
.how-steps li::before { content: counter(s); width: 1.6rem; height: 1.6rem; border-radius: 50%; background: var(--accent);
  color: var(--on-accent); font-weight: 700; display: grid; place-items: center; font-size: .8rem; }
.keys { display: grid; grid-template-columns: max-content 1fr; gap: .3rem .9rem; font-size: .85rem; }
kbd { display: inline-block; min-width: 1.3rem; padding: .05rem .35rem; border: 1px solid var(--border-strong); border-bottom-width: 2px;
  border-radius: 4px; background: var(--bg-elevated); color: var(--text-bright); font: 600 .75rem var(--mono); text-align: center; }

/* the top line folds away: every layout reads --navbar-height, so zero gives the room back */
html.nav-hidden { --navbar-height: 0px; }
html.nav-hidden .navbar { display: none; }
.navbar-collapse { width: 1.7rem; height: 1.7rem; flex: none; padding: 0; border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: transparent; color: var(--text-muted); cursor: pointer; font-size: .8rem; line-height: 1; }
.navbar-collapse:hover { color: var(--accent-highlight); border-color: var(--accent-highlight); }
.nav-reveal { display: none; position: fixed; top: 0; left: 50%; transform: translateX(-50%); z-index: 1100;
  width: 2.6rem; height: .95rem; padding: 0; border: 1px solid var(--border); border-top: 0; border-radius: 0 0 6px 6px;
  background: var(--bg-elevated); color: var(--text-muted); cursor: pointer; font-size: var(--fs-2xs); line-height: 1; }
.nav-reveal:hover { color: var(--bg); background: var(--accent-highlight); }
html.nav-hidden .nav-reveal { display: block; }

/* navbar additions */
.navbar-link.is-on { color: var(--text-bright); }
.navbar-help { width: 1.9rem; height: 1.9rem; flex: none; padding: 0; border-radius: 50%; border: 1px solid var(--border); background: var(--bg-elevated);
  color: var(--text-secondary); cursor: pointer; font-weight: 700; }
.navbar-help:hover { color: var(--bg); background: var(--accent-highlight); border-color: var(--accent-highlight); }
.navbar-help[hidden] { display: none; }
@media (max-width: 1100px) { .navbar-sub { display: none; } }
@media (max-width: 960px) {
  .navbar-container, .navbar-menu { gap: .8rem; }
  .navbar-role { display: none; }
  .navbar-user { max-width: 8rem; }
}
/* A phone or a narrow window: the brand, the help, the menu button and the fold stay on the line; the rest is one tap away. */
@media (max-width: 760px) {
  .navbar-container { gap: .6rem; padding: 0 .8rem; }
  .navbar-menu-toggle { display: grid; }
  .navbar-menu { display: none; position: absolute; top: 100%; left: 0; right: 0; flex-direction: column; align-items: stretch; gap: 0;
    padding: .35rem 1rem .9rem; background: var(--bg-secondary); border-bottom: 1px solid var(--border);
    box-shadow: 0 18px 36px rgba(0, 0, 0, .5); max-height: calc(100vh - var(--navbar-height)); overflow-y: auto; }
  .navbar.is-open .navbar-menu { display: flex; }
  .navbar-menu .navbar-link { padding: .7rem .2rem; font-size: .95rem; border-bottom: 1px solid var(--border); }
  .navbar-menu .navbar-link.is-on { color: var(--accent-highlight); }
  .navbar-menu .navbar-user { max-width: none; padding: .7rem .2rem .5rem; }
  .navbar-menu .navbar-role { display: inline; }
  .navbar-menu .navbar-form .btn, .navbar-menu > .btn { width: 100%; padding: .55rem .8rem; text-align: center; margin-top: .35rem; }
  .main-content { padding-left: 1rem; padding-right: 1rem; }
  .hero h1 { font-size: 1.6rem; }
  .kv th { width: auto; }
}

/* modern form controls — one look for every page */
fieldset.field { border: 0; margin: 0; padding: 0; min-width: 0; }
fieldset.field > legend { padding: 0; margin-bottom: .35rem; }
.field { display: grid; gap: .3rem; min-width: 0; }
.field-row { display: flex; flex-wrap: wrap; gap: .8rem 1rem; align-items: end; }
.field-row > .field { flex: 1 1 12rem; }
.field-row > .field-narrow { flex: 0 1 9rem; }
.field-label { display: flex; align-items: center; gap: .2rem; color: var(--text-secondary); font-size: .8rem; font-weight: 600; }
.field-hint { color: var(--text-muted); font-size: .75rem; }
.input, .select, .field input[type="text"], .field input[type="number"], .field input:not([type]), .field select {
  width: 100%; min-width: 0; height: 2.3rem; padding: 0 .7rem; background: var(--bg); color: var(--text-primary);
  border: 1px solid var(--border-input); border-radius: 7px; font: inherit; font-size: .9rem; transition: border-color .12s; }
.field select, .select { appearance: none; padding-right: 2rem; cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, var(--text-muted) 50%), linear-gradient(135deg, var(--text-muted) 50%, transparent 50%);
  background-position: calc(100% - 15px) 50%, calc(100% - 10px) 50%; background-size: 5px 5px; background-repeat: no-repeat; }
.field input:hover, .field select:hover { border-color: var(--text-muted); }
.field input:focus, .field select:focus { border-color: var(--accent); outline: none; box-shadow: 0 0 0 3px var(--accent-soft); }
.segmented { justify-self: start; display: inline-flex; flex-wrap: wrap; gap: 2px; padding: 2px; background: var(--bg); border: 1px solid var(--border); border-radius: 8px; }
.segmented label { position: relative; }
.segmented input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.segmented span { display: block; padding: .35rem .8rem; border-radius: 6px; color: var(--text-secondary); font-size: .85rem; cursor: pointer; }
.segmented input:checked + span { background: var(--accent-soft); color: var(--text-bright); box-shadow: inset 0 0 0 1px var(--accent); }
.segmented input:focus-visible + span { box-shadow: var(--focus); }
.segmented input:disabled + span { opacity: .45; cursor: not-allowed; }
.switch { display: inline-flex; align-items: center; gap: .55rem; cursor: pointer; font-size: .88rem; color: var(--text-secondary); }
.switch input { appearance: none; width: 2.2rem; height: 1.25rem; border-radius: 1rem; background: var(--border-input); position: relative; cursor: pointer; transition: background .15s; margin: 0; }
.switch input::after { content: ""; position: absolute; top: 2px; left: 2px; width: calc(1.25rem - 4px); height: calc(1.25rem - 4px); border-radius: 50%; background: var(--text-bright); transition: transform .15s; }
.switch input:checked { background: var(--accent); }
.switch input:checked::after { transform: translateX(.95rem); }
/* a switch with its (i) beside it — the (i) stays outside the <label>, so it never becomes part of the switch's name */
.switch-row { display: flex; align-items: center; gap: .2rem; flex-wrap: wrap; }
.btn { transition: border-color .12s, background .12s, color .12s; }
.btn-primary:hover { background: var(--accent-highlight); border-color: var(--accent-highlight); }
.btn-lg { padding: .6rem 1.2rem; font-size: .95rem; border-radius: 8px; }
.btn[disabled] { opacity: .5; cursor: not-allowed; }
.badge { display: inline-flex; align-items: center; gap: .25rem; padding: .08rem .5rem; border-radius: 999px; font-size: .72rem;
  border: 1px solid var(--border); color: var(--text-secondary); background: var(--bg-elevated); white-space: nowrap; }
.badge-ok { color: var(--success); border-color: rgba(34,197,94,.4); background: rgba(34,197,94,.08); }
.badge-warn { color: var(--warning); border-color: rgba(245,158,11,.4); background: var(--accent-soft); }
.badge-no { color: var(--danger); border-color: rgba(239,68,68,.4); background: rgba(239,68,68,.08); }
.card { background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 12px; padding: 1.2rem 1.3rem; min-width: 0; }
.card-title { display: flex; align-items: center; gap: .4rem; font-size: 1.05rem; margin: 0 0 .9rem; }
.page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 1rem; flex-wrap: wrap; margin-bottom: 1rem; }
.page-head h1 { margin: 0; }
.page-head .lede { margin: .3rem 0 0; font-size: .95rem; }
.empty { text-align: center; color: var(--text-muted); padding: 2rem 1rem; border: 1px dashed var(--border); border-radius: 10px; }
.empty strong { display: block; color: var(--text-secondary); margin-bottom: .3rem; }
.hero-cta { display: flex; flex-wrap: wrap; gap: .6rem; margin: -.4rem 0 1.4rem; }
.badge-level { color: var(--accent-highlight); border-color: rgba(251,191,36,.35); background: var(--accent-soft); text-transform: none; }
.levels-card { display: grid; gap: 1rem; justify-items: start; }

/* The error pages (403, 404, 500): one card, what happened in words, and the way back. */
.error-page { max-width: 36rem; margin: 3rem auto; }
.error-code { color: var(--accent); font: 700 .8rem var(--mono); letter-spacing: .14em; text-transform: uppercase; }
.error-page h1 { margin: .35rem 0 .8rem; }
.error-page .explainer { margin: 0 0 1.2rem; }
.error-actions { display: flex; flex-wrap: wrap; gap: .6rem; }
.error-shell .navbar-container { justify-content: space-between; }

/* The landing headline: balanced lines, no forced break on a phone */
.hero h1 { text-wrap: balance; }
@media (max-width: 760px) { .hero h1 br { display: none; } }

/* The public footer (the landing page, the collector's page) — below the content, full width */
.site-footer { border-top: 1px solid var(--border); background: var(--bg-secondary); }
.site-footer-inner { max-width: 1040px; margin: 0 auto; padding: 1.1rem 1.25rem 1.6rem; display: flex; flex-wrap: wrap;
  gap: .4rem 1.4rem; justify-content: space-between; color: var(--text-muted); font-size: var(--fs-md); }

/* The collector's page (/robot/): four manners two by two, the robots.txt group, the contact form */
.steps-two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 560px) { .steps-two { grid-template-columns: minmax(0, 1fr); } }
code.ua { overflow-wrap: anywhere; color: var(--text-primary); }
.robot-ways { margin: 0; padding-left: 1.3rem; display: grid; gap: .7rem; max-width: 74ch; color: var(--text-secondary); }
.section-title[id] { scroll-margin-top: calc(var(--navbar-height) + 1rem); }   /* #stop, #contact: below the fixed top line */
.robot-ways > li { min-width: 0; }          /* a grid item: the snippet scrolls in it rather than widening the page */
.robot-ways strong { color: var(--text-bright); }
.snippet { margin: .45rem 0 .5rem; padding: .7rem .9rem; background: var(--bg-secondary); border: 1px solid var(--border);
  border-radius: var(--radius-sm); overflow-x: auto; }
.snippet code { color: var(--text-primary); font-size: .88rem; white-space: pre-wrap; overflow-wrap: anywhere; }   /* wraps on a phone: soft wraps are not copied */
.contact-card { max-width: 44rem; display: grid; gap: 1rem; }
.contact-card .alert { margin: 0; }
.contact-form { display: grid; gap: 1rem; }
.field input[type="email"] { width: 100%; min-width: 0; height: 2.3rem; padding: 0 .7rem; background: var(--bg);
  color: var(--text-primary); border: 1px solid var(--border-input); border-radius: 7px; font-size: .9rem; }
.field textarea { width: 100%; min-width: 0; min-height: 7.5rem; padding: .5rem .7rem; background: var(--bg);
  color: var(--text-primary); border: 1px solid var(--border-input); border-radius: 7px; font-size: .9rem;
  line-height: 1.5; resize: vertical; }
.field textarea:hover { border-color: var(--text-muted); }
.field textarea:focus { border-color: var(--accent); outline: none; box-shadow: 0 0 0 3px var(--accent-soft); }
.field .errorlist { margin: 0; }
.hp { position: absolute; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden; }
.privacy { border-top: 1px solid var(--border); padding-top: .9rem; color: var(--text-secondary); font-size: var(--fs-md); }
.privacy p:last-child { margin-bottom: 0; }

/* « Quit game » (propriétaire, 6 oct. 2026) : dans une partie, la barre du haut n'offre plus de destination qui en
   sorte d'un clic — le propriétaire a quitté une partie en cliquant « Games », et rien ne l'y ramenait. Un seul bouton,
   explicite, posé près du compte et de « Sign out ». */
.navbar-quit { margin-left: auto; }

/* Les TROIS niveaux dans la barre du haut (propriétaire, 11 oct. 2026) : « un drop down qui mentionne tactique,
   opératif », étendu au stratégique. Un `details` : le seul menu déroulant qui s'ouvre sans script. Sans cette
   feuille il resterait utilisable — un triangle, trois lignes dessous —, elle ne fait que le poser au-dessus de la
   page au lieu de pousser la barre, et distinguer les trois états : où l'on est, où l'on peut aller, et ce qui
   n'est pas construit. Ce menu est projeté à la séance du CPCO : il doit se lire de loin. */
.navbar-level { position: relative; flex: none; }
.navbar-level > summary { list-style: none; cursor: pointer; white-space: nowrap; font-size: .88rem;
  color: var(--text-secondary); padding: .3rem .6rem; border: 1px solid var(--border);
  border-radius: var(--radius-sm); background: var(--bg-elevated); }
.navbar-level > summary::-webkit-details-marker { display: none; }
.navbar-level > summary:hover, .navbar-level[open] > summary { color: var(--accent-highlight); border-color: var(--accent-highlight); }
.navbar-level-menu { position: absolute; top: calc(100% + .35rem); right: 0; z-index: 1001; display: flex;
  flex-direction: column; gap: .15rem; min-width: 15rem; padding: .35rem; background: var(--bg-secondary);
  border: 1px solid var(--border); border-radius: var(--radius-sm); box-shadow: 0 14px 28px rgba(0, 0, 0, .5); }
.navbar-level-row { display: grid; grid-template-columns: auto 1fr; gap: 0 .5rem; padding: .4rem .55rem;
  color: var(--text-secondary); border-radius: var(--radius-sm); border-left: 2px solid transparent; }
.navbar-level-row .lvl-name { font-size: .9rem; color: var(--text-bright); white-space: nowrap; }
.navbar-level-row .lvl-scale { font-size: var(--fs-md); color: var(--text-muted); text-align: right; white-space: nowrap; align-self: baseline; }
.navbar-level-row .lvl-why { grid-column: 1 / -1; font-size: var(--fs-2xs); color: var(--text-muted); }
a.navbar-level-row:hover { background: var(--bg-elevated); border-left-color: var(--accent-highlight); text-decoration: none; }
a.navbar-level-row:hover .lvl-name { color: var(--accent-highlight); }
/* Un monde à trois niveaux (19 oct. 2026) : changer de niveau est un envoi — un bouton qui se lit comme les liens. */
.navbar-level-form { margin: 0; }
button.navbar-level-row { width: 100%; background: none; border-top: 0; border-right: 0; border-bottom: 0;
  font: inherit; text-align: left; cursor: pointer; }
button.navbar-level-row:hover { background: var(--bg-elevated); border-left-color: var(--accent-highlight); }
/* N6 (plans/A1_TROIS_NIVEAUX.md §11) : les niveaux que le siège TIENT — le système joue les autres */
.navbar-held { display: flex; flex-wrap: wrap; gap: .3rem .7rem; align-items: center; padding: .45rem .55rem;
  border-top: 1px solid var(--border); }
.navbar-held .lvl-why { flex-basis: 100%; font-size: var(--fs-2xs); color: var(--text-muted); }
.navbar-held-row { font-size: var(--fs-xs); color: var(--text-secondary); white-space: nowrap; }
button.navbar-level-row:hover .lvl-name { color: var(--accent-highlight); }
.navbar-level-row.is-on { background: var(--bg-elevated); border-left-color: var(--accent-highlight); }
/* Non construit : gris, et son mot dessous. Il ne mène nulle part — ce n'est pas un lien, donc rien à désactiver. */
.navbar-level-row.is-off { cursor: not-allowed; }
.navbar-level-row.is-off .lvl-name { color: var(--text-muted); }
/* Sur un téléphone la barre est déjà un volet déplié : le menu s'y pose dans le flux, sans ombre ni position. */
@media (max-width: 760px) {
  .navbar-level, .navbar-level > summary { width: 100%; text-align: center; }
  .navbar-level-menu { position: static; min-width: 0; box-shadow: none; margin-top: .35rem; }
  .navbar-level-row { text-align: left; }
}
/* Le menu « Projects » (24 oct. 2026) : la même mise en page que le menu des niveaux, sous ses propres noms. */
.navbar-projects { position: relative; flex: none; }
.navbar-projects > summary { list-style: none; cursor: pointer; white-space: nowrap; font-size: .88rem;
  color: var(--text-secondary); padding: .3rem .6rem; border: 1px solid var(--border);
  border-radius: var(--radius-sm); background: var(--bg-elevated); }
.navbar-projects > summary::-webkit-details-marker { display: none; }
.navbar-projects > summary:hover, .navbar-projects[open] > summary { color: var(--accent-highlight); border-color: var(--accent-highlight); }
.navbar-projects-menu { position: absolute; top: calc(100% + .35rem); right: 0; z-index: 1001; display: flex;
  flex-direction: column; gap: .15rem; min-width: 15rem; padding: .35rem; background: var(--bg-secondary);
  border: 1px solid var(--border); border-radius: var(--radius-sm); box-shadow: 0 14px 28px rgba(0, 0, 0, .5); }
.navbar-projects-row { display: grid; grid-template-columns: auto 1fr; gap: 0 .5rem; padding: .4rem .55rem;
  color: var(--text-secondary); border-radius: var(--radius-sm); border-left: 2px solid transparent; }
.navbar-projects-row .lvl-name { font-size: .9rem; color: var(--text-bright); white-space: nowrap; }
.navbar-projects-row .lvl-scale { font-size: var(--fs-md); color: var(--text-muted); text-align: right; white-space: nowrap; align-self: baseline; }
.navbar-projects-row .lvl-why { grid-column: 1 / -1; font-size: var(--fs-2xs); color: var(--text-muted); }
a.navbar-projects-row:hover { background: var(--bg-elevated); border-left-color: var(--accent-highlight); text-decoration: none; }
a.navbar-projects-row:hover .lvl-name { color: var(--accent-highlight); }
.navbar-projects-row.is-on { background: var(--bg-elevated); border-left-color: var(--accent-highlight); }
.navbar-projects-row.is-off { cursor: not-allowed; }
.navbar-projects-row.is-off .lvl-name { color: var(--text-muted); }
@media (max-width: 760px) {
  .navbar-projects, .navbar-projects > summary { width: 100%; text-align: center; }
  .navbar-projects-menu { position: static; min-width: 0; box-shadow: none; margin-top: .35rem; }
  .navbar-projects-row { text-align: left; }
}

/* « In development » — la balise d'une place réservée (propriétaire, 17 oct. 2026 : faire tester l'UX sans frustrer) :
   un liseré en tirets, la couleur d'avertissement, focalisable ; sa bulle dit ce qui est enregistré et ce qui ne l'est
   pas encore. La bannière la reprend en tête d'une page qui en porte plusieurs. */
.wip-badge { display: inline-flex; align-items: center; gap: .25rem; margin: 0 .35rem; padding: .05rem .45rem;
  border: 1px dashed var(--warning); border-radius: 999px; color: var(--warning); font-size: var(--fs-xs);
  font-weight: 600; letter-spacing: .02em; text-transform: uppercase; white-space: nowrap; vertical-align: middle;
  cursor: help; }
.wip-badge::before { content: "\25B2"; font-size: .7em; }
.wip-badge:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.wip-banner { display: flex; align-items: flex-start; gap: .5rem; margin: .5rem 0 1rem; padding: .55rem .8rem;
  border: 1px dashed var(--warning); border-radius: var(--radius-sm); color: var(--text-secondary);
  font-size: var(--fs-sm); }

/* L'icône-bouton et les tuiles d'état (24 oct. 2026, « 00 - PROMPTS/PROMPT_HTMX_STYLE.md » §1 et §7) : un geste répété sur
   chaque ligne devient une icône (glyphe aria-hidden + nom .sr-only + infobulle), l'état d'un panneau une rangée de tuiles */
.ux-ico { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 1.75rem; height: 1.75rem;
  padding: 0; cursor: pointer; list-style: none; font: inherit; line-height: 1; color: var(--text-secondary);
  background: var(--bg-secondary); border: 1px solid var(--border-strong); border-radius: var(--radius-sm); }
.ux-ico::-webkit-details-marker { display: none; }
.ux-ico:hover, details[open] > .ux-ico { color: var(--text-bright); border-color: var(--accent); background: var(--accent-soft); }
.ux-ico:focus-visible { outline: none; box-shadow: var(--focus); }
.ux-ico-add { color: var(--success); }
.ux-ico-danger { color: var(--danger-text); }
.ux-ico-danger:hover { color: var(--danger-text); border-color: var(--danger); background: var(--bg-elevated); }
.ux-tiles { display: flex; flex-wrap: wrap; gap: .5rem; margin: 0 0 .75rem; }
.ux-tile { display: flex; flex-direction: column; gap: .15rem; min-width: 8.5rem; padding: .45rem .7rem;
  background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius); }
.ux-tile-k { font-size: var(--fs-xs); color: var(--text-secondary); text-transform: uppercase; letter-spacing: .04em; }
.ux-tile-v { font-size: 1.2rem; font-weight: 600; color: var(--text-bright); display: flex; flex-wrap: wrap; align-items: center; gap: .3rem; }
.ux-of { font-size: var(--fs-sm); font-weight: 400; color: var(--text-muted); }

/* ---- les ajouts du plan (aesop_arena_plan, P0) ------------------------------------------------------------------
   La barre porte des GROUPES (Analysis, Library) : un <details> sur le modèle du menu des niveaux du jeu
   (.navbar-level), sans script. Une entrée non bâtie porte « dev » (.navbar-dev). La bannière DCS (.dcs-banner) ne
   paraît qu'au-dessus de PUBLIC — jamais en v1. */
.navbar-group > summary { color: var(--text-secondary); font-size: .88rem; }
.navbar-dev { color: var(--text-muted); font-size: var(--fs-2xs); letter-spacing: .06em; text-transform: uppercase;
  border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 0 .25rem; margin-left: .15rem; }
.dcs-banner { background: var(--bg-elevated); color: var(--text-bright); text-align: center; font-size: var(--fs-sm);
  font-weight: 700; letter-spacing: .08em; padding: .15rem .5rem; border-bottom: 1px solid var(--border); }

/* Q0, le parcours au navigateur (24 oct. 2026) : à 390 px, une table de chiffres trop large faisait défiler la page
   entière (la frise du cas : 596 px pour 390). Chaque .data-table d'un gabarit est désormais dans un .table-wrap
   (tests/guards/test_table_wrap.py), qui défile en elle-même ; la table garde sa sémantique. L'enveloppe est
   positionnée : un .sr-only (absolu) d'une cellule restait sinon hors d'elle, et la page défilait encore (la scène :
   643 px pour 390). */
.table-wrap { position: relative; }
@media (max-width: 760px) {
  .table-wrap { overflow-x: auto; max-width: 100%; }
}

/* Q15 (spec §22) — l'opération courante : le menu « Operation ▾ » de la barre (le modèle .navbar-level, ouvert vers
   la droite puisqu'il est le premier de la barre), le choix posé dans une page, et le bandeau d'un autre cas. Le titre
   courant se coupe d'une ellipse : la barre ne s'élargit jamais avec lui, et 390 px ne défile pas. */
.navbar-operation > summary { display: inline-flex; align-items: baseline; gap: .35rem; max-width: 13rem; }
@media (max-width: 1500px) { .navbar-sub { display: none; } }   /* la barre cède le sous-titre au menu de l'opération */
.navbar-operation > summary .op-k { color: var(--text-muted); font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: .05em; }
.navbar-operation > summary .op-v { min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--text-bright); }
.navbar-operation.is-on > summary { border-color: var(--accent-highlight); }
.navbar-operation-menu { left: 0; right: auto; min-width: 20rem; max-width: min(28rem, calc(100vw - 2rem));
  max-height: calc(100vh - var(--navbar-height) - 2rem); overflow-y: auto; }
.operation-row .lvl-name { white-space: normal; overflow-wrap: anywhere; }
.operation-fell { margin: 0 0 .3rem; padding: .4rem .55rem; border: 1px dashed var(--warning); border-radius: var(--radius-sm);
  color: var(--text-secondary); font-size: var(--fs-xs); }
.operation-none { margin: .2rem .55rem; color: var(--text-muted); font-size: var(--fs-xs); }
.operation-picker { margin: 0 0 1.2rem; }
.operation-picker .section-title { margin-top: 0; overflow-wrap: anywhere; }
.operation-picker-rows { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 19rem), 1fr)); gap: .3rem; }
.operation-picker-rows .operation-row { border: 1px solid var(--border); }
.operation-picker-new { margin: .7rem 0 0; display: flex; flex-wrap: wrap; gap: .5rem; }
.operation-banner { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .5rem 1rem;
  margin: 0 0 1rem; padding: .5rem .8rem; border: 1px dashed var(--accent); border-radius: var(--radius-sm);
  background: var(--accent-soft); color: var(--text-secondary); font-size: var(--fs-sm); overflow-wrap: anywhere; }
.operation-banner form, .operation-open { margin: 0; }
.operation-open { display: inline; }
@media (width < 1280px) { .navbar-operation > summary { max-width: 11rem; } .navbar-operation > summary .op-k { display: none; } }
@media (max-width: 760px) {
  .navbar-operation > summary { max-width: none; justify-content: center; }
  .navbar-operation > summary .op-k { display: inline; }
  .navbar-operation-menu { min-width: 0; max-width: none; max-height: none; }
}
/* Q25 (spec §32.3) — le menu du compte : le dernier de la barre, il s'ouvre aligné sur la droite (le .navbar-level-menu
   du jeu) et ne dépasse jamais la fenêtre — une adresse longue se coupe. Sous 760 px, il se replie sous ☰ comme les
   autres (le modèle .navbar-level). */
.navbar-account > summary .navbar-user { display: inline-block; vertical-align: bottom; color: var(--text-bright); }
.navbar-account.is-on > summary { border-color: var(--accent-highlight); }
.navbar-account-menu { max-width: min(22rem, calc(100vw - 2rem)); }
.navbar-account-email { margin: 0 0 .2rem; padding: .3rem .55rem .4rem; border-bottom: 1px solid var(--border);
  color: var(--text-muted); font-size: var(--fs-xs); overflow-wrap: anywhere; }
@media (max-width: 760px) {
  .navbar-menu .navbar-account > summary .navbar-user { padding: 0; }
  .navbar-account-menu { max-width: none; }
}
/* L'accueil (Q25, §32.1) : les cartes Today et Reserved tiennent une liste, une ligne par pan. */
.step-lines { margin: .2rem 0 0; padding-left: 1.1rem; }
.step-lines > li + li { margin-top: .3rem; }

/* Les onglets d'une page (26 oct. 2026 : l'environnement, les considérations) — [data-tabs], app_home/js/tabs.js.
   Sans JS, les panneaux sont empilés et la bande est une table des ancres ; le script pose .is-tabbed. À 390 px, la
   bande passe à la ligne : la page ne défile jamais de côté. Le dessin est celui du volet Actions du jeu (.coa-at-*). */
.tabs { margin-top: 1rem; min-width: 0; }
.tab-strip { display: flex; flex-wrap: wrap; gap: .25rem; border-bottom: 1px solid var(--border-strong); margin-bottom: .6rem; }
.tab { display: inline-flex; align-items: center; gap: .35rem; max-width: 100%; padding: .4rem .7rem; margin-bottom: -1px;
  border: 1px solid transparent; border-bottom: 2px solid transparent; border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  color: var(--text-secondary); text-decoration: none; font-size: var(--fs-md); }
.tab:hover, .tab:focus { color: var(--text-primary); background: var(--bg-secondary); text-decoration: none; }
.tab:focus-visible { outline: none; box-shadow: var(--focus); }
.tabs.is-tabbed .tab[aria-selected="true"] { color: var(--text-bright); border-color: var(--border-strong);
  border-bottom-color: var(--accent); background: var(--accent-soft); font-weight: 600; }
.tab-n { padding: 0 .4rem; border-radius: 999px; font-size: var(--fs-xs); font-weight: 400; white-space: nowrap;
  border: 1px solid var(--border-strong); color: var(--text-secondary); background: var(--bg-elevated); }
.tab-panel { min-width: 0; }
/* Q24 (spec §31) — une bande qui ne passe jamais à la ligne : [data-strip-scroll] tient sur une ligne et défile de côté
   dans sa propre bande quand elle déborde (la page, jamais) ; app_plan/case.js y ramène en vue l'élément ouvert. */
[data-strip-scroll] { display: flex; flex-wrap: nowrap; overflow: auto hidden; overscroll-behavior-x: contain;
  scrollbar-width: thin; -webkit-overflow-scrolling: touch; min-width: 0; padding-top: 3px; position: relative; }
[data-strip-scroll] > * { flex: none; white-space: nowrap; }
[data-strip-scroll] { gap: .15rem; }
[data-strip-scroll] > .tab { margin-bottom: 0; padding-inline: .5rem; }   /* rien sous la bande (pas un pixel de trop en hauteur), un pas plus serré */
/* relecture Fable : une bande qui défile rogne l'anneau extérieur — dedans, l'anneau est intérieur (WCAG 2.4.7) */
[data-strip-scroll] .tab:focus-visible, [data-strip-scroll] > a:focus-visible, [data-strip-scroll] > button:focus-visible
  { outline: none; box-shadow: inset 0 0 0 2px var(--accent); }
.tab-panel:focus-visible { outline: none; box-shadow: var(--focus); border-radius: var(--radius-sm); }
.tab-panel + .tab-panel { margin-top: 1.2rem; }
.tabs.is-tabbed .tab-panel + .tab-panel { margin-top: 0; }

/* — Q17 (spec §24.5) — le genre d'une conclusion : un badge par code, une couleur par famille, le code toujours écrit
   (la couleur n'est jamais seule porteuse). La page des facteurs et celle de la traçabilité le lisent. Le texte est la
   couleur de la famille sur une teinte d'elle-même : ≥ 4.5:1 sur --bg, --bg-secondary et --bg-elevated. */
.kb-action, .fam-action { --fam: var(--path); }
.kb-frame, .fam-frame { --fam: var(--warning); }
.kb-risk, .fam-risk { --fam: var(--danger-text); }
.kb-intel, .fam-intel { --fam: var(--info); }
.kb-cc, .fam-cc { --fam: var(--energy-nuclear); }
.kbadge { display: inline-block; min-width: 2.6em; text-align: center; padding: .05rem .4rem; border-radius: var(--radius-sm);
  font-family: var(--mono); font-size: var(--fs-xs); font-weight: 700; letter-spacing: .04em; line-height: 1.5;
  color: var(--fam, var(--text-secondary)); border: 1px solid color-mix(in srgb, var(--fam, var(--border)) 55%, transparent);
  background: color-mix(in srgb, var(--fam, var(--bg-elevated)) 12%, transparent); white-space: nowrap; }

/* ---- Q28 (spec §35) — deux thèmes, sombre et clair ---------------------------------------------------------------
   Le sombre reste le défaut et ne change pas : les jetons du :root en haut de ce fichier (la copie du jeu). Le CLAIR
   redéfinit ici chaque jeton de couleur de ce :root, sous :root[data-theme="light"] — <html data-theme> est écrit par
   le serveur (app_home/theme.py), sans script. Une feuille d'application ne porte aucune couleur littérale
   (tests/guards/test_no_colour_literal.py) : elle lit ces jetons, et suit le thème d'elle-même.
   Le contraste (tools/contrast.py, rejouable ; test_q28_theme.py le joue) : AA dans les deux thèmes — 4,5:1 pour un
   texte sur chaque surface, 3:1 pour le bord d'un champ et l'anneau du focus. Le cyan est assombri (cyan 700 / 800)
   pour se lire sur le blanc ; les états passent à leurs teintes 600–800, qui se lisent en texte. Les tuiles OSM ne
   changent pas ; l'impression (print.css) reste claire. */
:root[data-theme="light"] {
  color-scheme: light;
  /* Q33 (§40.6) — les jetons du schéma au clair : les valeurs claires du prompt de style. */
  --band-1: #A1267F; --band-2: #A1267F; --band-3a: #1668B5; --band-3b: #1668B5; --band-4a: #0C8F6C; --band-4b: #0C8F6C;
  --band-res: #5B6770; --flow-down: #007FA6; --flow-up: #B84A1E;
  --prov-measured: #2E7D4F; --prov-estimated: #4F5DB8; --prov-illustrative: #A9620A; --prov-empty: #67767E;
  /* Q28 — les trois tons adverses de la carte (Q10) au clair : le plus probable en rouge sang sombre, les autres en rose
     grisé ; le plus dangereux reste --danger. Sur --map-bg : MD 4.67, ML 10.2, autre 3.21 ; entre eux : MD/ML 2.19,
     MD/autre 1.45, ML/autre 3.18 (les seuils de test_map_dashes : 3, 1.9, 1.35, 2.5). */
  --opp-ml: #6b0a0a;
  --opp-other: #ad6f78;
  --bg: #f3f5f8;
  --bg-secondary: #ffffff;
  --bg-elevated: #e9edf2;
  --surface-tooltip: #ffffff;
  --map-bg: #e4e8ee;
  --border: #d3d9e2;
  --border-strong: #aab3c1;
  --border-input: #7a8394;
  --text-primary: #1b2130;
  --text-secondary: #374051;
  --text-muted: #545d6f;
  --text-bright: #0a0e16;
  --on-accent: #ffffff;
  --accent: #0e7490;
  --accent-highlight: #155e75;
  --accent-soft: rgba(14, 116, 144, 0.10);
  --success: #166534;
  --warning: #9a3f07;
  --danger: #c81e1e;
  --danger-text: #991b1b;
  --info: #075985;
  --path: #3f6212;
  --energy-nuclear: #6d28d9;
  --energy-coal: #475569;
  --energy-hydro: #0369a1;
  --energy-solar: #a16207;
  --energy-wind: #15803d;
  --digital: #a21caf;
  --row-highlight: #dcf0f5;
  --row-good: #e0f1e5;
  --pending: #e0530a;
}
/* --pending : l'état « pas encore atteint » du graphe des étapes (/cases/#cases-process, app_plan/plan.css) — une
   boîte, son bord, son signe, la pastille de la légende ; jamais un texte. Dans le sombre, l'ambre des états, inchangé ;
   dans le clair, un orange vif (#e0530a, à un pas d'orange 600 ; le propriétaire, 31 oct. 2026) : l'ambre de texte
   (--warning, assombri pour 4,5:1) y virait au brun. Un symbole et un bord : 3:1 contre la page et une carte
   (tools/contrast.py) — d'où, dans le clair, une boîte en attente survolée qui reste à 12 % (à 30 %, le signe orange
   sur sa propre teinte tombait à 2,3:1) et marque le survol par son bord plein. */
:root { --pending: var(--warning); }
:root[data-theme="light"] .pm-box.is-pending:hover .pm-bg { fill-opacity: .12; stroke-opacity: 1; }
/* Les littéraux du haut (la copie du jeu, qu'on ne touche pas) : les mêmes teintes, en mélanges de jetons. Dans le
   sombre, color-mix(--success 50 %, transparent) EST rgba(34, 197, 94, .5) : rien n'y change ; dans le clair, la teinte
   suit le jeton. */
.message-success { border-color: color-mix(in srgb, var(--success) 50%, transparent); }
.message-warning { border-color: color-mix(in srgb, var(--warning) 50%, transparent); }
.message-error { border-color: color-mix(in srgb, var(--danger) 50%, transparent); }
.badge-ok { border-color: color-mix(in srgb, var(--success) 40%, transparent);
  background: color-mix(in srgb, var(--success) 8%, transparent); }
.badge-warn { border-color: color-mix(in srgb, var(--warning) 40%, transparent); }
.badge-no { border-color: color-mix(in srgb, var(--danger) 40%, transparent);
  background: color-mix(in srgb, var(--danger) 8%, transparent); }
/* Le clair seul : le bord ambré du badge de niveau (un reste du jeu) prend l'accent, et les ombres — noires à 45–60 %
   sur le sombre — s'allègent sur le blanc ; le voile d'une modale aussi. */
:root[data-theme="light"] .badge-level { border-color: color-mix(in srgb, var(--accent) 35%, transparent); }
:root[data-theme="light"] .ui-tip { box-shadow: 0 8px 24px color-mix(in srgb, var(--text-bright) 16%, transparent); }
:root[data-theme="light"] dialog.ui-dialog { box-shadow: 0 24px 64px color-mix(in srgb, var(--text-bright) 22%, transparent); }
:root[data-theme="light"] dialog.ui-dialog::backdrop { background: color-mix(in srgb, var(--text-bright) 40%, transparent); }
:root[data-theme="light"] .navbar-level-menu,
:root[data-theme="light"] .navbar-projects-menu { box-shadow: 0 14px 28px color-mix(in srgb, var(--text-bright) 14%, transparent); }
@media (max-width: 760px) {
  :root[data-theme="light"] .navbar-menu { box-shadow: 0 18px 36px color-mix(in srgb, var(--text-bright) 14%, transparent); }
  :root[data-theme="light"] .navbar-level-menu, :root[data-theme="light"] .navbar-projects-menu { box-shadow: none; }
}

/* L'interrupteur de la barre (§35.2) : un bouton rond comme l'aide (?), hors du menu replié — à côté de ☰ sous 760 px. */
.navbar-theme-form { flex: none; display: flex; }
.navbar-theme { width: 1.9rem; height: 1.9rem; flex: none; padding: 0; display: grid; place-items: center;
  border-radius: 50%; border: 1px solid var(--border-input); background: var(--bg-elevated); color: var(--text-secondary);
  cursor: pointer; font-size: 1rem; line-height: 1; }
.navbar-theme:hover { color: var(--accent-highlight); border-color: var(--accent-highlight); }

/* La barre tient à chaque largeur (Q28, mesuré par l'étape « navbar » de tools/browser_walk.py). Connecté, la ligne
   entière demande ~1 400 px (la marque, Operation ▾ et le titre du cas, Analysis ▾, cinq liens, Library ▾, Chat,
   Diodote chat, le compte, ☀, ?, ▴) : à 1 024 px, le menu se tassait sous l'aide et « Diodote chat » passait sous un
   bouton, le compte coupé au bord droit — sans défilement, la barre étant fixe. Donc :
   - de 1 280 à 1 500 px, la ligne se resserre : des écarts plus courts, le rôle tu (il reste dans le menu replié), le
     nom du compte borné ;
   - sous 1 280 px, le menu passe sous ☰ — le patron des 760 px du haut (la copie du jeu), repris ici jusqu'à 1 279 px,
     en volet aligné à droite sous ☰ plutôt qu'en pleine largeur. La marque, ☀, ?, ▴ et ☰ restent sur la ligne.
   Anonyme, la ligne (« Sign in », « Create an account ») tient partout au-dessus de 760 px : le repli de 761 à 1 279 px
   ne vaut que pour une personne connectée (.navbar[data-signed-in], navbar.html). Les bornes sont écrites en intervalles
   (width < 1280px, width >= 1280px) : une largeur fractionnaire (un zoom) tombe toujours dans l'une des deux branches. */
/* Le menu ne se tasse jamais sous ses voisins : c'est le sous-titre (coupé d'une ellipse) qui cède la place — à 1 501 px,
   le menu tassé passait de 8 px sous ☀. */
@media (width >= 1280px) { .navbar-menu { flex-shrink: 0; } }
@media (1280px <= width <= 1500px) {
  .navbar-container, .navbar-menu { gap: .75rem; }
  .navbar-account .navbar-role { display: none; }
  .navbar-account > summary .navbar-user { max-width: 8rem; }
}
/* de 1 280 à 1 365 px, le titre de l'opération se coupe plus tôt (et son mot « Operation » se tait) : la ligne garde
   ~120 px de marge (l'aide ?, la pastille du chat, un nom long) — mesuré à 1 280 px, 94 px de marge avant cette règle */
@media (1280px <= width < 1366px) {
  .navbar-operation > summary { max-width: 9rem; }
  .navbar-operation > summary .op-k { display: none; }
}
@media (760px < width < 1280px) {
  .navbar[data-signed-in] .navbar-container { gap: .8rem; }
  .navbar[data-signed-in] .navbar-menu-toggle { display: grid; }
  .navbar[data-signed-in] .navbar-menu { display: none; position: absolute; top: 100%; right: 0; left: auto;
    width: min(24rem, 100vw); flex-direction: column; align-items: stretch; gap: 0; padding: .35rem 1rem .9rem;
    background: var(--bg-secondary); border: 1px solid var(--border); border-top: 0; border-radius: 0 0 0 var(--radius);
    box-shadow: 0 18px 36px color-mix(in srgb, var(--bg) 70%, transparent);
    max-height: calc(100vh - var(--navbar-height)); overflow-y: auto; }
  :root[data-theme="light"] .navbar[data-signed-in] .navbar-menu {
    box-shadow: 0 18px 36px color-mix(in srgb, var(--text-bright) 14%, transparent); }
  .navbar[data-signed-in].is-open .navbar-menu { display: flex; }
  .navbar[data-signed-in] .navbar-menu .navbar-link { padding: .7rem .2rem; font-size: .95rem; border-bottom: 1px solid var(--border); }
  .navbar[data-signed-in] .navbar-menu .navbar-link.is-on { color: var(--accent-highlight); }
  .navbar[data-signed-in] .navbar-menu .navbar-user { max-width: none; }
  .navbar[data-signed-in] .navbar-menu .navbar-role { display: inline; }
  .navbar[data-signed-in] .navbar-menu .navbar-level, .navbar[data-signed-in] .navbar-menu .navbar-level > summary { width: 100%;
    text-align: center; }
  .navbar[data-signed-in] .navbar-menu .navbar-level-menu { position: static; min-width: 0; max-width: none; max-height: none;
    box-shadow: none; margin-top: .35rem; }
  .navbar[data-signed-in] .navbar-menu .navbar-level-row { text-align: left; }
  .navbar[data-signed-in] .navbar-menu .navbar-level + .navbar-level,
  .navbar[data-signed-in] .navbar-menu .navbar-link + .navbar-level { margin-top: .35rem; }
  .navbar[data-signed-in] .navbar-menu .navbar-operation > summary { max-width: none; justify-content: center; }
  .navbar[data-signed-in] .navbar-menu .navbar-operation > summary .op-k { display: inline; }
}
