/* ═══════════════════════════════════════════════════════════════════════
   Parcells' tokens (m394 C4): the one source of its colours, shapes and type, and of shadcn's variable
   names on them. Loaded first by every page of the app that loads static/page.css (sign-in, invitation,
   Équipe, Abonnement, legal, 404, /espace/aucun, the public site) and imported by the React shell's
   stylesheet (web/src/index.css), so a Jinja page and React read the same values; routers/partage.py
   inlines it in the shared page. Do not add raw colours elsewhere: add a token here.

   The brand guide's values (m243 C2, boards 4 and 8 of the UI audit v9). Primary (the parcel's green) for the
   UI; jalon (the yellow point) only for the logo's full stop, the end of a bornage and the greeting's full
   stop, never a fill; blue only in map data (--map-*).
   Theme: `.dark` on <html> (templates/_theme.html, from the promoimo_theme cookie, before the first paint);
   without script, the device's theme (`:root:not(.light):not(.dark)`); print puts the light values back.
   Dark is the frame's only (m431-06 C5): the rail, pages, panels and dialogs; the basemap, plans and PDFs stay light,
   and the map's paint keeps its light values (--map-*, --bm-*, and .map-paint below for the tokens a map layer
   reads). Outside the map, data swatches take --data-outline in dark and the stages' hues are lightened 35 % toward
   white (m394, board 8).
   ═══════════════════════════════════════════════════════════════════════ */

/* ─── The guide's tokens, light ─────────────────────────────────────── */
:root {
    --chalk: #f6f4ee;             /* the rail, the pages' ground, wells */
    --surface: #ffffff;           /* sheets, cards, popovers */
    --ground: #ebe8df;            /* under the map (the shell) */
    --ink: #1f2a22;
    --ink-2: #3c473e;             /* between ink and muted */
    --muted: #5d665c;             /* muted ink, ≥ 4.5:1 on chalk, surface and ground */
    --line: #e2e2d9;
    --line-strong: #7f877d;       /* a field's edge, icons, placeholders; never body text */
    --primary: #2f5a3e;           /* the parcel's green */
    --primary-hover: #2c5139;
    --primary-soft: #e6ebe8;
    --on-primary: #f6f4ee;
    --jalon: #e2a52a;             /* the yellow point: a dot, never a fill */
    --ok: #1f6a52;
    --warn: #8f4a10;
    --warn-inverse: #ec9b62;      /* the warn on the toast, the page's negative: the dark theme's warn */
    --danger: #a6301e;
    --grid: #e2e2d9;              /* the map's cadastral grid */
    --chart-1: #2a78d6;
    --chart-2: #eb6834;
    --edge: none;                 /* the logo's outline (dark only) */
    /* What floats (dialog, sheet, menu, popover, toast): its only shadow */
    --shadow: 0 1px 2px rgba(31, 42, 34, .06), 0 12px 28px -12px rgba(31, 42, 34, .22);
    --shadow-rgb: 31, 42, 34;     /* older shadows below: ink in light, black in dark */
    /* « Mes terrains » stages (web/src/routes/terrains reads them): data colours, ≥ 3:1 on paper for the dots and the
       map fills; signed and abandoned are ok and danger */
    --stage-repere: var(--line-strong);
    --stage-proprietaire: #3f6f9f;
    --stage-contacte: #5a62a8;
    --stage-discussion: #a0457a;
    --stage-offre: #7d5a9e;
    /* « Mes terrains » alerts on the map and in the Alertes tab: a sale is warn, a PLU change ok, a permit its
       own olive (no stage's hue, so an alert's point is never read as a deal's stage) */
    --alert-permit: #6e6a1a;
    --data-outline: transparent;  /* around a data swatch: nothing in light */
    --oap-ink: #5b21b6;           /* OAP's text-safe violet */
    --overlay: rgba(var(--shadow-rgb), 0.35);
    --shadow-md: 0 6px 20px -8px rgba(var(--shadow-rgb), 0.18);
    --shadow-lg: 0 12px 32px rgba(var(--shadow-rgb), 0.10);
    color-scheme: light;
}

