/* Portfolio Tester — global stylesheet */

/* 6.71 — Réserver en permanence la gouttière de scrollbar verticale → la
   largeur de viewport disponible est constante, page longue (scroll) ou courte
   (pas de scroll). Sans ça, le contenu centré se recentrait dans une largeur
   qui variait de ~15px selon la présence de la barre → glissement horizontal
   du bord gauche en navigation. `stable` (et non `overflow-y:scroll`) ne pose
   pas de barre grise inutile sur les pages courtes. */
html { scrollbar-gutter: stable; }

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  max-width: 860px;
  margin: 2rem auto;
  padding: 0 1rem;
  color: #222;
  line-height: 1.4;
}

h1 { font-size: 1.5rem; margin: 0 0 1.5rem 0; }
h2 { font-size: 1.1rem; margin: 2rem 0 0.75rem 0; color: #333; border-bottom: 1px solid #ddd; padding-bottom: 0.25rem; }

/* shared site nav rules removed in 6.65 — superseded by .pt-site / .pt-app
   header.site-nav skins (6.60/6.64) ; the old flat nav.site-nav markup no
   longer exists in any page, so these globals matched nothing. */

/* --- form fields (used by xsl/form.xsl) --- */
.field { margin-bottom: 1rem; display: flex; flex-direction: column; }
.field label { font-weight: 600; margin-bottom: 0.25rem; font-size: 0.9rem; }
.field select, .field input {
  padding: 0.45rem 0.5rem;
  font-size: 1rem;
  border: 1px solid #bbb;
  border-radius: 3px;
  background: #fff;
}
.field select:focus, .field input:focus {
  outline: none; border-color: #4a90e2;
}

/* Étape 6.34.3 : masquage des champs gérés en interne par le pipeline
   composite (portfolio-70-30). Appliqué par form.xsl::applyUniverse
   quand UNIVERSES[key].composite est vrai. Le backend ignore de toute
   façon les valeurs POSTées de ces champs en mode composite — le
   masquage UI est cosmétique mais indispensable pour la lisibilité. */
.hidden-for-composite { display: none !important; }

/* 7.152 : lien d'aide contextuel « ? » → paragraphe du Guide. Exposant discret,
   couleur atténuée, soulignement au survol SEULEMENT. Aucune dépendance JS
   (bulle = attribut title natif). */
.help-link {
  font-size: 0.62em; vertical-align: super; margin-left: 0.25em;
  color: var(--pt-muted, #6B665C); text-decoration: none; font-weight: 600;
}
.help-link:hover, .help-link:focus-visible { color: var(--pt-accent, #1B5E54); text-decoration: underline; }

/* 7.153 : widget « PMP multidevise » (cost-basis.js). Styles scoped sous
   #cost-basis-widget / .cb-* ; palette --pt-*. Aucun impact hors page outil. */
#cost-basis-widget { margin: 0 0 1.5rem; }
.cb-fallback { padding: 14px 16px; background: var(--pt-tint, #EDF3F0);
  border: 1px solid var(--pt-hair, #E7E1D4); border-radius: 6px; color: var(--pt-soft, #43423D); }
.cb-toolbar { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 12px; }
.cb-btn { font: inherit; font-size: 14px; font-weight: 600; cursor: pointer;
  padding: 7px 14px; border-radius: 6px; border: 1px solid var(--pt-hair, #E7E1D4);
  background: var(--pt-card, #fff); color: var(--pt-soft, #43423D); }
.cb-btn:hover { border-color: var(--pt-accent, #1B5E54); color: var(--pt-accent-dk, #123F38); }
.cb-btn:focus-visible { outline: 2px solid var(--pt-accent, #1B5E54); outline-offset: 1px; }
.cb-btn-primary { background: var(--pt-accent, #1B5E54); color: #fff; border-color: var(--pt-accent, #1B5E54); }
.cb-btn-primary:hover { background: var(--pt-accent-dk, #123F38); color: #fff; }
.cb-btn-danger:hover { border-color: var(--pt-neg, #B14A33); color: var(--pt-neg, #B14A33); }
.cb-note { margin: 0 0 12px; font-size: 13px; color: var(--pt-muted, #6B665C); font-style: italic; }
.cb-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.cb-table th { text-align: left; font-size: 12px; font-weight: 600; color: var(--pt-muted, #6B665C);
  padding: 6px 8px; border-bottom: 1px solid var(--pt-rule, #D8CFBB); white-space: nowrap; }
.cb-table td { padding: 4px 8px; border-bottom: 1px solid var(--pt-hair, #E7E1D4); vertical-align: middle; }
.cb-table input, .cb-table select { font: inherit; font-size: 14px; padding: 5px 6px;
  border: 1px solid var(--pt-hair, #E7E1D4); border-radius: 4px; background: var(--pt-card, #fff);
  color: var(--pt-ink, #1A1916); width: 100%; box-sizing: border-box; }
.cb-table input[type="number"] { max-width: 90px; }
.cb-table input[type="date"] { max-width: 150px; }
.cb-table input:focus, .cb-table select:focus { outline: none; border-color: var(--pt-accent, #1B5E54); }
.cb-num { font-variant-numeric: tabular-nums; white-space: nowrap; }
.cb-pos { color: var(--pt-pos, #2F7D5B); font-weight: 600; }
.cb-neg { color: var(--pt-neg, #B14A33); font-weight: 600; }
.cb-err { color: var(--pt-neg, #B14A33); font-size: 12.5px; }
.cb-row-error { background: #FBEDE9; }
.cb-empty { padding: 16px 8px; color: var(--pt-muted, #6B665C); font-style: italic; }
.cb-del { font: inherit; cursor: pointer; border: none; background: transparent;
  color: var(--pt-muted, #6B665C); font-size: 18px; line-height: 1; padding: 2px 6px; }
.cb-del:hover { color: var(--pt-neg, #B14A33); }
.cb-summary { display: flex; flex-wrap: wrap; gap: 28px; margin: 18px 0 0;
  padding: 14px 18px; background: var(--pt-tint, #EDF3F0); border-radius: 6px;
  border-left: 3px solid var(--pt-accent, #1B5E54); }
.cb-summary h3 { margin: 0 0 8px; font-size: 13px; font-weight: 600; color: var(--pt-soft, #43423D);
  text-transform: uppercase; letter-spacing: 0.03em; }
.cb-kv { display: flex; justify-content: space-between; gap: 18px; font-size: 14px; padding: 2px 0; }
.cb-k { color: var(--pt-muted, #6B665C); } .cb-v { font-variant-numeric: tabular-nums; font-weight: 600; }
@media (max-width: 640px) { .cb-table { display: block; overflow-x: auto; } }
/* 7.156 : réglages multi-pays (pays / méthode / devise) + lots FIFO. */
.cb-settings { display: flex; flex-wrap: wrap; gap: 14px 18px; margin: 0 0 14px;
  padding: 14px 18px; background: var(--pt-tint, #EDF3F0); border-radius: 6px; }
.cb-set { display: flex; flex-direction: column; gap: 4px; }
.cb-set-lbl { font-size: 11.5px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--pt-muted, #6B665C); }
.cb-settings select { font: inherit; font-size: 14px; padding: 6px 8px; border-radius: 4px;
  border: 1px solid var(--pt-hair, #E7E1D4); background: var(--pt-card, #fff); color: var(--pt-ink, #1A1916); }
.cb-settings select:focus { outline: none; border-color: var(--pt-accent, #1B5E54); }
.cb-country-note { margin: 0 0 12px; font-size: 13.5px; color: var(--pt-soft, #43423D); }
.cb-indicative { margin: 0 0 12px; padding: 10px 14px; font-size: 13.5px; color: var(--pt-soft, #43423D);
  background: #FBF3E2; border-left: 3px solid #C79A3A; border-radius: 4px; }
.cb-lots { margin: 18px 0 0; }
.cb-lots h3 { margin: 0 0 8px; font-size: 13px; font-weight: 600; color: var(--pt-soft, #43423D);
  text-transform: uppercase; letter-spacing: 0.03em; }
.cb-lots-table { max-width: 480px; }
/* 7.156 : tables éditoriales (méthodes par pays, exemple comparatif). */
.cb-countries, .cb-example { width: 100%; border-collapse: collapse; font-size: 14px; margin: 0 0 14px; }
.cb-countries th, .cb-example th { text-align: left; font-size: 12px; font-weight: 600;
  color: var(--pt-muted, #6B665C); padding: 6px 10px; border-bottom: 1px solid var(--pt-rule, #D8CFBB); }
.cb-countries td, .cb-example td { padding: 5px 10px; border-bottom: 1px solid var(--pt-hair, #E7E1D4);
  vertical-align: top; }
.cb-countries td:nth-child(2), .cb-example td:nth-child(1), .cb-example td:nth-child(3) {
  white-space: nowrap; font-variant-numeric: tabular-nums; }
.cb-example { max-width: 420px; }
.cb-asof { font-size: 13px; color: var(--pt-muted, #6B665C); font-style: italic; margin: 0 0 14px; }
@media (max-width: 640px) { .cb-countries, .cb-example { display: block; overflow-x: auto; } }

/* 7.150 : repli « réglages avancés » des composites (divulgation progressive).
   En-tête caché par DÉFAUT (no-JS → invisible, formulaire complet) ; révélé par
   form-fold.js via .is-composite sur le <form>. En expand (.advanced-open), on
   ré-affiche les 6 champs masqués (.field = display:flex). Purement visuel. */
.advanced-toggle { display: none; }
form.is-composite .advanced-toggle {
  display: flex; align-items: center; gap: 0.4rem;
  width: 100%; margin: 0 0 1rem; padding: 0.5rem 0.6rem;
  background: var(--pt-tint, #EDF3F0); border: 1px solid var(--pt-hair, #E7E1D4);
  border-radius: 6px; cursor: pointer;
  font: inherit; font-size: 0.88rem; font-weight: 600; color: var(--pt-soft, #43423D);
  text-align: left;
}
/* 7.150.b : survol/focus LISIBLES. La règle générique `.pt-app button:hover`
   (0,2,1) repeint le fond en vert très sombre (--pt-accent-dk) sans toucher la
   couleur du texte (--pt-soft, sombre) → sombre-sur-sombre. On RÉAFFIRME ici un
   fond clair + texte foncé lisible + bordure accent (sélecteur 0,3,1 > 0,2,1). */
form.is-composite .advanced-toggle:hover,
form.is-composite .advanced-toggle:focus-visible {
  background: var(--pt-tint, #EDF3F0);
  color: var(--pt-accent-dk, #123F38);
  border-color: var(--pt-accent, #1B5E54);
}
form.is-composite .advanced-toggle:focus-visible { outline: 2px solid var(--pt-accent, #1B5E54); outline-offset: 1px; }
.advanced-caret { color: var(--pt-accent, #1B5E54); font-size: 0.8em; line-height: 1; }
/* Expand : surclasse .hidden-for-composite (0,1,0 !important) avec une règle
   plus spécifique (0,2,0) !important → ré-affiche les champs fixés. */
form.advanced-open .hidden-for-composite { display: flex !important; }

/* Étape 6.34.4 : deux signal-cards côte à côte sur la page composite
   (un par composante). Le .signal-card existant utilise flex horizontal
   pour la page mono (signal-meta gauche + signal-scores droite) — ici
   on overrride en stack vertical avec table interne, et on conteneurise
   les deux cards dans .signal-cards-pair (flex row, wrap si étroit). */
.signal-cards-pair {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
  margin: 0.75rem 0 1rem 0;
}
.signal-cards-pair .signal-card {
  flex: 1 1 45%;
  flex-direction: column;
  align-items: stretch;
  margin: 0;
}
.signal-cards-pair .signal-card h3 {
  margin: 0 0 0.4rem 0;
  font-size: 1rem;
}
.signal-cards-pair .signal-card .signal-date {
  font-size: 0.85rem;
  color: #555;
  margin: 0.1rem 0;
}
table.signal-scores {
  display: table;            /* override .signal-scores { display: flex } pour
                                la mono — la classe est partagée mais ici on
                                rend un vrai <table>. */
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
  margin-top: 0.4rem;
}
table.signal-scores th,
table.signal-scores td {
  padding: 0.25rem 0.5rem;
  border-bottom: 1px solid #e0e0e0;
  text-align: left;
  font-variant-numeric: tabular-nums;
}
table.signal-scores td:nth-child(3) { text-align: right; }

/* type="display" (Étape 6.16): read-only constant exposed to the user.
   No <input>, no POST round-trip. Grey background + monospace signal
   "lecture seule, valeur technique server-side". */
.field-display .display-value {
  padding: 0.45rem 0.5rem;
  background-color: #f5f5f5;
  border: 1px solid #ddd;
  border-radius: 3px;
  color: #555;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.95rem;
}

button[type="submit"] {
  margin-top: 1rem;
  padding: 0.6rem 1.2rem;
  font-size: 1rem;
  background: #4a90e2;
  color: white;
  border: none;
  border-radius: 3px;
  cursor: pointer;
}
button[type="submit"]:hover { background: #357ab8; }

/* --- submission result (used by xsl/submit-result.xsl) --- */
dl.params {
  display: grid;
  grid-template-columns: max-content 1fr;
  column-gap: 1.5rem;
  row-gap: 0.5rem;
  margin: 1rem 0 1.5rem 0;
}
dl.params dt { font-weight: 600; color: #555; }
dl.params dd { margin: 0; }

ul.errors {
  list-style: disc inside;
  color: #c0392b;
  padding-left: 0;
  margin: 1rem 0 1.5rem 0;
}
ul.errors li { padding: 0.2rem 0; }

a.back-link {
  display: inline-block;
  margin-top: 1.5rem;
  color: #4a90e2;
  text-decoration: none;
}
a.back-link:hover { text-decoration: underline; }

/* --- backtest result (xsl/backtest-result.xsl) --- */

/* Strategy summary: reuse dl.params styling */
dl.summary {
  display: grid;
  grid-template-columns: max-content 1fr;
  column-gap: 1.5rem;
  row-gap: 0.4rem;
  margin: 0.5rem 0 1rem 0;
}
dl.summary dt { font-weight: 600; color: #555; }
dl.summary dd { margin: 0; }

/* Info note */
.note {
  background: #f5f5f5;
  border-left: 3px solid #888;
  padding: 0.6rem 0.9rem;
  margin: 1rem 0;
  font-size: 0.9rem;
  color: #555;
  font-style: italic;
}

/* Metrics: 2-column key/value table */
table.metrics {
  border-collapse: collapse;
  margin: 0.5rem 0 1rem 0;
}
table.metrics th, table.metrics td {
  padding: 0.4rem 1rem;
  text-align: left;
  border: 1px solid #ddd;
}
table.metrics th { background: #fafafa; font-weight: 600; color: #555; }
table.metrics td { font-variant-numeric: tabular-nums; }

/* Equity curve: full width, compact */
table.equity-curve {
  border-collapse: collapse;
  width: 100%;
  font-size: 0.85rem;
  margin: 0.5rem 0 1rem 0;
}
table.equity-curve th, table.equity-curve td {
  padding: 0.3rem 0.6rem;
  border: 1px solid #e4e4e4;
  text-align: right;
}
table.equity-curve th {
  background: #fafafa;
  font-weight: 600;
  color: #555;
  text-align: center;
}
table.equity-curve td:first-child { text-align: center; font-variant-numeric: tabular-nums; }
table.equity-curve td { font-variant-numeric: tabular-nums; }
table.equity-curve tbody tr:nth-child(even) { background: #fbfbfb; }

/* Signed-value coloring */
.positive { color: #1f8a3a; }
.negative { color: #c0392b; }
.neutral  { color: #555; }

/* Benchmark comparison "Active" column — text-only, no fill, to avoid
   competing visually with .positive / .negative in adjacent cells. */
.metric-better { color: #1f8a3a; font-weight: 600; }
.metric-worse  { color: #c0392b; font-weight: 600; }

table.comparison { margin: 0.5rem 0 1rem 0; }
table.comparison td:nth-child(n+2) { text-align: right; }
table.comparison td:last-child { font-variant-numeric: tabular-nums; }

/* --- Up/Down capture table (Étape 6.9.4) --- */
table.capture { margin: 0.5rem 0 0.5rem 0; }
table.capture td:nth-child(n+2) { text-align: right; }
table.capture td.capture-ratio  { font-weight: 600; font-variant-numeric: tabular-nums; }
.capture-note,
.active-note {
  margin: 0.25rem 0 1rem 0;
  font-size: 0.85rem;
  color: #666;
  font-style: italic;
  max-width: 720px;
}

/* --- Equity curve chart (inline SVG, xsl/backtest-result.xsl <chart>) --- */
svg.equity-chart {
  width: 100%;
  height: auto;
  max-width: 800px;
  display: block;
  margin: 1rem 0;
}
svg.equity-chart .plot-bg     { fill: #fafafa; }
svg.equity-chart .grid-line   { stroke: #e4e4e4; stroke-width: 1; }
svg.equity-chart .zero-line   { stroke: #888; stroke-width: 1; stroke-dasharray: 3,3; }
svg.equity-chart .equity-line { stroke: #1f8a3a; stroke-width: 2; fill: none; }
svg.equity-chart .axis-label  {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 11px;
  fill: #555;
}
svg.equity-chart .axis-label.x { text-anchor: middle; }
svg.equity-chart .axis-label.y { text-anchor: end; }

/* --- Dual Momentum result page (xsl/dual-momentum-result.xsl) --- */

/* Current signal card: meta on the left, two side-by-side score boxes on
   the right. Background and left border tinted by the decision. */
.signal-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1rem 1.25rem;
  margin: 0.75rem 0 1rem 0;
  border-left: 4px solid #888;
  background: #f5f5f5;
  border-radius: 0 3px 3px 0;
}
.signal-card.risk          { border-left-color: #1f8a3a; background: #eef7f0; }
.signal-card.out_of_market { border-left-color: #b58900; background: #faf5e6; }
.signal-meta .signal-date     { font-size: 0.9rem; color: #555; }
.signal-meta .signal-decision { font-size: 1.05rem; margin-top: 0.2rem; }
.signal-scores {
  display: flex;
  gap: 1rem;
}
.signal-score {
  text-align: center;
  padding: 0.5rem 0.75rem;
  background: #fff;
  border: 1px solid #ddd;
  border-radius: 3px;
  min-width: 6rem;
}
.signal-score-asset {
  font-size: 0.8rem;
  color: #666;
  margin-bottom: 0.15rem;
}
.signal-score-value {
  font-weight: 600;
  font-size: 1.05rem;
  font-variant-numeric: tabular-nums;
}

/* --- Current signal scores table (Étape 6.10.4, multi-asset) --- */
table.current-signal-scores { margin: 0.5rem 0 1rem 0; }
table.current-signal-scores td:nth-child(1) { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; font-weight: 600; }
table.current-signal-scores td.role-cell    { color: #555; font-size: 0.9rem; }
table.current-signal-scores td.score-cell   { text-align: right; font-variant-numeric: tabular-nums; }
table.current-signal-scores td.selection-cell { font-size: 0.85rem; color: #1f8a3a; font-weight: 600; }
table.current-signal-scores tr.selected-asset { background: rgba(34, 197, 94, 0.10); }
.filter-status            { font-size: 0.85rem; margin-left: 0.4rem; }
.filter-status.filter-ok  { color: #1f8a3a; }
.filter-status.filter-fail{ color: #c0392b; }

/* Trades table: calqué sur table.metrics + colonnes compactes */
table.trades {
  border-collapse: collapse;
  width: 100%;
  font-size: 0.85rem;
  margin: 0.5rem 0 1rem 0;
}
table.trades th, table.trades td {
  padding: 0.3rem 0.6rem;
  border: 1px solid #e4e4e4;
  text-align: right;
}
table.trades th {
  background: #fafafa;
  font-weight: 600;
  color: #555;
  text-align: center;
}
table.trades td:nth-child(1),    /* # */
table.trades td:nth-child(2),    /* signal date */
table.trades td:nth-child(3),    /* asset */
table.trades td:nth-child(4) {   /* period */
  text-align: center;
}
table.trades td { font-variant-numeric: tabular-nums; }
table.trades tbody tr:nth-child(even) { background: #fbfbfb; }

/* --- Annual Returns table --- */
table.annual-returns { margin: 0.5rem 0 0.75rem 0; }
table.annual-returns td:nth-child(1) { text-align: center; }
table.annual-returns td:nth-child(2),
table.annual-returns td:nth-child(3) { text-align: right; }
.partial-flag { color: #888; font-size: 0.85rem; font-style: italic; }

/* --- Bar charts (annual returns + similar) --- */
svg.bar-chart {
  width: 100%;
  height: auto;
  max-width: 800px;
  display: block;
  margin: 1rem 0;
}
svg.bar-chart .plot-bg     { fill: #fafafa; }
svg.bar-chart .grid-line   { stroke: #e4e4e4; stroke-width: 1; }
svg.bar-chart .zero-line   { stroke: #888;    stroke-width: 1; }
svg.bar-chart .axis-label  {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 11px;
  fill: #555;
}
svg.bar-chart .axis-label.x { text-anchor: middle; }
svg.bar-chart .axis-label.y { text-anchor: end; }
svg.bar-chart .bar.bar-positive { fill: #1f8a3a; }
svg.bar-chart .bar.bar-negative { fill: #c0392b; }
/* Étape 6.73 : plus de fondu d'année partielle — la barre de l'année en cours
   reste à pleine teinte ; le signal « incomplet » est porté par l'astérisque
   « 2026* » de l'étiquette. La classe .bar-partial reste émise par le SVG comme
   hook inoffensif (aucune règle d'opacité ne doit la délaver). */

/* Multi-series annual-returns chart (Étape 6.9.3): DM stays at full
   saturation, B&H gets a strong opacity reduction so the two series
   are distinguishable while preserving sign coloring. */
svg.bar-chart .bar.bar-benchmark { opacity: 0.40; }
svg.bar-chart .legend-swatch.bar-strategy.bar-positive,
svg.bar-chart .legend-swatch.bar-strategy             { fill: #1f8a3a; }
svg.bar-chart .legend-swatch.bar-benchmark            { fill: #1f8a3a; opacity: 0.40; }
svg.bar-chart .legend-text {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 12px; fill: #333;
}

/* --- Monthly Returns heat map (compactée Étape 6.8.1) --- */
/* Wrapper avec scroll horizontal de secours si le viewport est très étroit
   (< ~720 px). Au-dessus de ça, les 13 colonnes tiennent sans scroll. */
.monthly-returns-wrapper { overflow-x: auto; margin: 1rem 0; }
table.monthly-returns {
  border-collapse: collapse;
  font-size: 0.75rem;          /* ~12 px à font-size base 16 */
  font-variant-numeric: tabular-nums;
  table-layout: fixed;          /* colonnes de largeur prévisible */
  width: 100%;
  max-width: 820px;
}
table.monthly-returns th,
table.monthly-returns td {
  padding: 0.2rem 0.25rem;
  border: 1px solid #e4e4e4;
  text-align: right;
}
/* Colonne "Year" plus étroite que les colonnes mois */
table.monthly-returns thead th:first-child,
table.monthly-returns tbody th             { width: 3em; text-align: center; }
/* Colonnes mois : largeur uniforme calculée pour 5 caractères max (-99.9% à +99.9%) */
table.monthly-returns thead th:not(:first-child),
table.monthly-returns tbody td             { width: 4.2em; }
table.monthly-returns thead th,
table.monthly-returns tbody th {
  background: #fafafa;
  font-weight: 600;
  color: #555;
  text-align: center;
}
/* Heat-map cell tints: 4 buckets per sign (|return| in 0..2%, 2..5%,
   5..10%, >=10%). Alpha rises with magnitude. */
.monthly-returns .cell-empty       { background: transparent; color: transparent; }
.monthly-returns .cell-neutral-1,
.monthly-returns .cell-neutral-2,
.monthly-returns .cell-neutral-3,
.monthly-returns .cell-neutral-4   { background: rgba(0,0,0,0.04); color: #555; }
.monthly-returns .cell-positive-1  { background: rgba(34,197,94,0.10); }
.monthly-returns .cell-positive-2  { background: rgba(34,197,94,0.22); }
.monthly-returns .cell-positive-3  { background: rgba(34,197,94,0.35); }
.monthly-returns .cell-positive-4  { background: rgba(34,197,94,0.50); }
.monthly-returns .cell-negative-1  { background: rgba(239,68,68,0.10); }
.monthly-returns .cell-negative-2  { background: rgba(239,68,68,0.22); }
.monthly-returns .cell-negative-3  { background: rgba(239,68,68,0.35); }
.monthly-returns .cell-negative-4  { background: rgba(239,68,68,0.50); }

/* --- Drawdowns underwater chart --- */
svg.dd-chart {
  width: 100%;
  height: auto;
  max-width: 800px;
  display: block;
  margin: 1rem 0;
}
svg.dd-chart .plot-bg    { fill: #fafafa; }
svg.dd-chart .grid-line  { stroke: #e4e4e4; stroke-width: 1; }
svg.dd-chart .zero-line  { stroke: #888; stroke-width: 1; }
svg.dd-chart .axis-label {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 11px;
  fill: #555;
}
svg.dd-chart .axis-label.x { text-anchor: middle; }
svg.dd-chart .axis-label.y { text-anchor: end; }
svg.dd-chart .dd-area { fill: rgba(239,68,68,0.22); stroke: none; }
svg.dd-chart .dd-line { stroke-width: 1.5; fill: none; }
/* DM-vs-B&H overlay (Étape 6.9.2): same colour palette as the equity chart
   for visual continuity. */
svg.dd-chart .dd-line.line-strategy  { stroke: #c0392b; }                /* DM red, solid */
svg.dd-chart .dd-line.line-benchmark { stroke: #f59e0b; stroke-dasharray: 4,3; }
svg.dd-chart .legend-dot.line-strategy  { fill: #c0392b; }
svg.dd-chart .legend-dot.line-benchmark { fill: #f59e0b; }
svg.dd-chart .legend-text {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 12px; fill: #333;
}

/* Top-3 drawdown annotations (Étape 6.8.4) */
svg.dd-chart .dd-annotation-dot   { fill: #ef4444; stroke: #fff; stroke-width: 1; }
svg.dd-chart .dd-annotation-label {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 10px;
  font-weight: 600;
  fill: #4b1212;
  text-anchor: middle;
  /* white halo around the text so it stays readable when it sits on top of
     the red drawdown fill */
  paint-order: stroke;
  stroke: #ffffff;
  stroke-width: 2.5;
  stroke-linejoin: round;
}

/* --- Drawdowns top-10 table --- */
table.drawdowns-table .ongoing { font-style: italic; color: #555; }
table.drawdowns-table .ongoing td:nth-child(1)::after { content: " (open)"; font-size: 0.7rem; color: #888; }

/* --- Multi-line chart (rolling returns + future overlays) --- */
svg.multi-line-chart {
  width: 100%;
  height: auto;
  max-width: 800px;
  display: block;
  margin: 1rem 0;
}
svg.multi-line-chart .plot-bg    { fill: #fafafa; }
svg.multi-line-chart .grid-line  { stroke: #e4e4e4; stroke-width: 1; }
svg.multi-line-chart .zero-line  { stroke: #888; stroke-width: 1; stroke-dasharray: 3,3; }
svg.multi-line-chart .axis-label {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 11px;
  fill: #555;
}
svg.multi-line-chart .axis-label.x { text-anchor: middle; }
svg.multi-line-chart .axis-label.y { text-anchor: end; }

svg.multi-line-chart .line { fill: none; stroke-width: 1.8; }
svg.multi-line-chart .line.multi-series-0 { stroke: #2563eb; }   /* blue */
svg.multi-line-chart .line.multi-series-1 { stroke: #ea580c; }   /* orange */
svg.multi-line-chart .line.multi-series-2 { stroke: #1f8a3a; }   /* green */

/* DM equity overlay (Étape 6.7.1): strategy in blue, benchmark in amber */
svg.multi-line-chart .line.line-strategy   { stroke: #2563eb; stroke-width: 2; }
svg.multi-line-chart .line.line-benchmark  { stroke: #f59e0b; stroke-width: 1.6; stroke-dasharray: 4,3; }

/* Composite portfolio equity overlay (Étape 6.34.4) : portfolio
   dominant en bleu épais, composantes en dérivés (cyan + magenta),
   benchmark en ambre dashé identique à la page mono. */
svg.multi-line-chart .line.line-portfolio   { stroke: #2563eb; stroke-width: 2.2; }
svg.multi-line-chart .line.line-component-a { stroke: #06b6d4; stroke-width: 1.4; }
svg.multi-line-chart .line.line-component-b { stroke: #be185d; stroke-width: 1.4; }

svg.multi-line-chart .legend-dot.multi-series-0 { fill: #2563eb; }
svg.multi-line-chart .legend-dot.multi-series-1 { fill: #ea580c; }
svg.multi-line-chart .legend-dot.multi-series-2 { fill: #1f8a3a; }
svg.multi-line-chart .legend-dot.line-strategy  { fill: #2563eb; }
svg.multi-line-chart .legend-dot.line-benchmark { fill: #f59e0b; }
svg.multi-line-chart .legend-dot.line-portfolio   { fill: #2563eb; }
svg.multi-line-chart .legend-dot.line-component-a { fill: #06b6d4; }
svg.multi-line-chart .legend-dot.line-component-b { fill: #be185d; }

/* --- Combined dual-panel chart (7.64): equity panel (top) + drawdown panel
   (translated below) inside ONE <svg class="dual-panel-chart">. The panels are
   now <g class="panel-equity"> / <g class="panel-drawdown">, so the existing
   svg.multi-line-chart / svg.dd-chart descendant rules no longer reach them
   (they require an <svg> ancestor with those classes). The rules below re-home
   that styling 1:1, scoped per panel — values mirror the source wrappers. --- */
svg.dual-panel-chart { width: 100%; height: auto; max-width: 800px; display: block; margin: 1rem 0; }

/* shared chrome (identical in both source wrappers) */
svg.dual-panel-chart .plot-bg   { fill: #fafafa; }
svg.dual-panel-chart .grid-line { stroke: #e4e4e4; stroke-width: 1; }
svg.dual-panel-chart .axis-label {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 11px;
  fill: #555;
}
svg.dual-panel-chart .axis-label.x { text-anchor: middle; }
svg.dual-panel-chart .axis-label.y { text-anchor: end; }

/* equity panel — mirrors svg.multi-line-chart (+ svg.equity-chart chrome) */
svg.dual-panel-chart .panel-equity .zero-line { stroke: #888; stroke-width: 1; stroke-dasharray: 3,3; }
svg.dual-panel-chart .panel-equity .line { fill: none; stroke-width: 1.8; }
svg.dual-panel-chart .panel-equity .line.multi-series-0 { stroke: #2563eb; }
svg.dual-panel-chart .panel-equity .line.multi-series-1 { stroke: #ea580c; }
svg.dual-panel-chart .panel-equity .line.multi-series-2 { stroke: #1f8a3a; }
svg.dual-panel-chart .panel-equity .line.line-strategy   { stroke: #2563eb; stroke-width: 2; }
svg.dual-panel-chart .panel-equity .line.line-benchmark  { stroke: #f59e0b; stroke-width: 1.6; stroke-dasharray: 4,3; }
svg.dual-panel-chart .panel-equity .line.line-portfolio   { stroke: #2563eb; stroke-width: 2.2; }
svg.dual-panel-chart .panel-equity .line.line-component-a { stroke: #06b6d4; stroke-width: 1.4; }
svg.dual-panel-chart .panel-equity .line.line-component-b { stroke: #be185d; stroke-width: 1.4; }
svg.dual-panel-chart .panel-equity .legend-dot.multi-series-0 { fill: #2563eb; }
svg.dual-panel-chart .panel-equity .legend-dot.multi-series-1 { fill: #ea580c; }
svg.dual-panel-chart .panel-equity .legend-dot.multi-series-2 { fill: #1f8a3a; }
svg.dual-panel-chart .panel-equity .legend-dot.line-strategy  { fill: #2563eb; }
svg.dual-panel-chart .panel-equity .legend-dot.line-benchmark { fill: #f59e0b; }
svg.dual-panel-chart .panel-equity .legend-dot.line-portfolio   { fill: #2563eb; }
svg.dual-panel-chart .panel-equity .legend-dot.line-component-a { fill: #06b6d4; }
svg.dual-panel-chart .panel-equity .legend-dot.line-component-b { fill: #be185d; }

/* drawdown panel — mirrors svg.dd-chart */
svg.dual-panel-chart .panel-drawdown .zero-line { stroke: #888; stroke-width: 1; }
svg.dual-panel-chart .panel-drawdown .dd-area { fill: rgba(239,68,68,0.22); stroke: none; }
svg.dual-panel-chart .panel-drawdown .dd-line { stroke-width: 1.5; fill: none; }
svg.dual-panel-chart .panel-drawdown .dd-line.line-strategy  { stroke: #c0392b; }
svg.dual-panel-chart .panel-drawdown .dd-line.line-benchmark { stroke: #f59e0b; stroke-dasharray: 4,3; }
svg.dual-panel-chart .panel-drawdown .legend-dot.line-strategy  { fill: #c0392b; }
svg.dual-panel-chart .panel-drawdown .legend-dot.line-benchmark { fill: #f59e0b; }
svg.dual-panel-chart .panel-drawdown .legend-text {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 12px; fill: #333;
}
svg.dual-panel-chart .panel-drawdown .dd-annotation-dot   { fill: #ef4444; stroke: #fff; stroke-width: 1; }
svg.dual-panel-chart .panel-drawdown .dd-annotation-label {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 10px;
  font-weight: 600;
  fill: #4b1212;
  text-anchor: middle;
  paint-order: stroke;
  stroke: #ffffff;
  stroke-width: 2.5;
  stroke-linejoin: round;
}

/* --- 7.64.2 — re-home the .pt-app theme + 12px legend onto the combined
   dual-panel chart (fixes the 7.64 regression). Renaming the wrappers
   <svg class="multi-line-chart"> / <svg class="dd-chart"> to <g class="panel-*">
   orphaned the .pt-app svg.multi-line-chart / svg.dd-chart theme rules AND
   svg.multi-line-chart .legend-text {font-size:12px}, so the combined chart
   showed the base palette (blue/amber) + a ~16px legend, out of step with the
   rolling chart below it. These mirror the orphaned rules onto the panels.
   The base block above supplies geometry (widths/dash/fill); these supply the
   --pt-* colours + 12px legend. EXTENSION ONLY — nothing existing is modified;
   the selector keeps `svg.dual-panel-chart` (faithful to the original
   `.pt-app svg.<wrapper>` form) so it outranks the base .panel-* rules without
   !important (bare `.pt-app .panel-X` would be one class too weak). The shared
   svg.multi-line-chart rules (still used by the rolling chart) are untouched. */
.pt-app svg.dual-panel-chart .panel-equity .legend-text,
.pt-app svg.dual-panel-chart .panel-drawdown .legend-text { font-size: 12px; fill: var(--pt-soft); }
.pt-app svg.dual-panel-chart .panel-equity .zero-line  { stroke: var(--pt-soft); }
.pt-app svg.dual-panel-chart .panel-drawdown .zero-line { stroke: var(--pt-soft); }

/* equity panel — themed multi-line palette (hero teal, benchmark warm grey,
   composantes ochre/slate), matching svg.multi-line-chart under .pt-app */
.pt-app svg.dual-panel-chart .panel-equity .line.line-strategy,
.pt-app svg.dual-panel-chart .panel-equity .line.line-portfolio,
.pt-app svg.dual-panel-chart .panel-equity .line.multi-series-0 { stroke: var(--pt-accent); }
.pt-app svg.dual-panel-chart .panel-equity .line.line-benchmark { stroke: var(--pt-bench); }
.pt-app svg.dual-panel-chart .panel-equity .line.line-component-a,
.pt-app svg.dual-panel-chart .panel-equity .line.multi-series-1 { stroke: var(--pt-series-2); }
.pt-app svg.dual-panel-chart .panel-equity .line.line-component-b,
.pt-app svg.dual-panel-chart .panel-equity .line.multi-series-2 { stroke: var(--pt-series-3); }
.pt-app svg.dual-panel-chart .panel-equity .legend-dot.line-strategy,
.pt-app svg.dual-panel-chart .panel-equity .legend-dot.line-portfolio,
.pt-app svg.dual-panel-chart .panel-equity .legend-dot.multi-series-0 { fill: var(--pt-accent); }
.pt-app svg.dual-panel-chart .panel-equity .legend-dot.line-benchmark { fill: var(--pt-bench); }
.pt-app svg.dual-panel-chart .panel-equity .legend-dot.line-component-a,
.pt-app svg.dual-panel-chart .panel-equity .legend-dot.multi-series-1 { fill: var(--pt-series-2); }
.pt-app svg.dual-panel-chart .panel-equity .legend-dot.line-component-b,
.pt-app svg.dual-panel-chart .panel-equity .legend-dot.multi-series-2 { fill: var(--pt-series-3); }

/* 7.65: out-of-market bands (defensive months) + legend swatch — a discreet
   neutral grey at 0.10 opacity, like the site (does not obscure the curves). */
.pt-app svg.dual-panel-chart .panel-equity .oom-band { fill: var(--pt-bench); opacity: 0.10; }

/* drawdown panel — themed underwater. 7.64.3: the strategy curve+area are
   re-tinted from brick (--pt-neg) to teal (--pt-accent) so the drawdown
   represents the SAME entity as the equity panel's main curve (portfolio /
   strategy), matching the site look (drawdown in the curve's colour, not red).
   Retargets the 7.64.2 values in place (a fresh `.pt-app .panel-drawdown` rule
   would be one class too weak to override them). B&H + trough dots unchanged. */
.pt-app svg.dual-panel-chart .panel-drawdown .dd-area { fill: var(--pt-accent); fill-opacity: 0.20; }
.pt-app svg.dual-panel-chart .panel-drawdown .dd-line.line-strategy  { stroke: var(--pt-accent); }
.pt-app svg.dual-panel-chart .panel-drawdown .dd-line.line-benchmark { stroke: var(--pt-bench); }
.pt-app svg.dual-panel-chart .panel-drawdown .legend-dot.line-strategy  { fill: var(--pt-accent); }
.pt-app svg.dual-panel-chart .panel-drawdown .legend-dot.line-benchmark { fill: var(--pt-bench); }
.pt-app svg.dual-panel-chart .panel-drawdown .dd-annotation-dot { fill: var(--pt-neg); }

/* 7.64.4: "Drawdown" sub-panel title in the inter-panel gap (ink, like the
   site's sub-panel titles — a title, not a series, so no teal). */
.pt-app svg.dual-panel-chart .panel-drawdown .dd-panel-title {
  fill: var(--pt-ink);
  font-size: 13px;
  font-weight: 600;
}

svg.multi-line-chart .legend-text {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 12px;
  fill: #333;
}

/* --- Rolling Returns summary table (7 cols depuis 6.9.1) --- */
table.rolling-summary {
  margin: 0.5rem 0 0.75rem 0;
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
}
table.rolling-summary th,
table.rolling-summary td        { padding: 0.3rem 0.55rem; }
table.rolling-summary td:nth-child(1) { text-align: center; font-weight: 600; }
table.rolling-summary td:nth-child(n+2) { text-align: right; }
/* Visual separator between the DM and B&H column groups */
table.rolling-summary th:nth-child(5),
table.rolling-summary td:nth-child(5) { border-left: 2px solid #ccc; }

/* --- Table of contents (Étape 6.8.3) --- */
nav.toc {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.8rem;
  margin: 0.5rem 0 1.5rem 0;
  padding: 0.6rem 0.9rem;
  background: #f5f5f5;
  border-left: 3px solid #4a90e2;
  border-radius: 0 3px 3px 0;
  font-size: 0.85rem;
}
nav.toc a {
  color: #4a90e2;
  text-decoration: none;
  font-weight: 500;
}
nav.toc a:hover { text-decoration: underline; }
nav.toc a + a::before {
  content: "·";
  color: #aaa;
  margin-right: 0.6rem;
  font-weight: bold;
}

/* --- Étape 6.17 : form intégré en haut des pages résultats --------- */
.form-result-separator {
  margin: 2rem 0;
  border: 0;
  border-top: 1px solid #ddd;
}
.placeholder {
  color: #888;
  font-style: italic;
  text-align: center;
  margin: 2rem 0;
}

/* --- Future signal page (Étape 6.37.4) ---------------------------- */
/* Header band at the top of the live-signal page : market-state badge
   + universe + lookback preset + fetched-at timestamp. Wraps gracefully
   on narrow viewports. */
.future-signal-header {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1rem;
  align-items: baseline;
  padding: 0.6rem 0.9rem;
  margin: 0.6rem 0 1rem;
  background: #f5f7fb;
  border: 1px solid #e1e6f0;
  border-radius: 6px;
  font-size: 0.9rem;
}
.future-signal-meta-row { color: #444; }
.future-signal-note     { color: #b58900; font-style: italic; }
/* Perf line (6.48) — held-strategy MTD/YTD, set apart with a left rule and a
   light wash; the +/- figures inherit .positive / .negative colouring. */
.future-signal-perf {
  font-weight: 600;
  padding-left: 0.7rem;
  border-left: 2px solid #cdd6e6;
  cursor: help;
}
.future-signal-intro    { color: #555; font-size: 0.95rem; margin: 0.4rem 0 1.4rem; }
.future-signal-error    { color: #c0392b; font-weight: 600; margin: 1rem 0 0.4rem; }
.future-signal-error-detail {
  background: #faf0ee;
  border-left: 4px solid #c0392b;
  padding: 0.6rem 0.9rem;
  white-space: pre-wrap;
  font-size: 0.85rem;
  color: #6a1f15;
  margin: 0.4rem 0 1rem;
}

/* Market-state pill. Color tracks the trading session state — green
   when open, amber pre/after-hours, grey closed, red on error. */
.market-state-badge {
  display: inline-block;
  padding: 0.15rem 0.6rem;
  border-radius: 999px;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: #fff;
  background: #6b7a8f;
}
.market-state-open        { background: #1f8a3a; }
.market-state-pre_market  { background: #b58900; }
.market-state-after_hours { background: #b58900; }
.market-state-closed      { background: #6b7a8f; }
.market-state-error       { background: #c0392b; }

/* Snapshots table : same baseline as table.metrics, plus a monospace
   timestamp column and tinted source pill. */
.snapshots-note { color: #555; font-size: 0.9rem; margin: 0.3rem 0 0.6rem; }
table.snapshots-table td.numeric   { text-align: right; font-variant-numeric: tabular-nums; }
table.snapshots-table td.timestamp { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.85rem; color: #555; }
table.snapshots-table td.source    { font-size: 0.85rem; color: #555; }
table.snapshots-table td.source.source-latest_trade { color: #1f8a3a; font-weight: 600; }
table.snapshots-table td.source.source-daily_bar    { color: #555; }

/* Composite aggregate-allocation table. Compact (2 cols), right-aligned
   weights. Sits below the side-by-side .signal-cards-pair. */
.aggregate-note { color: #555; font-size: 0.9rem; margin: 0.3rem 0 0.6rem; }
table.aggregate-allocation-table { max-width: 28rem; }
table.aggregate-allocation-table td.score-cell {
  text-align: right;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* ===================================================================
   Rebalance order widget (7.122) — client-side helper on future-signal.
   Hors zone hashée (page future-signal n'a pas de <nav class="toc">).
   Boutons scoped sous .rebalance-widget (0,2,0) → battent .pt-app button
   (0,1,1), cf. piège 7.111.
   =================================================================== */
.rebalance-widget { margin: 2rem 0 1rem; }
.rebalance-widget .rebalance-intro {
  color: var(--pt-muted);
  font-size: 0.92rem;
  max-width: 46rem;
  margin: 0.3rem 0 1rem;
}
.rebalance-widget .rebalance-noscript {
  color: var(--pt-soft);
  font-size: 0.92rem;
  background: var(--pt-tint);
  border: 1px solid var(--pt-hair);
  border-radius: 8px;
  padding: 0.6rem 0.9rem;
}
.rebalance-widget .rebalance-body {
  display: flex;
  flex-wrap: wrap;
  gap: 1.6rem 2.4rem;
  align-items: flex-start;
}
.rebalance-widget .rebalance-input,
.rebalance-widget .rebalance-output { flex: 1 1 22rem; min-width: 18rem; }
.rebalance-widget h3 {
  font-size: 0.95rem;
  margin: 0 0 0.5rem;
  color: var(--pt-soft);
}
.rebalance-widget table {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}
.rebalance-widget th,
.rebalance-widget td {
  padding: 0.35rem 0.5rem;
  border-bottom: 1px solid var(--pt-hair);
  text-align: left;
}
.rebalance-widget th {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--pt-muted);
}
.rebalance-widget td .tk { font-weight: 600; }
.rebalance-widget .rb-amount { width: 8.5rem; max-width: 100%; text-align: right; }
.rebalance-widget .rb-ticker-input { width: 6rem; max-width: 100%; text-transform: uppercase; }
.rebalance-widget .rb-num { color: var(--pt-soft); }
.rebalance-widget .rb-order { font-weight: 600; white-space: nowrap; }
.rebalance-widget .rb-buy  { color: #1f8a3a; }
.rebalance-widget .rb-sell { color: #c0392b; }
.rebalance-widget .rb-neutral { color: var(--pt-muted); font-weight: 400; }
.rebalance-widget .rb-add {
  margin-top: 0.6rem;
  background: transparent;
  color: var(--pt-accent);
  border: 1px solid var(--pt-hair);
  border-radius: 8px;
  padding: 0.4em 0.9em;
  font-size: 0.88rem;
  font-weight: 600;
  cursor: pointer;
}
.rebalance-widget .rb-add:hover {
  background: var(--pt-tint);
  color: var(--pt-accent-dk);
}
.rebalance-widget .rb-remove {
  background: transparent;
  color: var(--pt-muted);
  border: none;
  padding: 0 0.2em;
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
}
.rebalance-widget .rb-remove:hover { background: transparent; color: #c0392b; }
.rebalance-widget .rebalance-checksum {
  margin: 0.7rem 0 0;
  font-size: 0.85rem;
  color: var(--pt-muted);
  font-variant-numeric: tabular-nums;
}

/* Future-signal button : the CTA placed on each DM result page (mono +
   composite) between the static Current signal and Annual Returns. Drives
   the user to /portfolio/cgi-bin/future-signal.pl with the current
   universe + lookback preset preserved in the query string. */
.future-signal-blurb {
  color: #555;
  font-size: 0.95rem;
  max-width: 50rem;
  margin: 0.4rem 0 0.8rem;
}
a.btn-future-signal {
  display: inline-block;
  padding: 0.55em 1.1em;
  background: #2563eb;
  color: #fff;
  text-decoration: none;
  border-radius: 4px;
  font-weight: 600;
  margin: 0 0 1.2rem;
}
a.btn-future-signal:hover { background: #1d4ed8; }

/* Back-form : a submit button styled to mimic the existing back-link.
   Reusing .back-link on the <button> handles most of the styling; this
   override strips the default form margin/border. */
form.future-signal-back-form {
  margin-top: 1.5rem;
}
form.future-signal-back-form button.back-link {
  background: transparent;
  border: none;
  cursor: pointer;
  font: inherit;
  padding: 0;
}

/* ===================================================================
   Étape 6.40.3 — Page de revue de rebalancement (rebalance-review.pl).
   Réutilise .market-state-badge, table.metrics, a.back-link.
   =================================================================== */
.rebalance-strategy { color: #555; font-size: 0.95rem; margin: 0 0 1rem; font-weight: 600; }
.rebalance-intro    { color: #555; font-size: 0.95rem; max-width: 52rem; margin: 0.4rem 0 1.2rem; }
.rebalance-note     { color: #b58900; font-weight: 600; margin: 0.6rem 0; }
.rebalance-empty    { color: #555; font-style: italic; margin: 0.4rem 0 1rem; }
.rebalance-back     { margin-top: 1.6rem; }
.rebalance-seq-note { color: #555; font-size: 0.88rem; font-style: italic; margin: 0.3rem 0 0.8rem; }
.rebalance-plan-meta { color: #333; font-size: 0.95rem; margin: 0.4rem 0 0.8rem; }

.rebalance-header {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1rem;
  align-items: baseline;
  padding: 0.6rem 0.9rem;
  margin: 0.6rem 0 1rem;
  background: #f5f7fb;
  border: 1px solid #e1e6f0;
  border-radius: 6px;
  font-size: 0.9rem;
}
.rebalance-meta-row { color: #444; }

/* Tables : right-align numeric cells (baseline table.metrics). */
table.rebalance-account td.numeric,
table.rebalance-signal  td.numeric,
table.rebalance-target  td.numeric,
table.rebalance-current td.numeric,
table.rebalance-orders  td.numeric,
table.rebalance-submitted td.numeric,
table.rebalance-failed  td.numeric {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
table.rebalance-account { max-width: 40rem; }
table.rebalance-account th { text-align: left; }

/* Signal rows tinted by decision (vert in-market / amber out). */
tr.signal-row.risk          td { background: #eef7f0; }
tr.signal-row.out_of_market td { background: #faf5e6; }

/* Order rows : ventes en ambre, achats en bleu, échecs en rouge. */
tr.order-row.order-sell   td { background: #fdf3e3; }
tr.order-row.order-buy    td { background: #eef3fd; }
tr.order-row.order-failed td { background: #faf0ee; }

.badge-to-zero {
  display: inline-block;
  padding: 0.1rem 0.5rem;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
  color: #fff;
  background: #c0392b;
}
.order-id  { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.82rem; color: #555; }
.error-cell { font-size: 0.85rem; color: #6a1f15; }

.rebalance-warning {
  background: #faf5e6;
  border-left: 4px solid #b58900;
  padding: 0.5rem 0.9rem;
  margin: 0.6rem 0;
  font-size: 0.9rem;
  color: #6a5300;
}
.rebalance-capped {
  background: #faf0ee;
  border-left-color: #c0392b;
  color: #6a1f15;
  font-weight: 600;
}

/* Bannière d'exécution (rapport). */
.execution-banner {
  padding: 0.7rem 1rem;
  border-radius: 6px;
  font-weight: 600;
  margin: 0.6rem 0 1.2rem;
}
.execution-banner.exec-ok      { background: #eef7f0; border: 1px solid #1f8a3a; color: #1f6b30; }
.execution-banner.exec-partial { background: #faf5e6; border: 1px solid #b58900; color: #6a5300; }

.rebalance-error { color: #c0392b; font-weight: 600; margin: 1rem 0 0.4rem; }
.rebalance-error-detail {
  background: #faf0ee;
  border-left: 4px solid #c0392b;
  padding: 0.6rem 0.9rem;
  white-space: pre-wrap;
  font-size: 0.85rem;
  color: #6a1f15;
  margin: 0.4rem 0 1rem;
}

/* Formulaires (entry + panorama). */
form.rebalance-form {
  background: #f9fafc;
  border: 1px solid #e1e6f0;
  border-radius: 8px;
  padding: 1rem 1.2rem;
  margin: 0.6rem 0 1.2rem;
  max-width: 40rem;
}
.passphrase-row, .rebalance-field-row { margin: 0.6rem 0; display: flex; flex-direction: column; gap: 0.3rem; }
.passphrase-row label, .rebalance-field-row label, .order-type-fieldset legend {
  font-weight: 600; color: #444; font-size: 0.9rem;
}
.passphrase-row input, .rebalance-field-row input[type="text"] {
  padding: 0.5em 0.7em;
  border: 1px solid #c8d0de;
  border-radius: 4px;
  font: inherit;
  max-width: 22rem;
}
.field-hint { color: #777; font-size: 0.82rem; }
.order-type-fieldset { border: 1px solid #e1e6f0; border-radius: 6px; padding: 0.6rem 0.9rem; }
.order-type-fieldset label { display: block; font-weight: 400; margin: 0.3rem 0; }

.rebalance-actions { margin-top: 1rem; display: flex; gap: 0.8rem; flex-wrap: wrap; }
.btn-primary, .btn-secondary, .btn-danger {
  padding: 0.6em 1.2em;
  border: none;
  border-radius: 4px;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.btn-primary   { background: #2563eb; color: #fff; }
.btn-primary:hover   { background: #1d4ed8; }
.btn-secondary { background: #e1e6f0; color: #333; }
.btn-secondary:hover { background: #d2d9e8; }
.btn-danger    { background: #c0392b; color: #fff; }
.btn-danger:hover    { background: #a93226; }

/* --- Print mode (Étape 6.8.3, A4 portrait calibration 6.9.6) ------- */
/* Fix the paper size + outer margins so @media print rules below can
   target the printable area predictably. 8 mm leaves ~194 mm of usable
   width on A4 portrait (210 mm - 2 × 8 mm), which is what the
   Monthly Returns override below assumes. */
@page { size: A4 portrait; margin: 8mm; }

@media print {
  /* Hide on paper what only makes sense interactively. */
  nav.toc,
  a.back-link             { display: none !important; }

  /* Keep coloured cells / chart fills on paper (browsers default to
     stripping backgrounds when printing). */
  body,
  .monthly-returns .cell,
  table.rolling-summary,
  table.metrics,
  table.comparison,
  table.annual-returns,
  table.drawdowns-table,
  table.trades,
  .signal-card,
  svg                     { -webkit-print-color-adjust: exact;
                            print-color-adjust:         exact; }

  /* Atomic blocks: never split across pages. */
  svg,
  table.metrics,
  table.comparison,
  table.annual-returns,
  table.drawdowns-table,
  table.rolling-summary,
  .signal-card,
  .note                   { page-break-inside: avoid;
                            break-inside:      avoid; }

  /* Long tables CAN split between pages, but a row must stay together. */
  table.monthly-returns,
  table.trades            { page-break-inside: auto; break-inside: auto; }
  table.monthly-returns tr,
  table.trades tr         { page-break-inside: avoid; break-inside: avoid; }

  /* Slightly tighter type so the result fits in fewer pages. */
  body                    { font-size: 11pt; }
  h1                      { font-size: 1.3rem; }
  h2                      { font-size: 1.05rem; }

  /* Monthly Returns: shrink for A4 portrait fit (Étape 6.9.6).
     The 820 px / 0.75 rem / 0.2 rem calibration of 6.8.1 targets the
     HTML viewport. On A4 portrait at 8 mm margins (~194 mm usable),
     12 month columns + year column at 0.75 rem clip the Dec column.
     0.65 rem cells with 0.1/0.15 rem padding give ~115 mm of table
     width, well inside the print area. */
  .monthly-returns-wrapper { overflow: visible; }
  table.monthly-returns    { font-size: 0.65rem; max-width: 100%; }
  table.monthly-returns th,
  table.monthly-returns td { padding: 0.1rem 0.15rem; }
}

/* ===== Mini-site editorial design (6.60) — scoped to body.pt-site ===== */
:root{
  --pt-paper:#FBF9F4; --pt-ink:#1A1916; --pt-muted:#6B665C; --pt-soft:#43423D;
  --pt-accent:#1B5E54; --pt-accent-dk:#123F38; --pt-hair:#E7E1D4; --pt-tint:#EDF3F0; --pt-card:#FFFFFF;
  --pt-rule:#D8CFBB;  /* 7.13 : filet de rangée un cran plus net que --pt-hair (toujours ivoire/sépia) */
  --pt-prose:720px;   /* editorial text-column width (caps main>* children) */
  --pt-serif:'Fraunces',Georgia,serif; --pt-sans:'Hanken Grotesk',system-ui,sans-serif;
  --pt-mono:'IBM Plex Mono',ui-monospace,monospace; --pt-maxw:704px;
}
@font-face{font-family:'Fraunces';font-weight:400;font-style:normal;font-display:swap;src:url('../fonts/fraunces-400.woff2') format('woff2');}
@font-face{font-family:'Fraunces';font-weight:500;font-style:normal;font-display:swap;src:url('../fonts/fraunces-500.woff2') format('woff2');}
@font-face{font-family:'Fraunces';font-weight:600;font-style:normal;font-display:swap;src:url('../fonts/fraunces-600.woff2') format('woff2');}
@font-face{font-family:'Hanken Grotesk';font-weight:400;font-style:normal;font-display:swap;src:url('../fonts/hanken-400.woff2') format('woff2');}
@font-face{font-family:'Hanken Grotesk';font-weight:500;font-style:normal;font-display:swap;src:url('../fonts/hanken-500.woff2') format('woff2');}
@font-face{font-family:'Hanken Grotesk';font-weight:600;font-style:normal;font-display:swap;src:url('../fonts/hanken-600.woff2') format('woff2');}
@font-face{font-family:'IBM Plex Mono';font-weight:500;font-style:normal;font-display:swap;src:url('../fonts/plexmono-500.woff2') format('woff2');}

/* max-width:none + padding:0 : neutralise la règle de base `body{max-width:860px;
   padding:0 1rem}` (6.72) qui fuyait sur les bodies skinnés et clampait le cadre
   interne 1040 à ~828px. Le cadre vient désormais UNIQUEMENT de .wrap/main/
   body:has(nav.toc) → 1040 centré réel partout. */
body.pt-site{background:var(--pt-paper);color:var(--pt-ink);font-family:var(--pt-sans);
  font-size:17px;line-height:1.72;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;margin:0;max-width:none;padding:0;}
.pt-site a{color:var(--pt-accent);text-decoration:none;}
.pt-site a:hover{color:var(--pt-accent-dk);text-decoration:underline;text-underline-offset:3px;}

.pt-site .site-nav{background:var(--pt-paper);}  /* hairline portée par .site-nav .inner (6.68) */
/* 6.67 — Dimensionnement du bandeau nav UNIFIÉ (source unique, non scopée par
   skin) : bandeau pixel-identique sur toutes les pages (mini-site + form +
   résultats) → aucun saut vertical/horizontal en navigation. Largeur = celle
   de la page résultats (la plus dense, cœur de l'outil) ; padding = valeurs
   data. Le contenu sous la nav garde sa propre largeur par page. Les règles
   `.pt-site/.pt-app .site-nav .inner` divergentes ont été retirées (6.67). */
.site-nav .inner{max-width:var(--pt-frame);margin:0 auto;padding:16px 28px;border-bottom:1px solid var(--pt-hair);display:flex;
  align-items:baseline;justify-content:space-between;gap:20px;flex-wrap:wrap;}
.pt-site .brand{font-family:var(--pt-serif);font-weight:600;font-size:19px;color:var(--pt-ink);}
/* 7.151v2 : align-items:baseline → tous les items (liens nus ET navlink-group)
   alignent leur TEXTE sur la même ligne de base. Sans ça (défaut stretch),
   l'item .current (border-bottom + padding-bottom) rend la rangée plus haute et
   les liens nus (ex. « À propos ») se collent en haut → flottent au-dessus des
   groupes (qui centrent en interne). Les sous-menus restent absolus (intacts). */
.pt-site .navlinks{display:flex;align-items:baseline;gap:22px;font-size:14.5px;flex-wrap:wrap;}
.pt-site .navlinks a{color:var(--pt-muted);}
.pt-site .navlinks a:hover{color:var(--pt-accent-dk);text-decoration:none;}
.pt-site .navlinks a.current{color:var(--pt-accent);border-bottom:2px solid var(--pt-accent);padding-bottom:3px;}

/* Sélecteur de langue (7.110) — dropdown « globe + code » (variante A).
   Générique (non préfixé) → statique (.pt-site) ET dynamique (.pt-app).
   Déclencheur fermé = globe (pine) + code courant (ink) + chevron (gris).
   Menu = nom plein + code mono, langue courante teintée pine.
   No-JS : le menu s'ouvre sur :focus-within (clic-focus souris / clavier /
   tap mobile focalise le bouton). JS (pages dynamiques) ajoute .js-dropdown
   qui neutralise focus-within et active le toggle .lang-open au clic →
   click-to-open maîtrisé sans conflit. CSS externe → md5-algo neutre. */
.lang-switch{position:relative;display:inline-flex;font-size:13px;}
/* Déclencheur (option 1, 7.111) — préfixé `.lang-switch ` pour battre la règle
   générique `.pt-app button` (main.css:1198, spécificité 0,1,1) qui, sur les pages
   DYNAMIQUES, peignait le bouton en pine plein + globe pine invisible (vert/vert).
   `.lang-switch .lang-trigger` = (0,2,0) > (0,1,1) ; hover (0,3,0) > `.pt-app
   button:hover` (0,2,1) → gagne indépendamment de l'ordre source. Statique
   (`.pt-site`, sans règle button générique) : rendu inchangé (fond paper sur header
   paper). Globe/caret/code dimensionnés ici via CSS (`stroke-width` est une propriété
   CSS → override de l'attribut SVG, AUCUN edit de markup). */
.lang-switch .lang-trigger{display:inline-flex;align-items:center;gap:7px;
  padding:5px 11px;border:0.5px solid var(--pt-hair);border-radius:8px;
  background:var(--pt-paper);color:var(--pt-ink);font:inherit;font-size:14px;font-weight:500;
  line-height:1;letter-spacing:0.04em;cursor:pointer;}
.lang-switch .lang-trigger:hover{background:var(--pt-card);border-color:var(--pt-accent);}
.lang-globe{width:16px;height:16px;color:var(--pt-accent);stroke-width:1.5;flex:none;}
.lang-switch .lang-trigger .lang-code{color:var(--pt-ink);font-weight:600;}
.lang-caret{width:11px;height:7px;color:var(--pt-muted);stroke-width:1.6;flex:none;
  transition:transform 0.15s ease;}
/* Pivot du chevron quand le menu est ouvert — consomme le hook `.lang-open` déjà
   posé par le JS toggle 7.110 (pas de recâblage JS ; lacune CSS comblée, 7.111). */
.lang-switch.lang-open .lang-caret{transform:rotate(180deg);}

.lang-menu{position:absolute;top:calc(100% + 6px);right:0;z-index:30;
  min-width:150px;margin:0;padding:5px;list-style:none;
  max-height:min(70vh,340px);overflow-y:auto;   /* 7.166 : 7 items → scroll si déborde (mobile) */
  background:var(--pt-paper);border:0.5px solid var(--pt-hair);border-radius:8px;
  box-shadow:0 6px 20px rgba(26,25,22,0.12);display:none;}
.lang-switch:focus-within>.lang-menu{display:block;}                /* repli no-JS */
.lang-switch.js-dropdown:focus-within>.lang-menu{display:none;}     /* JS actif : focus n'ouvre plus */
.lang-switch.js-dropdown.lang-open>.lang-menu{display:block;}       /* JS : toggle au clic */

.lang-menu li{margin:0;}
.lang-menu a{display:flex;align-items:center;justify-content:space-between;gap:18px;
  padding:7px 11px;border-radius:5px;color:var(--pt-muted);text-decoration:none;
  white-space:nowrap;}
.lang-menu a:hover{background:var(--pt-tint);color:var(--pt-accent-dk);text-decoration:none;}
.lang-menu .lang-code{font-family:var(--pt-mono);font-size:11.5px;letter-spacing:0.06em;
  color:var(--pt-muted);}
.lang-menu a.lang-active{background:var(--pt-tint);color:var(--pt-accent);font-weight:600;}
.lang-menu a.lang-active .lang-code{color:var(--pt-accent);}

/* ── Sommaire ancré en tête des pages éditoriales (7.141) ──────────────────
   Liste compacte de liens internes vers les <h2> (classe page-toc, JAMAIS
   `toc` qui marque la zone canari des pages résultat). Discret, multi-colonnes
   si la largeur le permet. Statique (pas de sticky → mobile sûr). */
.page-toc{margin:0 0 32px;padding:14px 18px;background:var(--pt-paper);
  border:1px solid var(--pt-hair);border-left:3px solid var(--pt-accent);border-radius:6px;}
.page-toc ul{list-style:none;margin:0;padding:0;display:grid;
  grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:3px 24px;}
.page-toc li{margin:0;}
.page-toc a{display:block;padding:2px 0;font-size:13.5px;line-height:1.35;
  color:var(--pt-muted);text-decoration:none;}
.page-toc a:hover{color:var(--pt-accent-dk);text-decoration:underline;}

/* ── Sous-menus dropdown du header (7.141) ─────────────────────────────────
   PUR CSS : hover (souris) + focus-within (clavier/tap du lien). Aucun JS →
   comportement identique sur pages statiques ET dynamiques (form/résultats/
   future-signal). Émis dans le header site-nav, AU-DESSUS de <nav class="toc">
   → md5-neutre. Le lien de 1er niveau reste cliquable (tap = navigation vers
   la page, qui montre alors son propre sommaire). Réutilise la logique du
   sélecteur de langue (variante CSS focus-within). */
.navlinks .navlink-group{position:relative;display:inline-flex;align-items:center;}
.navlinks .submenu{position:absolute;top:calc(100% + 12px);left:-14px;z-index:30;
  display:none;min-width:240px;max-width:340px;max-height:72vh;overflow:auto;
  margin:0;padding:8px 0;list-style:none;background:var(--pt-paper);
  border:1px solid var(--pt-hair);border-radius:8px;box-shadow:0 8px 28px rgba(0,0,0,.12);}
/* bridge transparent : franchit le gap lien→menu sans perdre le survol */
.navlinks .navlink-group::after{content:"";position:absolute;top:100%;left:0;right:0;height:16px;}
.navlinks .navlink-group:hover>.submenu,
.navlinks .navlink-group:focus-within>.submenu{display:block;}
.navlinks .submenu li{margin:0;}
.navlinks .submenu a{display:block;padding:6px 16px;font-size:13px;line-height:1.3;
  color:var(--pt-muted);white-space:normal;border-bottom:0;}
.navlinks .submenu a:hover{background:var(--pt-tint);color:var(--pt-accent-dk);text-decoration:none;}

/* ── Bandeau de preuves de la home (7.144, remplace le chapeau 7.142) ───────
   3 cartes sobres 10/25/100 ans sous le <h1>, au-dessus du formulaire (home
   uniquement, body.pt-app). Cohérent avec .page-toc (bordure accent, paper).
   Empilement vertical en mobile (≤ 720px). Pas de JS, pas de couleurs criardes. */
.pt-app .proof-strip{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin:2px 0 14px;}
.pt-app .proof-card{display:flex;flex-direction:column;gap:6px;padding:13px 16px;
  background:var(--pt-paper);border:1px solid var(--pt-hair);border-left:3px solid var(--pt-accent);
  border-radius:6px;text-decoration:none;}
.pt-app .proof-card:hover{border-color:var(--pt-accent);background:var(--pt-card);}
.pt-app .proof-label{font-size:11.5px;font-weight:600;letter-spacing:.04em;
  text-transform:uppercase;color:var(--pt-accent);}
.pt-app .proof-claim{font-size:12.5px;line-height:1.45;color:var(--pt-soft);}
.pt-app .proof-foot{max-width:var(--pt-prose);margin:0 0 26px;font-size:13px;
  line-height:1.5;color:var(--pt-muted);}
.pt-app .proof-foot a{color:var(--pt-accent);text-decoration:none;border-bottom:1px solid transparent;}
.pt-app .proof-foot a:hover{border-bottom-color:var(--pt-accent);}
/* 7.176-b : carte 10 ans = <form> POST (display:contents → le <button> devient
   l'item de grille) ; reset des surcharges génériques .pt-app button (text-align
   center / font / color / bg) pour que le bouton rende comme l'<a class=proof-card>. */
.pt-app .proof-strip form{display:contents;}
.pt-app button.proof-card{font:inherit;text-align:left;color:inherit;width:100%;}
@media (max-width:720px){.pt-app .proof-strip{grid-template-columns:1fr;}}

/* ── Fil de lecture : « Continuer » en pied de page éditoriale (7.145) ──────
   Bloc entre </main> et <footer> : lien « ← Précédent » discret à gauche, carte
   « next » (kicker + titre + accroche) à droite. Empilement en mobile. */
.read-next{max-width:var(--pt-prose);margin:10px 0 0;display:flex;flex-wrap:wrap;
  align-items:flex-start;justify-content:space-between;gap:16px;
  padding-top:22px;border-top:1px solid var(--pt-hair);}
.read-next .prev{align-self:center;color:var(--pt-muted);font-size:14px;text-decoration:none;}
.read-next .prev:hover{color:var(--pt-accent-dk);}
.read-next .next{margin-left:auto;display:flex;flex-direction:column;gap:3px;
  max-width:360px;padding:13px 16px;text-decoration:none;
  background:var(--pt-paper);border:1px solid var(--pt-hair);
  border-left:3px solid var(--pt-accent);border-radius:6px;}
.read-next .next:hover{border-color:var(--pt-accent);background:var(--pt-card);}
.read-next .next .kicker{margin:0;font-size:11px;font-weight:600;letter-spacing:.08em;
  text-transform:uppercase;color:var(--pt-accent);}
.read-next .next .title{font-family:var(--pt-serif);font-size:17px;line-height:1.2;color:var(--pt-ink);}
.read-next .next .teaser{font-size:12.5px;line-height:1.4;color:var(--pt-soft);}
@media (max-width:600px){.read-next{flex-direction:column;}
  .read-next .next{margin-left:0;max-width:none;}}

.pt-site main{max-width:var(--pt-frame);margin:0 auto;padding:54px 28px 72px;}
/* 6.69 — Cadre unique : la prose est bridée pour la lisibilité (~75 car.) mais
   PAS recentrée (pas de margin:auto) → elle démarre au bord gauche du cadre,
   identique au nav et aux pages data ; blanc à droite (asymétrie éditoriale). */
.pt-site main>*{max-width:var(--pt-prose);}
.pt-site .kicker{text-transform:uppercase;letter-spacing:.16em;font-size:12px;font-weight:600;color:var(--pt-accent);margin:0 0 14px;}
.pt-site h1{font-family:var(--pt-serif);font-weight:600;font-size:clamp(2.2rem,6vw,2.75rem);line-height:1.08;letter-spacing:-.012em;margin:0 0 26px;}
.pt-site h2{font-family:var(--pt-serif);font-weight:600;font-size:1.5rem;line-height:1.25;margin:50px 0 16px;padding-top:24px;border-top:1px solid var(--pt-hair);letter-spacing:-.005em;}
.pt-site p{margin:0 0 20px;}
.pt-site .lede{font-size:19.5px;line-height:1.6;}
.pt-site em{font-style:italic;} .pt-site strong{font-weight:600;}

.pt-site .universe{margin:30px 0 8px;padding:24px 26px;background:var(--pt-card);border:1px solid var(--pt-hair);border-radius:10px;}
.pt-site .universe .note{font-size:15px;color:var(--pt-muted);margin:0 0 16px;line-height:1.6;}
.pt-site .universe ul{list-style:none;margin:0;padding:0;}
.pt-site .universe li{padding:13px 0;border-top:1px solid var(--pt-hair);font-size:15.5px;line-height:1.65;}
.pt-site .universe li:first-child{border-top:none;padding-top:0;}
.pt-site .cat{display:block;text-transform:uppercase;letter-spacing:.1em;font-size:11.5px;font-weight:600;color:var(--pt-accent);margin-bottom:6px;}
.pt-site .tk{font-family:var(--pt-mono);font-weight:500;font-size:13.5px;letter-spacing:.01em;color:var(--pt-soft);}

.pt-site .caveat{margin:46px 0 0;padding:18px 22px;background:var(--pt-tint);border-left:3px solid var(--pt-accent);}
.pt-site .caveat .lbl{display:block;text-transform:uppercase;letter-spacing:.14em;font-size:11.5px;font-weight:600;color:var(--pt-accent-dk);margin-bottom:7px;}
.pt-site .caveat p{font-size:15.5px;color:var(--pt-soft);margin:0;line-height:1.62;}

/* Chart figures (7.7) — responsive, explicitly capped to the prose column and
   left-aligned with the text (don't rely only on the main>* cap). box-sizing on
   the image keeps its 1px border inside the column (no sub-pixel overhang). */
.pt-site figure.chart{max-width:var(--pt-prose);margin:34px 0 8px;margin-left:0;padding:0;}
.pt-site figure.chart img{box-sizing:border-box;width:100%;height:auto;display:block;border:1px solid var(--pt-hair);border-radius:10px;background:var(--pt-card);}
.pt-site figure.chart figcaption{margin-top:12px;font-size:14px;color:var(--pt-muted);line-height:1.6;}
.pt-site figure.chart figcaption strong{color:var(--pt-soft);font-weight:600;}

.pt-site footer{max-width:var(--pt-frame);margin:0 auto;padding:26px 28px 52px;border-top:1px solid var(--pt-hair);color:var(--pt-muted);font-size:13.5px;}

.pt-site main>*{animation:pt-rise .55s cubic-bezier(.2,.6,.2,1) both;}
.pt-site main>*:nth-child(1){animation-delay:.02s} .pt-site main>*:nth-child(2){animation-delay:.06s}
.pt-site main>*:nth-child(3){animation-delay:.10s} .pt-site main>*:nth-child(4){animation-delay:.14s}
.pt-site main>*:nth-child(5){animation-delay:.18s} .pt-site main>*:nth-child(n+6){animation-delay:.22s}
@keyframes pt-rise{from{opacity:0;transform:translateY(9px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.pt-site main>*{animation:none}}

/* 7.23 — Tableaux de correspondance fonds AV ↔ proxy US (methodology). Le mini-site
   n'avait pas de <table> ; style minimal sur les tokens existants (filets ivoire
   --pt-hair, muted, mono via .tk) — aucune couleur ni dimension inventée. Rendu
   dans une carte .universe voisine, titre en .cat. */
.pt-site table.fund-map{width:100%;border-collapse:collapse;margin:6px 0 2px;font-size:14px;}
.pt-site table.fund-map th,.pt-site table.fund-map td{
  text-align:left;vertical-align:top;padding:8px 10px;border-bottom:1px solid var(--pt-hair);line-height:1.5;}
.pt-site table.fund-map thead th{
  text-transform:uppercase;letter-spacing:.07em;font-size:11px;font-weight:600;
  color:var(--pt-muted);border-bottom:1.5px solid var(--pt-hair);}
.pt-site table.fund-map tbody tr:last-child td{border-bottom:none;}
.pt-site table.fund-map .tk{font-size:12.5px;}

/* ===== 7.160 — onglets répliques assurance-vie (CSS pur, 0 JS) =====
   Radios visually-hidden (jamais display:none → focus/flèches natifs) + label
   adjacent + panneaux. IDs identiques sur les 4 pages langue (documents distincts
   → pas de collision ; CSS partagé). */
.pt-site .av-tabs{margin:24px 0;display:flow-root;}
.pt-site .av-tab-radio{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;
  overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;}
.pt-site .av-tab{display:inline-block;padding:9px 15px;margin:0 4px -1px 0;cursor:pointer;
  font-size:14px;font-weight:600;color:var(--pt-muted);background:var(--pt-card);
  border:1px solid var(--pt-hair);border-radius:8px 8px 0 0;position:relative;}
.pt-site .av-tab:hover{color:var(--pt-accent);}
.pt-site .av-tab-radio:checked+.av-tab{color:var(--pt-accent-dk);background:var(--pt-card);
  border-bottom-color:var(--pt-card);z-index:2;}
.pt-site .av-tab-radio:focus-visible+.av-tab{outline:2px solid var(--pt-accent);outline-offset:2px;}
.pt-site .av-panel{display:none;clear:both;border:1px solid var(--pt-hair);
  border-radius:0 10px 10px 10px;padding:18px 22px;background:var(--pt-card);}
.pt-site .av-panel>:first-child{margin-top:0;}
.pt-site .av-panel>:last-child{margin-bottom:0;}
.pt-site .av-dist{font-size:14px;color:var(--pt-muted);margin:10px 0 14px;line-height:1.6;}
.pt-site #av-spirit2:checked~#av-panel-spirit2,
.pt-site #av-swisslife:checked~#av-panel-swisslife,
.pt-site #av-suravenir:checked~#av-panel-suravenir,
.pt-site #av-generali:checked~#av-panel-generali{display:block;}
/* 7.160 v6 — carte récapitulative des paramètres opérationnels (dl, hairline rows,
   2 colonnes label|valeur ; empile sous 520px ; pas de JS). */
.pt-site .av-card{display:grid;grid-template-columns:minmax(150px,34%) 1fr;
  margin:0 0 5px;border-top:1px solid var(--pt-hair);font-size:13.5px;}
.pt-site .av-card dt{padding:7px 14px 7px 0;font-weight:600;color:var(--pt-muted);
  border-bottom:1px solid var(--pt-hair);}
.pt-site .av-card dd{margin:0;padding:7px 0 7px 14px;color:var(--pt-ink);line-height:1.55;
  border-bottom:1px solid var(--pt-hair);}
.pt-site .av-card-foot{font-size:12px;color:var(--pt-muted);font-style:italic;margin:0 0 14px;}
@media (max-width:520px){
  .pt-site .av-card{grid-template-columns:1fr;}
  .pt-site .av-card dt{border-bottom:none;padding:7px 0 1px;}
  .pt-site .av-card dd{padding:1px 0 7px;}
}
/* impression : tous les panneaux ouverts et empilés, onglets masqués */
@media print{
  .pt-site .av-tab{display:none;}
  .pt-site .av-panel{display:block!important;border-radius:10px;margin-bottom:14px;page-break-inside:avoid;}
}

/* ===== Data/app skin (6.61) — scoped to body.pt-app. Reuses 6.60 tokens. ===== */
:root{ --pt-amber:#8A5A12; --pt-amber-bg:#F6EEDD; --pt-maxw-app:980px; --pt-frame:1040px; }

body.pt-app{background:var(--pt-paper);color:var(--pt-ink);font-family:var(--pt-sans);font-size:15.5px;line-height:1.6;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;margin:0;max-width:none;padding:0;}
.pt-app a{color:var(--pt-accent);text-decoration:none;} .pt-app a:hover{color:var(--pt-accent-dk);text-decoration:underline;}
.pt-app .num,.pt-app .tk{font-family:var(--pt-mono);font-weight:500;font-variant-numeric:tabular-nums;font-feature-settings:"tnum";letter-spacing:.01em;}
.pt-app .tk{color:var(--pt-soft);}

/* .pt-app .site-nav : hairline portée par .site-nav .inner (6.68) */
/* .pt-app .site-nav .inner : dimensionnement retiré en 6.67 → géré par la règle
   unique non scopée `.site-nav .inner` (nav unifiée, anti-saut). */
.pt-app .brand{font-family:var(--pt-serif);font-weight:600;font-size:19px;color:var(--pt-ink);}
.pt-app .navlinks{display:flex;align-items:baseline;gap:22px;font-size:14.5px;flex-wrap:wrap;}
.pt-app .navlinks a{color:var(--pt-muted);} .pt-app .navlinks a.current{color:var(--pt-accent);border-bottom:2px solid var(--pt-accent);padding-bottom:3px;}

.pt-app main,.pt-app .wrap{max-width:var(--pt-frame);margin:0 auto;padding:36px 28px 64px;}
.pt-app .kicker{text-transform:uppercase;letter-spacing:.16em;font-size:11.5px;font-weight:600;color:var(--pt-accent);margin:0 0 10px;}
.pt-app h1{font-family:var(--pt-serif);font-weight:600;font-size:2rem;line-height:1.1;letter-spacing:-.01em;margin:0 0 10px;}
.pt-app h2{font-family:var(--pt-serif);font-weight:600;font-size:1.3rem;margin:34px 0 12px;}
.pt-app .subline{color:var(--pt-muted);font-size:14.5px;display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:0 0 18px;}
.pt-app .chip{display:inline-flex;align-items:center;gap:6px;background:var(--pt-tint);color:var(--pt-accent-dk);font-size:12px;font-weight:600;padding:3px 10px;border-radius:999px;}
.pt-app .chip .dot{width:7px;height:7px;border-radius:50%;background:var(--pt-accent);display:inline-block;}
.pt-app .notice{margin:0 0 26px;padding:11px 16px;background:var(--pt-tint);border-left:3px solid var(--pt-accent);font-size:13.5px;color:var(--pt-soft);}

/* 7.12 : `div.metrics` (et non `.metrics`) — la grille de cartes dashboard ne doit
   PAS s'appliquer aux `table.metrics` des pages résultat (DM/composite), sinon le
   <table> devient une grille → <thead> et <tbody> côte à côte (en-têtes désalignés
   des colonnes). Les conteneurs de cartes sont toujours des <div class="metrics">
   (future-signal / rebalance) ; les tableaux résultat sont des <table class="metrics">. */
.pt-app div.metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:14px;margin:0 0 30px;}
.pt-app .metric{background:var(--pt-card);border:1px solid var(--pt-hair);border-radius:10px;padding:16px 18px;}
.pt-app .metric .lbl{text-transform:uppercase;letter-spacing:.1em;font-size:11px;font-weight:600;color:var(--pt-muted);margin:0 0 8px;}
.pt-app .metric .val{font-family:var(--pt-mono);font-weight:500;font-size:28px;letter-spacing:-.01em;color:var(--pt-ink);font-variant-numeric:tabular-nums;}
.pt-app .metric .val.pos{color:var(--pt-accent);}
.pt-app .metric .sub{font-size:12px;color:var(--pt-muted);margin-top:6px;}

.pt-app .panel{background:var(--pt-card);border:1px solid var(--pt-hair);border-radius:10px;margin:0 0 18px;overflow:hidden;}
.pt-app .panel .head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;padding:16px 20px;border-bottom:1px solid var(--pt-hair);flex-wrap:wrap;}
.pt-app .panel .head .t{font-family:var(--pt-serif);font-weight:600;font-size:17px;}
.pt-app .panel .head .w{font-size:12.5px;color:var(--pt-muted);}
.pt-app table{width:100%;border-collapse:collapse;font-size:14px;}
.pt-app thead th{text-align:left;text-transform:uppercase;letter-spacing:.08em;font-size:10.5px;font-weight:600;color:var(--pt-muted);padding:10px 20px;border-bottom:1px solid var(--pt-hair);}
.pt-app th.r,.pt-app td.r{text-align:right;}
.pt-app tbody td{padding:11px 20px;border-bottom:1px solid var(--pt-hair);}
.pt-app tbody tr:last-child td{border-bottom:none;}
.pt-app tbody tr.lead td{background:var(--pt-tint);}
.pt-app tbody tr.lead td:first-child{font-weight:600;}

.pt-app .pill,.pt-app .tag{font-size:11px;font-weight:600;padding:2px 9px;border-radius:6px;}
.pt-app .pill.hold,.pt-app .tag.hold{background:var(--pt-tint);color:var(--pt-accent-dk);}
.pt-app .pill.skip,.pt-app .tag.def{background:var(--pt-amber-bg);color:var(--pt-amber);}

.pt-app .target{display:flex;align-items:center;gap:10px;flex-wrap:wrap;background:var(--pt-card);border:1px solid var(--pt-hair);border-radius:10px;padding:16px 20px;margin:24px 0 0;}
.pt-app .target .lbl{text-transform:uppercase;letter-spacing:.1em;font-size:11px;font-weight:600;color:var(--pt-muted);}

.pt-app label{font-size:13.5px;font-weight:500;color:var(--pt-soft);}
.pt-app select,.pt-app input,.pt-app button,.pt-app textarea{font-family:var(--pt-sans);font-size:14.5px;color:var(--pt-ink);}
.pt-app select,.pt-app input[type=text],.pt-app input[type=number],.pt-app input[type=password]{background:var(--pt-card);border:1px solid var(--pt-hair);border-radius:8px;padding:8px 10px;}
.pt-app select:focus,.pt-app input:focus{outline:none;border-color:var(--pt-accent);box-shadow:0 0 0 3px var(--pt-tint);}
.pt-app button,.pt-app input[type=submit]{background:var(--pt-accent);color:#fff;border:none;border-radius:8px;padding:10px 18px;font-weight:600;cursor:pointer;}
.pt-app button:hover,.pt-app input[type=submit]:hover{background:var(--pt-accent-dk);}
.pt-app footer{max-width:var(--pt-frame);margin:0 auto;padding:24px 28px 48px;border-top:1px solid var(--pt-hair);color:var(--pt-muted);font-size:13px;}

/* Scoped fix-ups: keep semantic button variants distinct from the default
   accent button, and keep "back" submit-buttons as plain text links. All
   under .pt-app — no leak to the locked result page. */
.pt-app button.back-link,.pt-app input[type=submit].back-link{background:transparent;color:var(--pt-accent);border:none;padding:0;font-weight:600;cursor:pointer;}
.pt-app button.back-link:hover{background:transparent;color:var(--pt-accent-dk);text-decoration:underline;}
.pt-app .btn-danger{background:#B23B2E;} .pt-app .btn-danger:hover{background:#8F2F25;}
.pt-app .btn-secondary{background:var(--pt-tint);color:var(--pt-accent-dk);} .pt-app .btn-secondary:hover{background:var(--pt-hair);}
.pt-app .metric .val.positive,.pt-app .metric .val.pos{color:var(--pt-accent);}
.pt-app .metric .val.negative,.pt-app .metric .val.neg{color:#B23B2E;}
.pt-app .metric .val.neutral{color:var(--pt-muted);}
.pt-app .cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:18px;margin:0 0 18px;}
.pt-app th.numeric,.pt-app td.numeric{text-align:right;}

/* ===================================================================
   Results pages skin (6.63 / 2b-i) — scoped body.pt-app.
   Le markup des pages résultats est VERROUILLÉ (canari md5-algo) : seul
   ajout markup = class="pt-app" sur <body> (avant nav.toc). Ces règles
   ciblent donc UNIQUEMENT les classes DÉJÀ émises par
   dual-momentum-result.xsl / composite-portfolio-result.xsl.
   Hors périmètre 2b-i (→ 2b-ii) : fills/strokes des SVG + couleurs des
   cellules de la heatmap mensuelle (jamais touchées ici).
   =================================================================== */

/* Le <body> des pages résultats contient le contenu en direct (pas de
   .wrap). On le centre + élargit pour les tables denses, SANS toucher aux
   pages déjà wrappées (form/future-signal/rebalance n'ont pas de nav.toc). */
body.pt-app:has(nav.toc){max-width:var(--pt-frame);margin:0 auto;padding:0 28px 64px;}

/* Table of contents → carte discrète, accent pin. */
.pt-app nav.toc{background:var(--pt-card);border:1px solid var(--pt-hair);
  border-left:3px solid var(--pt-accent);border-radius:8px;}
.pt-app nav.toc a{color:var(--pt-muted);font-weight:500;}
.pt-app nav.toc a:hover{color:var(--pt-accent-dk);text-decoration:none;}
.pt-app nav.toc a + a::before{color:var(--pt-hair);}

/* Filet form↔résultats + notes discrètes. */
.pt-app .form-result-separator{border-top:1px solid var(--pt-hair);}
.pt-app .capture-note,.pt-app .active-note,.pt-app .signal-note,
.pt-app .future-signal-blurb,.pt-app .trades-summary{color:var(--pt-muted);}

/* CTA Future signal → bouton accent (cohérence pt-app). */
.pt-app a.btn-future-signal{background:var(--pt-accent);border-radius:8px;color:#fff;}
.pt-app a.btn-future-signal:hover{background:var(--pt-accent-dk);color:#fff;}

/* --- Tables « confortables » (peu de colonnes) : filets fins, en-têtes
   muted, valeurs tabulaires. Re-ciblage par classe (markup verrouillé). --- */
.pt-app table.metrics,.pt-app table.comparison,.pt-app table.capture,
.pt-app table.annual-returns,.pt-app table.rolling-summary,
.pt-app table.current-signal-scores,.pt-app table.benchmark-comparison,
.pt-app table.signal-scores{
  width:100%;border-collapse:collapse;font-size:14px;margin:0.4rem 0 1.5rem;}
.pt-app table.metrics th,.pt-app table.metrics td,
.pt-app table.comparison th,.pt-app table.comparison td,
.pt-app table.capture th,.pt-app table.capture td,
.pt-app table.annual-returns th,.pt-app table.annual-returns td,
.pt-app table.rolling-summary th,.pt-app table.rolling-summary td,
.pt-app table.current-signal-scores th,.pt-app table.current-signal-scores td,
.pt-app table.benchmark-comparison th,.pt-app table.benchmark-comparison td,
.pt-app table.signal-scores th,.pt-app table.signal-scores td{
  padding:9px 14px;border:none;border-bottom:1px solid var(--pt-hair);
  text-align:left;vertical-align:top;}
.pt-app table.metrics thead th,.pt-app table.comparison thead th,
.pt-app table.capture thead th,.pt-app table.annual-returns thead th,
.pt-app table.rolling-summary thead th,.pt-app table.current-signal-scores thead th,
.pt-app table.benchmark-comparison thead th,.pt-app table.signal-scores thead th{
  text-transform:uppercase;letter-spacing:.07em;font-size:10.5px;
  font-weight:600;color:var(--pt-muted);background:transparent;}
/* th de ligne (label gauche, tables clé/valeur). */
.pt-app table.metrics th,.pt-app table.comparison tbody th,
.pt-app table.capture tbody th{font-weight:600;color:var(--pt-soft);background:transparent;}
/* Valeurs en mono tabulaire (sauf metrics : contient de la prose composite). */
.pt-app table.comparison tbody td,.pt-app table.capture tbody td,
.pt-app table.annual-returns tbody td,.pt-app table.rolling-summary tbody td,
.pt-app table.current-signal-scores tbody td,
.pt-app table.benchmark-comparison tbody td,
.pt-app table.signal-scores tbody td{
  font-family:var(--pt-mono);font-variant-numeric:tabular-nums;
  font-feature-settings:"tnum";font-size:13px;}
.pt-app table.metrics td{font-variant-numeric:tabular-nums;}
/* Colonnes numériques alignées à droite (spécificité > la règle de base
   ci-dessus qui remet text-align:left). */
.pt-app table.comparison td:nth-child(n+2),
.pt-app table.capture td:nth-child(n+2),
.pt-app table.annual-returns td:nth-child(n+2),
.pt-app table.rolling-summary td:nth-child(n+2),
.pt-app table.benchmark-comparison td:nth-child(n+2),
.pt-app table.signal-scores td:nth-child(3),
.pt-app table.current-signal-scores td.score-cell{text-align:right;}
/* 7.13 — En-têtes des colonnes NUMÉRIQUES alignés à droite, comme leurs td
   (sinon titre à gauche / valeur à droite = grand vide, l'œil ne relie plus
   titre et colonne). Miroir exact des sélecteurs td ci-dessus → chaque en-tête
   suit l'alignement de sa colonne ; les colonnes texte (Metric/Year/Asset/
   Role/Window) restent à gauche. */
.pt-app table.comparison thead th:nth-child(n+2),
.pt-app table.capture thead th:nth-child(n+2),
.pt-app table.annual-returns thead th:nth-child(n+2),
.pt-app table.rolling-summary thead th:nth-child(n+2),
.pt-app table.benchmark-comparison thead th:nth-child(n+2),
.pt-app table.signal-scores thead th:nth-child(3),
.pt-app table.current-signal-scores thead th:nth-child(3){text-align:right;}

/* 7.16 — Colonne SERIES (texte) du Rolling Returns COMPOSITE alignée à gauche.
   Le composite (`rolling-summary` SANS `metrics` — le mono est
   `metrics rolling-summary`) met la colonne Window en <th rowspan="2"> : la
   numérotation nth-child des colonnes SE DÉCALE entre les deux rangées d'une
   fenêtre. La rangée « Portfolio » (avec le th) a SERIES en colonne 2 → la règle
   7.13 `td:nth-child(n+2)` la passe à DROITE ; la rangée « B&H SPY » (sans th) a
   SERIES en colonne 1 → reste à gauche → Portfolio et B&H SPY désalignés. SERIES
   est une colonne de NOMS : on la force à gauche (comme Window), sans toucher aux
   colonnes numériques (Average/High/Low/Count restent à droite). Ciblage robuste
   au décalage rowspan :
     • td:first-child  → la cellule SERIES de la rangée SANS th (B&H SPY) ;
     • th + td         → la cellule SERIES juste après le th (Portfolio) ;
     • thead th:nth-child(2) → l'en-tête « Series ».
   Mono exclu par :not(.metrics) (pas de colonne SERIES). */
.pt-app table.rolling-summary:not(.metrics) tbody td:first-child,
.pt-app table.rolling-summary:not(.metrics) tbody th + td,
.pt-app table.rolling-summary:not(.metrics) thead th:nth-child(2){text-align:left;}

/* 7.13 — Séparateurs de rangées un cran plus nets (toujours ivoire/sépia, pas
   de noir dur) : filet --pt-rule sur les rangées du tbody + sous l'en-tête. */
.pt-app table.metrics tbody th,.pt-app table.metrics tbody td,
.pt-app table.comparison tbody th,.pt-app table.comparison tbody td,
.pt-app table.capture tbody th,.pt-app table.capture tbody td,
.pt-app table.annual-returns tbody td,
.pt-app table.rolling-summary tbody th,.pt-app table.rolling-summary tbody td,
.pt-app table.current-signal-scores tbody td,
.pt-app table.benchmark-comparison tbody th,.pt-app table.benchmark-comparison tbody td,
.pt-app table.signal-scores tbody td{border-bottom-color:var(--pt-rule);}
.pt-app table.metrics thead th,.pt-app table.comparison thead th,
.pt-app table.capture thead th,.pt-app table.annual-returns thead th,
.pt-app table.rolling-summary thead th,.pt-app table.current-signal-scores thead th,
.pt-app table.benchmark-comparison thead th,.pt-app table.signal-scores thead th{
  border-bottom:1.5px solid var(--pt-rule);}

/* 7.14 — Filet de dernière rangée tronqué (Performance « Initial / Final »,
   Benchmark « Final value ») : ces tables clé/valeur portent un <th> de ligne ;
   la règle générique `.pt-app tbody tr:last-child td{border-bottom:none}` (6.61)
   supprime le filet des <td> de la dernière rangée mais PAS celui du <th> → un
   trait résiduel sous le seul label, qui n'atteint pas le bord droit du tableau.
   On supprime aussi le filet du <th> de la dernière rangée → bord bas propre,
   cohérent avec les tables sans <th> de ligne (capture/annual…), dont la dernière
   rangée n'a déjà aucun filet. */
.pt-app table.metrics tbody tr:last-child th,
.pt-app table.comparison tbody tr:last-child th,
.pt-app table.benchmark-comparison tbody tr:last-child th,
.pt-app table.capture tbody tr:last-child th,
.pt-app table.rolling-summary tbody tr:last-child th{border-bottom:none;}
/* rolling-summary composite : la colonne Window porte un <th rowspan="2"> ;
   celui de la DERNIÈRE fenêtre vit dans l'avant-dernière rangée mais son filet
   bas (rowspan) atterrit au bas du tableau, SOUS LA SEULE colonne Window → un
   moignon qui n'atteint pas le bord (les <td> de la dernière rangée sont déjà
   nettoyés par la règle 6.61). On neutralise ce filet → bord bas propre.
   Mono (Window en <td>, pas de rowspan) : aucun <th> en avant-dernière rangée
   → règle inerte. */
.pt-app table.rolling-summary tbody tr:nth-last-child(2) th{border-bottom:none;}

/* 7.14 — Largeur des blocs résultat unifiée. Les graphiques SVG et la heatmap
   mensuelle étaient plafonnés à 800/820px tandis que les tables remplissent le
   conteneur de contenu (width:100% → bord droit du cadre). On lève le plafond
   UNIQUEMENT sur la page résultat (body.pt-app:has(nav.toc)) → tables, graphiques
   et heatmap partagent le MÊME bord droit. Les autres pages (future-signal /
   rebalance) gardent leur plafond 800px (règles globales svg.*-chart /
   table.monthly-returns intactes). Ratio viewBox préservé (width:100% +
   height:auto) → graphiques ~2:1, hauteur raisonnable. */
body.pt-app:has(nav.toc) svg.equity-chart,
body.pt-app:has(nav.toc) svg.bar-chart,
body.pt-app:has(nav.toc) svg.dd-chart,
body.pt-app:has(nav.toc) svg.multi-line-chart,
body.pt-app:has(nav.toc) table.monthly-returns{max-width:none;}

/* --- Tables denses (beaucoup de colonnes) : padding compact ré-affirmé
   pour neutraliser le skin « confortable » générique de 6.61. --- */
.pt-app table.monthly-returns,.pt-app table.trades,.pt-app table.drawdowns{
  width:100%;border-collapse:collapse;}
.pt-app table.monthly-returns{font-size:0.72rem;}
.pt-app table.trades,.pt-app table.drawdowns{font-size:0.82rem;margin:0.4rem 0 1.5rem;}
.pt-app table.monthly-returns th,.pt-app table.monthly-returns td{
  padding:0.22rem 0.3rem;border:1px solid var(--pt-hair);}
.pt-app table.trades th,.pt-app table.trades td,
.pt-app table.drawdowns th,.pt-app table.drawdowns td{
  padding:0.34rem 0.6rem;border:1px solid var(--pt-hair);}
.pt-app table.monthly-returns thead th,.pt-app table.trades thead th,
.pt-app table.drawdowns thead th{
  text-transform:uppercase;letter-spacing:.04em;font-size:10px;
  font-weight:600;color:var(--pt-muted);background:transparent;}
.pt-app table.trades tbody td,.pt-app table.drawdowns tbody td,
.pt-app table.monthly-returns tbody td{
  font-family:var(--pt-mono);font-variant-numeric:tabular-nums;}
/* 7.13 — Tables denses (bordées) de la famille .trades : en-têtes alignés sur
   le même découpage que les td (4 colonnes meneuses texte/dates centrées, perf
   numériques à droite). Couvre mono trades, composite trades, mono drawdowns
   (class="trades drawdowns-table"). Le composite drawdowns nu reste cohérent
   (boxé, tout-gauche) → non touché. */
.pt-app table.trades thead th{text-align:right;}
.pt-app table.trades thead th:nth-child(-n+4){text-align:center;}

/* --- Current signal : carte propre façon panel. --- */
.pt-app .signal-card{background:var(--pt-card);border:1px solid var(--pt-hair);
  border-left:3px solid var(--pt-accent);border-radius:10px;padding:16px 20px;}
.pt-app .signal-card.risk{border-left-color:var(--pt-accent);background:var(--pt-card);}
.pt-app .signal-card.out_of_market{border-left-color:var(--pt-amber);background:var(--pt-amber-bg);}
.pt-app .signal-meta .signal-date{color:var(--pt-muted);}
.pt-app .signal-score{background:var(--pt-paper);border:1px solid var(--pt-hair);border-radius:8px;}
.pt-app .signal-score-value{font-family:var(--pt-mono);font-variant-numeric:tabular-nums;}

/* --- Impression : la peau écran ne doit pas casser la calibration A4
   (les sélecteurs body.pt-app/.pt-app h1/h2 battent les règles print
   génériques en spécificité → on les ré-aligne ici, scopé pt-app). --- */
@media print {
  body.pt-app{background:#fff;font-size:11pt;}
  body.pt-app:has(nav.toc){max-width:100%;margin:0;padding:0;}
  .pt-app h1{font-size:1.3rem;}
  .pt-app h2{font-size:1.05rem;}
}

/* ===================================================================
   Chart + heatmap colours (6.65 / 2b-ii) — scoped body.pt-app.
   Tout est CSS : le markup SVG (Chart.pm) ne pose AUCUNE couleur inline,
   les couleurs viennent de classes (.line-strategy, .bar-positive, …) ;
   la heatmap utilise des classes par bucket (cell-<sign>-<n>). On harmonise
   la palette SANS aplatir l'information (séries distinctes, +/- divergents).
   Spécificité : `.pt-app svg.<chart> .<x>` (≥0,4,1) bat les règles d'origine.
   =================================================================== */
:root{
  --pt-pos:#2F7D5B; --pt-neg:#B14A33; --pt-bench:#A39C8C;
  --pt-series-2:#B07B2B; --pt-series-3:#3E5C76;
}

/* --- Structure commune des graphes : aire de tracé claire, filets hair --- */
.pt-app svg .plot-bg{fill:#FFFFFF;}
.pt-app svg .grid-line{stroke:var(--pt-hair);}
.pt-app svg .zero-line{stroke:var(--pt-soft);}
.pt-app svg .axis-label{fill:var(--pt-muted);}
.pt-app svg .legend-text{fill:var(--pt-soft);}

/* --- Equity / rolling (multi-line-chart) : héros teal, benchmark gris chaud,
   composantes ocre/ardoise, fenêtres rolling en 3 teintes mates. --- */
.pt-app svg.multi-line-chart .line.line-strategy,
.pt-app svg.multi-line-chart .line.line-portfolio,
.pt-app svg.multi-line-chart .line.multi-series-0{stroke:var(--pt-accent);}
.pt-app svg.multi-line-chart .line.line-benchmark{stroke:var(--pt-bench);}
.pt-app svg.multi-line-chart .line.line-component-a,
.pt-app svg.multi-line-chart .line.multi-series-1{stroke:var(--pt-series-2);}
.pt-app svg.multi-line-chart .line.line-component-b,
.pt-app svg.multi-line-chart .line.multi-series-2{stroke:var(--pt-series-3);}
.pt-app svg.multi-line-chart .legend-dot.line-strategy,
.pt-app svg.multi-line-chart .legend-dot.line-portfolio,
.pt-app svg.multi-line-chart .legend-dot.multi-series-0{fill:var(--pt-accent);}
.pt-app svg.multi-line-chart .legend-dot.line-benchmark{fill:var(--pt-bench);}
.pt-app svg.multi-line-chart .legend-dot.line-component-a,
.pt-app svg.multi-line-chart .legend-dot.multi-series-1{fill:var(--pt-series-2);}
.pt-app svg.multi-line-chart .legend-dot.line-component-b,
.pt-app svg.multi-line-chart .legend-dot.multi-series-2{fill:var(--pt-series-3);}

/* --- Barres annual / active : positif vert posé, négatif rouge brique.
   bar-benchmark garde son opacité réduite (même teinte, B&H discret). --- */
.pt-app svg.bar-chart .bar.bar-positive{fill:var(--pt-pos);}
.pt-app svg.bar-chart .bar.bar-negative{fill:var(--pt-neg);}
.pt-app svg.bar-chart .legend-swatch.bar-strategy.bar-positive,
.pt-app svg.bar-chart .legend-swatch.bar-strategy{fill:var(--pt-pos);}
.pt-app svg.bar-chart .legend-swatch.bar-benchmark{fill:var(--pt-pos);}

/* --- Drawdowns underwater : aire de perte rouge brique translucide ;
   DM en rouge brique plein, B&H en gris chaud dashé (distinguables). --- */
.pt-app svg.dd-chart .dd-area{fill:rgba(177,74,51,0.20);}
.pt-app svg.dd-chart .dd-line.line-strategy{stroke:var(--pt-neg);}
.pt-app svg.dd-chart .dd-line.line-benchmark{stroke:var(--pt-bench);}
.pt-app svg.dd-chart .legend-dot.line-strategy{fill:var(--pt-neg);}
.pt-app svg.dd-chart .legend-dot.line-benchmark{fill:var(--pt-bench);}
.pt-app svg.dd-chart .dd-annotation-dot{fill:var(--pt-neg);}

/* --- Heatmap mensuelle : échelle divergente harmonisée (translucide pour
   garder un texte foncé lisible). Positifs = teal (27,94,84), négatifs =
   brique (177,74,51), neutre ≈ gris chaud très léger. Divergence préservée. --- */
.pt-app .monthly-returns .cell-positive-1{background:rgba(27,94,84,0.10);}
.pt-app .monthly-returns .cell-positive-2{background:rgba(27,94,84,0.22);}
.pt-app .monthly-returns .cell-positive-3{background:rgba(27,94,84,0.38);}
.pt-app .monthly-returns .cell-positive-4{background:rgba(27,94,84,0.55);}
.pt-app .monthly-returns .cell-negative-1{background:rgba(177,74,51,0.10);}
.pt-app .monthly-returns .cell-negative-2{background:rgba(177,74,51,0.22);}
.pt-app .monthly-returns .cell-negative-3{background:rgba(177,74,51,0.38);}
.pt-app .monthly-returns .cell-negative-4{background:rgba(177,74,51,0.55);}
.pt-app .monthly-returns .cell-neutral-1,
.pt-app .monthly-returns .cell-neutral-2,
.pt-app .monthly-returns .cell-neutral-3,
.pt-app .monthly-returns .cell-neutral-4{background:rgba(107,102,92,0.10);color:var(--pt-soft);}

/* ===================================================================
   6.68 — Bandeau nav ROBUSTE (revert du full-bleed fragile de 6.67).
   Anti-saut SANS hack : la règle unique `.site-nav .inner` (max-width 980 =
   largeur du plus étroit conteneur centré — le .wrap du form ; margin:0 auto)
   place le contenu du bandeau au MÊME endroit sur toutes les pages, car tous
   les conteneurs (body pleine largeur ; body 1040 des résultats ; .wrap 980 du
   form) sont centrés dans le viewport. La hairline est portée par `.inner`
   (bande 980 centrée) → séparateur identique partout, sans débordement
   horizontal. Les bricolages de 6.67 (full-bleed, clip de débordement, marge
   négative de flush) ont été retirés.
   Flush-top SANS marge négative : padding-top:0 du conteneur au-dessus du
   bandeau. Résultats : body:has(nav.toc) a déjà padding-top:0. Form : le
   bandeau est DANS .wrap → on annule le padding-haut de CE .wrap via :has. ===*/
.pt-app .wrap:has(> .site-nav){padding-top:0;}

/* ===================================================================
   6.70 — Alignement PIXEL du bord gauche bandeau/contenu.
   Quand le bandeau est IMBRIQUÉ dans un conteneur de cadre déjà inseté de 28px
   (résultats : body:has(nav.toc) ; form : .wrap), le `.inner` ne doit PAS
   ré-appliquer son padding horizontal — sinon double inset (28+28) → le
   wordmark se retrouve 28px à droite du contenu. On l'annule dans ces 2 cas.
   Ailleurs (mini-site, future-signal, rebalance) le bandeau est enfant direct
   d'un body NON inseté → le padding 28 du `.inner` EST l'inset du cadre, gardé.
   Résultat : wordmark-left = contenu-left = bord-cadre + 28, sur toutes les pages.
   =================================================================== */
body.pt-app:has(nav.toc) > .site-nav .inner,
.pt-app .wrap > .site-nav .inner{padding-left:0;padding-right:0;}