/* ─── Dark (m209 C2, board 8) ───────────────────────────────────────── */
:root.dark {
    --chalk: #121a15;
    --surface: #19231d;
    --ground: #0d140f;
    --ink: #e4eae2;
    --ink-2: #c4cdc3;
    --muted: #93a095;
    --line: #28342c;
    --line-strong: #6d7c70;
    --primary: #8cc39c;
    --primary-hover: #9ccaa9;
    --primary-soft: #243328;
    --on-primary: #102016;
    --jalon: #e2a52a;
    --ok: #6fc9a9;
    --warn: #ec9b62;
    --warn-inverse: #8f4a10;
    --danger: #f3877b;
    --grid: #222d26;
    --chart-1: #3987e5;
    --chart-2: #d95926;
    --edge: #3a4c3f;
    --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 12px 28px -12px rgba(0, 0, 0, .6);
    --shadow-rgb: 0, 0, 0;
    --stage-proprietaire: color-mix(in srgb, #3f6f9f 65%, #ffffff);
    --stage-contacte: color-mix(in srgb, #5a62a8 65%, #ffffff);
    --stage-discussion: color-mix(in srgb, #a0457a 65%, #ffffff);
    --stage-offre: color-mix(in srgb, #7d5a9e 65%, #ffffff);
    --alert-permit: color-mix(in srgb, #6e6a1a 60%, #ffffff);
    --data-outline: color-mix(in srgb, var(--ink) 55%, transparent);
    --oap-ink: #c4b5fd;
    --overlay: rgba(0, 0, 0, 0.55);
    --shadow-md: 0 6px 20px -8px rgba(0, 0, 0, 0.5);
    --shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.4);
    color-scheme: dark;
}
/* Without script (no class on <html>): the device's theme, the same values */
@media (prefers-color-scheme: dark) {
    :root:not(.light):not(.dark) {
        --chalk: #121a15;
        --surface: #19231d;
        --ground: #0d140f;
        --ink: #e4eae2;
        --ink-2: #c4cdc3;
        --muted: #93a095;
        --line: #28342c;
        --line-strong: #6d7c70;
        --primary: #8cc39c;
        --primary-hover: #9ccaa9;
        --primary-soft: #243328;
        --on-primary: #102016;
        --jalon: #e2a52a;
        --ok: #6fc9a9;
        --warn: #ec9b62;
        --warn-inverse: #8f4a10;
        --danger: #f3877b;
        --grid: #222d26;
        --chart-1: #3987e5;
        --chart-2: #d95926;
        --edge: #3a4c3f;
        --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 12px 28px -12px rgba(0, 0, 0, .6);
        --shadow-rgb: 0, 0, 0;
        --stage-proprietaire: color-mix(in srgb, #3f6f9f 65%, #ffffff);
        --stage-contacte: color-mix(in srgb, #5a62a8 65%, #ffffff);
        --stage-discussion: color-mix(in srgb, #a0457a 65%, #ffffff);
        --stage-offre: color-mix(in srgb, #7d5a9e 65%, #ffffff);
        --alert-permit: color-mix(in srgb, #6e6a1a 60%, #ffffff);
        --data-outline: color-mix(in srgb, var(--ink) 55%, transparent);
        --oap-ink: #c4b5fd;
        --overlay: rgba(0, 0, 0, 0.55);
        --shadow-md: 0 6px 20px -8px rgba(0, 0, 0, 0.5);
        --shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.4);
        color-scheme: dark;
    }
}

/* ─── The seasonal decor (decor.py, <html data-decor>): decoration only, read by nothing else ─────────────
   One line, the green of the theme thinned, and one accent a moment: its hue mixed toward the ink, so it goes darker
   on a light page and lighter on a dark one. Winter and Noël keep to the greens. Never under a text, never on the map. */
:root {
    --decor-line: color-mix(in srgb, var(--primary) 50%, transparent);
    --decor-accent: var(--decor-line);
}
:root[data-decor="printemps"] { --decor-accent: color-mix(in srgb, #bb6a86 80%, var(--ink)); }
:root[data-decor="ete"], :root[data-decor="nouvel-an"] { --decor-accent: color-mix(in srgb, #bb8a2c 80%, var(--ink)); }
:root[data-decor="automne"] { --decor-accent: color-mix(in srgb, #b8652b 80%, var(--ink)); }
:root[data-decor="halloween"] { --decor-accent: color-mix(in srgb, #c96a1e 85%, var(--ink)); }
:root[data-decor="hiver"], :root[data-decor="noel"] { --decor-accent: color-mix(in srgb, var(--primary) 70%, transparent); }
.dc { display: block; pointer-events: none; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.dc path, .dc circle { stroke-width: 1.25; vector-effect: non-scaling-stroke; }
.dc .dc-l { stroke: var(--decor-line); }
.dc .dc-a { stroke: var(--decor-accent); fill: color-mix(in srgb, var(--decor-accent) 10%, transparent); }
.dc .dc-f { fill: var(--decor-accent); stroke: none; }
.dc .dc-j { fill: var(--jalon); stroke: none; }
.dc-glyph path, .dc-glyph circle { stroke-width: 1.5; }
/* Cut by a phone's width: the drawing fades at its two ends instead of stopping on half a tree */
.dc-band { mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent); }
.decor-stop { color: var(--jalon); font-weight: 700; }
@media (prefers-reduced-motion: no-preference) {
    .door-decor .dc, .dc-band { animation: dc-settle 900ms ease-out both; }
}
@keyframes dc-settle {
    from { opacity: 0; transform: translateY(-4px); }
}
@media print, (forced-colors: active) {
    .dc { display: none; }
}

/* ─── Derived names: they read the values above, so they follow the theme ─ */
:root {
    /* shadcn's variables (m394 C4). Its `--muted` is not redefined: Parcells' --muted stays the muted ink
       (shadcn's muted fill is --primary-soft, mapped in web/src/index.css) */
    --background: var(--ground);
    --foreground: var(--ink);
    --card: var(--surface);
    --card-foreground: var(--ink);
    --popover: var(--surface);
    --popover-foreground: var(--ink);
    --primary-foreground: var(--on-primary);
    --secondary: var(--primary-soft);
    --secondary-foreground: var(--ink-2);
    --muted-foreground: var(--muted);
    --accent: var(--wash);
    --accent-foreground: var(--ink);
    --destructive: var(--danger);
    --destructive-foreground: var(--on-primary);
    --border: var(--line);
    --input: var(--line-strong);  /* a field's edge, ≥ 3:1 on the surface */
    --ring: var(--primary);
    --radius: 10px;               /* field and button; badge 6, card 12, dialog 16, pill 999 */
    --sidebar: var(--chalk);
    --page: var(--surface);       /* a routed page's ground right of the rail (web/src/index.css #react-page) */
    --panel: var(--chalk);        /* a section that stands apart from its page (Mes terrains' band, the kanban's columns) */
    --sidebar-foreground: var(--ink);
    --sidebar-primary: var(--primary);
    --sidebar-primary-foreground: var(--on-primary);
    --sidebar-accent: var(--wash);
    --sidebar-accent-foreground: var(--ink);
    --sidebar-border: var(--line);
    --sidebar-ring: var(--primary);

    /* The hover and highlight wash (menus, ghost buttons, inline code, a chip's hover): ink at 6 % (#f1f2f1
       on the surface in light, #252f29 in dark), at 3 % for table stripes */
    --wash: color-mix(in srgb, var(--ink) 6%, transparent);
    --wash-2: color-mix(in srgb, var(--ink) 3%, transparent);
    /* A skeleton's lines (shadcn's Skeleton, board 7): ink at 10 %, and 6 % for a second line, so they show on
       the surface, the chalk and the ground alike, in both themes */
    --skeleton: color-mix(in srgb, var(--ink) 10%, transparent);
    --skeleton-2: color-mix(in srgb, var(--ink) 6%, transparent);
    /* States: ok, warn and danger are text with a word, never a background (m243 C2): the soft steps are
       transparent, their lines stay (#b1cbc2, #cdae93, #e0b7b0 on the surface in light) */
    --ok-soft: transparent;
    --ok-line: color-mix(in srgb, var(--ok) 35%, var(--surface));
    --warn-soft: transparent;
    --warn-line: color-mix(in srgb, var(--warn) 45%, var(--surface));
    --danger-soft: transparent;
    --danger-line: color-mix(in srgb, var(--danger) 35%, var(--surface));
    --focus: var(--primary);      /* the one ring: 2 px, 2 px off */

    /* The older names the stylesheets read (web/src/styles/carte.css, page.css, ui.css…) */
    --desk: var(--ground);
    --brand: var(--primary);
    --brand-ink: var(--primary-hover);
    --brand-200: var(--line);
    --brand-100: var(--line);
    --brand-soft: var(--primary-soft);
    --brand-50: var(--chalk);
    --brand-gradient: linear-gradient(var(--brand), var(--brand));
    --braise: var(--jalon);       /* the dot and micro-signs, never a fill to act on */
    --accent-ink: var(--primary);
    --accent-line: color-mix(in srgb, var(--primary) 30%, var(--surface));
    --accent-soft: var(--primary-soft);
    --ai: var(--brand);           /* AI actions look like any primary action */
    --ai-gradient: linear-gradient(var(--ai), var(--ai));
    --ink-muted: var(--muted);
    --subtle: var(--line-strong);
    --surface-2: var(--chalk);
    --surface-3: var(--ground);
    --bg: var(--chalk);
    --disabled: var(--ground);
    --night: var(--ink);          /* toasts, bulk bar */
    --night-2: var(--ink-2);
    /* Labels on fills: on primary, on-primary; on a state fill, the surface; on a data or app colour (PLU
       zones, DPE, stages, mousse), white in both themes; on a light data hue (PLU AU, A, other, U),
       --on-data-ink, near black in both themes, which keeps 4.5:1 where white does not */
    --on-brand: var(--on-primary);
    --on-state: var(--surface);
    --on-data: #ffffff;
    --on-data-ink: #0a0a0a;
    /* Picked plots (an ensemble, a study's plots): the map's selection hue, tinted on the surface */
    --pick-soft: color-mix(in srgb, var(--map-selection) 10%, var(--surface));
    --pick-line: color-mix(in srgb, var(--map-selection) 45%, var(--surface));
    --info: var(--brand);
    --info-soft: var(--brand-soft);
    --stage-signe: var(--ok);
    --stage-abandonne: var(--danger);

    /* PLU zone types, as the Géoportail zoning drawn on the map */
    --plu-u: #e53935;
    --plu-au: #f9a825;
    --plu-a: #43a047;
    --plu-n: #2e7d32;
    --plu-other: #8a94a6;
    /* The product's app colour (the mark beside the assistant's answers): the light green in both themes */
    --app-promoimo: #2f5a3e;

    /* Map data (web/src/map reads them): Parcells' blue stays here */
    --map-brand: #2563b8;
    --map-brand-ink: #1d4f96;
    --map-accent-ink: #b4450b;
    --map-scan-parcel: #1e6fd9;
    --map-scan-group: #ea6a1f;
    --map-selection: #ea6a1f;
    --map-majic: #7b1fa2;
    --map-selection-line: #ff8a3d;  /* the discussion's minimap: the selection's line */
    --map-apart: #ef4444;           /* … and a plot set apart */
    --map-grid: #e2e2d9;            /* the cadastre's line: the light grid in both themes (the map stays light) */
    --map-chosen: #2f5a3e;          /* the chosen parcel: 3 px of the light primary, no fill, in both themes */
    --map-oap: #7c3aed;
    --map-bati: #c9ced8;
    --map-bati-line: #8a93a3;
    --map-bati-2: #b7bdc8;
    --map-dvf-1: #fee8c8;           /* DVF prices, low to high (the map's heat ramp) */
    --map-dvf-2: #fdbb84;
    --map-dvf-3: #e34a33;
    --map-dvf-4: #7f0000;
    --map-risk: #c62828;            /* risk layers (routers/dossier.py draws them too) */
    --map-risk-water: #1e88e5;
    --map-risk-fire-from: #fdd835;
    --map-risk-fire: #fb8c00;
    --map-site: #dd0000;
    --map-top10: #14513f;           /* the top 10's numbered points */
    --plan-frame: #d81b60;          /* the parcel framed on a PLU plan's page, in the viewer (board 59: magenta) */
    /* An owner's answer in the client space (routers/espace_client.py AVIS_COLORS draws the same) */
    --avis-none: #f3c623;
    --avis-interesse: #1f8a5c;
    --avis-pas-interesse: #b3382a;
    --avis-a-discuter: #2f6db3;
    --avis-a-discuter-ink: #2a5f9e;
    /* The basemap's pictures (layer menu), an ink line on it, a server-drawn plan, a PDF's page: unchanged in dark,
       like the tiles themselves (--bm-tone-* below) */
    --bm-white: #ffffff;
    --bm-ink: #1f2a22;
    --drawing: #ffffff;
    --bm-plan: #eef0ea;
    --bm-plan-road: #f5d88a;
    --bm-plan-green: #cfe6c3;
    --bm-sat-1: #56704a;
    --bm-sat-2: #6b5b45;
    --bm-sat-3: #3d5a3b;
    --bm-sat-4: #7b8a5d;
    --bm-sat-5: #a59b7a;
    --bm-osm: #f2efe9;
    --bm-osm-road: #f7c77f;
    --bm-osm-green: #add19e;
    --bm-topo-line: rgba(150, 110, 60, 0.35);
    --bm-topo-1: #e8e3d0;
    --bm-topo-2: #cfd9b8;

    /* Shape: badge 6, field and button 10, card 12, dialog 16 (the older scale's names) */
    --r-xs: 6px;
    --r-sm: 10px;
    --r-md: 10px;
    --r-lg: 12px;
    --r-xl: 16px;
    --r-pill: 10px;
    --shadow-xs: 0 1px 2px rgba(var(--shadow-rgb), 0.05);
    --shadow-sm: 0 1px 2px rgba(var(--shadow-rgb), 0.05), 0 4px 14px rgba(var(--shadow-rgb), 0.06);
    --shadow-side: 0 4px 12px rgba(var(--shadow-rgb), 0.12);   /* a sheet or panel over the map */
    --shadow-float: 0 12px 32px rgba(var(--shadow-rgb), 0.16);
    --shadow-brand: none;
    --shadow-seg: 0 1px 2px rgba(var(--shadow-rgb), 0.1);          /* a segmented control's chosen item */
    --shadow-edge: -14px 0 36px rgba(var(--shadow-rgb), 0.10);     /* a sheet standing at the right edge */
    --shadow-edge-2: -14px 0 36px rgba(var(--shadow-rgb), 0.14);   /* … the assistant's, over a sheet */

    /* Type: Asap large (Asap at wdth 112.5, static/fonts/fonts.css) for every word, Geist Mono 13 for codes.
       Board 4's scale (size/line): 32/40, 28/36, 20/28, 17/24, 15/22, 13/18, 12/16 */
    --font: "Asap", "Asap fallback", "Segoe UI", system-ui, sans-serif;
    --mono: "Geist Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
    --fs-xs: 12px;
    --fs-sm: 12px;
    --fs-md: 14px;
    --fs-lg: 16px;
    --fs-xl: 20px;
    --fs-2xl: 24px;
    --fs-code: 13px;
    --sp-1: 4px;
    --sp-2: 8px;
    --sp-3: 12px;
    --sp-4: 16px;
    --sp-5: 20px;
    --sp-6: 24px;
    /* Buttons (m394 C4): sm 34, default 40, icon 40 or 34; the field's 10 px corners */
    --btn-h: 40px;
    --btn-h-sm: 34px;
    --btn-r: 10px;

    /* Motion, touch */
    --ease: cubic-bezier(0.2, 0.8, 0.2, 1);
    --dur: 0.2s;
    --touch: 44px;
    --soft: var(--surface-2);
}

/* A skeleton in dark is opaque, ink at 10 % (6 %) on the surface: through a transparent mix it took the tone of what
   lay under it, so on the ground (the Assistant's list and thread) it sank to near black while it showed on the
   surface (Mes terrains, Équipe). Opaque, it is the same grey on every background, lighter than all of them (m379-94).
   Light keeps the transparent mix: there the ground is darker than the surface and a mix with it shows. */
:root.dark {
    --skeleton: color-mix(in srgb, var(--ink) 10%, var(--surface));
    --skeleton-2: color-mix(in srgb, var(--ink) 6%, var(--surface));
}
@media (prefers-color-scheme: dark) {
    :root:not(.light):not(.dark) {
        --skeleton: color-mix(in srgb, var(--ink) 10%, var(--surface));
        --skeleton-2: color-mix(in srgb, var(--ink) 6%, var(--surface));
    }
}

/* The basemap's tiles (map/layers.ts basemapTone, MapLibre's raster paint): as they come, in both themes (m431-06 C5:
   the maps stay light in the dark theme, Ivan 2026-10-21). Only the frame goes dark; no dark override here */
:root {
    --bm-tone-brightness: 1;
    --bm-tone-saturation: 0;
    --bm-tone-contrast: 0;
}

/* The dark frame (m431-06 C5): the rail one step lighter than the content, --surface over the --chalk pages, whose
   cards and panels are --surface again */
:root.dark {
    --sidebar: var(--surface);
    --page: var(--chalk);
    --panel: var(--surface);
}
@media (prefers-color-scheme: dark) {
    :root:not(.light):not(.dark) {
        --sidebar: var(--surface);
        --page: var(--chalk);
        --panel: var(--surface);
    }
}

/* Map paint (routes/terrains/colors.ts tokenColor resolves every map colour inside this class): the light values in
   both themes, since the map under them stays light; the frame's tokens a map layer reads (a halo on --surface, a
   point in --ok…) and the stages' hues come back to their light values here */
.map-paint {
    --surface: #ffffff;
    --ink: #1f2a22;
    --muted: #5d665c;
    --line-strong: #7f877d;
    --primary: #2f5a3e;
    --jalon: #e2a52a;
    --ok: #1f6a52;
    --warn: #8f4a10;
    --danger: #a6301e;
    --subtle: var(--line-strong);
    --stage-repere: var(--line-strong);
    --stage-proprietaire: #3f6f9f;
    --stage-contacte: #5a62a8;
    --stage-discussion: #a0457a;
    --stage-offre: #7d5a9e;
    --stage-signe: var(--ok);
    --stage-abandonne: var(--danger);
    --alert-permit: #6e6a1a;
}

/* A page printed from the dark theme prints light: the light values, on paper */
@media print {
    :root.dark, :root:not(.light):not(.dark) {
        --chalk: #f6f4ee;
        --surface: #ffffff;
        --ground: #ebe8df;
        --ink: #1f2a22;
        --ink-2: #3c473e;
        --muted: #5d665c;
        --line: #e2e2d9;
        --line-strong: #7f877d;
        --primary: #2f5a3e;
        --primary-hover: #2c5139;
        --primary-soft: #e6ebe8;
        --on-primary: #f6f4ee;
        --jalon: #e2a52a;
        --ok: #1f6a52;
        --warn: #8f4a10;
        --danger: #a6301e;
        --grid: #e2e2d9;
        --edge: none;
        --shadow-rgb: 31, 42, 34;
        --overlay: rgba(31, 42, 34, 0.35);
        --data-outline: transparent;
        --stage-proprietaire: #3f6f9f;
        --stage-contacte: #5a62a8;
        --stage-discussion: #a0457a;
        --stage-offre: #7d5a9e;
        --alert-permit: #6e6a1a;
        --sidebar: var(--chalk);
        --page: var(--surface);
        --panel: var(--chalk);
        --warn-inverse: #ec9b62;
        color-scheme: light;
    }
}
