/* ==========================================================================
   Nota — design tokens and styles.
   Brand system: Nota blue-teal, midnight ink, and the Québec signal.
   Deviation from Tablix on purpose: squared corners (Tablix uses rounded-xl).
   All colors are tokens — no literal color values below the :root blocks.
   ========================================================================== */

/* ==========================================================================
   Les polices, servies par Nota — jamais par un tiers.
   Inter (texte) et Sora (titres) arrivaient de fonts.googleapis.com : l'adresse
   IP et l'agent de CHAQUE visiteur atteignaient Google avant toute bannière, sur
   un site qui vend des actes notariés (propriétaire, 2026-09-12). Les octets
   vivent désormais dans /fonts, licence OFL jointe (fonts/OFL.txt).
   Ce sont les versions VARIABLES : un seul fichier par tranche couvre toutes
   les graisses. `swap` garde le texte lisible pendant le chargement.
   ========================================================================== */
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url('/fonts/inter-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url('/fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: 'Sora'; font-style: normal; font-weight: 100 800; font-display: swap;
  src: url('/fonts/sora-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: 'Sora'; font-style: normal; font-weight: 100 800; font-display: swap;
  src: url('/fonts/sora-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }


:root {
  /* Nota blue ramp: institutional cobalt for trust and rigor, with a
     restrained light blue for digital interactions. */
  --nota-blue-50: #ebf1f5;
  --nota-blue-100: #e5eef3;
  --nota-blue-200: #c8dbe3;
  --nota-blue-300: #a7c1cd;
  --nota-blue-400: #78a9bf;
  --nota-blue-500: #407598;
  --nota-blue-600: #386888;
  --nota-blue-700: #386888;
  --nota-blue-800: #274a62;
  --nota-blue-900: #264961;
  --nota-blue-950: #101b26;
  /* Warm Nota accent: use the dark value for text on light surfaces and the
     brighter value on midnight surfaces so the orange remains readable. */
  --nota-orange-600: #b45309;
  --nota-orange-400: #f79009;
  --accent-warm: var(--nota-orange-600);
  /* Channel-only copies of the three steps that alpha tokens below need
     (shadows, focus glow, background wash). rgb() cannot take a hex var, so
     these exist so no ramp value is ever retyped as a literal downstream. */
  --nota-blue-400-rgb: 120 169 191;
  --nota-blue-500-rgb: 64 117 152;
  --nota-blue-700-rgb: 56 104 136;

  /* Semantic tokens (light) */
  --brand: var(--nota-blue-700);
  /* Couleurs de MARQUE des fournisseurs tiers (portes à venir). Ce sont des
     constantes appartenant à Google, Meta et LinkedIn : elles ne suivent pas
     le thème et ne se redéfinissent nulle part — mais elles restent des
     jetons nommés plutôt que des littéraux dispersés dans les règles. */
  --marque-google-chip: var(--paper); /* le « G » doit rester sur fond blanc */
  --marque-facebook: #1877f2;
  --marque-linkedin: #0a66c2;
  --brand-bright: var(--nota-blue-500);
  --brand-ink: var(--paper);
  --brand-hover: var(--nota-blue-800);
  --on-accent: var(--paper); /* text/knob on saturated accents (tier pills, toggle) — white in every theme */

  /* The LIGHT canvas, named once. Two blocks need these exact values: the
     light theme itself, and the print block far below, which has to restate a
     light canvas because both dark blocks outrank :root on paper. Naming them
     here means the print block aliases instead of retyping — a light value
     exists in exactly one place (ADR 0048). */
  --canvas-bg: #eef5f7;
  --canvas-surface: #fbfdfd;
  --canvas-surface-inset: #e6f0f4;
  --canvas-surface-hover: #dcecf2;
  --canvas-ink: #173b52;
  --canvas-ink-muted: #526b78; /* was #607986: 4.49:1 on the surface, 3.79 on the canvas — under AA for the 12–15px muted text it colours; #526b78 clears 4.6 everywhere (2026-09-11) */
  --canvas-subtitle-ink: #000000;
  --canvas-border: #c5d8df;
  --canvas-border-strong: #a9c3ce;
  --paper: #ffffff; /* true white — printed paper, and the ink on a brand fill */

  --bg: var(--canvas-bg);
  --surface: var(--canvas-surface);
  --surface-inset: var(--canvas-surface-inset);
  --surface-hover: var(--canvas-surface-hover);
  --ink: var(--canvas-ink);
  --ink-muted: var(--canvas-ink-muted);
  --subtitle-ink: var(--canvas-subtitle-ink);
  --border: var(--canvas-border);
  --border-strong: var(--canvas-border-strong);
  --ring: var(--nota-blue-600);

  /* The arrival canvas is intentionally quieter than the product theme. It
     keeps the brand blue in the mark and the actions without turning the
     whole first screen into a saturated colour field. */
  --intro-bg: #eef5f7;
  --intro-surface: #fbfdfd;
  --intro-surface-veil: color-mix(in srgb, var(--intro-surface) 84%, transparent);
  --intro-surface-inset: #e6f0f4;
  --intro-surface-hover: #dcecf2;
  --intro-ink: #173b52;
  --intro-ink-muted: #526b78;
  --intro-border: #c5d8df;
  --intro-border-strong: #a9c3ce;
  --intro-tint: rgb(64 117 152 / .06);

  --danger: #b42318;
  --warn: var(--accent-warm);
  --ok: var(--nota-blue-600);
  --danger-solid: #b42318; /* solid deep red for badge fills — dark --danger is a light salmon that fails white-text contrast */
  /* The tint pair (owner, 2026-08-27: « components carry no opacity — the
     background does »): --brand-tint keeps its alpha and is RESERVED for the
     background layers (the body's top fade, --wash-glow, the intro film),
     where translucency lets the drifting marks live. --brand-tint-solid is
     the SAME wash mixed down to the surface — fully opaque — and is what
     components (chips, badges, step discs, hover fills) paint with, so
     nothing ever bleeds through a component. Auto-follows each theme:
     the mix resolves against that theme's --brand-bright / --surface. */
  --brand-tint: rgb(var(--nota-blue-500-rgb) / 0.05); /* faint brand wash — background layers only */
  --brand-tint-mix: 6%;
  --brand-tint-solid: color-mix(in srgb, var(--brand-bright) var(--brand-tint-mix), var(--surface));
  /* The HIGHLIGHT tint: one step richer than the component wash, for the one
     card a pane singles out (the notaire reward). Own mix, because the dark
     themes need a much deeper pour — at the component mix the highlight
     reads as washed grey on near-black, not as brand. */
  --brand-tint-mix-strong: 12%;
  --brand-tint-solid-strong: color-mix(in srgb, var(--brand-bright) var(--brand-tint-mix-strong), var(--surface));
  /* The ink the highlight card writes with. On light the deep --brand clears
     AA over the strong tint; on dark it does not (the tint is a POUR of the
     accent, so ink and ground converge), so the dark themes step up to the
     accent itself. One token, so .pr-kicker / .pr-amount never
     have to know which theme they are in. */
  --brand-on-tint-strong: var(--brand);
  /* L'encre d'un ÉTAT VIVANT — un onglet retenu, une ligne de marché survolée,
     la carte d'acte choisie. Sur papier, c'est la marque elle-même. Sur fond de
     nuit, --brand (#407598) est plus SOMBRE que l'encre : le libellé tombait à
     2,5–3,3:1 — il s'ÉTEIGNAIT au moment même où le doigt le désigne
     (propriétaire, 2026-09-12 : « le hover sur le financement… quel acte ? »).
     Les thèmes sombres montent donc d'un barreau, exactement comme
     --brand-on-tint-strong juste au-dessus. Aucune règle d'état ne repasse par
     --brand nu dans un `color:` — contraste-etats.test.mjs le refuse. */
  --brand-on-surface: var(--brand);
  /* L'encre du MOT « OTA » du lockup. Elle vivait dans une règle tardive
     (.brand-word { color: var(--brand-hover) }) qui battait sans le dire la
     règle de base 6 500 lignes plus haut, et le film d'accueil — canevas
     CLAIR même quand la page est en nuit — héritait alors d'un bleu de nuit
     posé sur du blanc. Un jeton, une seule règle.
     LE MOT EST DE L'ENCRE (propriétaire, 2026-09-12 : « the brand nota make
     the font white ») : blanc sur la nuit, noir sur le jour — le registre
     d'encre des titres vaut aussi pour la marque. Le bleu ne reste que sur ce
     qui SIGNALE : le carré du sceau et le point final du mot. */
  --brand-word-ink: var(--ink);
  /* The earlier 95 % skin (owner, 2026-08-27: « blanc c'est très beau… mais on
     pourrait mettre un tout petit peu d'opacité, genre quatre-vingt-quinze
     pour cent » — superseding the earlier 90 %) — the shared translucent
     surface for the LARGE landing panels (calendar, reward cards, gate
     cards), always paired with a backdrop blur so what bleeds through
     reads as light, not marks. Small controls (buttons, chips, inputs) and
     anything stacked (dialogs, dropdowns, sticky header) stay fully opaque.
     An alias like --brand-tint-solid: auto-follows each theme's --surface. */
  /* 2026-09-12: lighter panels, with text opacity preserved at 100%. */
  --surface-veil-mix: 84%;
  --surface-veil: color-mix(in srgb, var(--surface) var(--surface-veil-mix), transparent);
  /* The hover wash at the same register — for rows that light up OVER a
     veiled panel (the landing's market rows): an opaque hover card over a
     translucent panel read as a pasted-on sticker (owner: « le hover sur le
     financement est bizarre »). Auto-follows each theme's --surface-hover. */
  --surface-soft-veil: color-mix(in srgb, var(--surface) 58%, transparent);
  --panel-border: color-mix(in srgb, var(--border) 70%, transparent);
  --motion-fast: 150ms;
  --motion-ui: 220ms;
  --motion-enter: 320ms;
  --ease-ui: cubic-bezier(.22, 1, .36, 1);
  --surface-hover-veil: color-mix(in srgb, var(--surface-hover) var(--surface-veil-mix), transparent);

  /* Tier accent ramp — cool (calm) to warm (urgent).
     All five are dark enough for white .pill text to meet WCAG AA (>=4.5:1). */
  --tier-standard: #64748b;
  --tier-rapide: #356c87;
  --tier-prioritaire: #906800;
  --tier-urgence: #c2410c;
  --tier-extreme: #b42318;
  /* Outline text/border tint per tier — light = base, dark = brighter for AA
     (the dark values live in BOTH dark blocks below; keep all three in sync).
     Rapide is the CALM baseline and covers most of a month's cells, so its ink
     is NEUTRAL (owner, 2026-08-28, twice: « trop vert ») — the cell's tier bar
     and the legend dot keep the blue; the saturated ramp starts at urgency. */
  --tier-rapide-ink: var(--ink-muted); --tier-prioritaire-ink: var(--tier-prioritaire);
  --tier-urgence-ink: var(--tier-urgence); --tier-extreme-ink: var(--tier-extreme);

  /* Per-service categorical hues — deliberately distinct from the blue brand
     and the blue→red tier ramp; used only as calendar data-viz fills (the
     per-service mix bar + its legend). TWO acts of the financing family
     (ADR 0010): each act owns its token here, and every theme block below
     redefines BOTH — a service colour must never fall back to a light value
     in the dark themes. */
  --svc-refinancement: #1677a5; /* cobalt blue → AA (>=4.5:1) for the small per-service count text */
  --svc-financement: #4f46e5; /* indigo → AA on light surfaces; clearly apart from the teal sibling */
  --svc-testament: #b45309;
  --svc-procuration: #7c3aed;

  /* Offer status: waiting for a notary vs. retained by one. var() aliases, so
     they track the theme automatically — do not duplicate into the dark blocks. */
  --status-ouverte: var(--brand-bright);
  --status-retenue: var(--ink-muted);

  /* Geometry — ONE square scale for every shape (owner's ask, 2026-08-27:
     « tout garder le même style carré »). No pills, no circles: controls and
     chips take --radius, badges and knobs --radius-sm, thin bars --radius-xs.
     Pure signal DOTS (≤8px, border-radius:50%) are the only round survivors —
     a dot is punctuation, not a component. */
  --radius: 8px;
  --radius-sm: 6px;
  --radius-xs: 3px;
  --radius-lg: 12px;

  color-scheme: light;
  --shadow-sm: 0 1px 2px rgb(16 27 38 / .04), 0 4px 12px -8px rgb(16 27 38 / .12);
  --shadow: 0 2px 6px -3px rgb(16 27 38 / .07), 0 16px 36px -20px rgb(16 27 38 / .2);
  --shadow-lg: 0 24px 50px -16px rgb(var(--nota-blue-700-rgb) / 0.24);
  --shadow-brand: 0 6px 18px -8px rgb(var(--nota-blue-700-rgb) / .24); /* brand-primary hover lift */
  --logo-shadow: 0 1px 2px rgb(16 27 38 / 0.15);       /* header brand mark */
  --focus-ring: rgb(var(--nota-blue-500-rgb) / 0.3);      /* brand focus glow (3px) */
  --backdrop: rgb(16 27 38 / 0.20);                    /* light dialog scrim keeps the page readable */
  --backdrop-soft: rgb(16 27 38 / 0.16);               /* the tour's light scrim — it guides, it does not seal the page */

  --font-sans: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, monospace;
  /* The wordmark uses a custom monoline SVG, so every letter stays aligned at
     every size. Sora is the display face of EVERY heading — owner, 2026-09-10:
     the Signature beta page is the reference and the whole app follows it. */
  --font-display: 'Sora', var(--font-sans);
  --weight-display: 700;
  /* --- Type scale: quieter headings, comfortable running text -----------
     One register for the whole app. No heading rule sets its own size, face
     or weight — it reads a step of this scale (typographie.test.mjs enforces
     it), so the three doors, the dialogs and the beta print one voice. */
  --type-h1: clamp(26px, 2.25vw, 36px); --type-h1-lh: 1.12; --type-h1-ls: -.04em;
  --type-h1-compact: clamp(26px, 6vw, 32px); /* the stacked (narrow) hero */
  --type-h2: clamp(19px, 1.5vw, 24px); --type-h2-lh: 1.2; --type-h2-ls: -.035em;
  --type-h3: 17px; --type-h3-lh: 1.3; --type-h3-ls: -.02em;
  --type-h4: 15px; --type-h4-lh: 1.3; --type-h4-ls: -.01em; /* dense card kickers (.nc-h, .nc-live-h, .nc-conformite-h) — ADR 0050, addendum 2026-09-11 */
  --type-lead: 16px; --type-lead-lh: 1.6;
  --type-eyebrow: 12px; --type-eyebrow-ls: .1em;
  /* Body register (owner, 2026-09-11: « every font size the same across ALL
     applications »): the running-text size and leading, named so the brand
     guide, the pitch deck and the business plan read the SAME step instead of
     15 / 16.5 / browser-default. Mirrored verbatim in tokens.css,
     signature.css, brand.html, pitch-deck.html, business-plan.html
     (typographie.test.mjs compares every copy). */
  --type-body: 16px; --type-body-lh: 1.5;

  --maxw: 1600px; /* maximized width — fills wide screens, side padding via .wrap */
  --gap: 20px;
  /* Spacing scale. These are the values already most used in this file, named
     so neighbouring components stop drifting 1-3px apart. */
  --space-1: 2px;  --space-2: 4px;   --space-3: 6px;   --space-4: 8px;
  --space-5: 10px; --space-6: 12px;  --space-7: 14px;  --space-8: 16px;
  --space-9: 18px; --space-10: 20px; --space-12: 24px; --space-14: 28px;
  --space-16: 32px;
  /* The intro's responsive breathing room, shared with anything that must
     top-align with the intro's first line (e.g. the notary sign-in card). */
  --intro-pad-top: clamp(16px, 1.8vw, 24px);
  /* Ambient gradients (owner, 2026-08-27, superseding the morning's
     « gradient on every component »: « the gradient and the opacity are for
     the REST, not the component themselves »). Atmosphere lives ONLY on the
     background layers — the body's top fade, --wash-glow behind sections,
     the #site-bg drift. Components are flat, fully opaque surfaces
     (--surface / --surface-inset / --brand-tint-solid): their contrast
     never shifts with what sits beneath, and nothing bleeds through. */
  /* Each glow must reach full transparency BEFORE every edge of the box it
     paints (nearest-edge distance / radius >= the fade stop on all four
     sides), otherwise the box boundary slices the light and draws the very
     edge this token exists to avoid. */
  --wash-glow:
    radial-gradient(38% 52% at 72% 38%, var(--brand-tint) 26%, transparent 72%),
    radial-gradient(30% 52% at 22% 62%, var(--brand-tint) 26%, transparent 72%);
  /* The three decisions everything else derives from. */
  --pad-card: var(--space-6) var(--space-7);
  --pad-card-lg: var(--space-8) var(--space-9);
  --pad-dialog: var(--space-12);

  --header-h: 52px;   /* sticky .site-header height — thin band, submenus carry the rest */
  --sticky-top: 72px; /* header height + breathing gap — used for scroll-padding / scroll-margin */

  /* Fixed third-party brand-mark colours (Google / Outlook calendar logos).
     These are brand IDENTITY constants, NOT theme tokens: they must render
     identically in every theme and must never be restyled. Defined here only so
     no literal colour lives in markup — reference via var() in the SVG fills. */
  /* --- Surfaces that stay dark in EVERY theme ------------------------------
     The signing room (ADR 0047) and the video frames are a dark room by
     design: they do not flip with the theme, so they cannot read --ink / --bg
     / --danger-solid, which do. The roles they need are named ONCE here, with
     the dark theme's own values, rather than retyped as literals in the rules
     below (ADR 0048: a one-off hex in a component rule is a defect). */
  --midnight-ink: #f4f8fa;                    /* = the dark theme's --ink */
  --midnight-matte: #000000;                  /* letterbox behind a video frame */
  --midnight-veil-soft: rgb(255 255 255 / 0.04);   /* block fill on the rail */
  --midnight-veil: rgb(255 255 255 / 0.06);        /* quiet button fill */
  --midnight-veil-strong: rgb(255 255 255 / 0.12); /* its hover */
  --sheen: rgb(255 255 255 / 0.34);           /* inset top highlight on a raised panel */
  --danger-solid-rgb: 180 35 24;              /* channels of --danger-solid, for alpha washes */
  --danger-wash: rgb(var(--danger-solid-rgb) / 0.18); /* alert ground on a midnight surface */
  --danger-pale: #ffe4e1;                     /* the ink that reads on --danger-wash */
  --on-warn: #1b1300;                         /* ink on an --accent-warm fill */

  --logo-google-blue: #4285f4;
  --logo-google-green: #34a853;
  --logo-google-yellow: #fbbc05;
  --logo-google-red: #ea4335;
  --logo-outlook-blue: #0f6cbd;
  --logo-microsoft-red: #f25022;
  --logo-microsoft-green: #7fba00;
  --logo-microsoft-blue: #00a4ef;
  --logo-microsoft-yellow: #ffb900;
  --logo-on-brand: var(--paper);
}

/* Dark theme — system preference.
   A STANDALONE @media block: prefers-color-scheme now actually applies. The old
   form comma-joined a selector list to an @media rule (`:root[...], @media {...}`),
   which is invalid CSS and was silently discarded — so system-dark users got the
   light UI. Excludes an explicit light opt-out via :not([data-theme='light']). */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --brand: var(--nota-blue-500);
    --brand-bright: var(--nota-blue-400);
    --brand-ink: #061c2a;
    --brand-hover: var(--nota-blue-400);
    --accent-warm: var(--nota-orange-400);

    /* A cool blue-black canvas keeps the dark experience aligned with the
       Nota mark; no green cast remains in the page background. */
    --bg: #101820;
    --surface: #0f2030;
    --surface-inset: #132b3f;
    --surface-hover: #19384d;
    --ink: #f4f8fa;
    --ink-muted: #afc2cf;
    --subtitle-ink: #f4f8fa;
    --border: #294353;
    --border-strong: #3f5f70;
    --ring: var(--nota-blue-400);

    --danger: #f97066;
    --warn: var(--accent-warm);
    --ok: var(--nota-blue-500);
    --danger-solid: #b42318;
    --brand-tint: rgb(var(--nota-blue-400-rgb) / 0.06); /* softened three times (owner, 2026-08-28 « trop vert », 2026-09-01 « trop intense ») */
    --brand-tint-mix: 8%;
    --brand-tint-mix-strong: 20%; /* deep pour: on near-black a component-level mix greys out — but 26 % pushed --brand ink on the highlight card below AA, so the card now carries --brand-on-tint-strong instead */
    --brand-on-tint-strong: var(--brand-bright);
    --brand-on-surface: var(--brand-bright); /* l’encre des états vivants : un barreau plus clair, sinon le libellé s’éteint au moment où on le désigne */
    --brand-word-ink: var(--ink); /* le mot du lockup est blanc sur la nuit : de l'encre, jamais du bleu */

    --tier-standard: #64748b;
    --tier-rapide: #356c87;
    --tier-prioritaire: #906800;
    --tier-urgence: #c2410c;
    --tier-extreme: #b42318;
    --tier-rapide-ink: var(--ink-muted); /* NEUTRAL — the green cast was too much (owner, 2026-08-28) */ --tier-prioritaire-ink: #e0b44a; --tier-urgence-ink: #f0894c; --tier-extreme-ink: #f97066;
    --svc-refinancement: #78a9bf;
    --svc-financement: #818cf8;
    --svc-testament: var(--nota-orange-400);
    --svc-procuration: #c4a7ff;

    /* Dark shadows are cast in black, not light ink, so they read on #0a0a0a. */
    --shadow-sm: 0 1px 2px rgb(0 0 0 / .2), 0 4px 12px -8px rgb(0 0 0 / .3);
    --shadow: 0 2px 6px -3px rgb(0 0 0 / .2), 0 16px 36px -20px rgb(0 0 0 / .5);
    --shadow-lg: 0 20px 40px -12px rgb(0 0 0 / 0.6);
    --shadow-brand: 0 6px 18px -8px rgb(0 0 0 / .4);
    --focus-ring: rgb(var(--nota-blue-400-rgb) / 0.45);
    color-scheme: dark;
  }
}

/* Explicit dark toggle — wins over system preference in both directions.
   Defines the SAME complete token set as the @media block above; keep the two in
   lockstep so no token (e.g. --warn, --shadow-lg) drifts back to its light value. */
:root[data-theme='dark'] {
  --brand: var(--nota-blue-500);
  --brand-bright: var(--nota-blue-400);
  --brand-ink: #061c2a;
  --brand-hover: var(--nota-blue-400);
  --accent-warm: var(--nota-orange-400);

  /* A cool blue-black canvas keeps the dark experience aligned with the
     Nota mark; no green cast remains in the page background. */
  --bg: #101820;
  --surface: #0f2030;
  --surface-inset: #132b3f;
  --surface-hover: #19384d;
  --ink: #f4f8fa;
  --ink-muted: #afc2cf;
  --subtitle-ink: #f4f8fa;
  --border: #294353;
  --border-strong: #3f5f70;
  --ring: var(--nota-blue-400);

  --danger: #f97066;
  --warn: var(--accent-warm);
  --ok: var(--nota-blue-500);
  --danger-solid: #b42318;
  --brand-tint: rgb(var(--nota-blue-400-rgb) / 0.06); /* softened three times (owner, 2026-08-28 « trop vert », 2026-09-01 « trop intense ») */
  --brand-tint-mix: 8%;
  --brand-tint-mix-strong: 20%; /* deep pour: on near-black a component-level mix greys out — but 26 % pushed --brand ink on the highlight card below AA, so the card now carries --brand-on-tint-strong instead */
  --brand-on-tint-strong: var(--brand-bright);
  --brand-on-surface: var(--brand-bright); /* l’encre des états vivants : un barreau plus clair, sinon le libellé s’éteint au moment où on le désigne */
  --brand-word-ink: var(--ink); /* le mot du lockup est blanc sur la nuit : de l'encre, jamais du bleu */

  --tier-standard: #64748b;
  --tier-rapide: #356c87;
  --tier-prioritaire: #906800;
  --tier-urgence: #c2410c;
  --tier-extreme: #b42318;
  --tier-rapide-ink: var(--ink-muted); /* NEUTRAL — the green cast was too much (owner, 2026-08-28) */ --tier-prioritaire-ink: #e0b44a; --tier-urgence-ink: #f0894c; --tier-extreme-ink: #f97066;
  --svc-refinancement: #78a9bf;
  --svc-financement: #818cf8;
  --svc-testament: var(--nota-orange-400);
  --svc-procuration: #c4a7ff;

  /* Dark shadows are cast in black, not light ink, so they read on #0a0a0a. */
  --shadow-sm: 0 1px 2px rgb(0 0 0 / .2), 0 4px 12px -8px rgb(0 0 0 / .3);
  --shadow: 0 2px 6px -3px rgb(0 0 0 / .2), 0 16px 36px -20px rgb(0 0 0 / .5);
  --shadow-lg: 0 20px 40px -12px rgb(0 0 0 / 0.6);
  --shadow-brand: 0 6px 18px -8px rgb(0 0 0 / .4);
  --focus-ring: rgb(var(--nota-blue-400-rgb) / 0.45);
  color-scheme: dark;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
/* Selected text answers to the brand, not to the browser's default blue —
     which read as a foreign UI on a dark Nota page and lost contrast on
   the light one. Both halves are stated (never colour alone on a veil). */
::selection { background: color-mix(in srgb, var(--brand) 30%, transparent); color: var(--ink); }

body {
  margin: 0;
  /* Sticky-footer column: without it the footer sits wherever the content ends
     and the rest of the viewport is bare canvas — 412px on Notaires, 784px on
     Profil. dvh (with a vh fallback) so mobile browser chrome does not add a
     phantom scrollbar. */
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  font-family: var(--font-sans);
  font-feature-settings: 'cv02', 'cv03', 'cv04', 'cv11';
  /* The page's ambient light: a full-width fade bleeding down from the top
     edge, over the flat token — every pane opens under it. 180deg only: a
     centred radial pooled in the middle of a wide screen and left the
     margins flat black (owner: « clash with black margin »). */
  background: linear-gradient(180deg, var(--brand-tint), transparent 460px) no-repeat, var(--bg);
  color: var(--ink);
  font-size: var(--type-body);
  line-height: var(--type-body-lh);
  -webkit-font-smoothing: antialiased;
  transition: background-color .25s ease, color .25s ease;
}

/* Takes the slack in the body column, so the footer is pushed to the bottom on
   short pages and simply follows the content on long ones. The bottom padding
   keeps every pane's last card off the footer rule. */
#main { flex: 1 0 auto; padding-bottom: var(--space-14); }

/* Every heading is display type on the shared scale; a pane only colours it. */
h1, h2, h3 { font-family: var(--font-display); font-weight: var(--weight-display); margin: 0; }
h1 { font-size: var(--type-h1); line-height: var(--type-h1-lh); letter-spacing: var(--type-h1-ls); text-wrap: balance; }
h2 { font-size: var(--type-h2); line-height: var(--type-h2-lh); letter-spacing: var(--type-h2-ls); }
h3 { font-size: var(--type-h3); line-height: var(--type-h3-lh); letter-spacing: var(--type-h3-ls); }

a { color: var(--brand); text-decoration: none; }
a:hover { text-decoration: underline; }

.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 clamp(16px, 4vw, 28px); }

/* --- Skip link ----------------------------------------------------------- */
.skip {
  position: absolute; left: -999px; top: 0;
  background: var(--brand); color: var(--brand-ink);
  padding: 10px 16px; z-index: 100; border-radius: 0 0 var(--radius) 0;
}
.skip:focus { left: 0; }
/* The hidden SVG symbol table (the logomark): zero-size, out of flow, never read. */
.svg-defs { position: absolute; width: 0; height: 0; overflow: hidden; }

/* --- Header -------------------------------------------------------------- */
.site-header {
  /* The menu is its OWN layer above the page (owner, 2026-08-27: « a bigger
     diff in between menu and body ») — and a SOLID one (same day, later:
     « components carry no opacity — the background does »): opaque surface
     plus a real shadow carry the separation. The former glass tone + blur
     let the page smear through the bar; WCAG-wise a translucent chrome's
     contrast shifts with whatever scrolls beneath — solid never does.
     Distinct without ever drawing a hairline. */
  background: var(--surface);
  box-shadow: var(--shadow);
  position: sticky; top: 0; z-index: 40;
}
.site-header .wrap {
  display: flex; align-items: center; gap: 12px;
  height: var(--header-h);
  position: relative;
}
/* The lockup's geometry (ADR 0048, 2026-09-11: design 02 « Signal repris par
   le badge », optical sizing at 50%): FIVE custom properties, declared
   ONCE on every lockup root. A surface sets --lockup-tile alone; the word's
   cap height, the two gaps and the badge follow as ratios of the tile, and the
   word is centred on the tile. The wordmark symbol's viewBox is its cap band,
   so a word box --lockup-word tall renders caps exactly that tall.
   signature.css and admin.css declare the same five with the same ratios —
   ux-nav.test.mjs (P2-19) keeps the three in lockstep. */
.brand, .footer-brand, .ig-wordmark {
  --lockup-tile: 28px;
  --lockup-word: calc(var(--lockup-tile) * .48);
  --lockup-gap: calc(var(--lockup-tile) * .12);
  --lockup-badge-gap: calc(var(--lockup-tile) * .16);
  --lockup-badge-size: max(9px, calc(var(--lockup-tile) * .16)); /* .16 of the tile, never under 9px: a 30px header tile gave 4.8px caps */
}
.brand {
  display: flex; align-items: center; gap: var(--lockup-badge-gap);
  font-weight: 800; font-size: 18px; letter-spacing: -0.03em; color: var(--ink);
}
.brand:hover { text-decoration: none; }
.brand-lockup {
  display: inline-flex; align-items: center; gap: var(--lockup-gap); flex: none;
  color: var(--brand); line-height: 1;
}
.brand-mark-svg { display: block; width: var(--lockup-tile, 28px); height: var(--lockup-tile, 28px); flex: none; transition: transform .2s cubic-bezier(.2, .8, .2, 1); }
.brand-word { display: inline-flex; align-items: center; width: calc(var(--lockup-word) * 91.8 / 28); height: var(--lockup-word); color: var(--brand-word-ink); line-height: 1; }
.brand-word-svg { display: block; width: 100%; height: 100%; overflow: visible; }
/* La valeur de repli n'est pas de la décoration : --lockup-tile n'est posé
   que par .brand-lockup, et une marque placée AILLEURS (l'en-tête du tiroir)
   voyait sa largeur devenir invalide, donc `auto` — 162 px de logo sur un
   téléphone de 375 (capture du propriétaire, 2026-09-12). */
.brand-mark { width: var(--lockup-tile, 28px); height: var(--lockup-tile, 28px); display: grid; place-items: center; }
.brand-mark img { display: block; width: 100%; height: 100%; filter: drop-shadow(var(--logo-shadow)); }
/* Québec has a soft neutral backdrop, kept subtle in both themes. */
.brand-sub {
  color: var(--ink-muted); font-weight: 800; font-size: var(--lockup-badge-size); text-transform: uppercase;
  letter-spacing: .1em; padding: .55em .7em; background: #eef0f2; background: light-dark(#eef0f2, #2b3035); border-radius: var(--radius-xs);
}
.result-count { font-size: 12px; font-weight: 600; color: var(--ink-muted); white-space: nowrap; }
/* Next-availability cue in the calendar toolbar — a live blue dot + soonest
   open date, so the carnet reads as active at a glance. */
.cal-avail { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 600; color: var(--ink); white-space: nowrap; padding: 4px 11px; border: 1px solid var(--border); border-radius: var(--radius); }
.cal-avail::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--brand-bright); flex: none; }
/* The captured partner code is visible only on this visitor's device. */
.referral-status { width: 100%; box-sizing: border-box; padding-top: 12px; padding-bottom: 0; flex: 0 0 auto; }
.referral-status[hidden] { display: none; }
.referral-status-card { display: flex; align-items: center; gap: 12px; padding: 12px 16px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
.referral-status-check { display: grid; place-items: center; width: 32px; height: 32px; flex: none; border-radius: 50%; color: var(--brand); background: var(--surface-inset); }
.referral-status-copy { display: grid; gap: 3px; flex: 1; min-width: 0; font-size: 13px; line-height: 1.45; }
.referral-status-copy > span { color: var(--ink-muted); }
.referral-status-card .btn { min-height: 44px; flex: none; }
@media (max-width: 540px) {
  .referral-status-card { flex-wrap: wrap; gap: 8px; }
  .referral-status-copy { flex-basis: calc(100% - 44px); }
  .referral-status-card .btn { margin-left: 40px; }
}
.book-referral { margin: 12px 0; }

.header-spacer { flex: 1; }

/* flex:none — the tab strip never shrinks below its labels: a squeezed header
   must slim its paddings (compact band below), never wrap a label to two lines.
   Three flat doors (ADR 0010 §2) — no submenu layer, so no wrappers either. */
.nav-tabs { display: flex; gap: 2px; flex: none; }
.nav-tab {
  appearance: none; border: 1px solid transparent; background: transparent;
  color: var(--ink-muted); font: inherit; font-weight: 600; font-size: 13.5px;
  padding: 6px 11px; border-radius: var(--radius); cursor: pointer;
  display: inline-flex; align-items: center; gap: 8px;
  white-space: nowrap;
  /* Same quiet colour ease as the language segment (.12s): the header's
     controls change state at one shared tempo. */
  position: relative;
  transition: background-color .18s ease, color .18s ease, border-color .18s ease, transform .18s ease;
}
.nav-tab-icon { flex: none; color: currentColor; transition: transform .18s ease; }
.nav-tab-badge {
  flex: none; margin-left: 1px; padding: 2px 5px;
  border: 1px solid currentColor; border-radius: var(--radius-xs);
  color: var(--brand); font-size: 9px; font-weight: 800;
  letter-spacing: .06em; line-height: 1; text-transform: uppercase;
}
.nav-tab:hover { background: var(--surface-inset); color: var(--ink); }
.nav-tab:hover .nav-tab-icon { transform: translateY(-1px); }
.nav-tab[aria-selected='true'] {
  background: transparent; color: var(--brand-on-surface);
  border-color: var(--brand);
}
/* The selected tab is carried by its quiet outline and brand text; no
   underline keeps the centered navigation visually balanced. */
.nav-tab[aria-selected='true']::after { display: none; }
@media (min-width: 1100px) {
  /* Center the primary doors in the viewport, independently of the logo and
     utility controls. */
  .site-header .nav-tabs {
    position: absolute; left: 50%; transform: translateX(-50%);
  }
}
/* Header compact band: between the drawer threshold (900) and a roomy desktop
   (1100) the full control set — brand, two tabs, language, theme, both auth
   buttons, avatar — only fits by slimming chrome: tighter gaps and paddings,
   and the QUÉBEC pill steps aside. Labels never wrap (nowrap above); this band
   is what guarantees they also never overflow. */
@media (min-width: 900px) and (max-width: 1099.98px) {
  .site-header .wrap { gap: 8px; padding-inline: 16px; }
  .brand-sub { display: none; }
  /* The tab GLYPHS step aside with the QUÉBEC pill. The band was measured in
     English, where the same controls need exactly 900px; French needs 1002 —
     « Espace notaire », « Partenaires », « Se connecter », « S'inscrire » —
     so from 900 to 1001 the signup button was painted past the right edge and
     clipped by `overflow-x: clip`, with no sideways scroll to reach it. Four
     icons and their gaps are 92px; the LABELS are what a door is, and they all
     stay. (e2e/french-fits.spec.js measures the fit in both languages.) */
  .nav-tab-icon { display: none; }
  .nav-tab { padding: 6px 8px; }
  .header-auth .btn { padding-left: 9px; padding-right: 9px; }
  /* The tool strip tightens with the band: narrower gaps and FR/EN cells
     (the hairlines re-centre themselves from --tools-gap). */
  .header-tools { --tools-gap: 8px; }
  .header-tools .mini-seg-btn { padding: 0 6px; }
}

.icon-btn {
  appearance: none; font: inherit; border: 1px solid var(--border-strong); background: transparent;
  color: var(--ink); width: 34px; height: 34px; border-radius: var(--radius);
  cursor: pointer; display: grid; place-items: center; font-size: 16px;
  transition: background-color .12s, color .12s, border-color .12s;
}
.icon-btn:hover { background: transparent; border-color: var(--brand); }
.icon-btn[aria-pressed='true'] { background: transparent; color: var(--brand-on-surface); border-color: var(--brand); }
.icon-btn svg { display: block; }
.icon-btn:active { transform: scale(0.94); }
/* Header tool group: guide "?" · FR | EN · theme switch sit TOGETHER on one
   shared control line (owner's ask, 2026-08-26: « les mettre ensemble et
   même grosseur »). The line itself stays unfilled; active controls carry
   their own surfaces. */
.header-tools {
  --tools-gap: 12px;
  display: inline-flex; align-items: center; gap: var(--tools-gap); flex: none;
  padding: 2px 4px; border-radius: var(--radius); background: var(--surface-inset);
}
.header-tools > * { position: relative; }
.header-tools > * + *::after {
  content: ''; position: absolute; top: 6px; bottom: 6px;
  left: calc(var(--tools-gap) / -2 - 0.5px); width: 1px; background: var(--border);
}
/* The guide « ? » — its own standalone bubble (owner's asks, 2026-08-26 +
   2026-08-27: always one tap away so people understand, but NEVER inside a
   menu). Fixed bottom-right on every DESKTOP band, signed in or out — phones
   drop it (ADR 0022: it painted over the calendar tiles; the first-visit
   onboarding and the footer link stay the phone doors). z-index 50:
   over content and the sticky header (40), under the drawer scrim (65),
   toasts (60) and native dialogs (top layer). */
.guide-fab {
  position: fixed; right: 16px; bottom: 16px; z-index: 50;
  width: 42px; height: 42px;
  background: var(--surface); border: 1px solid var(--border-strong);
  color: var(--ink-muted); box-shadow: var(--shadow);
}
.guide-fab:hover { background: var(--surface-hover); color: var(--ink); box-shadow: var(--shadow-lg); }

/* Small FR | EN segment: BOTH options stay visible and the current one sits
   raised on a filled pill — the state reads at a glance, where the old single
   button showed only the OTHER language. Active marking and clicks are wired
   by NotaI18N.wireToggles(). Used in the header strip and the drawer's
   preference rows; 28px tall everywhere, matching the "?" and the switch. */
.mini-seg {
  display: inline-flex; align-items: center; gap: 2px; flex: none;
  height: 28px; padding: 2px; border-radius: var(--radius); background: var(--surface-inset);
}
.mini-seg-btn {
  appearance: none; display: inline-flex; align-items: center; justify-content: center;
  height: 24px; padding: 0 9px; border: 1px solid transparent; background: transparent;
  color: var(--ink-muted); font: inherit; font-size: 11.5px; font-weight: 700;
  letter-spacing: 0.04em; line-height: 1; border-radius: var(--radius-sm);
  cursor: pointer; transition: background .12s, color .12s;
}
.mini-seg-btn:hover { color: var(--ink); }
.mini-seg-btn[aria-pressed='true'] {
  background: var(--surface); color: var(--brand-on-surface);
  border-color: var(--border); box-shadow: var(--shadow-sm);
}

/* Theme switch: a small sun/moon track whose knob covers the CURRENT side
   (checked = dark). The knob and icon tint follow html[data-theme] so the
   control is right from the first paint — before app.js boots; app.js then
   mirrors the state onto aria-checked (header + drawer twins) for AT.
   Geometry: 28 = 2px pad + 24px cell + 2px pad; two 24px icon cells; the
   24px knob slides one cell over. */
.tswitch {
  appearance: none; font: inherit; position: relative; display: inline-flex; align-items: center;
  justify-content: space-between; flex: none; width: 52px; height: 28px; padding: 2px;
  border: 0; border-radius: var(--radius);
  background: var(--surface-inset); color: var(--ink-muted); cursor: pointer;
}
.tswitch svg { position: relative; z-index: 1; display: block; flex: none; margin: 0 5.5px; }
.tswitch::before {
  content: ''; position: absolute; top: 2px; left: 2px; z-index: 0;
  width: 24px; height: 24px; border-radius: var(--radius-sm);
  background: var(--surface); border: 1px solid var(--border);
  box-shadow: var(--shadow-sm); transition: transform .16s ease;
}
:root[data-theme='dark'] .tswitch::before { transform: translateX(24px); }
:root[data-theme='dark'] .tswitch .tswitch-moon,
:root:not([data-theme='dark']) .tswitch .tswitch-sun { color: var(--brand); }

/* --- Notifications (bell + dropdown, paired with the email the API sends) -- */
.notif-wrap { position: relative; }
#notif-bell { position: relative; }
#notif-bell.has-unread { color: var(--brand); }
.notif-badge {
  position: absolute; top: -5px; right: -5px; min-width: 17px; height: 17px; padding: 0 4px;
  border-radius: var(--radius-sm); background: var(--danger-solid); color: var(--on-accent);
  font-size: 10px; font-weight: 800; line-height: 17px; text-align: center;
  border: 2px solid var(--surface);
}
.notif-panel {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 60;
  width: min(340px, calc(100vw - 32px));
  background: var(--surface); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
  overflow: hidden; animation: paneIn .16s cubic-bezier(.2, .8, .2, 1) both;
}
.notif-head {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 12px 14px; border-bottom: 1px solid var(--border);
}
.notif-head-title { font-weight: 700; font-size: 13px; }
.notif-list { max-height: min(420px, 70vh); overflow-y: auto; overscroll-behavior: contain; }
.notif-empty { padding: 24px 14px; text-align: center; color: var(--ink-muted); font-size: 13px; }
.notif-item {
  position: relative; padding: 11px 34px 11px 14px; border-bottom: 1px solid var(--border); cursor: default;
  transition: background-color .12s;
}
/* Per-item dismiss — a quiet ✕ that firms up on hover/focus, sized like the
   calendar's cell chevron so small round actions stay one family. */
.notif-x {
  position: absolute; top: 8px; right: 6px; display: grid; place-items: center;
  width: 24px; height: 24px; padding: 0; appearance: none; border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--ink-muted); font-size: 11px; line-height: 1; cursor: pointer;
}
.notif-x:hover { background: var(--surface-hover); color: var(--ink); }
.notif-x:focus-visible { outline: 2px solid var(--ring); outline-offset: -2px; }
.notif-item:last-child { border-bottom: 0; }
.notif-item[role='button'] { cursor: pointer; }
.notif-item[role='button']:hover { background: var(--surface-inset); }
.notif-item[role='button']:focus-visible { background: var(--surface-inset); outline: 2px solid var(--ring); outline-offset: -2px; }
.notif-item.is-unread { background: var(--surface-hover); }
.notif-item.is-unread .notif-title::before {
  content: ''; display: inline-block; width: 7px; height: 7px; margin-right: 7px;
  border-radius: 50%; background: var(--brand); vertical-align: middle;
}
.notif-title { font-size: 13px; font-weight: 600; color: var(--ink); }
.notif-body { font-size: 12px; color: var(--ink-muted); margin-top: 2px; }

/* Account menu (avatar) — merges profile + notifications + menu into one panel. */
.acct-btn { border-radius: var(--radius); border: 1px solid var(--border); }
.acct-btn:hover { border-color: var(--brand); }
.acct-btn[aria-expanded='true'] { border-color: var(--brand); color: var(--brand); }
.acct-panel { padding: 6px; }
.acct-panel-head { display: flex; align-items: flex-start; gap: 2px; }
.acct-panel-head .acct-head { flex: 1; min-width: 0; }
.acct-close { flex: none; color: var(--ink-muted); }
.acct-close:hover { color: var(--ink); }
.acct-item { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; appearance: none; background: transparent; border: 0; border-radius: var(--radius); padding: 9px 10px; font: inherit; color: var(--ink); cursor: pointer; }
.acct-item:hover { background: var(--surface-inset); }
.acct-item:focus-visible { background: var(--surface-inset); outline: 2px solid var(--ring); outline-offset: -2px; }
.acct-item svg { flex: none; color: var(--ink-muted); }
.acct-avatar { display: grid; place-items: center; width: 34px; height: 34px; border-radius: var(--radius); border: 1px solid var(--border); color: var(--brand); flex: none; }
.acct-labels { display: flex; flex-direction: column; min-width: 0; }
.acct-item-title { font-weight: 600; font-size: 14px; }
.acct-item-sub { font-size: 12px; color: var(--ink-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Role tag under the identity head (Client / Espace notaire). Outline pill, brand
   ink — never a filled swatch — so it reads as a label in both themes. */
.acct-role { align-self: flex-start; margin-top: 4px; font-size: 10px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--brand); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 1px 8px; }
/* Role-aware action rows reuse .acct-item; the group is just a stack. */
.acct-actions { display: flex; flex-direction: column; }
/* Unread notary messages (ADR 0033) ride the « Mon profil » door: a filled
   square count, brand on brand-ink. */
.acct-badge {
  display: inline-flex; align-items: center; justify-content: center; margin-left: auto;
  min-width: 20px; height: 20px; padding: 0 6px; font-size: 11px; font-weight: 800;
  border-radius: var(--radius-sm); background: var(--brand); color: var(--brand-ink);
  font-variant-numeric: tabular-nums;
}
.acct-sep { height: 1px; background: var(--border); margin: 6px 4px; }
.acct-panel .notif-head { padding: 6px 10px; border-bottom: 0; }
.acct-panel .notif-list { max-height: min(320px, 50vh); }
/* Legal links cluster at the foot of the account menu — compact wrapping links,
   not full-width buttons, so it reads as a footer. */
.acct-legal { display: flex; flex-wrap: wrap; gap: 2px; padding: 2px 2px 4px; }
.acct-legal-link { appearance: none; border: 0; background: transparent; color: var(--ink-muted); font: inherit; font-size: 12px; font-weight: 600; padding: 6px 8px; border-radius: var(--radius-sm); cursor: pointer; }
.acct-legal-link:hover { background: var(--surface-inset); color: var(--ink); }
.acct-legal-link:focus-visible { background: var(--surface-inset); outline: 2px solid var(--ring); outline-offset: -2px; }
/* Logged-out auth buttons (login + signup); the avatar takes over once signed in
   — the whole account wrap (bell + panel) is [hidden] while anonymous. */
.header-auth { display: inline-flex; align-items: center; gap: 6px; flex: none; }
.header-auth[hidden] { display: none; }
.header-auth .btn { white-space: nowrap; }
/* Safety cap so a long notifications list can never push the menu past the
   viewport. The cap subtracts the sticky header the panel hangs from (plus its
   8px gap and an 8px floor margin) — a bare 88vh ignored that offset and let
   the panel's bottom edge run past short landscape viewports. dvh line for
   mobile URL-bar honesty; the vh line above it is the older-browser fallback. */
.acct-panel { max-height: min(calc(100vh - var(--header-h) - 16px), 660px); overflow-y: auto; overscroll-behavior: contain; }
.acct-panel { max-height: min(calc(100dvh - var(--header-h) - 16px), 660px); }

/* --- Mobile navigation drawer (hamburger) -------------------------------- */
/* Phones and portrait tablets: the burger and its right-side drawer replace the
   inline tabs, login button and theme toggle below 900px. The wider touch
   band keeps the sticky header inside the viewport at tablet widths. */
.nav-burger { display: none; border: 0; }
.mnav-scrim {
  position: fixed; inset: 0; z-index: 65; background: var(--backdrop);
  opacity: 0; pointer-events: none; transition: opacity .2s ease;
}
.mnav-scrim.is-open { opacity: 1; pointer-events: auto; }
.mnav {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 70;
  width: min(320px, 84vw);
  display: flex; flex-direction: column;
  padding: var(--space-5) var(--space-7) calc(var(--space-8) + env(safe-area-inset-bottom, 0px));
  background: var(--surface); border-left: 1px solid var(--border); box-shadow: var(--shadow-lg);
  overflow-y: auto; overscroll-behavior: contain;
  /* visibility swaps AFTER the slide-out so the exit still animates; on open
     the delay is removed so the panel is interactive immediately. */
  transform: translateX(105%); visibility: hidden;
  transition: transform .24s cubic-bezier(.2, .8, .2, 1), visibility 0s .24s;
}
.mnav.is-open { transform: none; visibility: visible; transition: transform .24s cubic-bezier(.2, .8, .2, 1); }
/* No page scroll behind the open drawer. */
html.nav-open, html.nav-open body { overflow: hidden; }
/* Sticky for the same reason as the dialogs' ✕: the drawer scrolls, its close
   button must not. Background so links slide under it, not through it. */
.mnav-head { --lockup-tile: 26px; position: sticky; top: 0; z-index: 2; background: var(--surface); display: flex; align-items: center; gap: 10px; padding: var(--space-2) var(--space-2) var(--space-4); }
.mnav-title { font-weight: 800; font-size: 15px; letter-spacing: -0.01em; }
.mnav-group { display: flex; flex-direction: column; }
.mnav-link {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  appearance: none; background: transparent; border: 0; border-radius: var(--radius);
  padding: var(--space-5) var(--space-6); font: inherit; font-size: 14.5px; font-weight: 600;
  color: var(--ink); cursor: pointer; transition: background .12s, color .12s;
}
.mnav-link:hover { background: var(--surface-inset); text-decoration: none; color: var(--ink); }
.mnav-link.is-on { background: var(--surface-inset); color: var(--brand-on-surface); }
.mnav-link svg { flex: none; color: var(--ink-muted); }
.mnav-link.is-on svg { color: var(--brand-on-surface); }
.mnav-link .nav-tab-badge { margin-left: auto; }
/* Focus ring drawn INSIDE the row: the drawer's rows are full-bleed, so the
   default outer ring painted a giant box around the first row on open. */
.mnav-link:focus-visible { outline: 2px solid var(--ring); outline-offset: -2px; }
/* The legal fold — the drawer's one expandable row: icon + label left,
   chevron right. Only the CHEVRON rotates on expand — the row icon sits still.
   The section links themselves are flat (ADR 0010 §2), no accordions. */
.mnav-expandrow { justify-content: space-between; }
.mnav-row-l { display: flex; align-items: center; gap: 10px; }
.mnav-row-l svg { flex: none; color: var(--ink-muted); }
.mnav-chevron { transition: transform .16s; }
.mnav-expandrow[aria-expanded='true'] .mnav-chevron { transform: rotate(180deg); }
/* Sub-rows hang off a thin rail so they read as children of their row. */
.mnav-sub {
  display: flex; flex-direction: column; padding: 0 0 var(--space-3);
  margin-left: var(--space-6); border-left: 1px solid var(--border);
}
.mnav-sub[hidden] { display: none; }
.mnav-subitem {
  display: flex; flex-direction: column; gap: 2px; width: 100%; text-align: left;
  appearance: none; background: transparent; border: 0; border-radius: 0 var(--radius) var(--radius) 0;
  padding: var(--space-4) var(--space-6) var(--space-4) var(--space-5);
  font: inherit; color: var(--ink); cursor: pointer;
}
.mnav-subitem:hover { background: var(--surface-inset); text-decoration: none; color: var(--ink); }
.mnav-subitem:focus-visible { background: var(--surface-inset); outline: 2px solid var(--ring); outline-offset: -2px; }
.mnav-sep { height: 1px; background: var(--border); margin: var(--space-5) var(--space-2); flex: none; }
.mnav-auth { gap: var(--space-4); padding: 0 var(--space-2); }
.mnav-auth .btn { width: 100%; }
/* When the auth pair hides (signed in), its trailing separator must go with it
   or two hairlines stack. */
#mnav-auth[hidden] + .mnav-auth-sep { display: none; }
.mnav-legal .mnav-subitem { font-size: 13.5px; font-weight: 500; color: var(--ink-muted); padding-block: var(--space-4); }
.mnav-legal .mnav-subitem:hover { color: var(--ink); }
/* Preference rows (language, theme): label left, small toggle right. NOT
   .mnav-link — the drawer's "any choice closes" delegate must ignore them,
   because flipping a preference is not navigation. The label column reuses
   .mnav-row-l so its icon+text align with the rows above. */
.mnav-pref {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: var(--space-4) var(--space-6);
  font-size: 14.5px; font-weight: 600; color: var(--ink);
}
.mnav-pref .mnav-row-l svg { color: var(--ink-muted); }

/* --- Sign-in / sign-up modal -------------------------------------------- */
.auth-modal { border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface); color: var(--ink); box-shadow: var(--shadow-lg); padding: 0; width: min(420px, 92vw); max-height: 92vh; overflow: auto; }
/* Close ✕: the shared .dlg-x construction — see the base dialog rules. */
.auth-body { padding: 30px 26px 24px; display: flex; flex-direction: column; }
.auth-mark { display: grid; place-items: center; margin-bottom: 12px; }
.auth-mark .brand-badge { width: 46px; height: 46px; border-radius: var(--radius-lg); display: grid; place-items: center; background: var(--surface-inset); border: 1px solid var(--border); }
.auth-title { text-align: center; margin: 0; } /* a dialog title sits on the h2 rung (ADR 0050) */
.auth-sub { font-size: 13.5px; color: var(--ink-muted); text-align: center; margin: 6px 0 18px; line-height: 1.5; }
/* The base .seg lets the unselected option sit as bare text in the track, which
   reads as a label, not a button. Here both halves must read as the same kind of
   thing: equal widths, a hover fill that invites the click, and the selected one
   raised on a filled pill so the pair reads as one two-position control.
   Scoped to .auth-role only — the calendar's segments keep the base look. */
.auth-role { display: flex; width: 100%; margin-bottom: 16px; }
.auth-role .seg-btn { flex: 1; text-align: center; padding: 8px 14px; font-weight: 600; }
.auth-role .seg-btn:not(.is-on):hover { background: var(--surface-hover); color: var(--ink); }
/* Not var(--surface): in dark it sits below the inset track and would read
   sunken. --surface-hover stays lighter than the track in both themes; the
   strong hairline and the bigger shadow are what separate it from a hover. */
.auth-role .seg-btn.is-on { background: var(--surface-hover); border-color: var(--border-strong); box-shadow: var(--shadow); }
.auth-email { display: flex; flex-direction: column; gap: 8px; }
.auth-email .lbl { font-size: 12px; margin-bottom: 0; }
.auth-email input { width: 100%; }
.auth-continue { width: 100%; margin-top: 4px; }
.auth-fine { font-size: 12px; color: var(--ink-muted); line-height: 1.5; margin: 14px 0 0; text-align: center; }

/* --- Bascule inscription ↔ connexion ------------------------------------- */
/* Une phrase, pas un bouton : le geste principal reste le CTA au-dessus. */
.auth-switch { font-size: 13px; color: var(--ink-muted); text-align: center; margin: 14px 0 0; }
.auth-switch-btn {
  appearance: none; border: 0; background: none; padding: 0; margin-left: 4px;
  font: inherit; font-weight: 650; color: var(--brand); cursor: pointer;
  text-decoration: underline; text-underline-offset: 2px;
}
.auth-switch-btn:hover { color: var(--brand-hover); }

/* --- Séparateur ---------------------------------------------------------- */
/* Le filet passe DERRIÈRE le mot, qui porte le fond de la carte : pas de
   largeur codée en dur, donc il tient dans les deux langues. */
.auth-or {
  display: flex; align-items: center; gap: 12px;
  margin: 18px 0 14px; color: var(--ink-muted); font-size: 12px;
}
.auth-or::before, .auth-or::after { content: ''; flex: 1; height: 1px; background: var(--border); }

/* --- Fournisseurs d’authentification ------------------------------------- */
.auth-social { display: flex; flex-direction: column; gap: 8px; }
.auth-social-h {
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-muted); text-align: center; margin: 0 0 2px;
}
.auth-soc-list { display: flex; flex-direction: column; gap: 8px; }
/* Elles se lisent comme des boutons — c'est ce qu'elles seront — mais en
   retrait : elles n'entrent pas en concurrence avec le seul chemin qui marche.
   Pas de `filter: grayscale` : la marque doit rester reconnaissable, c'est tout
   l'intérêt de les montrer d'avance. */
.auth-soc-btn {
  appearance: none; font: inherit; cursor: not-allowed;
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 9px 12px; border-radius: var(--radius);
  border: 1px solid var(--border); background: var(--surface);
  color: var(--ink-muted); text-align: left;
  transition: border-color .12s, background .12s;
}
.auth-soc-btn:hover { border-color: var(--border-strong); background: var(--surface-inset); }
.auth-soc-btn:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
/* Le « G » de Google doit apparaître sur fond blanc, quel que soit le thème
   (exigence de marque) : la pastille le porte. Les deux autres logos sont
   monochromes et tiennent sur n'importe quel fond. */
.auth-soc-ic {
  display: grid; place-items: center; flex: none;
  width: 26px; height: 26px; border-radius: var(--radius-sm);
}
.auth-soc-btn[data-provider='google'] .auth-soc-ic {
  background: var(--marque-google-chip); border: 1px solid var(--border);
}
.auth-soc-t { flex: 1; font-size: 13.5px; font-weight: 600; color: var(--ink); }
.auth-social-note { text-align: center; margin: 4px 0 0; }
@media (max-width: 420px) {
  .auth-soc-btn { padding: 8px 10px; gap: 8px; }
  .auth-soc-t { font-size: 13px; }
}
/* La réponse au clic : vide, elle ne prend aucune place ; remplie, elle se lit
   comme une réponse et non comme une erreur. */
.auth-soc-live:empty { display: none; }
.auth-soc-live {
  margin: 8px 0 0; padding: 8px 10px; font-size: 12.5px; line-height: 1.45;
  color: var(--ink); text-align: center;
  background: var(--brand-tint-solid); border: 1px solid var(--border);
  border-radius: var(--radius);
}

/* --- First-visit onboarding guide --------------------------------------- */
/* Reuses the .auth-modal shell (card + backdrop); two views live in the DOM
   and are shown/hidden. Tokens only, so it tracks every theme automatically. */
/* 560px: wide enough for the week vignette's five columns to carry an act's
   name and the exact amount — "Refinancement" ellipsizes, still named by its
   glyph, colour and tooltip. The ≤380px container fallback covers phones,
   where 94vw wins. max-width included: the base `dialog` rule caps every
   dialog at 440px and would clamp it back. */
.onb-modal { border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface); color: var(--ink); box-shadow: var(--shadow-lg); padding: 0; width: min(560px, 94vw); max-width: 560px; max-height: 92vh; overflow: auto; }
.onb-body { padding: 30px 26px 24px; display: flex; flex-direction: column; }
.onb-title { text-align: center; margin: 0; } /* a dialog title sits on the h2 rung (ADR 0050) */
.onb-sub { font-size: 13.5px; color: var(--ink-muted); text-align: center; margin: 6px 0 18px; line-height: 1.5; }

/* VIEW 1 — two outline choice cards, side by side, stacking on narrow screens. */
.onb-choices { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.onb-choice { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; text-align: left; padding: 16px 15px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); color: var(--ink); cursor: pointer; transition: border-color .12s, background .12s, transform .06s; }
.onb-choice:hover { border-color: var(--brand); background: var(--surface-inset); }
.onb-choice:active { transform: translateY(1px); }
.onb-choice-ic { display: grid; place-items: center; width: 40px; height: 40px; border-radius: var(--radius); background: var(--surface-inset); border: 1px solid var(--border); color: var(--brand); }
.onb-choice-t { font-size: 14.5px; font-weight: 700; letter-spacing: -0.01em; }
.onb-choice-d { font-size: 12.5px; color: var(--ink-muted); line-height: 1.45; }
.onb-choice-live { min-height: 1.5em; font-size: 12px; font-weight: 650; color: var(--brand); margin-top: 2px; }

/* VIEW 2 — a numbered steps list with a brand-outline number chip. */
.onb-steps-title { margin-top: 2px; }
.onb-steps { list-style: none; margin: 4px 0 20px; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.onb-step { display: flex; align-items: flex-start; gap: 12px; }
.onb-step-n { flex: none; width: 26px; height: 26px; display: grid; place-items: center; border: 1px solid var(--brand); border-radius: var(--radius-sm); color: var(--brand); font-size: 13px; font-weight: 700; }
.onb-step-body { flex: 1; min-width: 0; }
.onb-step-t { font-size: 14px; font-weight: 700; letter-spacing: -0.01em; }
.onb-step-d { font-size: 12.5px; color: var(--ink-muted); line-height: 1.45; margin-top: 2px; }
.onb-step-ic { flex: none; display: grid; place-items: center; color: var(--ink-muted); margin-top: 2px; }
.onb-cta { width: 100%; }
/* Where-am-I marker for the two-view flow. */
.onb-progress { font-size: 11px; font-weight: 600; letter-spacing: 0.09em; text-transform: uppercase; color: var(--ink-muted); text-align: center; margin: 0 0 16px; }
/* The low-commitment exit: real enough to see, quiet enough not to compete
   with the primary CTA above it. */
.onb-alt { width: 100%; margin-top: 10px; appearance: none; border: 1px solid var(--border); border-radius: var(--radius); background: transparent; color: var(--ink); cursor: pointer; padding: 10px 14px; font: inherit; font-size: 13.5px; font-weight: 600; transition: border-color .12s, background .12s; }
.onb-alt:hover { border-color: var(--brand); background: var(--surface-inset); }
.onb-back { align-self: flex-start; appearance: none; border: 0; background: transparent; color: var(--ink-muted); cursor: pointer; padding: 2px 0; margin-bottom: 8px; font: inherit; font-size: 12.5px; }
.onb-back:hover { color: var(--brand-on-surface); }
.onb-skip { align-self: center; appearance: none; border: 0; background: transparent; color: var(--ink-muted); cursor: pointer; padding: 6px; margin-top: 12px; font: inherit; font-size: 12.5px; text-decoration: underline; }
.onb-skip:hover { color: var(--ink); }

@keyframes onb-dialog-in {
  from { opacity: 0; transform: translateY(10px) scale(.985); }
  to { opacity: 1; transform: none; }
}
@keyframes onb-view-in {
  from { opacity: 0; transform: translateY(7px); }
  to { opacity: 1; transform: none; }
}
@keyframes onb-step-in {
  from { opacity: 0; transform: translateY(5px); }
  to { opacity: 1; transform: none; }
}
.onb-modal[open] { animation: onb-dialog-in .28s cubic-bezier(.2,.8,.2,1) both; }
#onb-view-role.is-entering, #onb-view-steps.is-entering { animation: onb-view-in .32s cubic-bezier(.2,.8,.2,1) both; }
#onb-view-steps.is-entering .onb-step { animation: onb-step-in .32s cubic-bezier(.2,.8,.2,1) both; animation-delay: calc(var(--onb-step-index, 0) * 60ms); }
.onb-choice:focus-visible, .onb-alt:focus-visible, .onb-back:focus-visible, .onb-skip:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; }

@media (max-width: 420px) {
  .onb-choices { grid-template-columns: 1fr; }
}

/* --- Buttons ------------------------------------------------------------- */
.btn {
  appearance: none; font: inherit; font-weight: 500; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 6px 13px; border-radius: var(--radius);
  border: 1px solid var(--border); background: transparent; color: var(--ink);
  transition: background .12s, border-color .12s, transform .06s;
}
.btn:not(:disabled):hover { background: var(--surface-inset); }
.btn:not(:disabled):active { transform: translateY(1px); }
/* L'action principale se lit à la COULEUR DE MARQUE et à la GRAISSE, jamais à
   un aplat (propriétaire, 2026-09-12 : « je vois plusieurs boutons qui ont des
   backgrounds remplis… aucun background rempli »). La feuille le disait déjà
   pour la feuille de réservation le 2026-09-07 — « couleur de marque et graisse,
   jamais un aplat » ; la règle vaut désormais pour TOUS les boutons. L'encre
   passe par --brand-on-surface : --brand nu tombe à 2,5:1 sur fond de nuit. */
.btn-primary { background: transparent; color: var(--brand-on-surface); border-color: var(--brand); font-weight: 700; transition: background .18s, border-color .18s, transform .18s ease, box-shadow .18s ease; }
/* Au survol l'action se lève et son contour se renforce — la teinte reste le
   voile à 6/8 % de --brand-tint-solid, pas une couleur pleine. */
.btn-primary:not(:disabled):hover { background: var(--brand-tint-solid); border-color: var(--brand-hover); color: var(--brand-on-surface); transform: translateY(-1px); box-shadow: var(--shadow-brand); }
.btn-primary:not(:disabled):active { transform: translateY(0); box-shadow: none; }
.btn-ghost { border-color: transparent; background: transparent; color: var(--ink-muted); }
.btn-ghost:hover { background: var(--surface-inset); color: var(--ink); }
.btn-sm { padding: 5px 11px; font-size: 12.5px; }
.btn-lg { padding: 7px 14px; font-size: 14px; font-weight: 600; }

/* --- Mini icon buttons ---------------------------------------------------- */
/* The small round actions that sit ON a component (offer row, pulse row,
   notary card, footer). Icon-only by design, so every one carries a title +
   aria-label; 30px box, 44px on coarse pointers via the touch-target rule. */
.mini-btn {
  display: inline-grid; place-items: center; flex: none;
  width: 30px; height: 30px; padding: 0; font: inherit; border: 1px solid var(--border-strong); border-radius: var(--radius);
  background: none; color: var(--ink-muted); cursor: pointer;
  text-decoration: none; transition: background-color .12s ease, color .12s ease, border-color .12s ease, transform .12s ease;
}
.mini-btn:hover { background: transparent; border-color: var(--brand); color: var(--brand-on-surface); text-decoration: none; }
/* Pressing compresses — the standard tactile cue for an icon-only control. */
.mini-btn:active { background: transparent; border-color: var(--brand); transform: scale(.94); }
.mini-btn svg { display: block; }
/* Actions stay quiet until the row they belong to is hovered or focused —
   the data reads first, the tools appear when you go for them. */
/* Disabled reads through TOKENS, never element opacity (a half-transparent
   button lets the page bleed through it): muted ink, quiet edge, flat — et
   sans aplat, sinon l'inactif serait le SEUL bouton rempli de la page. */
.btn:disabled { cursor: not-allowed; background: transparent; border-color: var(--border); color: var(--ink-muted); box-shadow: none; }
.btn svg { flex: none; }

/* Hero call-to-action — the buyer's first, obvious action */
/* margin-top:auto pins the buttons to the BOTTOM of the copy column, so the
   two hero columns end on the same line instead of one trailing off. */
.hero-cta { display: flex; align-items: center; gap: var(--space-5); flex-wrap: wrap; margin-top: var(--space-8); padding-top: 0; }
/* Ce qui ne coûte rien, dit sous la décision et non dans les conditions
   (propriétaire, 2026-09-12). Une ligne d'aide, jamais une carte : c'est un
   fait rassurant, pas une offre. */
.hero-free { margin: var(--space-5) 0 0; max-width: 52ch; }
/* A slim, equal pair: ONE set height rather than padding-derived boxes, so the
   filled and the outlined button can never drift apart by a border or a wrap.
   Wide screens only — under 681px the pair keeps its full touch height. */
@media (min-width: 681px) {
  .hero-cta .btn { height: 32px; padding-top: 0; padding-bottom: 0; }
}

/* Guided step badges (1 · 2 · 3) in the offer panel */
.step {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border-radius: var(--radius-sm); flex: none;
  background: var(--brand); color: var(--brand-ink); font-size: 11px; font-weight: 800;
}

:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }

/* --- Hero / intro -------------------------------------------------------- */
/* A touch more floor than ceiling: the hero hands off to a PANEL below, and
   the seam between an open surface and a card needs the larger share of air. */
/* No wash of its own: the intro sits under the body's edge-to-edge fade — a
   boxed glow here ends at the content column and seams against the gutter. */
.intro { padding-block: var(--intro-pad-top); }
/* Split hero: copy on the left, live content on the right — the market pulse on
   Carnet, the "how it works" steps on Notaires. Both asides are CHROMELESS (no
   card, no border, no fill): the hero is one continuous surface, and the two
   columns are tied together by a shared top edge instead of a box. */
.intro--hero { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(20px, 4vw, 48px); align-items: stretch; }
.intro-main { min-width: 0; display: flex; flex-direction: column; justify-content: center; }
/* The pulse kicker sits on the SAME baseline as the .eyebrow opposite it:
   same 12px, same 700, same inherited 1.5 line-height (kept explicit — the
   two columns start on one line only as long as these agree). */
.hero-steps-title {
  font-size: 12px; font-weight: 700; line-height: 1.5; text-transform: uppercase;
  letter-spacing: .06em; color: var(--subtitle-ink); margin-bottom: 12px;
}
/* Hero pulse — live per-service medians beside the carnet hero. No rules, no
   box: the rows are separated by rhythm and by their own volume bar, and each
   one is a button that filters the carnet below. */
.pulse { min-width: 0; display: flex; flex-direction: column; }
.pulse-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 8px 16px;
}
.pulse .hero-steps-title { margin-bottom: 0; }
.pulse-head .hero-steps-title,
.pulse-month { min-width: 0; }
/* The month never breaks (« Septembre – octobre 2026 » is one fact); the
   kicker opposite it may, and must — both were nowrap, so in a column too
   narrow for the pair they simply painted over each other. */
.pulse-month { white-space: nowrap; }
/* fr-CA dates are lower-case (`jeudi 20 août`). `text-transform: capitalize`
   title-cases every word and produced `Jeudi 20 Août`; ::first-letter gives a
   heading its opening capital without touching the month. */
.pulse-month { font-size: 12px; font-weight: 600; color: var(--ink-muted); }
.pulse-month::first-letter { text-transform: uppercase; }
/* Rows hug their content at every viewport — no stretching to match the copy
   column. Distributing them over the hero's height (space-between + flex:1)
   opened huge gaps whenever the copy column was tall or the hero stacked. */
.pulse-rows { display: grid; gap: var(--space-2); margin-top: var(--space-3); align-content: start; }
.pulse-rows .collection-empty { margin: 0; padding: 14px 12px; border: 0; color: var(--ink-muted); text-align: center; background: none; font-size: 12px; font-weight: 700; }
/* Open rows group the filter and booking action without a card surface.
   The calendar action has its own 44px target and a quiet internal divider. */
.pulse-item {
  min-width: 0; display: flex; align-items: center; gap: 8px;
  padding: 4px 5px 4px 11px;
}
.pulse-item .pulse-row { flex: 1; min-width: 0; padding: 8px 0; margin: 0; }
.pulse-item .mini-btn {
  position: relative; width: 44px; height: 44px; margin: 0;
  border-color: transparent; color: var(--ink-muted);
}
.pulse-item .mini-btn::before {
  content: ''; position: absolute; left: -4px; top: 12px; bottom: 12px;
  width: 1px; background: var(--border);
}
.pulse-item .mini-btn:hover, .pulse-item .mini-btn:focus-visible {
  color: var(--brand-on-surface); border-color: var(--border-strong);
}
.pulse-item .mini-btn svg { width: 18px; height: 18px; }
.pulse-row {
  display: grid; grid-template-columns: auto minmax(24px, 1fr) auto; align-items: baseline;
  gap: 2px 12px; text-align: left;
  /* Bled out by its own padding so the text stays flush with the hero copy.
     The row
     STRETCHES (no width:100%, which would shrink the content box by the
     padding and pull the amounts 20px off the hero's right edge). */
  padding: 6px 10px; margin: 0 -10px;
  background: none; border: 0; border-radius: var(--radius);
  font: inherit; color: inherit; cursor: pointer;
}
/* Underline the service for hover and selection; keyboard focus keeps the
   shared focus ring. The rows remain unboxed in every state. */
.pulse-row:hover .pulse-svc, .pulse-row.is-on .pulse-svc {
  text-decoration: underline; text-underline-offset: 3px;
}
.pulse-svc { grid-column: 1 / 3; grid-row: 1; display: flex; align-items: center; gap: 7px; min-width: 0; font-size: clamp(12px, 1.1vw, 14px); font-weight: 700; line-height: 1.25; }
.pulse-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
/* One glyph per act, so a service is recognised before its name is read. */
.svc-ic { flex: none; display: block; }
.chip-svc { display: inline-flex; align-items: center; gap: 6px; }
.chip-svc .svc-ic { color: var(--svc-fallback, currentColor); }
.chip-svc[data-svc='refinancement'] .svc-ic { color: var(--svc-refinancement); }
.chip-svc[data-svc='financement'] .svc-ic { color: var(--svc-financement); }
.chip-svc[data-svc='testament'] .svc-ic { color: var(--svc-testament); }
.chip-svc[data-svc='procuration'] .svc-ic { color: var(--svc-procuration); }
.chip-svc.is-on .svc-ic { color: currentColor; }
.legend-item .svc-ic, .legend-status-item .svc-ic { margin-right: 1px; }
/* Two figures per act, because they answer two questions: the floor the server
   will accept at all, and what other clients are actually offering this month. */
.pulse-figs { grid-column: 3; grid-row: 1 / 3; display: flex; align-items: baseline; gap: clamp(10px, 1.4vw, 18px); min-width: max-content; white-space: nowrap; }
.pulse-fig { display: flex; flex-direction: column; align-items: flex-end; gap: 1px; }
.pulse-fig-k { font-size: 10.5px; font-weight: 600; color: var(--ink-muted); letter-spacing: .01em; white-space: nowrap; }
.pulse-fig-v { font-size: clamp(13px, 1.2vw, 15px); font-weight: 800; font-variant-numeric: tabular-nums; white-space: nowrap; }
.pulse-fig-v.is-empty { color: var(--ink-muted); font-weight: 600; }
.pulse-meta { grid-column: 1; grid-row: 2; font-size: 11.5px; color: var(--ink-muted); padding-left: 22px; white-space: nowrap; }
/* Share of the month's demand, in the service's own hue. The gauge runs the
   full middle column — from the counts to the figures — so on a wide hero the
   fill level stays readable instead of ending in a stub. */
.pulse-bar {
  grid-column: 2; grid-row: 2; align-self: center; justify-self: stretch;
  height: 4px; border-radius: var(--radius-xs);
  /* The track is --border, not --surface-inset: on dark the inset is a near
     twin of the page and the gauge read as a lone underline. The hairline
     token is tuned to stay visible against every surface in both themes, so
     the empty share of the month is a shape, not a guess. */
  background: var(--border); overflow: hidden; margin-left: 12px;
}
/* The fill eases to its level when the month's data lands — the motion is the
   "live" cue. Decelerating curve, so it settles rather than snaps. */
.pulse-bar > span { display: block; height: 100%; border-radius: inherit; min-width: 4px; transition: width .45s cubic-bezier(.22, 1, .36, 1); }
/* Phones: no per-width tuning of the stacked rows here any more — below the
   hero threshold (768) the strip changes SHAPE entirely (the two side-by-side
   act cards; see the hero threshold block near the end of this file). */

/* One column below 900px: the aside stacks under the copy, still chromeless —
   separated by space alone, and with roomier rows for touch. */
@media (max-width: 900px) {
  .pulse-row { padding-block: 10px; } /* comfortable touch target when stacked */
}
.intro h1 { margin-top: 4px; }
/* The lede mirrors the beta's: same size, leading and measure. */
.intro p { color: var(--ink-muted); max-width: 47ch; margin: 16px 0 0; font-size: var(--type-lead); line-height: var(--type-lead-lh); }
/* Block, not inline-block: as an inline box it sat on the line-box strut, so on
   wide viewports (where it fits on ONE line) it dropped ~4px below the aside's
   kicker opposite it and the two hero columns started off-line. */
.eyebrow {
  display: block; font-size: var(--type-eyebrow); font-weight: var(--weight-display); line-height: 1.5; text-transform: uppercase;
  letter-spacing: var(--type-eyebrow-ls); color: var(--subtitle-ink); margin-bottom: 16px;
}


/* --- Layout -------------------------------------------------------------- */
/* Only set vertical padding here — the horizontal padding comes from .wrap.
   A `padding: … 0 …` shorthand would reset .wrap's side padding, pushing the
   panels 28px past the hero content on each side (misalignment). */
/* minmax(0, 1fr), not 1fr: a bare 1fr's auto minimum is the panel's
   min-content, and the filter bar's nowrap scroll rows would force the track
   (and the page) wider than the phone viewport instead of scrolling. */
.layout { display: grid; grid-template-columns: minmax(0, 1fr); gap: clamp(14px, 2vw, 20px); padding-top: clamp(4px, 0.8vw, 8px); padding-bottom: clamp(24px, 4vw, 40px); align-items: start; }
/* Full-screen calendar (Fullscreen API on #carnet-panel): fill the viewport
   with a padded surface and taller day cells that use the extra height. */
#carnet-panel:fullscreen, #carnet-panel:-webkit-full-screen {
  background: var(--surface); padding: 10px 18px 20px; overflow: auto; border-radius: 0;
}
#carnet-panel:fullscreen .cal-cell, #carnet-panel:-webkit-full-screen .cal-cell { min-height: clamp(88px, 11vh, 128px); }

.panel {
  background: var(--surface);
  /* Ringless (owner: « ensure there is no clash with the calendar ») — a 1px
     border against the tinted band read as a box again; the gradient surface
     and the shadow carry every panel now. */
  border: 0;
  border-radius: var(--radius-lg); box-shadow: var(--shadow);
}
/* The calendar wears the shared 90 % skin (owner, 2026-08-27 evening: « une
   petite touche d'opacité pour le calendrier, environ 90 % » — superseding the
   morning's fully-opaque call, which had itself retired an 80 % backing). The
   backdrop blur keeps every cell legible: the drifting dice read as soft
   light through the veil, never as marks under the grid. */
#carnet-panel { background: var(--surface-veil); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); }
.panel-pad { padding: var(--space-9); }

/* --- Filters ------------------------------------------------------------- */
.filters { display: flex; flex-wrap: wrap; gap: 8px; padding: 12px 18px; }
.field { display: flex; flex-direction: column; gap: 4px; }
.field > label { font-size: 11px; font-weight: 600; color: var(--ink-muted); text-transform: uppercase; letter-spacing: .04em; }
select, input[type='text'], input[type='email'], input[type='tel'], input[type='number'], input[type='date'], textarea {
  font: inherit; padding: 8px 10px; border: 1px solid var(--border-strong);
  border-radius: var(--radius); background: var(--surface); color: var(--ink); min-width: 120px;
}
select:focus, input:focus, textarea:focus { border-color: var(--ring); outline: none; box-shadow: 0 0 0 3px var(--focus-ring); }
textarea { display: block; width: 100%; resize: vertical; }
/* Native checks everywhere take the brand accent — the scoped rules below
   (.check-line, .crit-flag, …) are kept as documentation of intent. */
input[type='checkbox'], input[type='radio'] { accent-color: var(--brand); }

/* --- Nota select ---------------------------------------------------------- */
/* The brand-styled dropdown drawn over a native <select> (enhanceSelect in
   app.js). The OS paints the native options popup with the OS appearance, not
   the page theme — a dark Nota page could open a white system menu — so the
   popup is ours to draw. The native control stays inside the wrapper, visually
   retired but still the form's source of truth. */
.nselect { position: relative; }
.nselect-native {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0;
  clip: rect(0 0 0 0); clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}
.nselect-btn {
  font: inherit; display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%; min-width: 120px; padding: 8px 10px; text-align: left; cursor: pointer;
  border: 1px solid var(--border-strong); border-radius: var(--radius);
  background: var(--surface); color: var(--ink);
  transition: border-color .15s, box-shadow .15s;
}
.nselect-btn:hover { border-color: var(--brand); }
.nselect-btn:focus-visible { border-color: var(--ring); outline: none; box-shadow: 0 0 0 3px var(--focus-ring); }
/* The chevron is two border strokes, so it reads in the ink of every theme. */
.nselect-btn::after {
  content: ''; flex: none; width: 7px; height: 7px; margin-top: -3px;
  border-right: 2px solid var(--ink-muted); border-bottom: 2px solid var(--ink-muted);
  transform: rotate(45deg); transition: transform .15s;
}
.nselect.is-open .nselect-btn::after { transform: rotate(-135deg); margin-top: 3px; }
.nselect-value { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nselect-value.is-placeholder { color: var(--ink-muted); }
.nselect-list {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 40;
  margin: 0; padding: 4px; list-style: none; max-height: min(280px, 40vh); overflow: auto;
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--radius); box-shadow: var(--shadow-lg);
}
.nselect-list[hidden] { display: none; }
.nselect-opt { padding: 7px 10px; border-radius: var(--radius-sm); cursor: pointer; font-size: 13.5px; color: var(--ink); }
.nselect-opt:hover, .nselect-opt.is-active { background: var(--surface-hover); }
.nselect-opt[aria-selected='true'] { color: var(--brand-on-surface); font-weight: 600; }

/* --- Filter panel: hidden until opened from the toolbar ------------------ */
.filterbar {
  margin: 0 0 var(--space-3); padding: var(--pad-card); display: flex; flex-direction: column; gap: var(--space-5);
  background: var(--surface-inset); border: 1px solid var(--border); border-radius: var(--radius);
}
.filterbar[hidden] { display: none; }
.filterbar-row { display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: center; }
.chip-group { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
  appearance: none; font: inherit; font-weight: 500; font-size: 12.5px; cursor: pointer;
  padding: 5px 12px; border-radius: var(--radius); border: 1px solid var(--border);
  background: transparent; color: var(--ink-muted); white-space: nowrap;
  transition: background .15s, color .15s, border-color .15s, box-shadow .15s, transform .1s;
}
.chip:hover { border-color: var(--brand); color: var(--ink); transform: translateY(-1px); }
.chip:active { transform: translateY(0); }
.chip.is-on { background: transparent; border-color: var(--brand); color: var(--brand-on-surface); font-weight: 600; box-shadow: none; }
.chip.sm { font-size: 11.5px; padding: 4px 11px; }

.seg { display: inline-flex; background: var(--surface-inset); border: 1px solid var(--border); border-radius: var(--radius); padding: 3px; gap: 2px; }
.seg-btn {
  appearance: none; font: inherit; font-weight: 500; font-size: 12.5px; cursor: pointer;
  padding: 5px 12px; border-radius: var(--radius-sm); border: 1px solid transparent; background: transparent; color: var(--ink-muted);
  transition: background .15s, color .15s, box-shadow .15s, border-color .15s;
}
.seg-btn:hover { color: var(--ink); }
/* Selected chip reads RAISED off the track: a fill lighter than the inset track
   plus a strong hairline, so it never looks sunken in dark. */
.seg-btn.is-on { background: var(--surface-hover); color: var(--brand-on-surface); border-color: var(--border-strong); box-shadow: var(--shadow-sm); }

/* --- Calendar ------------------------------------------------------------ */
.cal-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; row-gap: 8px; padding: 10px 14px; }
/* 44px targets 4px apart still mis-tap: 8px is the floor between neighbours. */
.cal-nav { display: inline-flex; gap: var(--space-4); }
.cal-title { font-weight: 700; font-size: 15px; white-space: nowrap; }
.cal-title::first-letter { text-transform: uppercase; }
/* Active-filter count riding on the Filtres toggle. */
.filter-count {
  display: inline-grid; place-items: center; min-width: 17px; height: 17px; margin-left: 6px;
  padding: 0 4px; border-radius: var(--radius-sm); background: var(--brand); color: var(--brand-ink);
  font-size: 11px; font-weight: 800; line-height: 1;
}
#filters-toggle.has-active { border-color: var(--brand); color: var(--brand); }

/* The month grid is a QUERY CONTAINER: cells always keep 7 columns, so their
   content must respond to the GRID's width — not the viewport — to stay legible
   in a narrow column, in fullscreen, or on a phone. See the @container rules below. */
.cal-grid { container: cal / inline-size; display: flex; flex-direction: column; gap: 5px; padding: 6px 14px 12px; }
.cal-empty { margin: 0 14px 12px; padding: 10px 14px; text-align: center; color: var(--ink-muted); border: 1px dashed var(--border); border-radius: var(--radius); }
.cal-row { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; }
.cal-dow { text-align: center; font-size: 11px; font-weight: 700; color: var(--ink-muted); padding: 4px 0; text-transform: uppercase; letter-spacing: .04em; }
.cal-cell {
  background: transparent; min-height: clamp(68px, 5.4vw, 98px); padding: 6px 8px 12px; position: relative;
  min-width: 0;
  display: flex; flex-direction: column; gap: 3px; cursor: pointer;
  border: 1px solid var(--border); border-radius: var(--radius-sm); scroll-margin-top: var(--sticky-top);
  text-align: left; font: inherit; color: var(--ink);
  transition: transform .1s ease, box-shadow .1s ease, border-color .1s;
}
/* z-index rides the lift: the transform makes the hovered cell a stacking
   context, which traps the .svc-tip bubble's own z-index — without this the
   DOM-later neighbour paints over the bubble mid-hover. */
.cal-cell:hover { background: var(--surface-hover); border-color: var(--border-strong); transform: translateY(-1px); box-shadow: var(--shadow-sm); z-index: 5; }
/* Adjacent-month days: present and readable, but clearly not this month. No
   border, no prices, and the date sits at the same weight a past day does.
   A future one navigates to its own month, so it takes a pointer. */
.cal-cell.is-out { background: transparent; border-color: transparent; cursor: default; }
.cal-cell.is-out .cal-daynum { color: var(--border-strong); }
.cal-cell.is-out.is-nav { cursor: pointer; }
.cal-cell.is-out.is-nav:hover .cal-daynum { color: var(--ink-muted); }
/* Past dates: blanked and inert, but kept in the grid so no row is lost. */
.cal-cell.is-past { background: transparent; border-color: transparent; cursor: default; pointer-events: none; box-shadow: none; }
.cal-cell.is-past .cal-daynum { color: var(--border-strong); }
.cal-cell.is-today { border-color: transparent; }
.cal-cell.is-selected { border-color: transparent; box-shadow: none; background: var(--surface-inset); }
.cal-cell:focus-visible { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--focus-ring); }
/* Demand days carry NO box of their own: the price + chance% (and the thin left
   tier strip) are the signal. No fill, no border — empty days stay blank, so the
   month reads as figures on a grid, not a wall of blue rectangles. */
.cal-cell.has-bids { background: transparent; }
.cal-cell.has-bids:hover { background: var(--surface-hover); }
/* Urgency, said in words and only on the dates where it changes the decision.
   A calm date shows nothing: its tier is a pure function of the date the cell
   already prints, so a marker there is noise. Elevated dates get a named label
   plus a matching left edge — colour reinforces the word, it never carries the
   meaning alone. */
/* IN FLOW at every width, between the date and the prices (it is what the
   price MEANS, so it reads before it). It was absolutely positioned top-right
   and printed over the day number on every mid-width grid (tablet, narrow
   desktop) — a badge in flow can never overlap anything, at any resolution. */
.cal-urgency {
  position: static; align-self: flex-start; order: 1;
  font-size: 11px; font-weight: 800; letter-spacing: .01em; white-space: nowrap;
  color: var(--ink-muted);
}
.cal-svc-bids, .cal-avg { order: 2; }
.cal-more { order: 3; }
.cal-urgency[data-tier='rapide'] { color: var(--tier-rapide-ink); }
.cal-urgency[data-tier='prioritaire'] { color: var(--tier-prioritaire-ink); }
.cal-urgency[data-tier='urgence'] { color: var(--tier-urgence-ink); }
/* The steepest step is the one a client must not miss: it takes the darkest
   ink of the four, but no fill — no number in the grid carries a background
   (owner, 2026-09-10), the word and the colour say it. */
.cal-urgency[data-tier='extreme'] { color: var(--tier-extreme-ink); }
.legend-mult { font-weight: 800; }
.cal-cell[data-tier]::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  border-radius: var(--radius-sm) 0 0 var(--radius-sm); pointer-events: none;
  background: var(--tier-standard);
}
.cal-cell[data-tier='rapide']::before { background: var(--tier-rapide); }
.cal-cell[data-tier='prioritaire']::before { background: var(--tier-prioritaire); }
.cal-cell[data-tier='urgence']::before { background: var(--tier-urgence); }
.cal-cell[data-tier='extreme']::before { background: var(--tier-extreme); width: 4px; }
/* align-self keeps the box on the text: a stretched flex item would span the
   whole cell and sit under the (absolute) chevron for no reason. min-height
   clears the chevron's 26px hit circle (top:4), so the in-flow price badge on
   the next line can never slide under it, however narrow the cell gets. */
.cal-daynum { font-size: 12px; font-weight: 600; color: var(--ink-muted); align-self: flex-start; min-height: 24px; }
/* The rolling window carries a month seam inside the grid: the 1st names its
   month beside the number ("1 sept"), the way every booking calendar labels it. */
.cal-daynum[data-month]::after {
  content: " " attr(data-month);
  font-size: 10px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--ink-muted);
}
/* Today is said in ink alone — brand colour and the heavy weight, no fill.
   Owner, 2026-09-10: « remove the colour fill from the 10 and any number » —
   a filled square read as a button, and a date is a fact, not a control. */
.cal-cell.is-today .cal-daynum {
  align-self: flex-start; display: inline-flex; align-items: center;
  min-height: 20px; color: var(--brand); font-weight: 800;
  /* The phone grid prints the weekday as ::before with a trailing space —
     flex layout drops that space from the flow, fusing « JEU27 ». The pill
     carries its own gap (inert on desktop, where no ::before exists). */
  gap: 4px;
}
/* Cell content: the day's AVERAGE offer (headline) + a plain availability chip. */
.cal-avg { font-size: 16px; font-weight: 800; letter-spacing: -0.02em; margin-top: auto; white-space: nowrap; color: var(--ink); }
/* Available days stay brand-tinted (inviting); fully-taken days read muted. */
.cal-cell.is-taken { background: var(--surface-inset); }
.cal-cell.is-taken:hover { background: var(--surface-hover); }
/* --- Per-act prices, and the chevron that opens the detail ---------------- */
/* A dot plus a price. The dot's colour is decoded by the Service key in the
   legend, so the act's name is never repeated on a cell or a card. */
.svc-bid { display: inline-flex; align-items: baseline; gap: 5px; min-width: 0; max-width: 100%; }
.svc-bid-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; align-self: center; }
.svc-bid-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
/* In a cell the glyph carries the act, so it is tinted rather than outlined. */
.svc-bid .svc-ic { align-self: center; }
.svc-bid-amount { font-weight: 800; letter-spacing: -0.02em; white-space: nowrap; }

/* A calendar cell prints the dot and the price only. Hovering the row raises a
   bubble that names the act — icon first — and, below, what the cell has no
   room to say: how many offers are still open and the act's starting price,
   so the printed figure reads as high or low at a glance. The same words sit
   in the DOM for screen readers. The bubble inherits the row's service colour
   as currentColor, which tints its wash, edge and icon without a per-service
   rule. Nothing on the path to the grid clips, so it escapes its cell cleanly. */
.cal-svc-bids .svc-bid { position: relative; }
.svc-tip {
  position: absolute; bottom: calc(100% + 8px); left: -6px;
  z-index: 6; padding: 10px 14px; border-radius: var(--radius);
  background: color-mix(in srgb, currentColor 9%, var(--surface));
  border: 1px solid color-mix(in srgb, currentColor 45%, var(--border-strong));
  border-left: 3px solid currentColor; box-shadow: var(--shadow);
  width: max-content; max-width: 260px;
  display: none; flex-direction: column; gap: 4px; pointer-events: none;
}
.svc-tip-head { display: inline-flex; align-items: center; gap: 7px; }
.svc-tip-head .svc-ic { flex: none; }
.svc-tip-name { color: var(--ink); font-size: 13.5px; font-weight: 700; }
.svc-tip-detail { color: var(--ink-muted); font-size: 12.5px; font-weight: 600; line-height: 1.4; white-space: normal; }
/* The bubble hangs off its row's left edge; in the last two columns that runs
   past the grid's right edge, so it right-aligns there instead. */
.cal-row .cal-cell:nth-child(n+6) .svc-tip { left: auto; right: -6px; }
@media (hover: hover) and (pointer: fine) {
  .cal-svc-bids .svc-bid:hover .svc-tip { display: flex; }
}
@media (prefers-reduced-motion: reduce) {
  .svc-tip { transition: none; }
  /* Motion-flavoured polish (lifts, nudges, eased fills) goes still; colour
     and shadow state changes remain. */
  .btn-primary, .mini-btn, .pulse-item, .pulse-bar > span, .cal-cell { transition: none; }
  .btn-primary:not(:disabled):hover, .cal-cell:hover { transform: none; }
  .mini-btn:active { transform: none; }
}
.cal-svc-bids { display: flex; flex-direction: column; gap: 2px; margin-top: auto; min-width: 0; font-size: 12.5px; }
.cal-svc-bids .svc-bid { min-width: 0; }

/* Collapsed is the resting state everywhere. The chevron is the only way in, so
   it works the same with a mouse, a finger or a keyboard. */
.cell-chevron {
  position: absolute; top: 4px; right: 4px; display: grid; place-items: center;
  width: 26px; height: 26px; padding: 0; appearance: none; font: inherit; border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--ink-muted); cursor: pointer;
  transition: transform .15s ease, background .12s ease, color .12s ease;
}
.cell-chevron:hover { background: var(--surface-inset); color: var(--ink); }
/* On a touch screen the 26px glyph keeps its size; its hit area grows to the
   44px the rest of the app promises on coarse pointers (the ✕ of a dialog, the
   legal nav) — the same pseudo-element trick, so nothing in the cell moves. */
@media (pointer: coarse) {
  .cell-chevron, .beta-teaser-info, .sub-link-toggle { position: relative; }
  .cell-chevron { position: absolute; }
  .cell-chevron::before, .beta-teaser-info::before { content: ''; position: absolute; inset: -9px; }
  .sub-link-toggle { min-height: 44px; }
}
/* --- Touch targets: the 44px promise, kept everywhere a finger lands ---------
   The 2026-09-11 twelve-viewport audit read every interactive control on a
   coarse pointer. The ones below sat between 18 and 38px: legible, but a
   miss for a thumb. Each keeps its resting size on a mouse; on touch it grows
   its hit area — by min-height where the control is a block, by a ::before
   extension where its box must not move (a switch, a fold glyph). Inline
   links set in running text are exempt (WCAG 2.5.8), so nothing here touches
   them. */
@media (pointer: coarse) {
  .book-rail-b, #day-date, .day-bids-toggle, .offer-hint-link, .sup-chip, #chat-topic-search,
  #onb-skip, #nc-cnq, #auth-switch-btn, .password-toggle { min-height: 44px; }
  .crit-sec-fold, #chat-close, .mini-seg-btn, .tswitch { position: relative; }
  .crit-sec-fold::before, #chat-close::before { content: ''; position: absolute; inset: -10px; }
  .mini-seg-btn { min-width: 44px; }
  /* ::after, PAS ::before : ::before est le galet de l'interrupteur (24 px,
     fond, cadre, ombre). Le redéclarer ici écrasait sa géométrie et le
     poussait hors de la piste sur tout pointeur grossier — c'est-à-dire sur
     tous les téléphones (capture du propriétaire, 2026-09-12). */
  .tswitch::after { content: ''; position: absolute; inset: -8px -4px; }
}
.cell-chevron[aria-expanded='true'] { transform: rotate(180deg); }
/* Touch: 26px alone is a mis-tap magnet. A transparent halo grows the hit
   circle to 40×40 without moving a pixel of layout — the glyph (and its
   expanded-state rotation, which the pseudo simply follows) stays put. */
@media (pointer: coarse) {
  .cell-chevron::after { content: ''; position: absolute; inset: -7px; border-radius: 50%; }
}

/* What the chevron reveals. */
.cal-more { display: none; }
.cal-cell.is-expanded .cal-more { display: flex; flex-wrap: wrap; gap: 2px 8px; margin-top: 4px; font-size: 10.5px; line-height: 1.35; color: var(--ink-muted); }
.cal-more-beat { font-weight: 700; color: var(--brand); }
/* An expanded cell must be able to outgrow its row without shoving neighbours. */
.cal-cell.is-expanded { z-index: 3; background: var(--surface); border-color: var(--border-strong); box-shadow: var(--shadow-lg); }




/* Responsive cells, driven by the GRID width (7 columns are fixed, so cell width
   ≈ grid width / 7). Detail is shed progressively so the essentials — day number,
   count, top price, urgency strip, service-mix + status bars — always fit cleanly
   at every resolution, and nothing ever clips mid-word. */
@container cal (max-width: 740px) {
  .cal-avg { font-size: 13px; }
  .cal-svc-bids .svc-bid-amount { font-size: 11.5px; }
  /* "En attente / Approuvé / Expiré" would clip, so collapse the own-offer badge to a status dot. */
}
@container cal (max-width: 560px) {
  .cal-cell { padding: 6px 6px 12px; min-height: clamp(66px, 15cqw, 96px); }
  .cal-daynum { font-size: 11px; }
  /* Cells get too narrow for "3 285 $": swap to the compact form (data-compact),
     which always fits. The full amount stays in the DOM + day dialog for a11y. */
  .cal-svc-bids .svc-bid-amount { font-size: 0; }
  .cal-svc-bids .svc-bid-amount::after { content: attr(data-compact); font-size: 11px; font-weight: 800; }
  .cal-avg { font-size: 0; }
  .cal-avg::after { content: attr(data-compact); font-size: 12.5px; font-weight: 800; letter-spacing: -0.02em; }
}
/* The in-flow urgency badge is ~66px at its widest ("dès 4 000 $", the 2× same-day
   ceiling on the 2 000 $ floor) and needs an
   ~84px cell — a 620px seven-column grid — or its nowrap text runs into the
   next day (measured 1-20px of bleed from 710px down to 500px viewports).
   Under that, swap it to the compact figure (data-compact, the same pattern as
   the amounts above). The full label stays in the DOM and in the badge's
   title, so screen readers and hover keep the exact price. */
@container cal (max-width: 620px) {
  .cal-urgency { font-size: 0; }
  .cal-urgency::after { content: attr(data-compact); font-size: 11px; font-weight: 800; letter-spacing: .01em; }
}
/* Phones. Seven columns are not negotiable, so on a 320px screen a cell is 34px
   wide with a 26px content box, and a glyph + gap + compact amount laid out in a
   ROW needs 45px. The row was clamped to the box while its text carried on
   painting over the next day, because the tooltip above deliberately leaves
   nothing on the path to the grid clipping. That tooltip is display:none without
   a fine pointer, so here the cell can safely contain its own content again.
   Measured at 320/375/414: every act still prints its price, and nothing leaves
   its cell. The cost is height (87px -> 127px at 320), which a phone scrolls. */
/* PHONES: the month grid drops from 7 columns to 3.
   Seven columns on a 320px screen give a 34px cell, which cannot carry a glyph
   and a price side by side however the content is tuned — the previous attempt
   stacked them and still had to compact "1 900 $" down to "1,9k". Three columns
   give an 82px cell, wider than the 7-column cell is at ANY phone size, so the
   cell renders the way it does on a desktop and the prices come back in full.

   What that costs: a cell is no longer under a weekday column, so the weekday
   header row goes and each cell prints its own ("MER 19", app.js sets data-dow).
   Empty padding cells and past days are dropped rather than blanked, so the grid
   opens on today and packs 13 real dates into 5 rows instead of 21 slots into 3.

   This is keyed on a container on the grid's PARENT: an element cannot respond
   to its own container query, and .cal-grid is the `cal` container itself. */
#view-calendrier { container: calwrap / inline-size; }
@container calwrap (max-width: 468px) {
  .cal-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-3); }
  .cal-row { display: contents; }
  .cal-dow-row { display: none; }
  /* Out-of-month blanks exist ONLY to hold a weekday column, and there are no
     weekday columns here. The dead history that anchors the rolling window's
     first week holds no place either: the phone grid opens on today. */
  .cal-cell.is-out, .cal-cell.is-past { display: none; }
}
/* Cell content in reflowed mode. The `cal` container is still narrow here, so
   the ≤560 compact-money swap is still matching — but the CELL is now 82px, and
   grid width no longer implies cell width once the column count changes. */
@container cal (max-width: 440px) {
  .cal-cell { padding: 7px 9px 10px; gap: 3px; overflow: hidden; }
  /* One stable header row: the label owns the cell's width and ellipsizes
     ("MAR 1 SE…") instead of wrapping under the chevron. The chevron corner is
     reserved only on offer days (the only cells that carry one), and never for
     today's date-circle — a padded pill would smear its fill sideways; the
     pill is short ("MER 27") and clears the glyph on its own. */
  .cal-daynum { align-self: stretch; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .cal-cell.has-bids:not(.is-today) .cal-daynum { padding-right: 30px; }
  /* The month seam used to ride the date line and ellipsized into
     « MAR 1 SE… » wherever the chevron reserve ate the right edge. A seam
     cell may wrap instead: « MAR 1 » stays whole and the month reads as its
     own quiet line beneath it — no leading space, it owns the line. */
  .cal-daynum[data-month] { white-space: normal; }
  .cal-daynum[data-month]::after { content: attr(data-month); display: block; line-height: 1.3; }
  /* Offer lines breathe the same whether the day holds one or three. */
  .cal-svc-bids { gap: 3px; }
  .cal-daynum::before {
    content: attr(data-dow) " ";
    font-size: 10px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  }
  /* An 82px cell fits "1 900 $" (57px with its glyph). Undo the compaction. */
  .cal-svc-bids .svc-bid-amount { font-size: 11.5px; }
  .cal-svc-bids .svc-bid-amount::after { content: none; }
  /* Three-column cells are ≥93px down to a ~350px screen: the full urgency
     label fits again. */
  .cal-urgency { font-size: 11px; }
  .cal-urgency::after { content: none; }
}
/* The very smallest screens (≤~350px): three-column cells drop under 83px and
   the widest label ("dès 4 000 $", ~66px) no longer fits — back to compact. */
@container cal (max-width: 265px) {
  .cal-urgency { font-size: 0; }
  .cal-urgency::after { content: attr(data-compact); font-size: 11px; font-weight: 800; letter-spacing: .01em; }
}

/* --- Agenda / bid list --------------------------------------------------- */
/* Agenda: a dense responsive grid of day-cards so it fills the full width below
   the calendar (no sparse full-width rows / blank space). */
/* Row-aligned grid: day-groups line up in tidy rows/columns. Each day shows only
   its best offer (the rest behind "+N autres offres"), so heights stay close and
   rows align without large gaps. */

/* Same bargain as the calendar cell: the resting card stays simple — the day,
   one amount, the odds — and hover is where a client digs into what it takes to
   be retained. Fine pointers only; on touch the tap opens the day dialog, which
   carries the same detail. */

/* Without hover (touch), the coaching line is simply always there. */

/* A day with no bet is still a full rectangle: the placeholder fills the card and doubles as a "reserve this date" affordance. */
/* The card header carries the date and, like the calendar cell, the odds of
   getting a notary that day — the list was the one view showing a price with no
   sense of how gettable the date is. */
.bid-row { display: flex; align-items: center; gap: 10px; padding: 9px var(--space-12) 9px 22px; border-top: 1px solid var(--border); border-left: 2px solid transparent; }
.bid-row.is-open { border-left-color: var(--status-ouverte); }
.bid-row.is-retenue { border-left-color: var(--status-retenue); }
.status-chip {
  font-size: 11px; font-weight: 700; padding: 3px 9px; border-radius: var(--radius-sm);
  background: var(--surface); color: var(--status-retenue); border: 1px solid var(--border-strong);
  max-width: 44%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: none;
}
/* A list card is only 240-390px wide at EVERY breakpoint (the grid packs 1-4
   columns), and a single flex line cannot hold amount + name + service + tier +
   actions: the client name and the service were ellipsised into "C..." /
   "Refi..." on phones AND on a 1920 desktop alike. Give the numbers one line and
   the identity its own full-width line beneath, via `order` (the markup order is
   amount, meta, tier, actions). The day dialog keeps the single-line row — it
   has 600px to work with. */
.bid-amount { font-weight: 800; font-size: 15px; min-width: 78px; }
.bid-meta { flex: 1; min-width: 0; }
.bid-who { font-size: 13px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bid-sub { font-size: 12px; color: var(--ink-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pill {
  font-size: 11px; font-weight: 700; padding: 3px 10px; border-radius: var(--radius-sm);
  color: var(--on-accent); white-space: nowrap;
}
.pill[data-tier='standard'] { background: var(--tier-standard); }
.pill[data-tier='rapide'] { background: var(--tier-rapide); }
.pill[data-tier='prioritaire'] { background: var(--tier-prioritaire); }
.pill[data-tier='urgence'] { background: var(--tier-urgence); }
.pill[data-tier='extreme'] { background: var(--tier-extreme); }
.pill-retenue { background: var(--surface-inset); color: var(--ink-muted); border: 1px solid var(--border-strong); }
.tag-anon { font-size: 11px; color: var(--ink-muted); border: 1px dashed var(--border-strong); border-radius: var(--radius-sm); padding: 1px 6px; margin-left: 6px; }

.legend { display: flex; flex-wrap: wrap; gap: 8px 10px; padding: 2px 14px 10px; font-size: 12px; color: var(--ink-muted); }
.legend-item, .legend-status-item { display: inline-flex; align-items: center; gap: 6px; }
.legend-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--ink); }
.legend-label--sep { margin-left: 4px; padding-left: 12px; border-left: 1px solid var(--border); }
.legend-dot { width: 10px; height: 10px; border-radius: var(--radius-sm); }
/* Full-width explainer under the colour keys: names the two figures each cell
   prints. Own line so it never competes with the dotted keys. */
.legend-note { flex: 1 0 100%; margin-top: 2px; font-size: 11.5px; line-height: 1.5; color: var(--ink-muted); }
.legend-note strong { color: var(--ink); font-weight: 700; }

/* --- Offer form (now inside the day-booking dialog) --------------------- */
.form-row { margin-bottom: 14px; }
.form-row label.lbl { display: flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 700; margin-bottom: 8px; }
.help { font-size: 12px; color: var(--ink-muted); margin-top: 4px; }

/* --- A held line --------------------------------------------------------
   The other half of ADR 0039. Some messages CANNOT go behind an « i »: a
   validation refusal, a character counter, a « ✓ enregistré », a live status
   line. They have to be read, out loud, in place. But `hidden` means
   `display: none`, so each one still took its line away with it — and the
   button the user was aiming at moved under their cursor at the exact moment
   the refusal explained why they had missed it.

   Here `hidden` stops meaning « take the line away » and starts meaning « say
   nothing on it ». An author `display` beats the UA's `[hidden]{display:none}`,
   so the box stays; `visibility` takes the content out of sight, out of the
   focus order and out of the accessibility tree — everything `hidden`
   promised, minus the jump. `.hold-line` adds the reserved height for the
   nodes that are EMPTIED when they fall silent (an error list, a counter);
   a node that keeps its text needs `.hold` alone. */
/* Voici la liste, en un seul endroit : `.hold` pour tout nouvel arrivant, et
   les lignes déjà nommées qui la rejoignent sans changer de nom. Le `display`
   est !important parce que le tapis général `.hidden, [hidden]` l'est aussi ;
   `block` suffit partout — un enfant de flex est de toute façon « blockifié »
   par le navigateur. `.hold-line` réserve la hauteur des nœuds qu'on VIDE
   quand ils se taisent (un compteur, une liste d'erreurs) ; un nœud qui garde
   son texte n'en a pas besoin. */
.hold[hidden],
.offer-hint[hidden], .day-beat[hidden],
.chat-error[hidden], .chat-count[hidden], .nc-chat-count[hidden], .nc-chat-err[hidden],
.nc-form-errors[hidden], .nc-field-err[hidden], .onb-choice-live[hidden],
.sup-count[hidden], .sup-reply-courriel[hidden], .ct-count[hidden],
.day-market-line[hidden], .cal-avail[hidden],
#chat-reply-error[hidden], #chat-reply-sent[hidden] { display: block !important; visibility: hidden; }
/* CE QUI N'EST PAS DANS CETTE LISTE, ET POURQUOI (ADR 0046). La ligne réservée
   est faite pour un message de VALIDATION : il apparaît et disparaît sous le
   doigt du visiteur, et sans elle le formulaire sauterait à chaque frappe. Une
   NOTE DE SITUATION, elle, change une fois par conversation — et si elle garde
   sa ligne, elle la garde tout le temps. « Conversation terminée » et l'avis
   d'escalade réservaient à eux deux 108 px de vide permanent au milieu d'un
   panneau de 380 px : c'était, littéralement, le trou qui faisait paraître la
   messagerie cassée. Ils se replient donc, comme les questions d'amorce. */
/* Les deux qui sont des conteneurs flex gardent leur flex : en `block` leur
   contenu se recomposerait, et une ligne tenue changerait de hauteur — soit
   exactement ce qu'on est venu empêcher. */
.day-market-line[hidden], .cal-avail[hidden] { display: flex !important; }
.hold-line { min-height: 1.5em; }

/* --- Info tip (« ⓘ ») ----------------------------------------------------
   The house pattern for a SITUATIONAL note — « this date is short notice »,
   « few notaries travel that far », « check these older answers ». Such a
   sentence used to print itself as an extra line under the question, so an
   answer that turned it on GREW its card and pushed everything below it down
   the page; answering the next question shoved it back. The sentence now
   rides a small « i » pinned to the question's own line and opens in a panel
   that floats OVER the page: the form's height never depends on what the
   notes have to say.

   The box is reserved whether or not the tip has something to say
   (visibility, never display) — so the label line does not jitter either, and
   a hidden tip is neither focusable nor read aloud.

   Three ways in, because a tooltip that only answers the mouse answers nobody
   on a phone or a keyboard: hover, keyboard focus, and a click that PINS the
   panel open until Escape, an outside click, or another tip takes over. The
   pinned panel takes the pointer, so its sentence can be selected and copied. */
.itip { position: relative; display: inline-flex; flex: none; vertical-align: -3px; margin-left: 6px; }
.itip[data-on='false'] { visibility: hidden; }
.itip-btn {
  appearance: none; border: 0; background: none; padding: 0; margin: 0;
  position: relative;
  width: 18px; height: 18px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius-xs); color: var(--ink-muted); cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
/* WCAG 2.2 « Target Size (Minimum) » asks for 24 × 24 CSS px. The glyph stays
   at 18 so it never lifts the label's line — the target is grown OUTWARD by an
   invisible pad, which costs the layout nothing because it is out of flow. */
.itip-btn::after { content: ''; position: absolute; inset: -3px; }
.itip[data-tone='warn'] .itip-btn { color: var(--warn); }
.itip-btn:hover, .itip[data-open='true'] .itip-btn { color: var(--ink); background: var(--surface-hover); }
.itip-btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
/* The panel: absolutely placed, so it costs the layout nothing. Its side and
   its alignment are chosen by script the moment it opens (placeItip), so it
   never opens off the edge of a dialog or a phone. */
/* L'aide d'une question vit maintenant DANS ce panneau : elle en prend la voix
   (le gris de .help se perdrait sur la surface du panneau) et n'y garde pas la
   marge qu'elle avait en pleine page. */
.itip-pop > .help { margin: 0; font-size: inherit; color: inherit; }
.itip-pop {
  position: absolute; z-index: 60; top: calc(100% + 6px); left: 50%; transform: translateX(-50%);
  width: max-content; max-width: min(280px, calc(100vw - 16px));
  padding: 8px 10px; text-align: left;
  font-size: 12.5px; font-weight: 500; line-height: 1.5; color: var(--ink);
  background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg);
  opacity: 0; visibility: hidden; pointer-events: none;
}
.itip[data-side='top'] > .itip-pop { top: auto; bottom: calc(100% + 6px); }
/* Hover is offered only where a pointer can actually hover: on a touch screen
   a tap leaves a « stuck » hover behind, and the panel would never close. There
   the pinning tap is the way in, and it has a way out. */
/* FERMÉE, la bulle sort de la mise en page (2026-09-06). Elle est hors flux,
   mais une boîte absolue invisible compte quand même dans le scrollWidth de son
   conteneur : à 375 px, quatre bulles de 280 px ancrées sur leur « i » faisaient
   dépasser la feuille de réservation de 30 px, et #day-dialog (overflow-y:auto,
   donc overflow-x calculé à auto) se laissait tirer de côté — rien à voir, tout
   à faire glisser. C'est la SEULE exception au registre « visibility, jamais
   display » du « i » : celui-ci ne tient aucune ligne, donc il n'en bouge
   aucune. Ouverte, elle reprend sa boîte AVANT qu'itipPlace la mesure (le clic
   pose data-open, le survol et le focus posent l'état CSS, puis l'événement). */
.itip-pop { display: none; }
@media (hover: hover) {
  .itip:hover > .itip-pop { opacity: 1; visibility: visible; display: block; }
}
.itip-btn:focus-visible ~ .itip-pop,
.itip[data-open='true'] > .itip-pop { opacity: 1; visibility: visible; display: block; }
.itip[data-open='true'] > .itip-pop { pointer-events: auto; }
@media (prefers-reduced-motion: no-preference) {
  .itip-pop { transition: opacity .12s ease, visibility .12s; }
  /* A note that has just turned on wakes its « i » once, so a signal that no
     longer takes a line of its own is still noticed. */
  @keyframes itip-wake {
    from { box-shadow: 0 0 0 4px color-mix(in srgb, currentColor 35%, transparent); }
    to { box-shadow: 0 0 0 4px transparent; }
  }
  .itip[data-fresh='true'] .itip-btn { animation: itip-wake 1.2s ease-out; }
}

/* Inside step 3, right above the amount: WHY it is pre-filled (delay tier +
   going range). Compact and muted — context, never a competing price signal. */
.tier-preview { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.tier-preview .pill { font-size: 11px; }
.tier-preview .tp-text { font-size: 12px; color: var(--ink-muted); }

.slider-row { display: flex; align-items: center; gap: 12px; }
/* La marge par défaut du navigateur (2 px) décalait la piste de son rail :
   le curseur commençait 2 px à droite du montant et des bornes au-dessus. */
input[type='range'] { flex: 1; margin: 0; accent-color: var(--brand); }
/* The slider's typed twin: a client who knows their number types it. */
.amount-input-wrap { display: inline-flex; align-items: center; gap: 4px; flex: none; }
.amount-input { width: 7ch; padding: 6px 8px; font: inherit; font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; border: 1px solid var(--border-strong); border-radius: var(--radius-sm); background: var(--surface); color: var(--ink); }
.amount-input:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
.amount-input-unit { font-size: 13px; font-weight: 700; color: var(--ink-muted); }
/* Where the slider starts and stops, in dollars, under its two ends. */
.slider-bounds { display: flex; justify-content: space-between; margin-top: 2px; font-size: 11.5px; color: var(--ink-muted); font-variant-numeric: tabular-nums; }
/* The reason the publish button is dead, said before it is pressed. Each
   named question is a door back to its own line — underlined, same voice. */
.offer-hint { margin: 0 0 8px; min-height: 1.5em; font-size: 12.5px; font-weight: 600; color: var(--warn); }
.offer-hint-link {
  appearance: none; border: 0; background: none; padding: 0; margin: 0;
  font: inherit; color: inherit; cursor: pointer;
  text-decoration: underline; text-underline-offset: 2px;
}
.offer-hint-link:hover, .offer-hint-link:focus-visible { color: var(--ink); }
/* Law 25 small print directly under the CTA: always visible, quiet. The
   negative margin tucks it against the button despite the form's flex gap. */
.consent-line { font-size: 11.5px; line-height: 1.5; }
.day-book > .consent-line { margin-top: -12px; }
.amount-big { font-size: 26px; font-weight: 800; letter-spacing: -0.02em; }

.gauge { height: 8px; border-radius: var(--radius-xs); background: var(--surface-inset); overflow: hidden; margin: 8px 0 4px; }
.gauge-fill { width: 0; height: 100%; background: linear-gradient(90deg, var(--tier-rapide), var(--tier-prioritaire), var(--tier-urgence)); }
.gauge-label { font-size: 12px; font-weight: 600; }

/* LE DEVIS (ADR 0031) — les deux lignes que le client paie, dans l'étape du
   montant. Il doit se lire comme un reçu, pas comme une alerte : aucune
   couleur d'accent, juste un filet et une ligne de total plus lourde. Le
   supplément de Nota n'est pas une mauvaise nouvelle qu'on cache, c'est un
   prix qu'on annonce — l'art. 68 du Code de déontologie interdit la publicité
   incomplète, et une ligne discrète mais toujours visible est la réponse. */
.devis { margin-top: 10px; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface-inset); }
.devis-l { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; font-size: 13px; line-height: 1.7; }
.devis-k { color: var(--ink-muted); }
.devis-v { font-variant-numeric: tabular-nums; font-weight: 600; }
.devis-total { margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--border); font-size: 14px; }
.devis-total .devis-k, .devis-total .devis-v { color: var(--ink); font-weight: 700; }
/* La revendication du modèle n'avait AUCUNE règle : elle héritait des 16 px du
   formulaire et parlait donc plus fort que le total juste au-dessus. Elle
   compte (art. 32.1 2° L.N.), mais elle se lit après le chiffre, pas avant. */
.devis-claim { margin: var(--space-5) 0 0; font-size: 12.5px; font-weight: 600; line-height: 1.5; color: var(--ink); }
.devis-note { margin: 6px 0 0; font-size: 11.5px; line-height: 1.5; color: var(--ink-muted); }

/* Discreet inline checkbox (the bid dialog's account opt-in): plain row, no
   switch chrome — the option must read as one more optional field, not a step. */
.check-line { display: flex; align-items: center; gap: 8px; font-size: 13.5px; cursor: pointer; }
.check-line input { width: 16px; height: 16px; margin: 0; flex: none; accent-color: var(--brand); }
.check-line input:disabled { cursor: not-allowed; }
.check-line:has(input:disabled) { color: var(--ink-muted); cursor: not-allowed; }

.switch-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 0; }
.switch { position: relative; width: 42px; height: 24px; flex: none; }
.switch input { opacity: 0; width: 0; height: 0; }
.switch .track { position: absolute; inset: 0; background: var(--border-strong); border-radius: var(--radius-sm); transition: background .12s; cursor: pointer; }
.switch .track::before { content: ''; position: absolute; width: 18px; height: 18px; left: 3px; top: 3px; background: var(--on-accent); border-radius: var(--radius-xs); transition: transform .12s; }
.switch input:checked + .track { background: var(--brand); }
.switch input:checked + .track::before { transform: translateX(18px); }
.switch input:focus-visible + .track { box-shadow: 0 0 0 3px var(--focus-ring); }

/* Délibérément PAS une ligne tenue (ADR 0039 §5) : une liste de refus répond à
   un envoi volontaire, pas à une frappe — le saut arrive une fois, à un moment
   où l'œil est déjà sur le message. La réserver mettrait ~27 px de vide
   permanent au-dessus de six boutons d'envoi, ce qui coûte plus cher que le
   saut qu'elle éviterait. Les listes qui répondent, elles, à CHAQUE frappe
   (.nc-form-errors, .nc-field-err) tiennent bien leur ligne. */
.errors { list-style: none; margin: 8px 0 0; padding: 0; }
.errors li { color: var(--danger); font-size: 13px; padding: 2px 0; }
/* « Nous joindre »: the message counter, shown only near the cap (app.js contactCount). */
.ct-count { margin: 4px 0 0; min-height: 1.5em; text-align: right; font-variant-numeric: tabular-nums; }

/* --- Partenaires (ADR 0011) ---------------------------------------------- */
/* Refonte du 2026-09-12 (propriétaire : « beaucoup trop de texte »). La page
   tient en deux registres : la promesse et ses deux montants d'un côté, le
   formulaire qui donne le code de l'autre. Tout ce qui la racontait une
   deuxième fois (sélecteur de métier du héros, estimateur, vignette en trois
   temps, bande d'étapes, FAQ) est parti — le CSS aussi, pas seulement le
   balisage. */
.pr-hero {
  display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: clamp(var(--gap), 3vw, 48px); align-items: center;
  margin-top: var(--intro-pad-top);
  /* Vertical breathing only (owner, 2026-08-27: « move to left ») — no side
     padding, so the copy starts flush on the wrap's left edge exactly like
     the intro of every other pane. */
  padding: clamp(16px, 2vw, 28px) 0;
  border-radius: var(--radius-lg);
  /* No box at all (owner, 2026-08-27: « add some gradient… no corner…
     smooth for the eyes ») — no surface backing, no shadow, no seam. The
     band is only light: two brand-tint glows that fade to transparent well
     inside the bounds, so there is no edge for the eye to catch. Tokens
     only — the tint carries both themes. */
  background: var(--wash-glow);
}
/* Same voice as every other pane (owner, 2026-08-27: « même taille et même
   style que espace notaire ») — the headline and lede mirror .intro h1/.intro p
   exactly, so the three doors open on one consistent register. */
.pr-hero h1 { margin-top: 4px; }
.pr-hero-copy > p:not(.pr-eligibility) { color: var(--ink-muted); max-width: 47ch; margin: 16px 0 0; font-size: var(--type-lead); line-height: var(--type-lead-lh); }
@media (max-width: 900px) {
  .pr-hero { grid-template-columns: minmax(0, 1fr); align-items: start; }
}
/* Les deux montants et leur règle d'acquisition : une seule colonne, rien
   d'autre. */
.pr-offer { min-width: 0; display: flex; flex-direction: column; gap: var(--space-6); }
/* Two tracks, one stat card each: kicker, big figure, cadence. The notary
   track pays more and carries the highlight (the STRONGER brand tint — never
   a ring) — tokens only. */
.pr-rewards { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr)); gap: var(--gap); }
/* Qui peut réclamer (art. 33 C. déont.), une ligne discrète sous la promesse. */
.pr-eligibility { margin: var(--space-5) 0 0; max-width: 60ch; font-size: 12.5px; line-height: 1.5; color: var(--ink-muted); }
/* Quand la récompense est acquise : dite UNE fois sous la paire, plus par
   carte — les deux voies suivent la même règle. */
.pr-earned { margin: 0; font-size: 13px; line-height: 1.5; color: var(--ink-muted); }
.pr-card {
  display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-9) var(--space-10);
  border-radius: var(--radius-lg);
  /* Transparent by design: the rewards belong to the page's visual field,
     while the hairline keeps each stat grouped without creating two opaque
     slabs on the dark background. */
  background: transparent;
  border: 1px solid color-mix(in srgb, var(--brand) 42%, var(--border));
  box-shadow: none;
  /* A plain stat (audit P1-3): a div that looked pressable was unreachable by
     keyboard and unnamed to a screen reader — no pointer, no lift, no arrow. */
}
.pr-card--notaire {
  /* The stronger border is enough to distinguish the higher-value track;
     keep the interior transparent so both cards sit on the same background. */
  border-color: var(--brand);
}
/* The kicker is a label with intent, not a whisper: brand ink (the readable
   pairing .auth-soon already proves over the strong tint in both themes) and
   a wider track. */
.pr-kicker { font-size: var(--type-eyebrow); font-weight: var(--weight-display); text-transform: uppercase; letter-spacing: var(--type-eyebrow-ls); color: var(--subtitle-ink); }
/* The figure IS the card (owner, 2026-08-27: « do better for 50 and 250 ») —
   display size, dense tracking, on its own line. */
.pr-amount {
  margin-top: var(--space-2);
  /* The house display face and the h1's own rung — at 50px in Inter the figure
     out-sized the page's headline by a third and sat on no rung of the scale
     (ADR 0050). It is still the loudest thing on the card; it is no longer
     louder than the door's title. */
  font-family: var(--font-display);
  font-size: var(--type-h2); font-weight: var(--weight-display);
  letter-spacing: -0.035em; color: var(--brand-on-tint-strong);
  font-variant-numeric: tabular-nums; line-height: 1;
}
/* The cadence tag — the one fact that separates the two offers (the 50 $
   repeats forever, the 250 $ pays once per referred notary). A quiet outlined
   chip: hairline brand mix, never a fill. */
.pr-freq {
  align-self: flex-start;
  font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .07em;
  color: var(--brand-on-surface);
  border: 1px solid color-mix(in srgb, var(--brand) 40%, transparent);
  border-radius: var(--radius-xs);
  padding: 3px 7px;
  white-space: nowrap;
}

/* Sous le héros il ne reste QUE l'action : le formulaire (et, une fois le code
   réclamé, le panneau de partage qui le précède) sur une seule colonne bornée
   à la mesure d'un formulaire, puis la mention du prix du client. */
/* --- Le circuit du code (2026-09-12 soir) ---------------------------------
   Montrer plutôt que décrire : un code en haut, deux voies côte à côte, une
   chaîne, deux fins. Chaque pièce entre en s'allumant (.is-on) — la scène
   n'est jamais vide, elle est seulement encore éteinte, ce qui laisse la
   hauteur stable d'un tour à l'autre. Tout est jeton : aucun aplat, aucune
   couleur littérale, un seul registre carré. */
.pr-flow {
  margin: var(--gap) 0 0; padding: var(--pad-card-lg);
  border-radius: var(--radius-lg);
  background: var(--surface-veil);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
.pr-flow-head { margin-bottom: var(--space-8); }
.pr-flow-head h2 { margin: 0; }
.pr-start { align-self: flex-start; min-height: 44px; padding-inline: 20px; font-weight: 700; }
.pr-flow-stage { display: grid; justify-items: center; gap: var(--space-7); }
/* Chaque pièce de la scène : éteinte, puis allumée. L'opacité de repos reste
   lisible pour l'œil qui balaie la page sans regarder la boucle. */
.pr-fl-seed, .pr-fl-step, .pr-fl-link, .pr-fl-said, .pr-fl-card, .pr-fl-beat, .pr-fl-end {
  opacity: 1; transform: none;
  transition: border-color .35s ease, background-color .35s ease;
}
.pr-fl-seed.is-on, .pr-fl-step.is-on, .pr-fl-link.is-on, .pr-fl-said.is-on,
.pr-fl-card.is-on, .pr-fl-beat.is-on, .pr-fl-end.is-on { opacity: 1; transform: none; }
/* Le code, en haut, seul : l'objet dont tout le reste découle. Il descend
   vers les deux voies par un filet — pas une flèche. */
.pr-fl-seed { display: grid; justify-items: center; gap: var(--space-3); position: relative; padding-bottom: var(--space-7); }
.pr-fl-seed::after {
  content: ''; position: absolute; left: 50%; bottom: 0; width: 1px; height: var(--space-6);
  background: var(--border-strong);
}
.pr-fl-lbl, .pr-fl-field-lbl, .pr-fl-end-lbl {
  font-size: var(--type-eyebrow); font-weight: var(--weight-display);
  text-transform: uppercase; letter-spacing: var(--type-eyebrow-ls); color: var(--subtitle-ink);
}
.pr-fl-code, .pr-fl-link, .pr-fl-said, .pr-fl-field {
  font-family: var(--font-mono); font-size: 13px; color: var(--ink);
  overflow-wrap: anywhere;
}
.pr-fl-code {
  font-size: 17px; font-weight: 700; letter-spacing: .08em;
  padding: var(--space-4) var(--space-6);
  border: 1px solid var(--brand); border-radius: var(--radius-sm);
}
/* Les deux voies : même largeur, même poids — ce sont deux choix, pas un
   chemin principal et un repli. */
.pr-fl-ways {
  width: 100%; display: grid; gap: var(--gap);
  grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
}
.pr-fl-way { display: grid; justify-items: center; align-content: start; gap: var(--space-5); text-align: center; }
.pr-fl-step { font-size: 14px; font-weight: 700; color: var(--ink); }
.pr-fl-link, .pr-fl-said {
  padding: var(--space-3) var(--space-5);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--ink-muted);
}
/* Le champ tel que le client le verra à l'écran 4 de la feuille de
   réservation — mêmes mots, même forme, pour qu'il se reconnaisse. */
.pr-fl-card {
  width: 100%; display: grid; gap: var(--space-3); justify-items: start; text-align: left;
  padding: var(--space-5) var(--space-6);
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface);
}
.pr-fl-field {
  width: 100%; min-height: 34px; display: flex; align-items: center;
  padding: var(--space-3) var(--space-5);
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  background: var(--surface-inset); letter-spacing: .08em; font-weight: 700;
}
/* Le curseur de la frappe : il ne bat que sur la voie où le client tape. */
.pr-fl-card.is-on .pr-fl-field--typed::after {
  content: ''; width: 1px; height: 15px; margin-left: 2px; background: var(--brand);
  animation: pr-fl-caret 1s steps(1, end) infinite;
}
@keyframes pr-fl-caret { 50% { opacity: 0; } }
.pr-fl-note { font-size: 12px; color: var(--ink-muted); }
/* La chaîne : trois temps séparés par un filet, jamais une flèche. */
.pr-fl-chain {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: var(--space-5);
}
.pr-fl-beat {
  display: inline-flex; align-items: center; gap: var(--space-3);
  font-size: 13px; font-weight: 700; color: var(--ink);
  padding: var(--space-3) var(--space-5);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.pr-fl-beat.is-on { border-color: color-mix(in srgb, var(--brand) 45%, var(--border)); }
.pr-fl-chain li + li::before { content: ''; width: var(--space-6); height: 1px; background: var(--border-strong); }
.pr-fl-chain li + li { gap: var(--space-5); }
/* Les deux fins, côte à côte : ce que le partenaire reçoit, ce que le client
   paie en plus. La seconde EST la réponse à « et moi, ça me coûte quoi ? ». */
.pr-fl-ends { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--gap); }
.pr-fl-end {
  display: grid; justify-items: center; gap: var(--space-3);
  padding: var(--space-6) var(--space-8);
  border: 1px solid var(--border); border-radius: var(--radius);
}
.pr-fl-end--vous { border-color: var(--brand); }
.pr-fl-end-amt {
  font-family: var(--font-display); font-size: var(--type-h3); font-weight: var(--weight-display);
  letter-spacing: -0.03em; font-variant-numeric: tabular-nums; line-height: 1; color: var(--ink);
  min-height: 1em; /* la place du chiffre est tenue avant qu'il arrive */
}
.pr-fl-end--vous .pr-fl-end-amt { color: var(--brand-on-surface); }
@media (max-width: 600px) {
  #pane-partenaires .pr-rewards { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  #pane-partenaires .pr-rewards .pr-card { padding: 14px 12px; animation: none; gap: 8px; }
  #pane-partenaires .pr-rewards .pr-amount { animation: none; }
  #pane-partenaires .pr-kicker { font-size: 12px; letter-spacing: 0; text-transform: none; }
  #pane-partenaires .pr-freq { font-size: 11px; white-space: normal; }
  #pane-partenaires .pr-start { align-self: stretch; }
  #partner-form .chip { min-height: 44px; }
  #pane-partenaires .pr-flow { padding: 16px; margin-top: 20px; }
  #pane-partenaires .pr-flow-stage { gap: 14px; }
  #pane-partenaires .pr-fl-seed { display: flex; gap: 12px; align-items: center; justify-content: space-between; width: 100%; padding: 0 0 12px; border-bottom: 1px solid var(--border); }
  #pane-partenaires .pr-fl-seed::after { display: none; }
  #pane-partenaires .pr-fl-ways { gap: 12px; }
  #pane-partenaires .pr-fl-way { grid-template-columns: minmax(0, 1fr); gap: 6px; justify-items: stretch; text-align: left; }
  #pane-partenaires .pr-fl-link, #pane-partenaires .pr-fl-said { padding: 6px 8px; font-size: 12px; }
  #pane-partenaires .pr-fl-card { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 5px 8px; padding: 8px; align-items: center; }
  #pane-partenaires .pr-fl-field-lbl { font-size: 11px; letter-spacing: 0; text-transform: none; }
  #pane-partenaires .pr-fl-field { font-size: 12px; letter-spacing: 0; min-height: 28px; padding: 3px 5px; }
  #pane-partenaires .pr-fl-note { grid-column: 1 / -1; font-size: 11px; }
  #pane-partenaires .pr-fl-chain { width: 100%; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
  #pane-partenaires .pr-fl-beat { justify-content: center; min-height: 42px; padding: 6px; text-align: center; font-size: 11px; line-height: 1.4; }
  #pane-partenaires .pr-fl-chain li + li::before { display: none; }
  #pane-partenaires .pr-fl-ends { width: 100%; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  #pane-partenaires .pr-fl-end { padding: 12px 8px; gap: 8px; }
  #pane-partenaires .pr-fl-end-lbl { font-size: 11px; letter-spacing: 0; text-transform: none; }
}
/* Mouvement réduit : la scène se lit d'un coup, éclairée et immobile — app.js
   allume tout et pose le chiffre final. */
@media (prefers-reduced-motion: reduce) {
  .pr-fl-seed, .pr-fl-step, .pr-fl-link, .pr-fl-said, .pr-fl-card, .pr-fl-beat, .pr-fl-end {
    transition: none; transform: none;
  }
  .pr-fl-card.is-on .pr-fl-field--typed::after { animation: none; }
}

.pr-grid {
  display: grid; grid-template-columns: minmax(0, 560px);
  gap: var(--gap); align-items: start; margin-top: var(--gap);
}
.pr-form-panel {
  padding: var(--pad-card-lg); border: 0; scroll-margin-top: var(--sticky-top);
  /* The landing-panel register: the 90 % skin over the ambient glow. */
  background: var(--surface-veil);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
.pr-form-panel input { width: 100%; }
.pr-form-panel .form-row { margin-bottom: var(--space-7); }
.pr-form-panel span.lbl { display: block; font-size: 14px; font-weight: 700; margin-bottom: var(--space-4); }
/* Le titre EST le dépliant : le résumé porte la voix de .h-sub, le chevron
   reste à sa place. */
.pr-form-panel .partner-details > summary { margin-bottom: var(--space-8); }
/* La mention du prix du client : une ligne de bas de page, jamais une carte
   encadrée — la voix .note encadrée reste pour les panneaux qui avertissent. */
.pr-grid .note { margin: 0; border-left: 0; background: transparent; padding: 0; max-width: 92ch; }

/* The claim form's payoff: the shareable link, ready to copy. */
/* Le bouton ne TRAVERSE plus la colonne (2026-09-07, même retour que la
   feuille de réservation) : une action large de 480 px pour deux mots se lit
   comme une bande, pas comme une cible. Il se dimensionne sur son libellé et
   s'aligne sur le bord gauche des champs qu'il conclut. */
#partner-form .btn-lg { margin-top: var(--space-6); width: auto; min-width: 200px; }
.partner-success { margin-top: var(--space-5); padding: var(--space-5) var(--space-6); border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-inset); }
.partner-success[hidden] { display: none; }
/* Le chemin d'un menu, écrit sous le lien qu'il faut y coller. Deux lignes,
   un nom d'application en tête, des chevrons entre les étapes : rien à
   cliquer ici, c'est une instruction, pas un contrôle. */
.sub-howto { list-style: none; margin: var(--space-4) 0 0; padding: 0; display: grid; gap: var(--space-2); }
.sub-howto li { font-size: 12px; line-height: 1.5; color: var(--ink-muted); }
.sub-howto-app { display: inline-block; margin-right: var(--space-3); font-weight: 800; color: var(--ink); }
.sub-howto-sep { margin: 0 4px; color: var(--border-strong); }

/* The ready-to-send message under the claimed link: a quiet inset block the
   partner reads once, then its own copy button. */
.partner-msg { margin-top: var(--space-6); padding-top: var(--space-5); border-top: 1px solid var(--border); }
.partner-msg-text { margin: var(--space-3) 0 var(--space-4); padding: var(--space-4) var(--space-5); font-size: 13px; line-height: 1.5; color: var(--ink); background: var(--surface-inset); border-radius: var(--radius-sm); white-space: pre-wrap; overflow-wrap: anywhere; }
/* A copy button that just worked: the label reads « Copié ✓ » in the ok ink for a beat (app.js flashCopied). */
.btn.is-copied { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 45%, transparent); }
.partner-link-row { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-top: 6px; }
.partner-link-row code { font-family: var(--font-mono); font-size: 13px; padding: 6px 10px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); overflow-wrap: anywhere; }

/* --- Dossier ------------------------------------------------------------- */
.dossier-bar { height: 8px; background: var(--surface-inset); border-radius: var(--radius-xs); overflow: hidden; margin: 8px 0; }
.dossier-bar > span { display: block; width: 0; height: 100%; background: var(--brand); }
/* The gate line (what's left before the demand is sellable) renders inside
   the consent card — right where the gate completes (ADR 0010 §3). */
.dossier-missing { min-height: 1.5em; font-size: 13px; color: var(--ink-muted); margin-top: 8px; }
.dossier-missing[data-ready='true'] { color: var(--ok); font-weight: 700; }
/* Heading over the preparation checklist — carries the 0/N count and bar of
   the list it measures (progress, never a gate, ADR 0010 §3). */
.dossier-prep-h { display: flex; flex-direction: column; gap: 2px; padding: 6px 2px 0; }
.dossier-prep-h strong { font-size: 14px; letter-spacing: -0.01em; }
.dossier-prep-count { font-size: 13px; color: var(--ink-muted); font-variant-numeric: tabular-nums; }
/* Upload and "already sent" side by side — two channels, one row. */
.doc-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 8px; }
/* The drag hint rides the actions row (inline, zeroed stacking margin) — its
   own line cost every empty card ~20px for eight muted words. The picker's own
   stacking margin is zeroed too: the row already carries the spacing. */
.doc-actions .file-note, .doc-actions .file-field { margin-top: 0; }
/* "Transmis autrement" (ADR 0010 §4): a distinct provided-state — the ok hue
   says done, the undo keeps it reversible. */
.doc-transmis { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 8px; }
.doc-transmis-lbl { font-size: 13px; font-weight: 700; color: var(--ok); }
.consent-toggle { display: inline-flex; align-items: center; gap: 8px; margin-top: 8px; font-size: 13px; font-weight: 600; cursor: pointer; }
.consent-toggle input { width: 18px; height: 18px; accent-color: var(--brand); cursor: pointer; }
/* Dossier: price card, consent, then the document checklist. The checklist
   packs into a card GRID — several small pieces per row instead of one
   full-width line each, so 7 items don't scroll for a screen and a half. */
.dossier-list { display: flex; flex-direction: column; gap: 8px; padding: 4px 0; }
.dossier-item { display: flex; gap: 10px; align-items: flex-start; padding: var(--space-5) var(--space-6); border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
.dossier-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 8px; }
/* Each checklist card: name + help on top, the action (upload / already-sent,
   or the answer field) pinned to the bottom so neighbouring cards end on the
   same line whatever the length of their help text. */
.dossier-row .dossier-body { display: flex; flex-direction: column; align-self: stretch; }
.dossier-row .doc-actions, .dossier-row .doc-transmis,
.dossier-row .dossier-body > input[type='text'] { margin-top: auto; }
.dossier-row .dossier-body > .help { margin-bottom: 8px; }
.dossier-pricing { padding: var(--space-6) var(--space-7); border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
/* Capped at 3 tracks: auto-fit on a wide screen spread 6 questions into one
   ragged row of uneven heights — 3×2 keeps the rows balanced and the help
   text wrapping instead of a dead right half. */
.dossier-pricing .o-criteria { margin-top: var(--space-6); display: flex; flex-direction: column; gap: var(--space-10); }
.dossier-pricing .crit-sec-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-5) var(--space-8); }
@media (max-width: 1100px) { .dossier-pricing .crit-sec-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 680px) { .dossier-pricing .crit-sec-grid { grid-template-columns: minmax(0, 1fr); } }
/* Les questions du notaire en SECTIONS (2026-09-05) : trois temps déclarés par
   le domaine — le prêt, l'immeuble, la signature. La pile des sections est
   verticale ; c'est DANS une section que les questions s'alignent sur la grille
   à deux colonnes (audit 2.15 : l'ordre de lecture est l'ordre du DOM, jamais
   du multicol qui coulait la question 3 sous la question 1). Les lignes
   s'alignent en haut, et le grand contrôle du déplacement traverse la grille. */
#o-criteria { display: flex; flex-direction: column; gap: var(--space-6); }
.crit-sec-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-6) var(--space-9); align-items: start; }
@media (max-width: 560px) { .crit-sec-grid { grid-template-columns: minmax(0, 1fr); } }
#o-criteria .crit-row { margin: 0; }
.crit-row--wide { grid-column: 1 / -1; }
/* Une question seule sur sa ligne PREND la ligne (retour du propriétaire,
   2026-09-05 : « avoid blank space ») : trois questions dans une grille à deux
   colonnes laissaient une demi-carte vide à droite de la troisième, et une
   section qui n'en pose qu'une (« L'immeuble ») laissait la moitié du cadre
   nu. Le dernier enfant d'un rang impair traverse la grille. */
.crit-sec-grid > .crit-row:last-child:nth-child(odd) { grid-column: 1 / -1; }
/* Et un rang qui PORTE TROIS CHOIX prend la ligne quoi qu'il arrive : dans une
   demi-largeur, « Approbation bancaire » s'empilait en trois lignes à côté d'un
   champ d'une seule — deux cellules d'une même paire, l'une trois fois plus
   haute que l'autre (retour du propriétaire, 2026-09-06). Sur la ligne entière
   les trois choix se rangent côte à côte, et la paire au-dessus est faite de
   deux rangs de même taille. Le tri du DOM (renderCriteriaSections) fait
   descendre ces rangs sous les compacts, donc aucune demi-cellule ne reste
   vide au-dessus d'eux. */
.crit-sec-grid > .crit-row[data-span='row'] { grid-column: 1 / -1; }
/* Et le rang compact resté SEUL DEVANT une bande prend la ligne à son tour
   (retour du propriétaire, 2026-09-07 : « enlever tous les espaces blancs ») :
   « Prêteur hypothécaire » gardait un demi-cadre nu à sa droite parce que la
   question suivante traversait déjà la grille — la règle du dernier rang impair
   ne voyait que la FIN de la section. Le filet CSS tient même là où rien n'est
   mesurable (dialogue fermé, impression) ; la passe mesurée, elle, évite le cas
   en faisant d'abord tenir les réponses sur une ligne. */
.crit-sec-grid > .crit-row:nth-child(odd):has(+ .crit-row[data-span='row']),
.crit-sec-grid > .crit-row:nth-child(odd):has(+ .crit-row--wide) { grid-column: 1 / -1; }
/* Et la dernière rangée de rangs compacts se remplit, quel que soit le nombre
   de colonnes : packCriteriaGrids compte les pistes réelles et dit ici combien
   il en reste à couvrir (le carnet du dossier en dessine trois, la feuille
   deux). Deux valeurs suffisent : aucune grille du produit ne va plus loin. */
.crit-sec-grid > .crit-row[data-fill='2'] { grid-column: span 2; }
.crit-sec-grid > .crit-row[data-fill='3'] { grid-column: span 3; }
/* Et elle OCCUPE la ligne au lieu de s'y perdre : les réponses en boutons
   s'étalent sur toute la largeur (flex: 1 1 auto), et une liste s'allonge
   jusqu'à une largeur de lecture — un contrôle de 320 px suivi d'un demi-cadre
   nu était le vide le plus visible de la grille. */
@media (min-width: 561px) {
  .crit-sec-grid > .crit-row:last-child:nth-child(odd) > .nselect,
  .crit-sec-grid > .crit-row:nth-child(odd):has(+ .crit-row[data-span='row']) > .nselect,
  .crit-sec-grid > .crit-row:nth-child(odd):has(+ .crit-row--wide) > .nselect,
  .crit-sec-grid > .crit-row[data-fill] > .nselect { max-width: 420px; }
}
/* Les écrans qui portent des SECTIONS ne portent plus leur propre cadre : deux
   boîtes emboîtées mangeaient 30 px de largeur de chaque côté et donnaient au
   dialogue trois niveaux de bordure. Le titre de l'écran coiffe les cartes. */
#o-criteria-step, .book-step-offer { padding: 0; border: 0; background: none; }
/* Une section est une CARTE, pas un simple filet (retour du propriétaire,
   2026-09-05 : « mieux découpler les sections, ajouter des petites marges »).
   Un trait à gauche ne suffisait pas : le titre de la section suivante venait
   coller à la dernière réponse de la précédente, et les trois temps se lisaient
   comme une seule colonne. Cadre + coin carré + air autour, et 20 px entre les
   cartes. Le FOND reste celui du dialogue : les contrôles à l'intérieur
   (segments, listes, volets) portent déjà --surface-inset, et remplir la carte
   de la même teinte les effacerait. */
.crit-sec, .offer-sec {
  display: flex; flex-direction: column; gap: var(--space-6);
  padding: var(--space-7) var(--space-8) var(--space-8);
  border: 1px solid var(--border); border-radius: var(--radius);
}
/* L'écran 3 emprunte le même registre (voir index.html) : trois cartes — le
   montant, le marché, le devis — au lieu de dix blocs à la file. Ses contenus
   se serrent un cran de plus que des questions : ce sont des lignes de lecture,
   pas des contrôles à viser. */
.offer-sec { gap: var(--space-5); }
.book-step-offer { gap: var(--space-8); }
/* Les boîtes intérieures se sont FONDUES dans leur carte : le marché et le
   devis portaient chacun leur propre cadre + fond, ce qui faisait deux cadres
   l'un dans l'autre dès qu'ils sont entrés en section. La carte est le cadre. */
.offer-sec > .day-market, .offer-sec > .devis {
  margin: 0; padding: 0; border: 0; background: none; border-radius: 0;
}
.offer-sec > .day-market .day-bids { margin: var(--space-4) 0 0; }
/* L'en-tête est une bande : le titre, son compte, sa raison d'être — puis un
   filet qui la sépare des questions. */
/* L'en-tête est une BANDE, pas un titre suivi d'un filet (2026-09-06) : elle
   court d'un bord à l'autre de la carte, sur sa propre teinte, et coiffe le
   sujet comme l'en-tête d'un tableau coiffe sa colonne. Un titre posé DANS le
   cadre, à la même distance des questions que les questions entre elles, ne
   disait pas où un sujet commençait. Les marges négatives valent le padding de
   .crit-sec — la bande est le haut de la carte, pas un bloc posé dedans. */
.crit-sec-h {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-5);
  margin: calc(-1 * var(--space-7)) calc(-1 * var(--space-8)) 0;
  padding: var(--space-5) var(--space-8);
  background: var(--surface-inset);
  border-bottom: 1px solid var(--border);
  border-radius: var(--radius) var(--radius) 0 0;
}
/* Repliée, la bande EST la carte : plus de trait sous elle, rien en dessous. */
.crit-sec[data-fold='true'] > .crit-sec-h { border-bottom-color: transparent; border-radius: var(--radius); }
.crit-sec[data-fold='true'] > .crit-sec-grid,
.crit-sec[data-fold='true'] > .crit-more { display: none; }
.crit-sec[data-fold='true'] { padding-bottom: 0; gap: 0; }
/* Le chevron du pli : muet, à droite du compte, tourné vers le bas quand la
   section est ouverte. Il porte le nom de sa section en aria-label — le titre
   est à deux centimètres, il n'a pas de mot à ajouter. */
.crit-sec-fold {
  appearance: none; border: 0; background: none; padding: 0; margin-left: var(--space-3);
  width: 24px; height: 24px; display: inline-grid; place-items: center; flex: none;
  color: var(--ink-muted); cursor: pointer; border-radius: var(--radius-xs);
  transition: color .12s, background-color .12s;
}
.crit-sec-fold:hover { color: var(--ink); background: var(--surface-hover); }
.crit-sec-fold .crit-sec-chev { transition: transform .15s ease; }
.crit-sec-fold[aria-expanded='false'] .crit-sec-chev { transform: rotate(-90deg); }
/* Le compte cesse de pousser le chevron au bout de la ligne : c'est LUI qui
   ferme la bande. */
.crit-sec-h:has(.crit-sec-fold) .crit-sec-n { margin-left: auto; }
/* Le titre de section portait 14px/700 quand la question en dessous porte
   13,5px/600 : un cheveu d'écart, donc aucune hiérarchie — l'œil ne trouvait
   pas où un sujet commençait (retour du propriétaire, 2026-09-06 : « comprendre
   d'un coup d'œil que ceci se rapporte à tel sujet »). Un vrai cran au-dessus. */
.crit-sec-t { font-size: 15px; font-weight: 800; color: var(--ink); letter-spacing: -0.01em; }
/* La pastille du sujet : même construction que celle des actes (glyphe au trait
   dans un carré à filet), un cran plus petite — c'est un en-tête, pas une
   cible. Elle passe à la marque quand la section est complète, si bien que
   l'avancement se lit sur la colonne des pastilles sans lire un seul compte. */
.crit-sec-ic {
  width: 28px; height: 28px; flex: none; display: inline-grid; place-items: center;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface-inset); color: var(--ink-muted);
  transition: color .15s, border-color .15s, background .15s;
}
.crit-sec:has(.crit-sec-n[data-state='done']) .crit-sec-ic {
  color: var(--brand); border-color: color-mix(in srgb, var(--brand) 45%, var(--border));
  background: color-mix(in srgb, var(--brand) 10%, transparent);
}
/* La raison d'être de la section prend toute la ligne suivante : elle explique,
   elle ne se dispute pas la première ligne avec le compte. Elle s'aligne sous
   le TITRE, pas sous la pastille : le bloc d'en-tête se lit alors comme un
   seul objet au lieu de deux lignes qui commencent à deux endroits. */
/* Elle RIDE la ligne du titre (2026-09-07) : une ligne entière par section
   pour se présenter, c'était trois lignes dépensées avant la première question
   — et l'écran s'ouvrait sur des bandes plutôt que sur des réponses à donner.
   Elle ne bascule sous le titre que si la largeur lui manque (flex-basis), et
   le compte reste collé au bord droit par sa marge automatique. */
.crit-sec-aide { flex: 1 1 240px; min-width: 0; margin: 0; font-size: 12px; color: var(--ink-muted); }
/* Sur un téléphone elle ne tient jamais à côté du titre : elle repasse SOUS la
   bande — mais après le compte et le chevron, sinon c'est le chevron qui tombe
   sur une troisième ligne et la bande coûte plus cher qu'avant. */
@media (max-width: 560px) {
  .crit-sec-aide { order: 1; flex: 1 0 100%; margin-top: var(--space-1); }
}
/* Le compte de la section — le même vocabulaire et les mêmes couleurs que le
   compte de l'étape : ambre tant qu'on attend, marque une fois complet. */
.crit-sec-n {
  margin-left: auto; min-width: 18px; padding: 1px 5px; border-radius: var(--radius-xs);
  background: color-mix(in srgb, var(--warn) 14%, transparent);
  font-size: 11.5px; font-weight: 700; color: var(--warn); text-align: center;
  white-space: nowrap; font-variant-numeric: tabular-nums;
}
.crit-sec-n[data-state='done'] { color: var(--brand); background: color-mix(in srgb, var(--brand) 12%, transparent); }
/* Les précisions d'une section, repliées à côté du cas qu'elles précisent. */
.crit-sec > .crit-more { margin: var(--space-1) 0 0; }
.crit-sec > .crit-more .crit-sec-grid { padding: var(--space-6) var(--space-7) var(--space-4); }
/* Le volet dit combien de questions il cache. */
.crit-more-n {
  margin-left: 7px; min-width: 16px; padding: 1px 5px; border-radius: var(--radius-xs);
  background: var(--surface-inset); color: var(--ink-muted);
  font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums;
}
/* Ce qu'une réponse change à la liste des documents, sous la réponse. Ligne
   RÉSERVÉE dès la première peinture et masquée par `visibility` (registre ADR
   0039) : répondre, se raviser, répondre à nouveau ne déplace jamais la
   question suivante. */
.crit-effet { font-size: 12px; color: var(--ink-muted); }
.crit-effet[data-on='false'] { visibility: hidden; }
.crit-effet-k { font-weight: 600; color: var(--brand); }
/* The card's payoff — the determined price — separated from the questions and
   said a size louder, not buried in the bottom-left corner. */
.dossier-price { margin-top: var(--space-5); padding-top: var(--space-4); border-top: 1px dashed var(--border); font-weight: 700; color: var(--brand); font-size: 15px; font-variant-numeric: tabular-nums; }
/* Profile: a top row of at-a-glance / set-once cards (offers · coordinates ·
   notifications) that auto-fit across the width, then a full-width documents
   work area below — no tall-thin void, honest use of the horizontal space. */
.profil-stack { display: flex; flex-direction: column; gap: 10px; }
/* Every section is a full-width band whose content lays out in a grid that
   fills the width (auto-fit) — no empty right half, no ragged inter-card void. */
/* Four equal tracks: the profile's four fields make ONE row on a wide screen —
   the whole Coordonnées band is head + a single line of inputs. Short values
   (code postal) simply breathe in theirs. */
.profil-fields { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px 16px; align-items: end; }
@media (max-width: 1000px) { .profil-fields { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .profil-fields { grid-template-columns: 1fr; } }
.profil-fields .form-row { margin: 0; }
/* Fill the cell: capped at 460px the inputs left ~100px of dead track beside
   each one, which read as a broken grid rather than as breathing room. */
.profil-fields .form-row input { width: 100%; }
.profil-switches { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 22px; max-width: 1060px; }
@media (max-width: 900px) { .profil-switches { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 700px) { .profil-switches { grid-template-columns: 1fr; } }
.profil-card { padding: 12px 16px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); display: flex; flex-direction: column; gap: 6px; }
.profil-card-title { font-size: 15px; font-weight: 700; color: var(--ink); }
/* Iconed section header so the bands are easy to tell apart at a glance. The
   caption (.profil-card-sub) rides the same row, wrapping under the title only
   when the width runs out — a full line per card was pure chrome. */
.profil-card-head { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 10px; }
.profil-card-sub { flex: 1 1 320px; min-width: 0; margin: 0; font-size: 12.5px; line-height: 1.45; color: var(--ink-muted); }
.profil-card-ic { display: grid; place-items: center; width: 26px; height: 26px; flex: none; border-radius: var(--radius-sm); background: var(--surface-inset); color: var(--brand); }
.profil-card-ic svg { display: block; }
/* The card is a flex column with its own gap — zero the children's stacking
   margins so field/switch spacing isn't doubled (the source of the void). */
.profil-card .form-row { margin-bottom: 2px; }
.profil-card .form-row label.lbl { margin-bottom: 6px; }
.profil-card .switch-row { padding: 4px 0; justify-content: flex-start; gap: 12px; }
.profil-card .help { margin-top: 0; }
/* Mes offres — the client's posted offers with live status. */
.my-offer:hover, .my-offer:focus-visible { border-color: var(--brand); outline: none; }
/* Documents inside the profile: upload / remove / mark-validated. */
.profil-doc-chips { margin: 2px 0 6px; }
/* Flex (not grid) so the LAST row's cards grow to fill the width — no empty
   right-side slots when the document count doesn't divide evenly. */
.profil-doc-list { display: block; }
/* The checklist collapses behind its progress line. .doc-rows carries the wrap
   that .profil-doc-list used to, so rows still pack 2-up and 3-up as they widen. */
.doc-rows { display: flex; flex-wrap: wrap; gap: var(--space-5); align-items: stretch; padding-top: var(--space-5); }
.profil-doc-list .doc-row { flex: 1 1 300px; }
.doc-disclose { border: 0; }
/* The whole progress line is the control, so it gets the thumb-sized target and
   the chevron the rest of the app uses for the same bargain. */
.doc-summary {
  display: flex; align-items: center; gap: var(--space-5);
  min-height: 44px; padding: var(--space-2) 0; cursor: pointer; list-style: none;
  border-radius: var(--radius-sm);
}
.doc-summary::-webkit-details-marker { display: none; }
.doc-summary .doc-progress { flex: 1; margin-bottom: 0; }
.doc-summary::after {
  content: ''; flex: none; width: 9px; height: 9px; margin-right: var(--space-2);
  border-right: 2px solid var(--ink-muted); border-bottom: 2px solid var(--ink-muted);
  transform: rotate(45deg) translate(-2px, -2px); transition: transform .15s ease;
}
.doc-disclose[open] > .doc-summary::after { transform: rotate(-135deg) translate(-2px, -2px); }
.doc-summary:hover::after { border-color: var(--ink); }
.doc-summary:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--focus-ring); }
/* Documents progress header: labelled bar, full-width above the checklist. */
.doc-progress { flex: 1 1 100%; display: flex; flex-direction: column; gap: 6px; margin-bottom: 2px; }
.doc-count { font-size: 12.5px; font-weight: 600; color: var(--ink-muted); }
.doc-count[data-complete='true'] { color: var(--ok); }
.doc-bar { height: 6px; background: var(--surface-inset); border-radius: var(--radius-xs); overflow: hidden; }
.doc-bar span { display: block; height: 100%; background: var(--brand-bright); border-radius: var(--radius-xs); transition: width .25s ease; }
.doc-progress[data-complete='true'] .doc-bar span { background: var(--ok); }
/* First-time empty state (Mes offres with no offers). */
/* Mes offres — four facts per offer, on one axis. Full-width bands spent about
   1500px of horizontal space per row saying four short things, and made seven
   offers an 800px wall. */
.my-offers { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.my-offers th {
  text-align: left; padding: 0 10px 6px;
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .02em;
  color: var(--ink-muted); border-bottom: 1px solid var(--border);
}
.my-offers td { padding: 9px 10px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.my-offers tbody tr:last-child td { border-bottom: 0; }
.my-offers .c-acte { font-weight: 600; min-width: 150px; }
.my-offers .c-date { width: 24%; min-width: 120px; }
.my-offers .c-montant { width: 16%; min-width: 92px; text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.my-offers .c-statut { width: 14%; min-width: 96px; }
/* The date is a door to that day on the carnet: a real button, styled as a link. */
.my-offer-day { display: block; padding: 0; border: 0; background: none; font: inherit; font-weight: 600; color: var(--brand); text-decoration: underline; text-underline-offset: 2px; cursor: pointer; text-align: left; }
.my-offer-day:hover { color: var(--ink); }
.my-offer-day:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: var(--radius-xs); }
.my-offer-rel { display: block; margin-top: 1px; font-size: 12px; color: var(--ink-muted); }
/* Under each row: the next step, the agenda links, and what a notary sent back. */
.my-offer-detail td { padding: 4px 10px 12px; }
.my-offer-next { display: flex; flex-wrap: wrap; gap: 4px 8px; font-size: 12.5px; line-height: 1.45; }
.my-offer-next-k { font-weight: 700; color: var(--ink-muted); text-transform: uppercase; font-size: 10.5px; letter-spacing: .03em; align-self: center; }
.my-offer-next-v { color: var(--ink); }
.my-offer-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
/* Le reçu du client : deux lignes et un total, dans le registre carré de la
   carte. Il paraît une fois l'acte réglé, au-dessus de l'évaluation. */
.my-offer-receipt { margin-top: 10px; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-inset); }
.my-offer-receipt-h { font-weight: 700; color: var(--ink-muted); text-transform: uppercase; font-size: 10.5px; letter-spacing: .03em; margin-bottom: 6px; }
.my-offer-receipt-lines { display: grid; grid-template-columns: 1fr auto; gap: 3px 12px; margin: 0; font-size: 12.5px; }
.my-offer-receipt-lines dt { color: var(--ink-muted); margin: 0; }
.my-offer-receipt-lines dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; color: var(--ink); }
.my-offer-receipt-lines .my-offer-receipt-total { font-weight: 700; color: var(--ink); border-top: 1px solid var(--border); padding-top: 4px; margin-top: 2px; }
/* ADR 0035 — la carte a été refusée au moment de réserver la somme. Un bloc
   qui se voit (filet rouge, fond teinté) sans crier : rien n'est perdu, mais
   il y a un geste à poser avant la signature. */
.my-offer-carte {
  margin-top: var(--space-4); padding: var(--space-4) var(--space-5);
  border: 1px solid var(--danger); border-left-width: 3px; border-radius: var(--radius-sm);
  background: var(--surface-inset);
}
.my-offer-carte-h { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; color: var(--danger); }
.my-offer-carte-t { margin: var(--space-2) 0 0; font-size: 13px; line-height: 1.5; color: var(--ink); }
/* Mise en relation (ADR 0010 §4): whom to contact once the offer is retained. */
.my-offer-contact { margin-top: 8px; font-size: 13px; line-height: 1.5; }
.my-offer-contact-mail { color: var(--brand); font-weight: 600; }
/* « Votre notaire » (ADR 0033): heading, name line, then one row per way to
   reach them — tel:, mailto:, the étude on a map. Facts only, square register. */
.my-offer-contact-h { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-muted); }
.my-offer-contact-name { margin-top: var(--space-2); font-size: 14px; }
.my-offer-contact-etude { color: var(--ink-muted); }
.my-offer-contact-rows { display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-8); margin-top: var(--space-2); }
.my-offer-contact-row {
  display: inline-flex; align-items: center; gap: 6px; min-height: 28px;
  font-size: 13px; font-weight: 600; color: var(--brand); text-decoration: none; overflow-wrap: anywhere;
}
.my-offer-contact-row:hover { text-decoration: underline; }
.my-offer-contact-tel { font-variant-numeric: tabular-nums; }
.my-offer-contact-addr { font-weight: 500; }
/* Unread notary messages beside the status: a door to the thread, a filled
   square badge while there is something to read, nothing when there is not. */
.my-offer-unread {
  display: inline-flex; align-items: center; margin-left: var(--space-3); padding: 2px 8px;
  border: 0; font: inherit; font-size: 11px; font-weight: 800; white-space: nowrap; cursor: pointer;
  border-radius: var(--radius-sm); background: var(--brand); color: var(--brand-ink);
}
.my-offer-unread:empty { display: none; }
.my-offer-unread:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
/* A notary's proposition / document request: the block that asks for a decision. */
.my-offer-prop, .my-offer-demande {
  margin-top: 10px; padding: 10px 12px; border-radius: var(--radius);
  border: 1px solid var(--brand); border-left-width: 4px; background: var(--surface-inset);
}
.my-offer-prop[data-status='acceptee'] { border-color: var(--ok); }
/* Settled blocks recede through muted ink, never element opacity. */
.my-offer-prop[data-status='refusee'], .my-offer-demande[data-fournie='true'] { border-color: var(--border); color: var(--ink-muted); }
.my-offer-prop-text { font-size: 13.5px; line-height: 1.45; }
.my-offer-prop-msg { margin: 6px 0 0; font-size: 12.5px; color: var(--ink-muted); font-style: italic; }
.my-offer-prop-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.my-offer-prop-state { margin-top: 6px; font-size: 12.5px; font-weight: 700; color: var(--ink-muted); }
.my-offer-prop-state.is-done { color: var(--ok); }
.my-offer-status {
  display: inline-block; padding: 2px 9px; border-radius: var(--radius-sm);
  border: 1px solid var(--border); color: var(--ink-muted);
  font-size: 11px; font-weight: 700; white-space: nowrap;
}
.my-offer-status[data-status='approved'] { color: var(--ok); border-color: var(--ok); }
.my-offer-status[data-status='pending'] { color: var(--brand); border-color: var(--brand); }
.my-offer-status[data-status='expired'] { color: var(--ink-muted); border-style: dashed; }
/* Offers whose date has passed are present, never diluting the live list. */
.my-offers-past { margin-top: 6px; }
.my-offers-past-sum { padding: 8px 0; font-size: 12.5px; color: var(--ink-muted); cursor: pointer; }
.my-offers-past tbody tr { color: var(--ink-muted); }

/* Below this a table cannot hold four columns without wrapping the act name to
   three lines, so each row becomes a card. The status pill gets its OWN row and
   may wrap: pinned beside the act name it forced the card past a 320px screen
   ("Ouverte — en attente d’un notaire" is 200px that must never be cut). */
@media (max-width: 860px) {
  .my-offers, .my-offers tbody, .my-offers tr, .my-offers td { display: block; width: auto; }
  .my-offers thead { display: none; }
  .my-offers tbody { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 8px; }
  .my-offers tbody tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: 'acte acte' 'date montant' 'statut statut';
    gap: 4px 10px; align-items: center;
    padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius);
  }
  .my-offers td { padding: 0; border: 0; min-width: 0; }
  /* The detail band joins its row's card on a phone (one card per offer). */
  .my-offers tbody tr.my-offer { border-bottom: 0; border-radius: var(--radius) var(--radius) 0 0; }
  .my-offers tbody tr.my-offer-detail { display: block; margin-top: -8px; padding: 0 12px 10px; border: 1px solid var(--border); border-top: 0; border-radius: 0 0 var(--radius) var(--radius); }
  .my-offers .c-acte { grid-area: acte; }
  .my-offers .c-statut { grid-area: statut; justify-self: start; }
  .my-offers .c-date { grid-area: date; }
  .my-offers .c-montant { grid-area: montant; }
  .my-offer-status { white-space: normal; }
}
@media (max-width: 560px) { .my-offers tbody { grid-template-columns: minmax(0, 1fr); } }
@media (pointer: coarse) { .my-offers-past-sum { min-height: 44px; display: flex; align-items: center; } }

/* Empty states are one compact row — the pitch left, the CTA right. The tall
   centered block spent ~250px of band height on one sentence and a button. */
.profil-empty { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 18px; padding: 2px 0; }
.profil-empty-text { margin: 0; font-size: 13.5px; line-height: 1.5; color: var(--ink-muted); max-width: 64ch; }
.profil-empty .btn { flex: none; }
.profil-empty-copy { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.profil-empty-copy .help { margin: 0; }
/* Parrainage — the claimed code, big enough to read out loud; the link row
   reuses .partner-link-row from the Partenaires pane. */
.parr-code-row { display: flex; align-items: baseline; gap: 10px; }
.parr-code-lbl { font-size: 12px; font-weight: 600; color: var(--ink-muted); }
.parr-code { font-family: var(--font-mono); font-size: 18px; letter-spacing: 0.06em; color: var(--ink); }
.doc-row { border: 1px solid var(--border); border-radius: var(--radius); padding: 10px 12px; display: flex; flex-direction: column; gap: 5px; background: var(--surface); }
/* Push the control to the bottom so every card in a row ends on the same line,
   whatever the length of its help text. */
.doc-row > .file-field, .doc-row > input[type='text'] { margin-top: auto; }
.doc-row[data-done='true'] { border-color: var(--brand); }
.doc-row-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.doc-row-name { font-weight: 600; font-size: 13.5px; }
.doc-valid { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: var(--ink-muted); white-space: nowrap; cursor: pointer; }
.doc-valid input { accent-color: var(--brand); }
.doc-file { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: 12.5px; color: var(--ink-muted); }
.doc-file-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The ✓ only shows once the item is actually provided — a blue check on
   every empty row made 0/8 read as done. */
.dossier-check { flex: none; margin-top: 2px; width: 18px; height: 18px; border: 1px solid var(--border-strong); border-radius: var(--radius-sm); display: grid; place-items: center; color: transparent; font-weight: 800; font-size: 12px; }
.dossier-check[data-on='true'] { background: transparent; color: var(--brand); border-color: var(--brand); }
.dossier-body { flex: 1; min-width: 0; }
.dossier-name { font-weight: 600; font-size: 13.5px; }
.dossier-item .help { margin-top: 2px; }
.dossier-item input[type='text'] { width: 100%; margin-top: 8px; }
.dossier-item[data-done='true'] .help { display: none; }
.dossier-item[data-done='true'] .dossier-name { color: var(--ink-muted); }
/* Themed file picker — hides the raw OS "Choose File" chrome. */
.file-field { display: inline-flex; align-items: center; gap: 8px; margin-top: 8px; cursor: pointer; }
input.file-native { position: absolute; width: 1px; height: 1px; opacity: 0; margin: 0; padding: 0; }
/* Square like every other action button (owner, 2026-08-27: « make it more
   square ») — the shared radius token, never a pill; pills stay for chips. */
.file-cta { display: inline-flex; align-items: center; padding: 5px 12px; border-radius: var(--radius); border: 1.5px solid var(--border-strong); background: var(--surface); color: var(--ink-muted); font-weight: 600; font-size: 12.5px; transition: border-color .15s, color .15s; }
.file-field:hover .file-cta { border-color: var(--brand); color: var(--ink); }
.file-native:focus-visible + .file-cta { outline: 2px solid var(--ring); outline-offset: 2px; }
.file-note { font-size: 12px; color: var(--ink-muted); margin-top: 6px; }
/* A refusal (format the notary could not open, oversize) is explained IN
   PLACE, in the danger hue — nothing is saved, nothing else moves. */
.file-error { font-size: 12.5px; font-weight: 600; color: var(--danger); margin-top: 6px; }
/* The whole checklist row is a drop target while a file hovers it. */
.dossier-item[data-drop='true'], .doc-row[data-drop='true'] { border-color: var(--brand); background: var(--surface-inset); }
/* The drag affordance is desktop prose — touch has no drag to speak of. */
@media (max-width: 720px), (pointer: coarse) { .file-hint { display: none; } }

/* --- Model / footer sections -------------------------------------------- */
.section { padding: clamp(24px, 4vw, 40px) 0; border-top: 1px solid var(--border); }
.section h2 { margin-bottom: 8px; }
.cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-top: 20px; }
@media (max-width: 780px) { .cards { grid-template-columns: 1fr; } }
.card { border: 1px solid var(--border); border-radius: var(--radius-lg); padding: var(--space-9); background: var(--surface); box-shadow: var(--shadow-sm); }
.card h3 { margin-bottom: 6px; }
.card p { color: var(--ink-muted); font-size: 14px; margin: 0; }
.price { font-size: 22px; font-weight: 800; color: var(--brand); }

.note {
  border-left: 3px solid var(--warn); background: var(--surface-inset);
  padding: 12px 16px; border-radius: var(--radius); font-size: 13px; color: var(--ink-muted);
}
.note strong { color: var(--ink); }

/* --- Progressive disclosure (native <details>, token-styled) --------------
   Keeps required copy (Loi 25, business model) available but collapsed by
   default, so the booking flow isn't buried under text. */
.disclosure {
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface-inset); margin: 10px 0 14px;
}
.disclosure > summary {
  list-style: none; cursor: pointer; user-select: none;
  display: flex; align-items: center; gap: 8px;
  padding: 9px 12px; font-size: 12px; font-weight: 600; color: var(--ink-muted);
}
.disclosure > summary::-webkit-details-marker { display: none; }
.disclosure > summary::before {
  content: ''; width: 6px; height: 6px; flex: none;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(-45deg); transition: transform .15s;
}
.disclosure[open] > summary::before { transform: rotate(45deg); }
.disclosure > summary:hover { color: var(--ink); }
.disclosure > summary:focus-visible {
  outline: none; border-radius: var(--radius-sm);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.disclosure-body { padding: 0 14px 14px; }
.disclosure-body p { font-size: 12px; color: var(--ink-muted); margin-top: 0; }
.disclosure-body p + p { margin-top: 8px; }

/* Structured footer: identity + contact on the left, two link columns beside
   it, and a base line (©, hosting note) under a hairline. Stacks on phones. */
.site-footer { border-top: 1px solid var(--border); padding: 28px 0 18px; color: var(--ink-muted); font-size: 13px; }
.site-footer a { color: var(--ink-muted); }
.site-footer a:hover { color: var(--brand-on-surface); text-decoration: none; }
.footer-grid { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr) minmax(0, 1fr); gap: 24px 32px; align-items: start; }
.footer-id { min-width: 0; }
.site-footer .footer-brand { display: inline-flex; align-items: center; gap: var(--lockup-badge-gap); color: var(--ink); font-weight: 700; }
.footer-tag { margin: 8px 0 0; max-width: 40ch; font-size: 12.5px; line-height: 1.55; }
.footer-col { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; }
.footer-col-h { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; color: var(--ink); margin-bottom: 6px; }
.footer-col a { padding: 3px 0; }
/* A footer ACTION (the guide opens a dialog) dressed like its link neighbours. */
.footer-col .footer-link { appearance: none; background: none; border: 0; padding: 3px 0; font: inherit; color: var(--ink-muted); cursor: pointer; text-align: left; }
.footer-col .footer-link:hover { color: var(--brand-on-surface); text-decoration: none; }
.footer-base { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 18px; margin-top: 22px; padding-top: 14px; border-top: 1px solid var(--border); font-size: 12px; }
@media (max-width: 680px) {
  .footer-grid { grid-template-columns: 1fr 1fr; gap: 20px 24px; }
  .footer-id { grid-column: 1 / -1; }
}

/* Final phone guardrails: keep the toolbar's flexible availability track and
   let priced questionnaire choices become one readable, full-width column. */
@media (max-width: 480px) {
  .cal-toolbar-meta {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    min-width: 0;
  }
  .cal-toolbar-meta .result-count { display: none; }
  .o-criteria .crit-row:has(.seg-btn .crit-add) .seg {
    flex-direction: column;
    align-items: stretch;
  }
  .o-criteria .crit-row:has(.seg-btn .crit-add) .seg-btn {
    width: 100%;
    min-width: 0;
  }
  .o-criteria .crit-row:has(.seg-btn .crit-add) .crit-add {
    margin-left: auto;
  }
}

/* --- Toast --------------------------------------------------------------- */
.toast {
  position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%) translateY(20px);
  background: var(--ink); color: var(--bg); padding: 12px 18px; border-radius: var(--radius);
  box-shadow: var(--shadow-lg); opacity: 0; pointer-events: none; transition: opacity .18s, transform .18s;
  z-index: 60; font-size: 14px; font-weight: 600; max-width: 90vw;
}

/* The SDLC story: a compact, self-contained visual that communicates the
   discipline without pretending that models or compliance are magic. */
@media (prefers-reduced-motion:reduce){.onb-modal[open],#onb-view-role.is-entering,#onb-view-steps.is-entering,#onb-view-steps.is-entering .onb-step{animation:none!important}#onb-view-steps.is-entering .onb-step{opacity:1;transform:none}}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* --- Dialog -------------------------------------------------------------- */
dialog {
  border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 0;
  background: var(--surface); color: var(--ink); max-width: 440px; width: 92vw; box-shadow: var(--shadow-lg);
}
/* ONE scrim for every dialog — the token plus the same soft blur. Scoped
   overrides drifted (two dialogs carried a hardcoded black): the shared shell
   owns the backdrop now. */
dialog::backdrop { background: var(--backdrop); -webkit-backdrop-filter: blur(.5px); backdrop-filter: blur(.5px); }
/* Every popup is built the same way: its first child is
   <form method="dialog" class="dlg-x-form"> holding one ✕ button. The form is
   sticky against the dialog's own scroll box with height:0, so the ✕ stays
   pinned to the top-right corner while the dialog scrolls and costs no layout.
   The filled circle keeps the glyph legible over whatever slides beneath it. */
.dlg-x-form { position: sticky; top: 0; height: 0; margin: 0; z-index: 6; display: flex; justify-content: flex-end; }
.dlg-x { appearance: none; border: 1px solid var(--border-strong); background: transparent; color: var(--ink-muted); cursor: pointer; width: 34px; height: 34px; margin: 10px 10px 0 0; border-radius: var(--radius); display: grid; place-items: center; flex: none; }
.dlg-x:hover { background: transparent; border-color: var(--brand); color: var(--ink); }
/* 34px is under the touch minimum — give fingers 44px without changing what a
   mouse sees. */
@media (pointer: coarse) { .dlg-x { width: 44px; height: 44px; } }
/* A modal owns the scroll. The lock must sit on <html>: the root element is
   the page's scroller, so hiding overflow on <body> alone still lets the page
   drift (and lose its place) under the wheel/touch behind the open dialog. */
html:has(dialog[open]), body:has(dialog[open]) { overflow: hidden; }
/* The account-link confirmation is created after the OAuth callback. */
#oauth-link-dialog { padding: 24px; width: min(440px, calc(100vw - 32px)); }
#oauth-link-dialog h2 { margin: 0 0 12px; }
#oauth-link-dialog form { display: grid; gap: 10px; margin: 18px 0; }
#oauth-link-dialog input { box-sizing: border-box; width: 100%; min-height: 44px; }
#oauth-link-dialog .help { line-height: 1.5; }
.dialog-pad { padding: 22px; }
.dialog-pad h3 { margin-bottom: 8px; }
.dialog-pad p { color: var(--ink-muted); font-size: 14px; margin: 0 0 16px; }
.dialog-actions { display: flex; justify-content: flex-end; gap: 8px; }
/* The public rating badge — brand star, tabular figures, quiet count. */
.rating-badge { color: var(--brand); font-weight: 700; font-size: 12.5px; white-space: nowrap; font-variant-numeric: tabular-nums; }
.nc-own-rating { margin-bottom: var(--space-4); }

/* The CNQ membership pill and the official fiche link (ADR 0016). */
.cnq-badge {
  display: inline-block; padding: 0 6px; border: 1px solid var(--brand); border-radius: var(--radius-sm);
  color: var(--brand); background: var(--brand-tint-solid); font-weight: 700; font-size: 11px;
  line-height: 18px; white-space: nowrap; vertical-align: middle;
}
.cnq-link { font-size: 12.5px; white-space: nowrap; }
/* ADR 0030 — la pastille de cote et sa note d'explication ont été retirées des
   vues client : l'art. 70 du Code de déontologie interdit au notaire de
   permettre qu'un témoignage d'appui le concernant soit utilisé, et une note
   affichée transforme un annuaire en recommandation. Ce qui reste à côté du
   badge CNQ est un FAIT : le nombre d'actes portés sur Nota. */
.my-offer-acts { white-space: nowrap; }
#notary-profil .form-row { margin-bottom: var(--space-4); }
#nc-profil-form .btn { margin-top: var(--space-3); }

/* --- Notary evaluation (after the signed act, ADR 0015) ------------------- */
.my-offer-eval { margin-top: var(--space-6); padding: var(--pad-card); background: var(--surface-inset); border-radius: var(--radius); display: flex; flex-direction: column; gap: var(--space-4); }
.my-offer-eval-t { font-size: 13.5px; }
.eval-stars { display: flex; gap: 2px; }
.eval-star { appearance: none; border: 0; background: transparent; cursor: pointer; font-size: 24px; line-height: 1; padding: 2px 4px; color: var(--brand); }
.eval-star:focus-visible { outline: 2px solid var(--ring); outline-offset: -2px; border-radius: var(--radius-sm); }
.eval-comment { resize: vertical; }
.eval-submit { align-self: flex-start; }
.my-offer-eval-done { font-size: 13.5px; }
.my-offer-eval-done strong { color: var(--brand); }

/* Destructive confirm (cancel an offer): quiet red outline, filled on hover —
   visible enough to read as consequence, never louder than the safe way out. */
.btn-danger { color: var(--danger); border-color: var(--danger); }
.btn-danger:hover { background: transparent; border-color: var(--danger); color: var(--danger); box-shadow: inset 0 0 0 1px var(--danger); }
.btn-offer-cancel { color: var(--danger); }
/* Per-offer help door: a visible secondary action with a compact help mark.
   It stays at the end of the row on wide cards and becomes full-width on a
   narrow card, so it never reads like an unrelated browser-default button. */
.my-offer-help {
  margin-left: auto; align-self: center; display: inline-flex; align-items: center;
  gap: 7px; min-height: 34px; padding-inline: 12px; border-color: var(--brand);
  color: var(--brand-on-surface); font-weight: 700; white-space: nowrap;
}
.my-offer-help:hover { background: var(--brand-tint-solid); border-color: var(--brand-hover); color: var(--brand-on-surface); }
.my-offer-help-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 19px; height: 19px; border: 1.5px solid currentColor; border-radius: 50%;
  font-size: 13px; line-height: 1; font-weight: 800;
}
.my-offer-help:focus-visible { outline-offset: 3px; }
@media (max-width: 560px) {
  .my-offer-help { margin-left: 0; width: 100%; justify-content: center; }
}
/* The « ou écrivez-nous » quick line under the contact form's submit. */
#ct-quick { margin-top: 12px; text-align: center; }
#ct-quick:empty { display: none; }
/* --- « Nous joindre » (2026-09-04 redesign) ----------------------------------
   Scoped to the contact dialog — the shared dialog shell (.dlg-x-form,
   .dialog-actions, the 440px column) is untouched. The pass tightens every
   small space to the token scale, seats nom + courriel on one row where the
   column is wide enough, lets the message box grow with the text, and gives
   the sent state a real confirmation with its two actions. Under 480px the
   dialog becomes a full-width sheet with its own scroll, so a 320px phone
   never hides the Envoyer button below an unreachable fold. */
#contact-dialog .ct-pad { padding: var(--space-9) var(--space-9) var(--space-8); }
/* The sticky ✕ sits in the top-right corner: the title line and the lede's
   first line keep clear of it instead of running underneath. */
#contact-dialog h3 { margin-bottom: var(--space-3); padding-right: 52px; }
#contact-dialog .ct-lede { padding-right: 28px; }
#contact-dialog .ct-lede { font-size: 14px; line-height: 1.45; margin: 0 0 var(--space-6); max-width: 52ch; }
#contact-dialog .ct-trust {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-2);
  margin: calc(-1 * var(--space-2)) 0 var(--space-7); padding: var(--space-3);
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-inset);
}
#contact-dialog .ct-trust-item {
  display: flex; align-items: flex-start; gap: var(--space-2); min-width: 0;
  color: var(--ink); font-size: 11px; line-height: 1.25;
}
#contact-dialog .ct-trust-item strong,
#contact-dialog .ct-trust-item small { display: block; }
#contact-dialog .ct-trust-item strong { font-size: 11px; font-weight: 800; }
#contact-dialog .ct-trust-item small { margin-top: 2px; color: var(--ink-muted); font-size: 10.5px; line-height: 1.25; }
#contact-dialog .ct-trust-mark {
  display: inline-grid; place-items: center; flex: none; width: 20px; height: 20px;
  border-radius: 50%; background: var(--brand-tint); color: var(--brand); font-weight: 800;
}
#contact-dialog .form-row { margin-bottom: var(--space-5); }
#contact-dialog .lbl { margin-bottom: var(--space-2); }
#contact-dialog .ct-field-help { margin: var(--space-2) 0 0; font-size: 11.5px; line-height: 1.35; }
/* Le libellé et son compteur partagent UNE ligne — le compteur garde sa
   réserve (ADR 0039) sur une hauteur qui existait déjà. */
#contact-dialog .lbl-row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-4); }
#contact-dialog .lbl-row .lbl { margin-bottom: var(--space-2); }
#contact-dialog .lbl-row .ct-count { margin: 0; }
#contact-dialog .lbl-hint { font-weight: 500; color: var(--ink-muted); }
#contact-dialog .ct-grid { display: grid; grid-template-columns: 1fr; gap: 0 var(--space-6); }
#contact-dialog textarea { min-height: 58px; max-height: 40vh; resize: vertical; }
#contact-dialog .ct-context { margin: calc(-1 * var(--space-3)) 0 var(--space-5); }

#contact-dialog #ct-quick { margin-top: var(--space-5); }
/* « Envoyer » suit le même registre que les autres formulaires (2026-09-07) :
   largeur de son libellé, jamais toute la feuille — et rangé à droite, là où
   .dialog-actions pose déjà les actions de tous les autres dialogues. */
#contact-dialog #ct-submit { display: flex; width: fit-content; min-width: 200px; margin-left: auto; }
/* The sent state: a check chip on the title line, one sentence, then the two
   actions — the messagerie first when the thread token came back. */
.ct-ok-head { display: flex; align-items: center; gap: var(--space-4); margin-bottom: var(--space-3); }
.ct-ok-ic { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; flex: none; border-radius: var(--radius); background: var(--brand-tint-solid-strong); color: var(--brand-on-tint-strong); }
.ct-ok-ic svg { width: 18px; height: 18px; }
#contact-dialog .ct-ok-title { margin: 0; font-size: 16px; color: var(--ink); }
#contact-dialog .ct-ok-body { margin: 0 0 var(--space-7); max-width: 46ch; }
.ct-ok-actions { flex-wrap: wrap; }
.ct-ok-actions .btn { flex: 1 1 auto; }
/* The dialog column is comfortable from 480px up; below, every side space
   shrinks one step and nom + courriel stack (a 300px column cannot hold two). */
@container (min-width: 380px) { #contact-dialog .ct-grid { grid-template-columns: 1fr 1fr; } }
#contact-dialog .dialog-pad { container-type: inline-size; }
@media (max-width: 479.98px) {
  #contact-dialog { width: calc(100vw - 16px); max-width: none; max-height: calc(100% - 16px); margin: 8px auto; }
  #contact-dialog .ct-pad { padding: var(--space-7) var(--space-6) var(--space-6); }
  #contact-dialog .ct-lede { margin-bottom: var(--space-5); padding-right: 52px; }
  #contact-dialog .ct-trust { grid-template-columns: 1fr; margin-bottom: var(--space-6); }
  #contact-dialog .form-row { margin-bottom: var(--space-5); }
  #contact-dialog textarea { min-height: 52px; }
}

/* --- Day detail dialog (enlarged day over a dimmed backdrop) -------------- */
/* La feuille suivait la fenêtre jusqu'à 620 px et s'arrêtait là, quelle que
   soit la taille de l'écran (2026-09-06) : sur un 27 pouces, les questions
   s'appariaient dans deux colonnes trop étroites, si bien qu'une réponse à
   trois boutons s'empilait en trois lignes à côté d'un simple champ. Elle
   grandit maintenant AVEC l'écran : 760 px reste le plancher de lecture et
   1 180 px le plafond, assez large pour que les choix et les champs forment
   des rangées nettes sans transformer la feuille en pleine largeur. */
#day-dialog { box-sizing: border-box; max-width: min(94vw, clamp(760px, 78vw, 1180px)); width: 94vw; max-height: min(90vh, 90dvh); overflow-y: auto; overscroll-behavior: contain; }
/* Sticky like the ✕ above it: the date being booked stays readable while the
   long booking form scrolls. padding-right clears the pinned ✕. */
.day-head { position: sticky; top: 0; z-index: 5; background: var(--surface); display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 8px 20px; padding: var(--space-8) 72px var(--space-5) var(--space-10); border-bottom: 1px solid var(--border); }
.day-heading { min-width: 0; }
.day-eyebrow { margin-bottom: 4px; font-size: 12px; line-height: 1.4; color: var(--subtitle-ink); }
.day-title { margin: 0; }
.day-title::first-letter { text-transform: uppercase; }
.day-sub { font-size: 13px; color: var(--ink-muted); margin-top: 2px; }
/* The header's native date picker: the date moves without closing the dialog.
   Pushed to the right edge, inside the padding that clears the pinned ✕. */
.day-date-edit { min-width: 0; max-width: 100%; }
.day-date-edit > summary { display: flex; align-items: center; min-height: 44px; cursor: pointer; font-size: 13px; font-weight: 600; color: var(--brand-on-surface); text-decoration: underline; text-underline-offset: 3px; list-style: none; }
.day-date-edit > summary::-webkit-details-marker { display: none; }
.day-date-pick { display: flex; flex-direction: column; gap: 4px; min-width: 0; font-size: 12px; font-weight: 600; color: var(--ink-muted); }
.day-date-input { box-sizing: border-box; width: 100%; max-width: 220px; min-width: 0; min-height: 44px; font: inherit; font-size: 16px; padding: 8px 10px; border: 1px solid var(--border-strong); border-radius: var(--radius-sm); background: var(--surface); color: var(--ink); }
.day-date-input:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
/* A tapped date opens a calm decision, with the market behind one disclosure.
   The same content stays readable in a phone sheet or on a touch desktop. */
#day-dialog[data-interaction='preview'] { width: min(94vw, 560px); max-width: 560px; }
#day-dialog[data-interaction='preview'] .day-head { grid-template-columns: minmax(0, 1fr); gap: 0; padding: 20px 68px 8px 20px; }
.day-preview { padding: 16px 20px max(20px, env(safe-area-inset-bottom)); }
.day-preview-intro { margin: 0 0 16px; color: var(--ink-muted); font-size: 14px; line-height: 1.5; }
#day-preview > button { width: 100%; min-height: 48px; justify-content: center; background: var(--brand); color: var(--brand-ink); border-color: var(--brand); }
#day-preview > button:hover { background: var(--brand-hover); color: var(--brand-ink); }
.day-preview-offers { margin-top: 20px; border-top: 1px solid var(--border); }
.day-preview-offers > summary { display: flex; align-items: center; gap: 8px; min-height: 52px; cursor: pointer; color: var(--ink-muted); font-size: 13px; font-weight: 600; list-style: none; }
.day-preview-offers > summary::-webkit-details-marker { display: none; }
.day-preview-offers > summary::after { content: '+'; margin-left: auto; font-size: 20px; font-weight: 400; }
.day-preview-offers[open] > summary::after { content: '−'; }
.day-preview-count { min-width: 22px; padding: 2px 6px; text-align: center; background: var(--surface-inset); border-radius: var(--radius-xs); font-variant-numeric: tabular-nums; }
.day-preview-empty { margin: 16px 0 0; font-size: 12px; line-height: 1.5; color: var(--ink-muted); }
#day-preview .day-bids { max-height: none; overflow: visible; margin: 0; border-top: 0; }
#day-preview .bid-row { padding: 12px 0; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px 12px; border-left: 0; background: transparent; }
#day-preview .bid-meta { grid-column: 1; grid-row: 1 / 3; display: flex; flex-direction: column-reverse; min-width: 0; }
#day-preview .bid-sub { font-size: 13px; line-height: 1.4; font-weight: 600; color: var(--ink); overflow-wrap: anywhere; }
#day-preview .bid-who { font-size: 12px; font-weight: 400; color: var(--ink-muted); }
#day-preview .bid-amount { grid-column: 2; grid-row: 1; font-size: 15px; white-space: nowrap; }
#day-preview .bid-row > .pill { display: none; }
#day-preview .status-chip { grid-column: 2; grid-row: 2; max-width: 14ch; font-size: 11px; }
#day-preview .day-bids-count { display: none; }
@media (max-width: 680px) {
  #day-dialog .day-head { grid-template-columns: minmax(0, 1fr); gap: 0; padding: 16px 64px 8px 16px; }
  #day-dialog[data-interaction='preview'] { width: 100%; max-width: 100%; }
  .day-preview { padding-inline: 16px; }
}
@media (max-height: 480px) and (min-width: 681px) {
  #day-dialog[data-interaction='preview'] { max-height: 96dvh; }
  #day-dialog[data-interaction='preview'] .day-head { grid-template-columns: minmax(0, 1fr) auto; padding-block: 12px; }
  .day-preview { padding-top: 12px; }
  .day-preview-intro { margin-bottom: 12px; }
  .day-preview-offers { margin-top: 12px; }
}
/* What happens after a real publication (success screen) and, back from
   Checkout, the same line standing on « Mes offres ». */
.offer-success-next { margin-top: 6px; }
.checkout-notice { padding: 12px 16px; border: 1px solid var(--border); border-left: 3px solid var(--brand); border-radius: var(--radius-sm); font-size: 13px; line-height: 1.5; color: var(--ink); }

/* --- Day booking surface (acte → offre à battre → book, all in one dialog) - */
/* Act-scoped market context: the offer to beat FOR THE SELECTED ACT — one
   quiet strip inside step 1 (it changes with the chips), so step 3 keeps the
   only big number in the dialog. */
.day-market { background: var(--surface-inset); border-radius: var(--radius-sm); padding: 8px 12px; overflow: hidden; }
/* Centre-aligned, and the LABEL is the flexible column (it wraps within
   itself): the reference figure and the one-tap pill hold the right rail of
   the same row at every dialog width — the pill never strands on an orphan
   row with dead space beside it (owner, 2026-08-27: « align »). */
.day-market-line { display: flex; align-items: center; gap: 4px 10px; flex-wrap: wrap; min-height: 1.5em; }
/* No open offer for the act → the line is hidden outright (every date is
   bookable, so there is no bar to print); the hint below owns the message. */
/* 2026-09-05 : la capitale d'affichage criait (« CE QUE D'AUTRES OFFRENT CE
   JOUR-LÀ · REFINANCEMENT » sur deux lignes) alors que la carte porte déjà son
   titre. Le libellé redevient une légende : casse normale, poids moyen. */
.day-value-k { font-size: 12px; font-weight: 600; color: var(--ink-muted); flex: 1 1 12ch; min-width: 0; }
.day-value-v { font-size: 15px; font-weight: 800; color: var(--ink); font-variant-numeric: tabular-nums; }
.day-value-note { min-height: 1.5em; font-size: 12px; color: var(--ink-muted); margin: 2px 0 0; }
/* The live line flips blue the moment the slider clears the bar. */
.day-value-note.is-ahead { color: var(--ok); font-weight: 600; }
/* One tap over the bar — small, inline, at the end of the strip's line. */
.day-beat {
  appearance: none; font: inherit; font-size: 12px; font-weight: 700; cursor: pointer;
  margin-left: auto; padding: 3px 10px; border-radius: var(--radius-sm);
  border: 1px solid var(--brand); background: transparent; color: var(--brand-on-surface);
  transition: background .15s, color .15s, border-color .15s;
}
.day-beat:hover { background: var(--brand-tint-solid); border-color: var(--brand-hover); color: var(--brand-on-surface); }
/* Stepping back does not take its place with it: the label is written even
   while the button is off show, so the strip's line keeps its height and its
   wrap (ADR 0039 — une ligne tenue). */
/* The headline lands with a small settle; the amount echoes it after a one-tap
   jump. Both sit still under prefers-reduced-motion. */
@keyframes day-best-in { from { opacity: 0; transform: translateY(3px); } }
.day-value-v.pulse { animation: day-best-in .25s ease-out; }
.amount-big.flash { animation: day-best-in .45s ease-out; }
@media (prefers-reduced-motion: reduce) { .day-value-v.pulse, .amount-big.flash { animation: none; } }
/* Says what the calendar's % means, for the date being booked. Sits under the
   header — it depends on the DATE, not on the act chosen below. Top padding
   keeps it off the sticky header's border. */
.day-chance { margin: 0; font-size: 12px; line-height: 1.5; color: var(--ink-muted); }
.day-bids { max-height: 30vh; overflow: auto; overscroll-behavior: contain; border-top: 1px solid var(--border); }
/* Inside the market strip the list bleeds to the edges, so its border-top
   spans the strip and the rows keep their own gutters. */
.day-market .day-bids { margin: 8px -12px -8px; }
.day-bids:empty { display: none; }
.day-bids .bid-row:first-child { border-top: 0; }
.day-bids-rest[hidden] { display: none; }
/* The door to the rest of the day is INLINE on the totals line (owner,
   2026-08-27: « compacter ») — a quiet link-weight button holding the right
   rail of the count's own row, never a stacked full-width bar. */
.day-bids-toggle {
  appearance: none; border: 0; background: none; font: inherit; cursor: pointer;
  font-size: 12px; font-weight: 700; color: var(--brand);
  padding: 0; margin-left: auto; white-space: nowrap;
}
.day-bids-toggle:hover { text-decoration: underline; }
/* The day's totals under the single headline offer: how many for the act being
   booked, and how many that date carries in all — with the unfold door at the
   end of the same line. */
.day-bids-count { display: flex; align-items: center; gap: 4px 12px; flex-wrap: wrap; padding: var(--space-4) var(--space-12); font-size: 12px; color: var(--ink-muted); line-height: 1.5; }
/* Scale guard: a day-group caps its rows and links to the full day view. */
.day-book { padding: var(--space-7) var(--space-10) var(--space-10); border-top: 1px solid var(--border); display: flex; flex-direction: column; gap: var(--space-6); }
/* Each step is its own bordered card so the three-beat flow reads at a glance.
   Regular card padding — the dialog is a working surface, not a brochure
   (owner, 2026-08-27: « compacter toutes les sections »). */
.book-step { display: flex; flex-direction: column; gap: var(--space-4); padding: var(--pad-card); border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
/* Step 3 — the offer — is the decision, so it is the dominant card. */
.book-step-offer { border-color: var(--border-strong); background: var(--surface-inset); }

/* --- La feuille de réservation en QUATRE ÉCRANS (ADR 0040) ---------------
   Retour du propriétaire (2026-09-05) : « l'expérience est vraiment confuse
   — le faire en plusieurs screens ». Les cinq blocs empilés donnaient une
   colonne à faire défiler où l'acte, les questions du notaire, le prix, le
   secteur et l'identité se disputaient le même premier regard.

   Un écran à la fois. La structure du formulaire NE CHANGE PAS : chaque bloc
   porte le numéro de l'écran auquel il appartient (`data-screen`), le
   formulaire porte celui où l'on est (`data-at`), et c'est le CSS seul qui
   n'en montre qu'un — un `display: none` retire déjà du parcours au clavier
   et de l'arbre d'accessibilité. */
.day-book > [data-screen] { display: none !important; }
.day-book[data-at='1'] > [data-screen='1'],
.day-book[data-at='2'] > [data-screen='2'],
.day-book[data-at='3'] > [data-screen='3'],
.day-book[data-at='4'] > [data-screen='4'] { display: block !important; }
/* BUG 2 — l'offre publiée : le rail et la barre d'action restaient à l'écran
   à côté de la carte de confirmation. « done » ne montre aucun écran, ni rail,
   ni barre. */
.day-book[data-at='done'] > .book-rail,
.day-book[data-at='done'] > .book-nav { display: none; }

/* Le rail : où l'on est, ce qui reste, et la porte de retour vers une étape
   déjà franchie. Une étape qu'on n'a pas encore atteinte n'est pas cliquable
   — on ne saute pas par-dessus une question du notaire. */
.book-rail { display: flex; align-items: stretch; gap: var(--space-2); list-style: none; margin: 0 0 var(--space-6); padding: 0; }
/* Le rail numérote les étapes ; la carte n'a pas à le refaire une ligne plus
   bas. Le libellé reste — il nomme l'écran — la pastille part. */
.day-book[data-at] .book-step > .book-step-lbl > .step { display: none; }
.book-rail li { flex: 1 1 auto; min-width: 0; }
.book-rail-b {
  appearance: none; width: 100%; height: 100%; display: flex; align-items: center; gap: 7px;
  padding: 7px 9px; font: inherit; font-size: 12px; font-weight: 650; text-align: left;
  color: var(--ink-muted); background: transparent; cursor: pointer;
  border: 0; border-top: 2px solid var(--border); border-radius: 0;
}
.book-rail-b[disabled] { cursor: default; opacity: 0.55; }
.book-rail-n {
  flex: none; width: 19px; height: 19px; display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 800; border-radius: var(--radius-xs);
  background: var(--surface-inset); color: var(--ink-muted);
}
.book-rail-t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.book-rail li[data-state='done'] .book-rail-b { color: var(--ink); border-top-color: var(--brand); }
.book-rail li[data-state='done'] .book-rail-n { background: var(--brand); color: var(--brand-ink); }
.book-rail li[data-state='at'] .book-rail-b { color: var(--ink); border-top-color: var(--brand); }
.book-rail li[data-state='at'] .book-rail-n { background: var(--brand); color: var(--brand-ink); }
/* Traversée sans y répondre : on peut y revenir, et le rail le dit. */
.book-rail li[data-state='open'] .book-rail-b { color: var(--ink); border-top-color: var(--warn); }
.book-rail li[data-state='open'] .book-rail-n { background: var(--warn); color: var(--surface); }
.book-rail-b:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
/* Une étape sautée (l'acte n'a pas de questions) se dit à voix basse. */
.book-rail li[data-state='skip'] { display: none; }

/* Une seule barre d'action, toujours au même endroit, en bas : « Retour » à
   gauche, et à droite l'action qui fait avancer. Au dernier écran c'est
   « Publier mon offre » qui prend cette place — jamais deux boutons primaires
   à la fois. */
.book-nav { display: flex; align-items: center; gap: var(--space-4); margin-top: var(--space-2); }
.book-nav .book-back { flex: none; }
/* L'action va AU BOUT DE LA BARRE, elle ne la remplit pas (retour du
   propriétaire, 2026-09-07 : « button are too big, do not fill them ») :
   étirée sur toute la largeur restante, « Continuer » faisait un bandeau de
   600 px pour un mot, et le regard n'avait plus de point à viser. Elle garde
   une largeur de vraie cible et se range à droite, « Retour » à gauche. */
.book-nav .book-fwd, .book-nav #offer-submit { flex: 0 0 auto; width: auto; min-width: 200px; margin: 0 0 0 auto; }
.book-nav > [hidden] { display: none !important; }
/* La barre porte la SEULE décision de l'écran, et elle ne se lisait pas comme
   telle (propriétaire, 2026-09-06) : 37 px de haut sur 578 px de large, un
   trait vert sous le formulaire. Elle prend la hauteur d'une vraie cible —
   44 px à la souris AUSSI, pas seulement au doigt — et une ligne de texte plus
   grande. « Retour » monte à la même hauteur pour que la barre tienne d'un
   bord à l'autre, mais garde son encre sourde : deux poids, une seule action. */
.book-nav .book-fwd, .book-nav #offer-submit { min-height: 44px; font-size: 15px; }
.book-nav .book-back { min-height: 44px; }
/* Et elle rentre dans le rang : l'exception de l'aplat vert est LEVÉE
   (2026-09-07). Elle avait été posée le 2026-09-06 parce qu'un contour de
   44 px sur 560 se lisait comme un trait de séparation — c'était la LARGEUR le
   problème, pas le contour. Rendue à sa taille, l'action se lit comme partout
   ailleurs dans l'application : couleur de marque et graisse, jamais un aplat.
   Redit ici parce que l'id #offer-submit l'emporte sur la classe .btn-primary ;
   désactivé, il retombe sur les jetons d'inactif pour la même raison. */
.book-nav .book-fwd, .book-nav #offer-submit {
  background: transparent; border-color: var(--brand); color: var(--brand-on-surface); font-weight: 700;
}
.book-nav .book-fwd:not(:disabled):hover, .book-nav #offer-submit:not(:disabled):hover {
  background: var(--brand-tint-solid); border-color: var(--brand);
}
.book-nav .book-fwd:disabled, .book-nav #offer-submit:disabled {
  background: transparent; border-color: var(--border); color: var(--ink-muted);
}
/* Le chevron dit le sens, et seulement où il est vrai : « Continuer » avance
   d'un écran, « Publier mon offre » conclut — celle-là n'en porte pas. */
.book-nav .book-fwd::after { content: '→'; font-size: 1.05em; line-height: 1; transition: transform .12s ease; }
.book-nav .book-fwd:not(:disabled):hover::after { transform: translateX(2px); }
@media (max-width: 480px) {
  /* Sur téléphone le rail garde les numéros et laisse tomber les mots : quatre
     libellés sur 375 px ne tiennent qu'en s'ellipsant tous. */
  .book-rail-t { display: none; }
  .book-rail-b { justify-content: center; padding-inline: 4px; }
}
/* Pricing criteria woven into the booking flow (dossier merged with the process). */
.o-criteria { display: flex; flex-direction: column; gap: 10px; }
.crit-row { display: flex; flex-direction: column; gap: 6px; }
.crit-flag { display: flex; align-items: flex-start; gap: 9px; cursor: pointer; }
/* La case se pose SUR le rail des libellés : les marges par défaut du
   navigateur (4 px à gauche, 3 px à droite) la poussaient de quatre pixels
   vers l'intérieur, si bien qu'une question à cocher ne commençait pas où
   commencent les autres questions de la même carte. */
.crit-flag input { margin: 3px 0 0; flex: none; accent-color: var(--brand); }
.crit-text { display: flex; flex-direction: column; gap: 1px; }
.crit-label { font-size: 13.5px; font-weight: 600; color: var(--ink); }
/* The question's own line. Everything that used to print itself UNDER a
   question and grow the card — the awaited-answer mark, the situational
   notes — rides here instead, on a line the label already occupies. */
.crit-head { display: flex; align-items: baseline; flex-wrap: wrap; min-width: 0; }
/* Les réponses d'une question sont des BOUTONS, pas un affichage segmenté
   (retour du propriétaire, 2026-09-05 : « our button and form is hard to
   understand — keep it really straight forward »). Sur la piste commune, une
   option non choisie n'avait ni fond ni cadre : trois libellés posés sur une
   barre, dont on ne devinait ni qu'ils étaient cliquables ni lequel était pris.
   Ici chaque option porte son propre cadre, la piste s'efface, et la réponse
   retenue est peinte à la marque. */
.crit-row .seg { display: flex; flex-wrap: wrap; gap: var(--space-3); padding: 0; border: 0; background: none; }
/* Une réponse se dimensionne sur CE QU'ELLE DIT (retour du propriétaire,
   2026-09-07 : « button are too big »). Étirées sur la ligne entière
   (flex: 1 1 auto), « Non » et « Oui » devenaient deux pavés de 400 px pour
   trois lettres : la cible était énorme et le mot perdu au milieu, si bien que
   deux réponses opposées se lisaient comme deux bandeaux. Elles gardent un
   plancher — une cible reste une cible, même pour « Oui » — et s'arrêtent là
   où leur libellé s'arrête. La piste, elle, reste alignée à gauche : c'est une
   suite de choix, pas une barre à remplir. */
.crit-row .seg-btn {
  flex: 0 1 auto; min-width: 92px; max-width: 100%; text-align: center;
  padding: 6px 14px; border-color: var(--border); background: var(--surface); color: var(--ink);
}
.crit-row .seg-btn:hover { border-color: var(--border-strong); background: var(--surface-hover); }
/* Sauf quand le rang PREND LA LIGNE ENTIÈRE (retour du propriétaire,
   2026-09-07 : « this is looking empty ») : trois réponses serrées contre le
   bord gauche d'une ligne de 900 px laissaient les deux tiers de la carte nus.
   Là, elles se répartissent sur la ligne — mais BORNÉES : au-delà d'environ un
   tiers de la ligne, un bouton redevient le pavé qu'on vient de retirer. Un
   rang qui PARTAGE sa ligne, lui, garde ses réponses à la taille du libellé :
   c'est la place disponible qui décide, jamais la question. */
.crit-row[data-large] .seg-btn { flex: 1 1 auto; max-width: 320px; }
/* À partir d'une grande feuille, une rangée explicitement large utilise
   l'espace disponible : deux choix opposés se lisent comme deux colonnes
   équilibrées, sans laisser un quart de carte vide après les libellés. Les
   rangées compactes gardent leur largeur naturelle. */
@media (min-width: 1100px) {
  .crit-row[data-large] .seg-btn { flex: 1 1 0; max-width: none; }
  /* On a wide sheet, a segmented answer is a question-wide decision. Keeping
     it in the two-column track leaves a conspicuous empty half-card whenever
     its neighbour has one more option. The controls share the full row and
     stay bounded to a comfortable reading width. */
  .crit-sec-grid > .crit-row:has(.seg) { grid-column: 1 / -1; }
  .crit-sec-grid > .crit-row:has(.seg) .seg-btn { flex: 1 1 0; max-width: 420px; min-height: 44px; font-size: 14px; }
  /* The financing group asks for the amount, then the context, then the
     lender in DOM order. Pin the two short fields to the first track so the
     wide context row cannot strand the lender below an empty half-card. */
  .crit-sec[data-groupe='pret'] .crit-row[data-crit='valeur_pret'] { grid-column: 1; grid-row: 1; }
  .crit-sec[data-groupe='pret'] .crit-row[data-crit='preteur'] { grid-column: 2; grid-row: 1; }
  .crit-sec[data-groupe='pret'] .crit-row[data-crit='contexte'] { grid-column: 1 / -1; grid-row: 2; }
  .crit-sec[data-groupe='pret'] .crit-row[data-crit='approbation_bancaire'] { grid-column: 1 / -1; grid-row: 3; }
  .crit-sec-t { font-size: 16px; }
  .crit-sec-aide { font-size: 13px; }
  .crit-label { font-size: 14px; }
}
/* La réponse retenue se RECONNAÎT, elle ne se REMPLIT pas (même retour : « do
   not fill them »). L'aplat de marque faisait de chaque réponse choisie une
   tuile verte pleine — six questions répondues et la carte n'était plus qu'une
   grille de blocs, où le prix « +400 $ » se lisait moins bien que le fond
   derrière lui. Ici : le cadre passe à la marque et double d'épaisseur (un
   `inset` plutôt qu'une bordure de 2 px, qui déplacerait le texte), l'encre
   suit, et une coche dit lequel est pris. Le registre du bouton primaire de
   l'application — couleur et graisse, jamais un aplat — vaut donc aussi pour
   les réponses.

   La coche a sa place RÉSERVÉE sur chaque option (registre ADR 0039) : elle
   n'apparaît pas, elle se dévoile — répondre, se raviser, répondre ailleurs ne
   fait jamais respirer la piste sous la main du client. */
.crit-row .seg-btn::before, .crit-row .seg-btn::after {
  content: '✓'; font-size: 11px; font-weight: 800; color: var(--brand); visibility: hidden;
}
.crit-row .seg-btn::before { margin-right: 6px; }
/* Le jumeau muet de la coche, à droite : la coche est posée AVANT le libellé,
   donc à elle seule elle décentrerait le mot de sept pixels sur une piste
   centrée. Il ne se montre jamais — il ne fait que rendre la boîte symétrique,
   à l'arrêt comme choisie. */
.crit-row .seg-btn::after { margin-left: 6px; }
.crit-row .seg-btn.is-on {
  background: var(--surface); border-color: var(--brand);
  box-shadow: inset 0 0 0 1px var(--brand);
  color: var(--brand-on-surface); font-weight: 700;
}
.crit-row .seg-btn.is-on::before { visibility: visible; }
/* When the options cannot share one line (settleSegTracks measures), the
   track restacks as full-width rows — answer left, price right — instead of
   a ragged 2+1 wrap that reads as two controls. */
.crit-row .seg.seg-stack { flex-direction: column; align-items: stretch; }
.crit-row .seg-stack .seg-btn { display: flex; align-items: baseline; justify-content: flex-start; text-align: left; }
.crit-row .seg-stack .crit-add { margin-left: auto; padding-left: 12px; }
/* A required question still awaiting its answer carries a quiet amber dot —
   the same signal the hint line and the step tally speak. Direct child only:
   a companion field's own label must not double the mark. */
.crit-row.crit-missing > .crit-head > .crit-label::after {
  content: ''; display: inline-block; width: 6px; height: 6px; margin-left: 7px;
  border-radius: 50%; background: var(--warn); vertical-align: 1px;
}
/* One flash when the hint's door lands here, so the eye finds the line. */
@keyframes crit-attn {
  from { box-shadow: 0 0 0 4px color-mix(in srgb, var(--warn) 40%, transparent); }
  to { box-shadow: 0 0 0 4px transparent; }
}
.crit-row.crit-attn { animation: crit-attn 1.4s ease-out; border-radius: var(--radius-sm); }
@media (prefers-reduced-motion: reduce) { .crit-row.crit-attn { animation: none; } }
/* Déplacement: two compact segmented bars — where it signs, then the radius —
   each under the question it answers (audit §3.2), then the online opt-in
   line (§3.3) and the static caveats (§1.1) toggled by the direction. */
.crit-dep { display: flex; flex-direction: column; gap: 6px; align-items: stretch; }
.crit-dep-km[hidden], .crit-sublabel[hidden] { display: none; }
.crit-sublabel { font-size: 12.5px; font-weight: 600; color: var(--ink-muted); margin-top: 4px; }
.crit-urgence { margin-top: 4px; }
/* A default the client has not touched reads as a suggestion: the pressed
   answer keeps its place but drops the accent fill until it is confirmed. */
/* Un défaut que le client n'a pas touché reste une SUGGESTION : cadre en
   pointillé, pas de trait doublé, et pas de coche — la coche dit « vous avez
   répondu », ce qui serait faux tant qu'on n'y a pas touché. */
.crit-row[data-default='true'] .seg-btn.is-on { background: transparent; border-style: dashed; box-shadow: none; }
.crit-row[data-default='true'] .seg-btn.is-on::before { visibility: hidden; }
/* The awaited-answer note (audit 2.5), beside the dot, once the form is started. */
/* Its OWN line inside the head (the question columns are too narrow to carry
   the label and the message side by side), reserved from the first paint and
   emptied by visibility — so a question that is answered, then cleared, then
   answered again never moves the sheet under the client's hand. */
/* Elle se range CONTRE le libellé quand la colonne le permet, et ne bascule
   sur sa propre ligne que si elle n'y tient pas — l'aide étant passée derrière
   le « i », une ligne réservée par question obligatoire était devenue le
   principal gaspillage de hauteur de la carte (2026-09-05). Réservée dans les
   deux cas : visible ou non, elle occupe la même boîte. */
.crit-req { flex: 0 1 auto; margin-left: var(--space-5); font-size: 12px; font-weight: 600; color: var(--warn); }
.crit-req[data-on='false'] { visibility: hidden; }
.crit-row input[type='number'] { max-width: 180px; }
/* The bracket figure and its unit read as one control (like the offer box). */
.crit-unit-wrap { display: inline-flex; align-items: center; gap: 6px; }
.crit-unit { font-size: 13px; font-weight: 700; color: var(--ink-muted); }
/* Long option lists (the lender catalogue) render as a select (domain ui hint),
   enhanced into a Nota select — the width cap rides on the wrapper. */
.crit-row .nselect { max-width: 320px; }
/* The select's free-text companion (« Autre prêteur » → its name), revealed
   only while the opening option is chosen. */
/* Le compagnon d'une liste (« Autre prêteur » → son nom) occupe la place que
   l'aide vient de libérer : une ligne pour une ligne, donc répondre à la
   question ne déplace rien de ce qui suit. */
/* Le compagnon d'une liste (« Autre prêteur » → son nom) se range À CÔTÉ de la
   liste, sur la place que la grille laisse libre : l'aide étant passée derrière
   le « i », il n'y a plus de ligne à céder — et une réponse ne doit toujours pas
   pousser ce qui la suit (ADR 0039). */
.crit-row:has(> .crit-other) { flex-flow: row wrap; align-items: flex-start; column-gap: var(--space-8); }
.crit-row:has(> .crit-other) > .crit-head, .crit-row:has(> .crit-other) > .crit-effet { flex: 1 0 100%; }
.crit-row:has(> .crit-other) > .nselect, .crit-row:has(> .crit-other) > .help { flex: 0 1 300px; }
.crit-row:has(> .crit-other) > .crit-other { flex: 1 1 240px; }
.crit-other { display: flex; flex-direction: column; gap: 6px; margin-top: 0; }
.crit-other[hidden] { display: none; }
.crit-other input[type='text'] { max-width: 320px; }
/* Flat dollar effect of an answer, printed on the answer itself; inherits the
   chip's on-state colour so it stays readable on the accent background. */
.crit-add { margin-left: 6px; font-size: 11px; font-weight: 600; color: var(--ink-muted); font-variant-numeric: tabular-nums; }
.chip.is-on .crit-add, .seg-btn.is-on .crit-add { color: inherit; }
/* bookGoTo pose le focus sur le titre de l'écran (tabindex -1) pour que le
   clavier et le lecteur d'écran repartent du haut. Ce titre n'est PAS un
   contrôle : on ne l'atteint jamais en tabulant, et l'anneau de focus générique
   dessinait une boîte verte autour de « Les questions du notaire » qui se lisait
   comme une sélection restée coincée. Le focus reste posé — seule sa bague
   part. */
.book-step-lbl:focus-visible, .book-step-lbl:focus { outline: none; }
/* Même raison pour le dialogue lui-même : showModal() y pose le focus quand
   rien n'est autofocusable, et l'anneau générique cernait TOUTE la feuille d'un
   trait vert qu'on lisait comme une sélection coincée. */
dialog:focus, dialog:focus-visible { outline: none; }
/* Wrap allowed: on a phone the parenthetical drops to its own line instead of
   squeezing the title into a ragged two-column fold. */
.book-step-lbl { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; font-size: 14px; font-weight: 700; color: var(--ink); }
.book-opt { color: var(--ink-muted); font-weight: 600; font-size: 12px; }
/* Step 2's live tally — amber while answers are awaited, brand once complete. */
.crit-count { margin-left: auto; font-size: 11.5px; font-weight: 600; color: var(--warn); white-space: nowrap; font-variant-numeric: tabular-nums; }
.crit-count[data-state='done'] { color: var(--brand); }
/* L'écran 1 ne pose qu'UNE question, alors la réponse prend la place (ADR
   0040, 2026-09-05 : « il y a trop d'info, c'est trop petit »). Deux cartes
   à parts égales, assez hautes pour se viser du pouce, jamais trois par
   ligne : sous 360 px de large elles s'empilent plutôt que de rétrécir. */
#o-service-chips { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-rows: 1fr; gap: var(--space-6); }
@media (max-width: 380px) { #o-service-chips { grid-template-columns: 1fr; } }
/* Booking chips are two lines — the act, then its own offre à battre for the
   date (no offer → no sub line: every act is always bookable, so only an
   amount is worth a line) — so the acts compare at a glance before one is
   chosen. */
#o-service-chips .chip {
  position: relative;
  justify-content: center; flex-direction: column; align-items: center; gap: var(--space-3);
  padding: var(--space-8) var(--space-6); border-radius: var(--radius);
}
/* Le crochet du choix : il n'apparaît que sur la carte retenue, et il dit le
   choix sans dépendre de la couleur (le cadre et la teinte, eux, en dépendent). */
#o-service-chips .chip-svc-check {
  position: absolute; top: var(--space-4); right: var(--space-5);
  font-size: 13px; font-weight: 700; line-height: 1; color: var(--brand);
  opacity: 0; transform: scale(.7); transition: opacity .15s ease, transform .15s ease;
}
#o-service-chips .chip.is-on .chip-svc-check { opacity: 1; transform: none; }
/* La pastille du glyphe : la marque de l'acte, visée avant que le nom se lise.
   Elle porte l'état de la carte (survol, choix) — le cadre de la carte ne
   change alors que d'un cheveu, et le choix se voit quand même de loin. */
#o-service-chips .chip-svc-badge {
  width: 36px; height: 36px; flex: none; display: inline-grid; place-items: center;
  border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface-inset);
  transition: background .15s, border-color .15s;
}
#o-service-chips .chip:hover .chip-svc-badge { border-color: var(--brand); }
/* La carte retenue : la teinte, le cadre, le crochet et la pastille disent le
   choix — le NOM, lui, est un titre et reste à l'encre. */
#o-service-chips .chip.is-on { background: var(--brand-tint-solid); color: var(--ink); }
#o-service-chips .chip.is-on .chip-svc-badge { background: var(--surface); border-color: var(--brand); }
#o-service-chips .chip-svc-main { font-size: 15px; }
.chip-svc-main { display: inline-flex; align-items: center; gap: var(--space-3); font-size: 14.5px; font-weight: 700; }
.chip-svc-sub { font-size: 12px; font-weight: 700; color: var(--ink-muted); font-variant-numeric: tabular-nums; }
/* Réservée seulement si le jour porte un chiffre : les deux puces gardent la
   même hauteur quand on change d'acte, sans qu'un jour sans offre paie une
   ligne vide dans chaque carte. */
#o-service-chips[data-sub='true'] .chip-svc-sub { min-height: 1.45em; }
#o-service-chips .chip.is-on .chip-svc-sub { color: inherit; }
/* Le catalogue annoncé (D.ACTES_A_VENIR) : même carte, même hauteur, même
   place — mais un trait pointillé, une encre sourde et aucun état survolé,
   pour que l'œil aille d'abord aux deux actes qui, eux, se réservent. */
#o-service-chips .chip-soon {
  cursor: default; background: transparent; color: var(--ink-muted);
  border-style: dashed; border-color: var(--border); box-shadow: none;
}
/* Rien ne s'y survole ni ne s'y anime : une annonce n'est pas une cible. */
#o-service-chips .chip-soon:hover { background: transparent; border-color: var(--border); color: var(--ink-muted); transform: none; }
#o-service-chips .chip-soon .chip-svc-main { font-weight: 600; }
#o-service-chips .chip-soon .chip-svc-badge { background: transparent; border-style: dashed; }
/* Sur une feuille assez LARGE, les cartes d'acte se couchent : le glyphe à gauche, le
   nom à sa droite, le prix (ou « Bientôt ») au bout de la ligne. Debout, elles
   encaissaient toute la largeur gagnée en VIDE — près de 400 px de carte pour
   un mot, et deux actes seulement annoncés qui pesaient autant que les deux
   qui se réservent (capture du propriétaire, 2026-09-06).
   C'est la largeur de la FEUILLE qui décide, pas celle de l'écran : la feuille
   est un dialogue centré, sa largeur ne suit pas la fenêtre au même rythme.
   Là où le pouce vise — téléphone, feuille étroite — rien ne change : les
   cartes restent debout et hautes. */
.day-book { container-type: inline-size; container-name: book; }
@container book (min-width: 600px) {
  #o-service-chips .chip {
    flex-direction: row; justify-content: flex-start; align-items: center;
    gap: var(--space-6); padding: var(--space-6) var(--space-7); text-align: left;
  }
  /* Le montant du jour ferme la ligne, aligné d'une carte à l'autre. */
  #o-service-chips .chip-svc-sub { margin-left: auto; padding-right: var(--space-6); }
  /* Le crochet du choix reprend sa place au coin, dégagé du montant. */
  #o-service-chips .chip-svc-check { top: 50%; transform: translateY(-50%) scale(.7); }
    #o-service-chips .chip.is-on .chip-svc-check { transform: translateY(-50%); }
}
/* On narrow phones the four acts intentionally stay in one column, but they
   are still simple choices — not four tall poster cards. Keep the 44px touch
   floor while placing the icon, name and day figure on a compact two-line
   rail. One column also gives long names their full reading width. */
@media (max-width: 520px) {
  #o-service-chips { grid-template-columns: 1fr; grid-auto-rows: auto; gap: 8px; }
  #o-service-chips .chip {
    display: grid; grid-template-columns: 36px minmax(0, 1fr);
    grid-template-rows: auto auto; align-items: center; justify-content: stretch;
    gap: 2px 10px; min-height: 76px; box-sizing: border-box;
    padding: 10px 12px; text-align: left; white-space: normal;
  }
  #o-service-chips .chip-svc-badge { grid-column: 1; grid-row: 1 / span 2; }
  #o-service-chips .chip-svc-main {
    grid-column: 2; grid-row: 1; min-width: 0; font-size: 14px;
    line-height: 1.25; overflow-wrap: anywhere;
  }
  #o-service-chips .chip-svc-sub {
    grid-column: 2; grid-row: 2; min-height: 0 !important; margin: 0;
    padding: 0; line-height: 1.2;
  }
  #o-service-chips .chip-svc-check { top: 8px; right: 8px; font-size: 12px; }
}
#o-service-chips .chip-soon .svc-ic { opacity: .7; }
/* « Bientôt » tient sur la ligne RÉSERVÉE AU PRIX, sous le nom (2026-09-06) :
   sur la ligne du nom, la pastille poussait « Procuration » hors de l'axe de
   son glyphe, et la rangée annoncée se lisait de travers sous une rangée
   centrée. La carte garde la hauteur d'une carte réservable — la ligne
   existait déjà — et la mention se lit comme une note, pas un bouton. */
.chip-soon-tag {
  font-size: 9.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--ink-muted); border: 1px solid var(--border);
  padding: 1px var(--space-3); border-radius: var(--radius-xs); white-space: nowrap;
}
.book-options { margin: 0; }
.book-options .form-row:last-of-type { margin-bottom: 0; }
/* The identity block of the booking sheet (ADR 0033): name, courriel,
   téléphone — set apart from the notary's questions by a rule, never folded.
   Les trois champs s'apparient sur la MÊME grille que les questions de
   l'écran 2 (2026-09-06) : trois champs à la file dans une feuille qui
   s'élargit devenaient trois barres de 700 px, et rien ne disait que le nom et
   le courriel vont ensemble. Même seuil que .crit-sec-grid, donc les deux
   écrans se replient au même endroit. */
/* TROIS colonnes tant que la feuille les porte (2026-09-07) : à deux, le
   téléphone fermait le bloc seul et traînait une demi-carte nue à sa droite —
   le dernier vide de l'écran 4. Les trois champs sont courts et se lisent d'une
   seule ligne ; `auto-fit` les replie à deux puis à un, sans palier écrit à la
   main. */
.book-identity {
  margin-top: var(--space-6); padding-top: var(--space-6); border-top: 1px solid var(--border);
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-6) var(--space-9); align-items: start;
}
/* Le sélecteur d'écran impose `display: block !important` à chaque bloc de la
   feuille (.day-book > [data-screen]) : le bloc d'identité le redit au même
   poids, sur le même sélecteur porté d'une classe, sans quoi la grille
   ci-dessus n'est jamais appliquée. */
.day-book[data-at='4'] > .book-identity[data-screen='4'] { display: grid !important; }
@media (max-width: 560px) { .book-identity { grid-template-columns: minmax(0, 1fr); } }
.book-identity .form-row { margin: 0; }
/* Un champ se dimensionne sur ce qu'on y écrit : une barre de 700 px pour dix
   chiffres promet autre chose que ce qu'elle attend. */
@media (min-width: 561px) {
  .book-identity #o-telephone { max-width: 260px; }
}
/* Les trois lignes d'aide de l'écran 4 sont des PROMESSES (à qui va ce champ,
   ce qui reste privé) : elles se lisent, donc elles restent — mais serrées
   sous leur champ, jamais espacées comme un paragraphe. */
.book-identity .help { margin: var(--space-3) 0 0; }
/* « Où signez-vous ? » : trois caractères dans un champ court suivis d'un
   demi-écran nu, et l'explication qui prenait deux lignes pleines sous lui. Le
   champ et son explication se rangent CÔTE À CÔTE — la carte tient sur deux
   lignes au lieu de quatre. */
#prefix-row {
  display: grid; grid-template-columns: auto minmax(0, 1fr);
  align-items: center; gap: var(--space-3) var(--space-8);
}
#prefix-row > .lbl, #prefix-row > .prefix-preview { grid-column: 1 / -1; }
#prefix-row > #o-prefix { width: 96px; }
#prefix-row > .help { margin: 0; }
@media (max-width: 560px) { #prefix-row { grid-template-columns: minmax(0, 1fr); } }

/* Brand utility classes — replace ad-hoc inline styles, keep markup on-brand */
.w-full { width: 100%; }
.uppercase { text-transform: uppercase; }
.mb-xl { margin-bottom: 32px; }
.mt-sm { margin-top: 14px; }
.mt-md { margin-top: 0; }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.actions-inline { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
.offer-success { margin-top: 14px; padding: 12px 14px; background: var(--surface-inset); border-radius: var(--radius); border-left: 3px solid var(--ok); }
.offer-success-head { display: flex; align-items: flex-start; gap: 10px; }
.offer-success-logo { flex: none; display: block; }
.offer-success .mt-sm { margin-top: 0; }
.switch-title { font-weight: 600; font-size: 14px; }
.panel-narrow { max-width: 560px; margin: 18px 0 32px; }
/* Legal pages: the long-form list panel fills the width (its list is 2-column)
   so there is no blank right half. */
#pane-confidentialite .panel-narrow, #pane-conditions .panel-narrow, #pane-charte .panel-narrow { max-width: none; }
.h-sub { font-size: var(--type-h3); line-height: var(--type-h3-lh); letter-spacing: var(--type-h3-ls); margin-bottom: 12px; }

/* Participation and subscription share the same visual weight. */
.participation-options { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.participation-options .eyebrow { display: block; margin-bottom: 12px; }
.participation-options .card p { line-height: 1.6; }
.participation-lifecycle { margin-top: 24px; }
.participation-lifecycle p { max-width: 80ch; color: var(--ink-muted); font-size: 14px; line-height: 1.6; margin: 0 0 16px; }
.participation-lifecycle a { display: inline-flex; align-items: center; min-height: 44px; font-size: 14px; }
.participation-availability { margin: 20px 0 12px; }
@media (max-width: 700px) {
  .participation-options { grid-template-columns: minmax(0, 1fr); }
}

.notary-model-access { position: relative; z-index: 1; margin: 12px 0 0; line-height: 1.6; }

/* --- Notary console ------------------------------------------------------ */
/* Two layouts on one pane, toggled by whether the sign-in gate is showing:
   • SIGNED-OUT → a two-column landing that FILLS the page width (value on the
     left, the tight sign-in on the right) so the pane no longer sits in a narrow
     strip with wide empty margins.
   • SIGNED-IN → the working console (demand lists + two-column prefs grid) needs
     room, so it uses a single wide column. */
#pane-notaires {
  --nc-offer-surface: color-mix(in srgb, var(--surface) 90%, var(--bg));
  --nc-offer-hover: color-mix(in srgb, var(--surface) 78%, var(--surface-inset));
}
#pane-notaires > .wrap { display: flex; flex-direction: column; }
/* Signed-out: the INVENTORY is the pitch. One line of copy, then the live open
   demands, with the sign-in sticky beside them — everything else (value grid,
   agenda band, guarantee) is supporting material, full width below the fold. */
/* The gate card seats ON the demand grid's own top line (owner's call,
   2026-08-27 evening: « Accédez aux demandes semble haut et pas aligné avec
   le reste » — superseding the morning's « must go up »). The hero owns the
   full first row; the right column then opens level with the first row of
   cards, edge to edge with them, so the gate reads as part of the inventory
   grid instead of floating alone beside the headline. */
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 420px);
  /* The inventory keeps twelve slots at every offer count. Compliance remains
     a full-width band below both columns, outside the sign-in card. */
  /* 2026-09-09 — l'agenda ferme la rangée SOUS les deux colonnes. Une carte
     limitée à gauche laissait un vide accidentel sous la porte d'accès dès
     que l'inventaire était court; le rail horizontal ci-dessous utilise cette
     largeur pour rendre la page continue. */
  grid-template-areas:
    "hero       hero"
    "livehead   beta"
    "live       console"
    "carnet     carnet"
    "conformite conformite"
    "guarantee  guarantee";
  column-gap: clamp(32px, 5vw, 80px);
  row-gap: 0;
  align-items: start;
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .nc-landing-head { grid-area: livehead; margin-top: var(--space-2); }
/* A month with nothing open (renderNotaryLive hides the inventory): no header
   for an inventory that is not there, and no half-empty two-column spread —
   the pane folds into one centred column: gate, then agenda. */
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])):has(#notary-live[hidden]) {
  grid-template-columns: minmax(0, 520px);
  grid-template-areas: "hero" "beta" "console" "conformite" "carnet" "guarantee";
  justify-content: center;
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])):has(#notary-live[hidden]) .nc-landing-head { display: none; }
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])):has(#notary-live[hidden]) #notary-console { margin-top: var(--space-6); }
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .intro--hero   { grid-area: hero; margin: 0; }
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .intro-main     { max-width: none; }
/* Keep a readable measure on the lede without capping the whole hero block. */
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .intro p { max-width: 78ch; }
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-ai-beta-note {
  grid-area: beta; align-self: start; width: 100%; margin-top: var(--space-2);
}
#pane-notaires .notary-ai-beta-note[hidden] { display: none !important; }
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .nc-live        { grid-area: live; align-self: start; }
/* L'agenda ferme la colonne de droite, sous la porte d'accès : les demandes
   restent la lecture principale à gauche et l'outil de prospection accompagne
   naturellement le compte notaire sans descendre sous tout le contenu. */
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-carnet  {
  grid-area: carnet; align-self: start;
  /* A full-width support rail closes the inventory row beneath both columns.
     Keeping it in the left column left a large, accidental-looking void under
     the access card on sparse inventories. The card uses a compact horizontal
     treatment below so the extra measure reads as useful space, not air. */
  margin-top: var(--space-16); padding-top: var(--space-12);
  border-top: 1px solid var(--border);
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-carnet .sub-card {
  display: grid;
  grid-template-columns: minmax(280px, .8fr) minmax(0, 1.6fr);
  grid-template-rows: auto auto auto;
  column-gap: clamp(24px, 4vw, 64px);
  align-items: center;
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-carnet .sub-card-head {
  grid-column: 1;
  grid-row: 1 / span 3;
  align-self: start;
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-carnet .sub-card-actions {
  grid-column: 2;
  grid-row: 1;
  margin-top: 0;
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-carnet .sub-card > details {
  grid-column: 2;
  grid-row: 2;
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-carnet .sub-card > .help:last-child {
  grid-column: 2;
  grid-row: 3;
  margin: 0;
}
/* The console anchors to the TOP of the "live" row — no margin at all: its
   top edge sits exactly on the first demand cards' top edge (card aligned to
   cards, the strongest line on the page), and it scrolls with the page like
   every other card (owner's call, 2026-08-25: a pinned money panel followed
   the reader around). */
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-console {
  grid-area: console; align-self: start;
  margin: 0;
  /* The gate is the page's ONE door, seated beside a grid of money — on the
     plain 90 % skin it read as furniture (owner, 2026-08-27: « ça semble
     faible versus la partie à gauche »). It takes a brand pour: tint alone,
     never a ring, same 90 % skin — the REGULAR tint, not the strong pour
     (owner, 2026-08-27 soir: the deep blue read too intense beside the
     grid). Signed in, the console is a workspace and stays fully opaque. */
  background: color-mix(in srgb, var(--brand-tint-solid) var(--surface-veil-mix), transparent);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
/* Conformité (ADR 0033 §5) — the compliance band: the three articles, run as
   one full-width row under the two-column band, the way a trust strip closes a
   marketplace landing. Inside the gate card it made the rail ~400px taller
   than the demand grid beside it; full width it is out of the balance entirely
   and its tiles get a readable measure instead of a 420px gutter. */
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #nc-conformite {
  grid-area: conformite; align-self: start;
  max-width: none; margin-top: var(--space-10);
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .nc-conformite-tiles {
  grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr));
}
/* The guarantee closes BOTH columns on one line — the page's last word, not a
   footnote hanging off the bottom of one column. */
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .nota-guarantee { grid-area: guarantee; }
/* Hero collapses to a single column on THIS pane only (the client carnet hero
   keeps its two columns). */
#pane-notaires .intro--hero { display: block; }
#pane-notaires > .wrap:has(#notary-authed:not([hidden])) .notary-ai-beta-note { display: none; }

/* Assisted-preparation announcement: it belongs in the right rail beside the
   inventory, with an outlined resting state and no filled slab. Its explanation
   is a hover/focus surface, so it floats over the page and never changes the
   height of the landing grid. */
.beta-teaser { position: relative; }
.beta-teaser-trigger {
  appearance: none; display: flex; align-items: center; gap: var(--space-4);
  width: 100%; min-height: 44px; box-sizing: border-box; padding: var(--space-5) var(--space-6);
  border: 1px solid var(--border); border-radius: var(--radius);
  background: transparent; color: var(--ink); font: inherit; text-align: left;
  transition: border-color .15s, box-shadow .15s;
}
.beta-teaser-trigger:hover,
.beta-teaser:focus-within .beta-teaser-trigger { border-color: var(--border-strong); }
.beta-teaser-copy { display: grid; gap: 1px; min-width: 0; }
.beta-teaser-trigger .sub-card-kicker { margin: 0; font-size: 9.5px; }
.beta-teaser-trigger .sub-card-title { font-size: 12.5px; line-height: 1.2; }
.beta-teaser-hint { margin-left: auto; color: var(--ink-muted); font-size: 12px; white-space: nowrap; }
.beta-teaser-info {
  appearance: none; display: grid; place-items: center; flex: none; width: 32px; height: 32px;
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm); color: var(--brand);
  background: var(--surface-inset); font: inherit; font-size: 15px; font-weight: 800; line-height: 1;
  cursor: pointer; transition: border-color .15s, transform .15s;
}
.beta-teaser-info:hover { border-color: var(--brand); transform: scale(1.05); }
.beta-teaser-info:focus-visible { outline: 3px solid var(--ring); outline-offset: 3px; }
.beta-teaser:hover, .beta-teaser:focus-within { z-index: 30; }
.beta-teaser-details {
  position: absolute; z-index: 40; top: calc(100% + var(--space-4)); right: 0;
  width: min(520px, calc(100vw - 32px)); max-height: min(70vh, 430px); box-sizing: border-box;
  overflow-y: auto; margin: 0; padding: var(--pad-card); border: 1px solid var(--border);
  border-radius: var(--radius-lg); background: var(--surface); box-shadow: var(--shadow-lg);
  opacity: 0; visibility: hidden; pointer-events: none; transform: translateY(-4px);
  transition: opacity .15s ease, visibility .15s ease, transform .15s ease;
}
.beta-teaser:hover .beta-teaser-details,
.beta-teaser:focus-within .beta-teaser-details {
  opacity: 1; visibility: visible; pointer-events: auto; transform: none;
}
.beta-teaser-details .sub-card-sub { margin-top: 0; }
.beta-teaser-details p { margin-inline: 0; }
.beta-teaser-details .help { margin: var(--space-5) 0 0; }
.beta-teaser-ask { margin: var(--space-5) 0 var(--space-3); color: var(--ink); font-size: 12.5px; font-weight: 700; }
.beta-teaser-details .btn { width: auto; }
@media (max-width: 560px) {
  .beta-teaser-details { right: auto; left: 0; width: min(520px, calc(100vw - 32px)); }
}
/* SIGNED-IN: the pane is a workspace, not a pitch. The hero keeps only its
   heading (panes focus their h1 on navigation), the lede goes, and the
   prospecting band slides behind the console (flex order — the wrap is a flex
   column signed-in) so the open demands are the first thing on screen. */
#pane-notaires > .wrap:has(#notary-authed:not([hidden])) .intro--hero p { display: none; }
#pane-notaires > .wrap:has(#notary-authed:not([hidden])) .intro--hero { margin-bottom: 0; }
/* Signed-in, the headline is a room label, not a pitch: it shrinks and the
   intro's air tightens so the first CONFIRMABLE demand lands on the first
   screen at every width. */
#pane-notaires > .wrap:has(#notary-authed:not([hidden])) .intro--hero h1 { font-size: var(--type-h3); line-height: var(--type-h3-lh); letter-spacing: var(--type-h3-ls); }
#pane-notaires > .wrap:has(#notary-authed:not([hidden])) .intro { padding-bottom: 6px; }
#pane-notaires > .wrap:has(#notary-authed:not([hidden])) .notary-carnet { order: 1; }
#pane-notaires > .wrap:has(#notary-authed:not([hidden])) .nota-guarantee { order: 2; }
/* Narrow screens: one column, in selling order — a line of pitch, the open
   demands, then the sign-in the cards funnel into; the rest follows.

   The threshold is 1200px: below that the fixed rail would leave a narrow
   demand column, especially on a zoomed desktop or a tablet in landscape.
   Stacking the two surfaces lets the inventory use the full measure and keeps
   the sign-in gate aligned beneath it instead of beside a tall sparse grid.

   The column takes the full width of .wrap; only the FORM remains readable and
   centred inside its card. */
@media (max-width: 1200px) {
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "hero" "beta" "livehead" "live" "console" "conformite" "carnet" "guarantee";
  }
  /* The two-column rule sizes this margin to seat the console on the hero
     H1's line. Stacked, the card steps down the page on the same --space-10
     beat as every other section instead. Longhand so the other three sides
     of the shorthand survive. */
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-console { align-self: stretch; margin-top: var(--space-10); }
  /* La carte va d'un bord à l'autre ; le formulaire, non — 440 px collés à
     gauche dans une carte de 940 px se lirait comme un oubli. */
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-console .nc-gate { margin-inline: auto; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-carnet .sub-card {
    display: block;
  }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-carnet .sub-card-actions {
    margin-top: 12px;
  }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-carnet .sub-card > .help:last-child {
    margin-top: 10px;
  }
}

/* The landing's centrepiece: the live open inventory, directly under the one
   line of pitch. Cards mirror the console's .nc-card surface; the whole card
   is a button into the sign-in. */
.nc-live[hidden] { display: none; }
.nc-live {
  padding: var(--space-5); border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--surface-veil); box-shadow: var(--shadow-sm);
}
.nc-live-head { display: flex; align-items: baseline; gap: var(--space-6); flex-wrap: wrap; margin-bottom: var(--space-5); }
.nc-live-h { font-size: var(--type-h4); line-height: var(--type-h4-lh); letter-spacing: var(--type-h4-ls); margin: 0; }
/* Signed-in the wrap is a flex column and the inventory is the console's own
   list — the landing header row has nothing to head. */
#pane-notaires > .wrap:has(#notary-authed:not([hidden])) .nc-landing-head { display: none; }
/* Real cards and inert empty slots share the same row size. Sparse inventory
   uses six slots: that is two rows on a wide column and three rows on a narrow
   two-column column. Additional rows appear only when real offers need them. */
.nc-live-grid { position: relative; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(215px, 100%), 1fr)); grid-auto-rows: minmax(128px, 1fr); gap: var(--space-5); }
.nc-live-slot, .nc-live-empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-width: 0; padding: var(--pad-card); text-align: center;
  border: 1px dashed var(--border-strong); border-radius: var(--radius-lg);
  background: var(--surface-inset); color: var(--ink-muted);
}
.nc-live-slot { font-size: 12px; }
.nc-live-grid--empty .nc-live-slot { visibility: hidden; }
.nc-live-empty { position: absolute; inset: 0; gap: var(--space-4); }
.nc-live-empty strong { color: var(--ink); font-size: 24px; letter-spacing: -0.02em; }
.nc-live-empty span { max-width: 28ch; font-size: 14px; }
/* The way out of an empty carnet. Deliberately not a card: a quiet band under
   the grid, so it reads as guidance and not as one more piece of inventory. */
.nc-live-next { display: flex; flex-direction: column; gap: var(--space-5); margin-top: var(--space-7); }
.nc-live-next-lede { max-width: 62ch; margin: 0; color: var(--ink-muted); font-size: 14px; line-height: 1.55; }
.nc-live-next-actions { display: flex; flex-wrap: wrap; gap: var(--space-5); }
/* The act's name never shares a line with the tier pill. It used to: at four
   up on a desktop the name had ~84px and read « Refinance… », at two up on a
   phone ~60px and read « Refin… » — refinancement and financement became the
   same card (owner, 2026-09-03). The act takes its own line, then the amount
   and its tier (the pairing a notary scans), then the date.

   container-type: the tile decides its own three- or four-line shape from ITS
   width, not from the viewport's — the same tile is 216px in a desktop rail of
   four and 175px two up on a phone, and it is the tile's width, never the
   screen's, that says whether « 9 410 $ » and « Prioritaire » fit on one line. */
.nc-live-card {
  container-type: inline-size;
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "svc svc" "amt pill" "meta meta";
  align-content: start; row-gap: 6px; column-gap: 8px; min-width: 0;
  padding: var(--pad-card); text-align: left; font: inherit; color: var(--ink);
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--surface-inset); cursor: pointer;
  transition: transform .14s, background-color .14s, border-color .14s, box-shadow .14s;
}
.nc-live-card .nc-live-svc { grid-area: svc; }
.nc-live-card .pill { grid-area: pill; justify-self: end; align-self: center; }
.nc-live-card .nc-live-amt { grid-area: amt; }
.nc-live-card .nc-live-meta { grid-area: meta; }
/* A narrow tile: the widest amount (« 12 000 $ », 82px) plus the widest tier
   (« Prioritaire », 74px) plus the gap needs ~164px, so under 168px of tile
   CONTENT (what an inline-size container query measures — the padding is
   already out) the pill drops to its own line rather than landing on top of
   the money. Explicit line placement, which outranks the named areas above. */
@container (max-width: 168px) {
  .nc-live-card .nc-live-amt { grid-column: 1 / -1; }
  .nc-live-card .pill { grid-row: 3; grid-column: 1 / -1; justify-self: start; }
  .nc-live-card .nc-live-meta { grid-row: 4; grid-column: 1 / -1; }
}
.nc-live-card:hover { transform: translateY(-2px); background: var(--surface-hover); border-color: var(--border-strong); box-shadow: var(--shadow); }
.nc-live-card:hover .nc-live-amt { color: var(--brand-on-surface); }
.nc-live-card:active { transform: translateY(0); box-shadow: var(--shadow-sm); }
/* display: contents — the name and the pill become tiles of the card's own
   grid, each on the line it belongs to. The wrapper stays in the markup so
   ncLiveCard() keeps building one "top" row. */
.nc-live-top { display: contents; }
/* The span's colour is the act's --svc-* token (set inline) — it paints the
   glyph via currentColor; the act's NAME stays ink. Same grammar as the carnet. */
.nc-live-svc { display: flex; align-items: center; gap: 7px; min-width: 0; }
.nc-live-svc-name { font-size: 12.5px; font-weight: 700; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nc-live-amt { font-size: 19px; font-weight: 800; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; transition: color .14s; }
.nc-live-meta { font-size: 12px; color: var(--ink-muted); }
/* Overflow card: "+N autres" — dashed, centred, brand-inked, same footprint.
   On hover the dashes resolve into a solid brand door with a faint wash — the
   card reads as the entrance it is, not a disabled placeholder. */
.nc-live-more {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; text-align: center; gap: 4px;
  border-style: dashed; border-color: var(--border-strong); background: transparent; color: var(--brand);
}

/* Phones: a compact grid — eight single-column tiles pushed the sign-in a full
   screen down, so the tiles run two up and the funnel's gate stays in reach.
   auto-fit, not a hard two: at 320px two tiles cannot hold an amount and a
   tier side by side at all, so the grid falls to one full-width tile instead.
   AFTER the base rules — same specificity, so order is what decides. */
@media (max-width: 640px) {
  .nc-live-grid { grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr)); gap: var(--space-4); }
  .nc-live-card { padding: var(--space-5) var(--space-6); row-gap: 4px; }
  .nc-live-amt { font-size: 17px; }
  .nc-live-meta { font-size: 11px; }
}

.nc-live-more:hover { border-style: solid; border-color: var(--brand); background: var(--brand-tint-solid); }
.nc-live-more strong { font-size: 14px; font-weight: 800; }
.nc-live-more .nc-live-meta { color: inherit; }

/* The hero's ONE pitch line, shown at every width. The old full paragraph and
   the numbered step list repeated what this line (and the guide) already
   say — one sentence carries the model, the CTAs carry the action. */
.hero-tagline strong { color: var(--ink); }

/* Week vignette — the marketplace played out with live data, in the onboarding
   dialog only. Real demands (D.weekAgenda) drop onto a Mon–Fri board one by one
   while the money counts up; the board then clears and replays the next batch.
   Borderless: the inset surface alone seats it. */
.nc-week[hidden] { display: none; }
.nc-week {
  /* ONE height for filled chips and empty ghost slots — a half-filled column
     must read as one grid, never as two misaligned ones. */
  --wk-cell-h: 46px;
  display: flex; flex-direction: column; gap: 12px;
  padding: var(--space-8) var(--space-9) 13px;
  border-radius: var(--radius);
  background: var(--surface-inset);
}
.nc-week-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.nc-week-kicker { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; color: var(--subtitle-ink); }
.nc-week-total { position: relative; display: inline-flex; align-items: baseline; gap: var(--space-3); font-size: 13px; color: var(--ink-muted); }
.nc-week-total strong { display: inline-block; color: var(--brand); font-weight: 800; font-variant-numeric: tabular-nums; }
/* A small pop each time money lands on the board. */
.nc-week-total strong.is-tick { animation: nc-week-tick .35s ease; }
@keyframes nc-week-tick { 40% { transform: scale(1.12); } }
/* The landed amount floats up off the counter and dissolves. Its whole travel
   (top offset + peak translate) stays under the box's 16px top padding, so the
   float never escapes the vignette onto whatever sits above it. */
.nc-week-delta {
  position: absolute; right: 100%; margin-right: var(--space-4); top: -3px;
  font-size: 11px; font-weight: 800; color: var(--brand);
  white-space: nowrap; opacity: 0; pointer-events: none;
}
.nc-week-delta.is-live { animation: nc-week-delta .8s ease forwards; }
@keyframes nc-week-delta {
  0% { opacity: 0; transform: translateY(4px); }
  25% { opacity: 1; }
  100% { opacity: 0; transform: translateY(-10px); }
}
/* The board leaves with a little weight, not a flat fade. */
.nc-week-board { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px; transition: opacity .45s ease, transform .45s ease; }
.nc-week-board.is-out { opacity: 0; transform: translateY(6px) scale(.985); }
.nc-week-col { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.nc-week-day { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-muted); text-align: center; }
/* The day that just received a chip lights up for a beat. */
.nc-week-day.is-hit { animation: nc-week-day-hit .5s ease; }
@keyframes nc-week-day-hit { 30% { color: var(--brand); } }
/* Ghost slot: the empty half-hour a demand has not claimed (yet). */
.nc-week-slot { height: var(--wk-cell-h); border: 1px dashed var(--border); border-radius: var(--radius); }
/* A demand chip. `color` carries the act's --svc-* token (set inline) and the
   DOT says the service — the same visual grammar as the carnet's cells, where
   coloured borders belong to urgency, never to the act. */
.nc-week-chip {
  position: relative; height: var(--wk-cell-h); padding: 0 7px; min-width: 0;
  display: flex; flex-direction: column; justify-content: center; gap: 1px;
  border: 1px solid var(--border-strong); border-radius: var(--radius);
  background: var(--surface);
  /* --tilt (set per chip by the builder) gives each drop its own slight lean,
     so eight landings read as eight objects instead of one stamped pattern. */
  opacity: 0; transform: translateY(-14px) scale(.88) rotate(var(--tilt, 0deg));
}
.nc-week-chip.is-in {
  opacity: 1; transform: none;
  transition: opacity .28s ease, transform .55s cubic-bezier(.18, 1.5, .35, 1);
}
.nc-week-chip.is-in:hover { transform: translateY(-1px); box-shadow: var(--shadow); transition: transform .15s ease, box-shadow .15s ease; }
.nc-week-chip-top { display: flex; align-items: center; gap: 4px; min-width: 0; }
.nc-week-chip-dot { flex: none; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
/* 10px + tight tracking: a short act name fits a five-column dialog cell
   whole; longer ones ("Refinancement") ellipsize, with the glyph, colour and
   tooltip still naming them. */
.nc-week-chip-name { font-size: 10px; letter-spacing: -0.01em; font-weight: 600; color: var(--ink-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nc-week-chip-amt { font-size: 12.5px; font-weight: 800; color: var(--ink); font-variant-numeric: tabular-nums; }
/* A taken demand flips once the board settles: the chip calms down and its ✓
   appears — the marketplace clearing, shown rather than claimed. */
.nc-week-chip-check {
  position: absolute; top: 3px; right: 6px;
  font-size: 10px; font-weight: 800; color: var(--brand);
  opacity: 0; transform: scale(.4);
}
.nc-week-chip.is-taken { opacity: .72; transition: opacity .4s ease; animation: nc-week-take .45s ease; }
@keyframes nc-week-take { 35% { transform: scale(.96); } }
.nc-week-chip.is-taken .nc-week-chip-check {
  opacity: 1; transform: none;
  transition: opacity .3s ease, transform .45s cubic-bezier(.2, 1.4, .4, 1);
}
.nc-week-note { margin: 0; font-size: 11.5px; line-height: 1.5; color: var(--ink-muted); }
.nc-week-note[hidden] { display: none; }
.nc-week-check-key { color: var(--brand); font-weight: 800; }
@media (prefers-reduced-motion: reduce) {
  .nc-week-board { transition: none; transform: none; }
  .nc-week-chip, .nc-week-chip-check, .nc-week-chip.is-taken { opacity: 1; transform: none; transition: none; animation: none; }
  .nc-week-total strong.is-tick, .nc-week-delta.is-live, .nc-week-day.is-hit { animation: none; }
}
/* In the welcome dialog: sits under both views, left-aligned against the
   dialog's centred text. At dialog width the chip keeps the base two-line
   grammar — glyph + act name over the EXACT amount — so the board says what
   is sold and for how much without a hover. The vignette is a container so
   the chips re-lay by the DIALOG's width, not the viewport's. */
.nc-week--onb { margin-top: 18px; text-align: left; container: ncweek / inline-size; }
.nc-week--onb .nc-week-chip { overflow: hidden; }
/* Only a phone-narrow container trades words for the compact form: the name
   goes (the glyph + colour still say the act, the tooltip keeps the words),
   the amount swaps to the calendar's data-compact ("2,9k"), and the glyph
   stacks centred over it on a shorter cell — slots shrink with the chips
   through the shared --wk-cell-h, so the grid never splits in two. */
@container ncweek (max-width: 380px) {
  .nc-week--onb { --wk-cell-h: 38px; }
  .nc-week--onb .nc-week-board { gap: 5px; }
  .nc-week--onb .nc-week-chip { align-items: center; gap: 2px; padding: 0 4px; }
  .nc-week--onb .nc-week-chip-name { display: none; }
  .nc-week--onb .nc-week-chip-amt { font-size: 0; white-space: nowrap; }
  .nc-week--onb .nc-week-chip-amt::after { content: attr(data-compact); font-size: 10.5px; font-weight: 800; letter-spacing: -0.01em; }
}
/* Sur la page des notaires (propriétaire, 2026-09-12) : la même vignette, mais
   dans la carte d'abonnement, au-dessus des quatre boutons qu'elle explique.
   Container comme la variante du dialogue — la carte traverse toute la largeur
   au-delà de 1200px et se retrouve à 300px en dessous, donc les puces doivent
   se relire sur la CARTE, jamais sur la fenêtre. */
.nc-week--agenda { margin: var(--space-5) 0 var(--space-6); text-align: left; container: ncweek / inline-size; }
.nc-week--agenda .nc-week-chip { overflow: hidden; }
/* The narrow subscription rail keeps the total without a floating label
   crossing the calendar heading. The total itself still animates. */
.nc-week--agenda .nc-week-delta { display: none; }
@container ncweek (max-width: 380px) {
  .nc-week--agenda { --wk-cell-h: 38px; }
  .nc-week--agenda .nc-week-board { gap: 5px; }
  .nc-week--agenda .nc-week-chip { align-items: center; gap: 2px; padding: 0 4px; }
  .nc-week--agenda .nc-week-chip-name { display: none; }
  .nc-week--agenda .nc-week-chip-amt { font-size: 0; white-space: nowrap; }
  .nc-week--agenda .nc-week-chip-amt::after { content: attr(data-compact); font-size: 10.5px; font-weight: 800; letter-spacing: -0.01em; }
}

/* Notary flavour only: the same board also lands in their agenda. Decorative
   (it lives inside the aria-hidden vignette) — brand marks + one muted line. */
.nc-week-providers { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; font-size: 11.5px; line-height: 1.5; color: var(--ink-muted); }
.nc-week-providers[hidden] { display: none; }
.nc-week-providers .brand-ic { flex: none; }
/* The three agenda marks file in one after the other when the row appears. */
.nc-week-providers.is-live .brand-ic { animation: nc-prov-in .45s ease backwards; }
.nc-week-providers.is-live .brand-ic:nth-of-type(2) { animation-delay: .12s; }
.nc-week-providers.is-live .brand-ic:nth-of-type(3) { animation-delay: .24s; }
@keyframes nc-prov-in { from { opacity: 0; transform: translateY(4px) scale(.8); } }

/* Bid vignette — the CLIENT onboarding step: ONE real demand played out end to
   end. The price climbs from the act's starting price to the offered amount,
   the demand is published au carnet, then a notaire retains it. Same inset
   surface as the week board; ob-bid-* names its own parts. */
.ob-bid[hidden] { display: none; }
.ob-bid {
  display: flex; flex-direction: column; gap: 12px;
  margin-top: 18px; padding: var(--space-8) var(--space-9) var(--space-7);
  border-radius: var(--radius);
  background: var(--surface-inset);
  text-align: left;
}
/* One bid's story fades out as a block before the next one begins. */
.ob-bid-scene { display: flex; flex-direction: column; gap: 10px; transition: opacity .45s ease; }
.ob-bid-scene.is-out { opacity: 0; }
.ob-bid-card {
  display: flex; align-items: center; gap: 10px; min-width: 0;
  padding: 10px 12px;
  border: 1px solid var(--border-strong); border-radius: var(--radius);
  background: var(--surface);
}
/* Each bid's card settles in fresh… */
.ob-bid-scene.is-live .ob-bid-card { animation: ob-bid-card-in .5s cubic-bezier(.2, 1.2, .4, 1) backwards; }
@keyframes ob-bid-card-in { from { opacity: 0; transform: translateY(8px) scale(.96); } }
/* …and rings once, the moment it lands au carnet. */
.ob-bid-card.is-pub { animation: ob-bid-pub .8s ease; }
@keyframes ob-bid-pub { 25% { border-color: var(--brand); box-shadow: 0 0 0 3px var(--ring); } }
/* `color` carries the act's --svc-* token (set inline); the glyph inherits it. */
.ob-bid-ic { flex: none; display: inline-flex; }
.ob-bid-main { flex: 1; display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.ob-bid-name { font-size: 12.5px; font-weight: 700; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ob-bid-date { font-size: 11px; color: var(--ink-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ob-bid-amt { flex: none; display: inline-block; font-size: 18px; font-weight: 800; color: var(--brand); font-variant-numeric: tabular-nums; }
.ob-bid-amt.is-tick { animation: nc-week-tick .35s ease; }
.ob-bid-stamps { display: flex; flex-direction: column; gap: 5px; }
/* Step stamps fade-and-rise in sequence: published, then retained/open. Each
   carries a dot that turns brand the moment its step is reached. */
/* flex-start + a nudged dot: when the stamp wraps to two lines on a narrow
   dialog, the dot stays with the FIRST line instead of floating between them. */
.ob-bid-stamp { display: flex; align-items: flex-start; gap: 7px; font-size: 11.5px; line-height: 1.5; color: var(--ink-muted); opacity: 0; transform: translateY(4px); }
.ob-bid-stamp::before { content: ''; flex: none; width: 5px; height: 5px; margin-top: 6px; border-radius: 50%; background: var(--border-strong); transition: background-color .3s ease; }
.ob-bid-stamp.is-on { opacity: 1; transform: none; transition: opacity .35s ease, transform .45s ease; }
.ob-bid-stamp.is-on::before { background: var(--brand); }
/* The closing stamp (retenue / ouverte) arrives with a touch more spring. */
#ob-bid-stamp-fin.is-on { animation: ob-bid-fin .5s cubic-bezier(.2, 1.3, .4, 1); }
@keyframes ob-bid-fin { from { transform: translateY(6px) scale(.97); } }
@media (prefers-reduced-motion: reduce) {
  .ob-bid-scene { transition: none; }
  .ob-bid-scene.is-out { opacity: 1; }
  .ob-bid-stamp { opacity: 1; transform: none; transition: none; }
  .ob-bid-scene.is-live .ob-bid-card, .ob-bid-card.is-pub, #ob-bid-stamp-fin.is-on,
  .ob-bid-amt.is-tick, .nc-week-providers.is-live .brand-ic { animation: none; }
}

#notary-console { margin-top: 12px; max-width: none; }

/* Paid AI preparation is an optional work surface, not a gate on the free
   dossier. Keep its conversion card compact and let the normal checklist lead. */
.nc-ai-product {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px 20px;
  align-items: center; margin: 0 0 var(--space-6); padding: 16px 18px;
  border: 1px solid color-mix(in srgb, var(--brand) 28%, var(--border));
  border-radius: var(--radius); background: color-mix(in srgb, var(--brand-tint-solid) 42%, var(--surface));
}
.nc-ai-product-copy { min-width: 0; }
.nc-ai-kicker { margin: 0 0 3px; color: var(--subtitle-ink); font-size: 10px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; }
.nc-ai-title { margin: 0; color: var(--ink); font-size: var(--type-h3); line-height: var(--type-h3-lh); letter-spacing: var(--type-h3-ls); }
.nc-ai-lead { margin: 5px 0 0; color: var(--ink-muted); font-size: 13px; line-height: 1.45; }
.nc-ai-product-actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 7px; }
.nc-ai-product-actions select, .nc-ai-product-actions input { min-height: 34px; max-width: 260px; padding: 6px 8px; border: 1px solid var(--border-strong); border-radius: var(--radius-sm); background: var(--surface); color: var(--ink); font: inherit; font-size: 12px; }
.nc-ai-product-actions input { width: 60px; }
.nc-ai-quota { padding: 7px 10px; border-radius: var(--radius-sm); background: var(--surface); color: var(--brand-ink); font-size: 12px; font-weight: 750; }
.nc-ai-product-status { grid-column: 1 / -1; margin: 0; }
.nc-ai-questions { margin: 8px 0 16px; padding-left: 20px; }
.nc-ai-questions > li { margin: 0 0 14px; }
.nc-ai-question-feedback { margin-top: 8px; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface-inset); }
.nc-ai-question-feedback .field { margin: 0 0 8px; }
.nc-ai-question-feedback textarea { width: 100%; min-height: 44px; resize: vertical; }
.nc-ai-question-feedback .btn { margin-top: 2px; }
.nc-ai-question-feedback [role='status'] { margin: 7px 0 0; }
@media (max-width: 680px) {
  .nc-ai-product { grid-template-columns: 1fr; }
  .nc-ai-product-actions { justify-content: flex-start; }
}
/* Gate headings (« Accédez aux demandes », « Vérifiez votre boîte courriel »)
   speak in the panel-heading register the partners form panel set: 18px,
   tightened, with the same breath below before the form begins. */
#notary-console .h-sub { margin-bottom: var(--space-8); }
/* Sign-in gate: ONE narrow column, shown as a solid card that anchors the right
   column of the landing (no bare floating field). The signed-in view keeps the
   same .panel .panel-pad card. */
.nc-gate { display: block; max-width: 440px; }
.nc-gate-main { min-width: 0; }
/* The gate's brand kicker — same grammar as the carnet card's « Votre outil
   de prospection », so the right column speaks with one voice. */
.nc-gate-kicker { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; color: var(--subtitle-ink); margin-bottom: var(--space-3); }
/* On the brand-poured card the gate heading carries the column: a step up
   from the console's working 18px, still under the hero's h1. */
#notary-console .nc-gate .h-sub { font-size: var(--type-h2); line-height: var(--type-h2-lh); letter-spacing: var(--type-h2-ls); margin-bottom: var(--space-7); }
/* Panes move focus to their <h1> on navigation so screen readers announce the new
   page; that programmatic focus must NOT paint a ring on a non-interactive heading. */
.tab-pane h1:focus, .intro h1:focus { outline: none; box-shadow: none; }
/* Live echo of what the carnet will publish for this bid, colour-keyed to the
   state of the entry (valid Quebec sector / still typing / off-format). */
.prefix-preview { margin: 6px 0 0; min-height: 1.5em; font-size: 12px; line-height: 1.5; color: var(--ink-muted); }
.prefix-preview[data-state='ok'] { color: var(--brand); }
.prefix-preview[data-state='warn'] { color: var(--status-retenue); }
.nc-auth .form-row { margin-bottom: var(--space-7); }
/* The email field matches the button under it: at 120px it sat in the middle of
   an otherwise empty column. Field and CTA share one taller, 15px register —
   the pair must weigh as much as a demand card across the gap. */
.nc-auth .form-row input { width: 100%; padding: 10px 12px; font-size: 15px; }
/* Opaque surface under the brand outline: on the poured card a transparent
   button let the tint bleed through and the door dissolved into its wall. */
.nc-auth-cta { width: 100%; padding: 10px 16px; font-size: 15px; background: transparent; color: var(--brand-on-surface); border-color: var(--brand); }
.nc-auth-fine { margin-top: 10px; }
/* New-notary welcome: the gate's second step. It REPLACES the email step (the
   "Continuer" action branched here), so it must read as a welcome, not as an
   error bolted under a login form. The "Première visite" marker is the same
   outline pill as "Bientôt" — labelled, never alarming. */
.nc-signup { margin-top: 16px; max-width: 560px; padding: var(--pad-card-lg); display: flex; flex-direction: column; gap: 12px; border: 1px solid var(--brand); border-radius: var(--radius); background: var(--surface-inset); }
.nc-signup:focus { outline: none; }
.nc-signup-tag { margin: 0; align-self: flex-start; padding: 1px 9px; border: 1px solid var(--brand); border-radius: var(--radius-sm); font-size: 11px; font-weight: 800; letter-spacing: .03em; color: var(--brand); text-transform: uppercase; }
.nc-signup-back { align-self: flex-start; }
.nc-signup-lead { margin: 0; font-size: 14px; line-height: 1.5; color: var(--ink); }
.nc-signup-steps { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 6px; font-size: 13.5px; line-height: 1.45; color: var(--ink); }
/* No identity row in the console: the header account menu already says who is
   connected and carries Se déconnecter — the panel opens on the agenda. */
.nc-h { font-size: var(--type-h4); line-height: var(--type-h4-lh); letter-spacing: var(--type-h4-ls); margin: 18px 0 10px; }
.nc-list { display: flex; flex-direction: column; gap: 10px; }
/* Console lists are grids: a 1240px-wide strip per demand wastes the row and
   caps how many dossiers fit one screen. Open demands pack ~3-up; retained
   cards carry the client dossier and the completion form, so they get a wider
   2-up track. Cards stretch to equal row height, actions pinned to the foot. */
/* 320px track: two demands fit side by side from tablet width (768px) up —
   the more open bids on one screen, the stronger the pane's one message. */
.nc-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr)); gap: 12px; }
.nc-grid--wide { grid-template-columns: repeat(auto-fill, minmax(min(480px, 100%), 1fr)); }

.nc-card {
  display: flex; flex-direction: column;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface-inset); padding: var(--space-7);
  transition: transform .14s, background-color .14s, border-color .14s, box-shadow .14s;
}
.nc-card:hover { transform: translateY(-1px); background: var(--surface-hover); border-color: var(--border-strong); box-shadow: var(--shadow-sm); }
.nc-card.is-retained { border-left: 3px solid var(--brand); }
.nc-card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.nc-card-title { font-size: 15px; font-weight: 700; letter-spacing: -0.01em; }
.nc-card-amount { font-size: 19px; font-weight: 800; letter-spacing: -0.02em; white-space: nowrap; }
/* Signals row: tier / complexity / readiness — the only pills on the card.
   Everything descriptive (lender, perimeter, code) drops to the quiet facts
   line below, so the pills that remain actually mean "compare me". */
.nc-card-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 10px; }
.nc-date { font-size: 12px; color: var(--ink-muted); }
/* Case-complexity signal on a notary's open-bid card (outline, colour by level). */
.nc-complexity { font-size: 11px; font-weight: 700; padding: 1px 8px; border-radius: var(--radius-sm); border: 1px solid var(--border); color: var(--ink-muted); }
.nc-complexity[data-level='simple'] { color: var(--ok); border-color: var(--ok); }
.nc-complexity[data-level='complexe'] { color: var(--danger); border-color: var(--danger); }
/* The facts line: one muted sentence-row, dot-separated — reads as context,
   never competes with the signal pills. Children keep their classes (tests,
   urgence accent) but shed the pill chrome here. */
.nc-card-facts { margin-top: 7px; font-size: 12px; line-height: 1.6; color: var(--ink-muted); }
.nc-card-facts > * + *::before { content: '·'; margin: 0 7px 0 3px; color: var(--border-strong); font-weight: 400; }
.nc-card-facts .nc-lender, .nc-card-facts .nc-deplacement, .nc-card-facts .nc-prefixe, .nc-card-facts .nc-distance, .nc-card-facts .nc-date {
  display: inline-block; padding: 0; border: 0; background: none;
  font-size: 12px; font-weight: 600; color: var(--ink-muted); white-space: nowrap;
}
.nc-card-facts .nc-date { font-weight: 700; color: var(--ink); }
.nc-card-facts .nc-date::first-letter { text-transform: uppercase; }
.nc-card-facts .nc-lender-virt { margin-left: 5px; }
.nc-card-facts .nc-deplacement[data-urgence='true'] { font-weight: 700; }
/* The complexity answers, quoted under the facts: a hairline rule instead of
   a floating paragraph, so the block reads as "the file says…". */
.nc-factors {
  margin-top: 8px; padding: 2px 0 2px 10px;
  border-left: 2px solid var(--border-strong);
  font-size: 12px; line-height: 1.55; color: var(--ink-muted);
}
.nc-prefixe {
  font-size: 11px; font-weight: 700; color: var(--ink-muted);
  border: 1px dashed var(--border-strong); border-radius: var(--radius-sm); padding: 1px 6px;
}
.nc-ready {
  font-size: 11px; font-weight: 700; padding: 3px 10px; border-radius: var(--radius-sm); white-space: nowrap;
  background: var(--surface-inset); color: var(--ink-muted); border: 1px solid var(--border-strong);
}
.nc-ready[data-ready='true'] { color: var(--ok); border-color: var(--ok); }
/* Retenir owns the card FOOT — the quiet toolbar (.nc-card-more) sits just
   above it, so the primary confirm is the last thing the card says. The
   auto-margin that pins the foot rides the toolbar (it comes first in DOM)
   and only in the open agenda: retained cards keep flowing content. */
/* flex-wrap: the armed confirm (« Confirmer · N $ » + Annuler) widens the
   row — Détails wraps under instead of overflowing the card border. */
.nc-card-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding-top: 8px; }
/* Every offer uses the same natural height, across rows as well as within a
   row. Text can wrap or grow with a larger font without clipping information. */
#notary-open-list .nc-card { min-width: 0; padding: 14px; cursor: pointer; overflow-wrap: anywhere; }
#notary-open-list .nc-agenda-grid { grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); align-items: stretch; grid-auto-rows: 1fr; }
#notary-open-list .nc-agenda-grid > .nc-card { align-self: stretch; }
#notary-open-list .nc-card-head { flex-wrap: wrap; gap: 4px 12px; }
#notary-open-list .nc-card-title { flex: 1 1 170px; }
#notary-open-list .nc-card-facts > * { max-width: 100%; white-space: normal; }
#notary-open-list .nc-card-meta > *, #notary-open-list .nc-status > * { white-space: normal; }
.nc-card-body { display: flex; flex-direction: column; gap: 2px; }
.nc-card-body[hidden] { display: none; }
.nc-card-location { display: flex; flex-wrap: wrap; gap: 4px 10px; color: var(--ink-muted); font-size: 13px; }
.nc-card-parameters { margin: 6px 0; color: var(--ink-muted); font-size: 13px; line-height: 1.5; }
.nc-card-parameters > div { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 12px; padding-block: 5px; border-bottom: 1px solid var(--border); }
.nc-card-parameters dd { margin: 0; color: var(--ink); font-weight: 600; }
#notary-open-list .nc-card-body { border-top: 1px solid var(--border); padding-top: 10px; margin-top: 4px; }
#notary-open-list .nc-card-actions { margin-top: auto; }
.nc-card-actions .nc-toggle { margin-left: auto; color: var(--ink-muted); }
/* Retenir owns the card foot at every width — the confirm is the card's one
   job; Décliner tucks beside it as a small secondary. The cap keeps it a
   button, not a banner, when a card runs wide. */
.nc-card-actions .nc-accept { flex: 1 1 auto; max-width: 340px; }

/* Signed in as a notary, the chrome drops the client doors: the console is
   the whole app, nothing in the header competes with the agenda (ADR 0019).
   Signing out restores the full menu. */
body.is-notary-session #tab-carnet,
body.is-notary-session #tab-partenaires,
body.is-notary-session .mnav-link[data-tab='carnet'],
body.is-notary-session .mnav-link[data-tab='partenaires'] { display: none; }
/* With its two siblings gone the strip holds ONE pressed tab — a dead
   button. Let it read as the place name instead: same selected chip, no
   hover invitation, no hand cursor. (Clicking a selected tab was already a
   no-op, so only the affordance changes.) */
body.is-notary-session #tab-notaires { pointer-events: none; }

/* --- Open agenda: one grid, the date on the card (ADR 0020) --------------- */
/* The date is an attribute of the demand, not a layout axis. A full-width
   band per day left the console 70 % empty whenever a day held one demand,
   and the lone card read as a bare price. Now the day strip sums the week in
   one slim row (each tile doubles as a day filter) and every card packs one
   responsive grid, chronological, saying its own signing day. */
.nc-open-tools {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px 14px; flex-wrap: wrap; margin: 0 0 14px;
}
.nc-filter { margin: 0; }
.nc-open-tools .nc-filter { flex: 1 0 100%; }
.nc-open-tools .nc-view-seg { margin-left: auto; }
.nc-filters-toggle { gap: 8px; min-height: 44px; }
.nc-filter-count { min-width: 20px; padding: 1px 5px; border-radius: var(--radius-xs); background: var(--brand-tint-solid); color: var(--brand-on-surface); }
.nc-filter-chevron { transition: transform .15s; }
.nc-filters-toggle[aria-expanded='true'] .nc-filter-chevron { transform: rotate(180deg); }
.nc-days[hidden], .nc-filters-toggle[hidden], .nc-filter-count[hidden] { display: none; }
@media (max-width: 420px) {
  .nc-open-tools { gap: 8px; }
  .nc-open-tools .nc-view-seg { flex: 1 1 auto; }
  .nc-open-tools .nc-view-seg .seg-btn { flex: 1; padding-inline: 8px; }
}
.nc-filter[hidden] { display: none; }
.nc-view-seg[hidden] { display: none; }
.nc-filter .chip-svc-sub { margin-left: 2px; }
#notary-open-reset[hidden], .nc-offer-notice[hidden] { display: none; }
.nc-offer-notice { display: flex; align-items: center; flex-wrap: wrap; gap: 12px; padding: 14px; margin-bottom: 16px; border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface); }
.nc-offer-notice p { flex: 1 1 260px; margin: 0; font-size: 14px; }
.nc-first-contact { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; padding: 12px 0; }
.nc-first-contact p { flex: 1 1 240px; margin: 0; font-size: 13px; color: var(--ink-muted); }
.nc-first-contact .btn { min-height: 44px; }
.nc-h .nc-h-amt { font-weight: 800; color: var(--brand); }
.nc-h .nc-h-sum { font-weight: 600; color: var(--ink-muted); }
.nc-agenda-list { display: flex; flex-direction: column; gap: 14px; }
/* The day rail: mini calendar cells — weekday over the day number, the day's
   money under it, the count as a corner badge. ONE scrollable row at every
   width (scroll-snap, thin scrollbar): a dozen wrapped tiles were a wall
   pushing the first demand below the fold. A pressed cell keeps only its day
   and the rest of the rail dims. */
.nc-days {
  display: flex; flex-wrap: nowrap; gap: 8px;
  overflow-x: auto; padding-bottom: 4px; scrollbar-width: thin;
  scroll-snap-type: x proximity;
}
.nc-daytile {
  /* Grow to share the full rail width (owner, 2026-08-27: no dead space at
     the end of the row); the 84px basis still overflows into scroll when a
     busy month packs more days than the row can hold. */
  position: relative; flex: 1 0 84px; scroll-snap-align: start;
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  min-width: 84px; padding: 8px 14px 9px; font: inherit; text-align: center; cursor: pointer;
  color: var(--ink); background: var(--surface-inset);
  border: 1px solid var(--border); border-radius: var(--radius);
  transition: background-color .14s, border-color .14s, box-shadow .14s, opacity .14s;
}
.nc-daytile:hover { background: var(--surface-hover); border-color: var(--border-strong); }
.nc-daytile.is-on { border-color: var(--brand); box-shadow: inset 0 0 0 1px var(--brand); background: var(--brand-tint-solid); }
/* Holding a day mutes the rest of the rail — the choice reads at a glance. */
.nc-days.has-day .nc-daytile:not(.is-on) { opacity: .55; }
.nc-days.has-day .nc-daytile:not(.is-on):hover { opacity: 1; }
.nc-daytile-cal { display: flex; flex-direction: column; align-items: center; line-height: 1.1; }
.nc-daytile-wd { font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-muted); }
.nc-daytile-num { font-size: 19px; font-weight: 800; letter-spacing: -0.02em; }
.nc-daytile-mo { font-size: 10px; font-weight: 600; color: var(--ink-muted); }
/* "Today" earns the brand accent — it's the day a notary can still fill. */
.nc-daytile[data-today='true'] { border-color: var(--brand); }
.nc-daytile[data-today='true'] .nc-daytile-wd { color: var(--brand); }
.nc-daytile-sum { font-size: 12px; white-space: nowrap; }
.nc-daytile-sum.nc-day-total { font-weight: 800; color: var(--brand); }
/* The per-day count: a small square badge tucked in the cell's corner. */
.nc-day-badge {
  position: absolute; top: 4px; right: 4px; min-width: 16px; padding: 1px 4px;
  font-size: 10px; font-weight: 800; line-height: 1.3;
  color: var(--ink-muted); background: var(--surface-hover);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.nc-daytile.is-on .nc-day-badge { color: var(--brand-on-surface); border-color: var(--brand); }
/* The card says its own day — a quiet kicker over the title; today keeps the
   brand accent so the fillable day pops out of the grid. */
.nc-card-when {
  display: flex; align-items: baseline; gap: 7px; margin-bottom: 6px;
  font-size: 11px; font-weight: 700; color: var(--ink-muted);
}
.nc-when-date::first-letter { text-transform: uppercase; }
.nc-when-rel { font-weight: 600; }
.nc-card-when[data-today='true'] .nc-when-rel { color: var(--brand); font-weight: 800; }

/* --- Card: status pills, secondary actions, inline forms ------------------ */
.nc-status { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.nc-pill {
  font-size: 11px; font-weight: 700; padding: 3px 10px; border-radius: var(--radius-sm); white-space: nowrap;
  background: var(--surface-inset); color: var(--ink-muted); border: 1px solid var(--border-strong);
}
/* The lender behind a demand — name + virtual (branchless) flag. The notary
   reads this before deciding; the roster in the préférences filters on it. */
.nc-lender {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11px; font-weight: 700; padding: 3px 10px; border-radius: var(--radius-sm); white-space: nowrap;
  background: var(--surface-inset); color: var(--ink); border: 1px solid var(--border-strong);
}
.nc-lender-virt, .chip-lender-virt {
  font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .03em;
  padding: 0 6px; border-radius: var(--radius-sm); color: var(--warn, var(--ink-muted));
  border: 1px solid currentColor;
}
.chip-lender-virt { margin-left: 6px; }
/* Who travels for the in-person signature (ADR 0017). The 100 %-online urgency
   band is the outlier a notary opted into — it earns the warning accent. */
.nc-deplacement {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11px; font-weight: 700; padding: 3px 10px; border-radius: var(--radius-sm); white-space: nowrap;
  background: var(--surface-inset); color: var(--ink); border: 1px solid var(--border-strong);
}
.nc-deplacement[data-urgence='true'] { color: var(--warn, var(--ink-muted)); border-color: currentColor; }
/* ADR 0035 — la garantie de paiement, sur la rangée de décision du notaire.
   Même registre que les autres signaux (même hauteur, même rayon) : ce n'est
   pas une alarme, c'est un fait à lire avant de retenir. Seul un refus ou une
   réservation expirée prend l'accent d'alerte — ce sont les deux seuls états
   qui appellent un geste. */
.nc-caution {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11px; font-weight: 700; padding: 3px 10px; border-radius: var(--radius-sm); white-space: nowrap;
  background: var(--surface-inset); color: var(--ink-muted); border: 1px solid var(--border-strong);
}
.nc-caution[data-caution='posee'] { color: var(--ok); border-color: var(--ok); }
.nc-caution[data-caution='refusee'], .nc-caution[data-caution='expiree'] { color: var(--danger); border-color: var(--danger); }
.nc-caution-line { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.nc-caution-sub { font-size: 12px; color: var(--ink-muted); }
.nc-caution-row { margin-top: 6px; }
.nc-prop-pill[data-status='en_attente'] { color: var(--brand); border-color: var(--brand); }
.nc-prop-pill[data-status='acceptee'], .nc-docs-pill[data-fournie='true'], .nc-via-prop { color: var(--ok); border-color: var(--ok); }
.nc-prop-pill[data-status='refusee'] { color: var(--danger); border-color: var(--danger); }
/* Secondary actions read as a quiet toolbar — link-weight ghosts, no borders:
   three outlined buttons under an outlined primary was four boxes fighting.
   Hover restores the affordance. */
.nc-card-more { display: flex; flex-wrap: wrap; align-items: center; gap: 2px; margin-top: 10px; }
.nc-card-more .btn {
  border-color: transparent; background: transparent;
  color: var(--ink-muted); font-weight: 600; padding-inline: 9px;
}
.nc-card-more .btn:not(:disabled):hover { background: var(--surface-hover); color: var(--ink); }
/* In the toolbar the agenda flows with its siblings — pushed right it dangled
   alone whenever the row wrapped. */
.nc-card-more .nc-agenda { margin-left: 0; }
.nc-card.is-declining { opacity: .75; }
.nc-undo-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: auto; padding-top: 12px; }
.nc-undo-lbl { font-size: 12px; font-weight: 700; color: var(--ink-muted); }

/* Agenda ▾ menu: a <details> that drops the three deeplinks under its button. */
.nc-agenda { position: relative; margin-left: auto; }
.nc-agenda > summary { list-style: none; cursor: pointer; }
.nc-agenda > summary::-webkit-details-marker { display: none; }
.nc-agenda > summary::after { content: ' ▾'; font-size: 10px; }
.nc-agenda-menu {
  position: absolute; right: 0; top: calc(100% + 4px); z-index: 3; min-width: 140px;
  display: flex; flex-direction: column; padding: 4px;
  background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--radius); box-shadow: var(--shadow);
}
.nc-agenda-item { display: block; padding: 7px 10px; font-size: 13px; font-weight: 600; color: var(--ink); text-decoration: none; border-radius: var(--radius-sm); }
.nc-agenda-item:hover { background: var(--surface-hover); }

/* Inline forms (proposition / documents) open under the card's actions. */
.nc-inline { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); display: flex; flex-direction: column; gap: 8px; }
.nc-form-h { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; color: var(--subtitle-ink); }
.nc-form-row { display: flex; flex-wrap: wrap; align-items: end; gap: 8px; }
.nc-form-lbl { display: flex; flex-direction: column; gap: 4px; font-size: 12px; font-weight: 600; color: var(--ink-muted); }
.nc-propose-amt { max-width: 140px; }
.nc-propose-delta { font-size: 13px; font-weight: 800; color: var(--ok); padding-bottom: 8px; }
.nc-form-msg { width: 100%; resize: vertical; font: inherit; font-size: 13px; }
.nc-form-foot { display: flex; align-items: center; gap: 8px; }
.nc-form-errors { min-height: 1.5em; }
.nc-docs-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(220px, 100%), 1fr)); gap: 6px; }
.nc-docs-item { display: flex; align-items: center; gap: 8px; font-size: 13px; cursor: pointer; }
.nc-docs-name { flex: 1; min-width: 0; }
.nc-missing { font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .05em; color: var(--danger); border: 1px solid var(--danger); border-radius: var(--radius-sm); padding: 0 6px; }

.nc-dossier { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); }
.nc-dossier-h { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; color: var(--subtitle-ink); margin-bottom: 8px; }
.nc-workflow { margin: 12px 0 16px; padding: 12px 14px; background: var(--surface-inset); border: 1px solid var(--border); border-radius: var(--radius); }
.nc-workflow .nc-dossier-h { margin-bottom: 6px; }
.nc-workflow-ai { margin: 8px 0; font-size: 13px; color: var(--ink); }
.nc-workflow-actions { display: grid; gap: 7px; margin: 8px 0 0; padding-left: 22px; }
.nc-workflow-action { padding-left: 3px; color: var(--ink); }
.nc-workflow-action-meta { display: block; margin-top: 2px; font-size: 12px; color: var(--ink-muted); }
.nc-kv { display: grid; grid-template-columns: minmax(120px, 38%) 1fr; gap: 4px 12px; margin: 0; }
.nc-kv dt { font-size: 12px; font-weight: 600; color: var(--ink-muted); }
.nc-kv dd { font-size: 13px; color: var(--ink); margin: 0; overflow-wrap: anywhere; }
.nc-cal { margin-top: 18px; }
.nc-cal-h { font-size: 13px; font-weight: 700; margin-bottom: 8px; }
.nc-complete { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); }
.nc-complete-h { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-muted); margin-bottom: 8px; }
.nc-complete-row { display: flex; flex-wrap: wrap; align-items: end; gap: 8px; }
.nc-complete-amt { white-space: nowrap; }
.nc-complete-lbl { display: flex; flex-direction: column; gap: 4px; font-size: 12px; font-weight: 600; color: var(--ink-muted); }
.nc-actval { max-width: 140px; }
.nc-complete-done { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.nc-done-badge { font-size: 11px; font-weight: 700; padding: 3px 10px; border-radius: var(--radius-sm); white-space: nowrap; background: transparent; color: var(--ok); border: 1px solid var(--ok); }
.nc-done-fee { font-size: 12px; color: var(--ink-muted); }

/* Dossier post-publish bridge (in the day modal). */
.dossier-next { margin-top: 12px; padding: 12px 14px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); }
.dossier-next-row { display: flex; align-items: flex-start; gap: 10px; }
.dossier-next-txt { flex: 1; min-width: 0; }
.dossier-next-h { font-weight: 700; font-size: 14px; }
.dossier-next-badge { flex: none; font-size: 12px; font-weight: 800; padding: 2px 9px; border-radius: var(--radius-sm); background: var(--surface-inset); color: var(--ink); }
.dossier-next .dossier-bar { margin: 10px 0 0; }

/* Notaires: onboarding form + console side by side (use the horizontal space). */
/* Single full-width notary console (the page's one tool) + get-paid step. */
.nota-guarantee { margin-top: var(--gap); }
/* Lead-delivery preferences — how (in-app/email/SMS) + pace + which acts. */
/* Alert preferences — settings, not the working surface: a collapsed panel
   below the money. The summary row is the whole control; a chevron flips open. */
.nc-prefs { margin: 18px 0 8px; padding: var(--space-6) var(--space-9); border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-inset); }
.nc-prefs[open] { padding-bottom: 16px; }
.nc-prefs-sum { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; cursor: pointer; list-style: none; }
.nc-prefs-sum::-webkit-details-marker { display: none; }
.nc-prefs-sum::after { content: '▾'; margin-left: auto; color: var(--ink-muted); font-size: 12px; transition: transform .14s; }
.nc-prefs[open] .nc-prefs-sum::after { transform: rotate(180deg); }
.nc-prefs-sum .nc-h { margin: 0; }
.nc-prefs-hint { font-size: 12px; color: var(--ink-muted); }
.nc-prefs > .help { margin-top: 10px; }
/* « Vos évaluations » (ADR 0021): the notary's track record inside the same
   collapsed register. Each evaluation carries the facteurs' hairline left
   rule — the client's words, quoted in quiet type under the stars. */
.nc-evals { margin-top: 10px; }
.nc-zero-count, .nc-svc-count, .chat-doc-count { color: var(--ink-muted); font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums; }
.nc-zero-count { margin: 8px 0; }
.nc-svc-count { margin: 2px 0 8px; }
.nc-evals-own { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; margin-bottom: var(--space-4); }
.nc-eval { margin-top: 10px; padding: 2px 0 2px 10px; border-left: 2px solid var(--border-strong); }
.nc-eval-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.nc-eval-stars { color: var(--brand); font-weight: 700; letter-spacing: 2px; white-space: nowrap; }
.nc-eval-svc { font-size: 13px; font-weight: 600; }
.nc-eval-date { font-size: 12px; color: var(--ink-muted); }
.nc-eval-date::first-letter { text-transform: uppercase; }
.nc-eval-comment { margin: 4px 0 0; font-size: 13px; line-height: 1.55; color: var(--ink-muted); }
.nc-prefs-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); gap: 8px 36px; margin-top: 8px; align-items: start; }
.nc-pref-block { min-width: 0; }
.nc-pref-title { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-muted); margin-bottom: 4px; }
.nc-pref-lbl { font-size: 13.5px; }
.nc-pref-pace { display: inline-flex; flex-wrap: wrap; margin: 2px 0 6px; max-width: 100%; }
.nc-pref-pace .seg-btn { font-size: 12.5px; }
/* The line is held whether or not the confirmation is on it — a note that
   appears for two seconds must not shove the preferences under it. */
.nc-prefs-saved { min-height: 1.5em; color: var(--ok); font-weight: 700; margin-top: 10px; }
.nc-pref-lenders { margin-top: 4px; }
/* The full lender roster reads better on its own row of the prefs grid. */
.nc-pref-block--wide { grid-column: 1 / -1; }

/* --- Retained-act conversation (client ↔ notaire) ------------------------ */
/* One construction for both sides: thread of bubbles (mine right, theirs
   left), then a write row. Tokens only — the theme swaps for free. */
.chat { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--border); }
.chat-thread { display: flex; flex-direction: column; gap: 6px; max-height: 260px; overflow-y: auto; }
.chat-empty { font-size: 12.5px; color: var(--ink-muted); margin: 0; }
.chat-msg { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; }
.chat-msg.is-mine { align-items: flex-end; }
.chat-bubble {
  max-width: 85%; padding: 7px 11px; font-size: 13.5px; line-height: 1.45;
  background: var(--surface-inset); color: var(--ink);
  border: 1px solid var(--border); border-radius: var(--radius-lg) var(--radius-lg) var(--radius-lg) var(--radius-xs);
  white-space: pre-wrap; overflow-wrap: anywhere;
}
.chat-msg.is-mine .chat-bubble {
  background: color-mix(in srgb, var(--brand) 12%, var(--surface));
  border-color: color-mix(in srgb, var(--brand) 35%, var(--border));
  border-radius: var(--radius-lg) var(--radius-lg) var(--radius-xs) var(--radius-lg);
}
.chat-when { font-size: 10.5px; color: var(--ink-muted); }
/* « Vu » (2026-09-04): the other side's read receipt, one quiet word under the
   last own message they have read — the same register as the time stamp. */
.chat-msg .chat-seen { display: block; font-size: 11px; color: var(--ink-muted); margin-top: 2px; }
.chat-msg.is-mine .chat-seen { text-align: right; }
.chat-row { display: flex; align-items: flex-end; gap: 8px; }
.chat-input { flex: 1 1 auto; resize: vertical; min-height: 40px; }
/* The shared composer (chatComposer): the write row, then a meta line — the
   refusal on the left, the « N / 500 » counter on the right from 400 on. */
.chat-write { display: flex; flex-direction: column; gap: 4px; }
.chat-composer .chat-input { resize: none; overflow-y: auto; max-height: 160px; }
.chat-meta { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-4); min-height: 0; }
.chat-error { margin: 0; font-size: 12.5px; color: var(--danger); }
.chat-count { margin-left: auto; font-size: 11px; color: var(--ink-muted); font-variant-numeric: tabular-nums; }
.chat-error, .chat-count { min-height: 1.5em; }
.nc-chat .nc-dossier-h, .my-offer-chat-h { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-muted); }

/* --- Withdrawal (désistement) after acceptance --------------------------- */
.nc-release { margin-top: 10px; padding-top: 8px; border-top: 1px dashed var(--border); }
.nc-release-open { font-size: 12.5px; color: var(--ink-muted); }
.nc-release-form { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.nc-release-motif { resize: vertical; min-height: 40px; }
.nc-release-actions { display: flex; align-items: center; gap: 8px; }
.nc-release-terms { margin: 0; }

/* --- La mise en relation est complète (ADR 0033) ------------------------- */
/* The contact gate, said over the working surface: a brand-tinted band
   naming the missing fields, one door into the form. Square register. */
.nc-banner {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap;
  gap: var(--space-6) var(--space-9); margin: 0 0 var(--space-7);
  padding: var(--space-6) var(--space-8);
  border: 1px solid var(--brand); border-radius: var(--radius); background: var(--brand-tint-solid);
}
.nc-banner[hidden] { display: none; }
.nc-banner-body { flex: 1 1 280px; min-width: 0; }
.nc-banner-h { font-size: 14px; font-weight: 800; letter-spacing: -0.01em; color: var(--subtitle-ink); }
.nc-banner-p { margin: var(--space-2) 0 0; font-size: 13px; color: var(--ink-muted); }
.nc-banner-list { margin: var(--space-2) 0 0; padding-left: 18px; font-size: 13px; color: var(--ink); }
.nc-banner-list li { padding: 1px 0; }
/* The identity fields (nom / étude / téléphone / adresse) sit two-up. */
.nc-profil-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr)); gap: 0 var(--space-8); }
.nc-field-err { min-height: 1.5em; color: var(--danger); }
/* « Votre client » leads the retained card: the name, the two contact links
   (the phone glyph rides the tel:), then the facts that frame the signing. */
.nc-client { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); }
.nc-client-nom { font-size: 15px; font-weight: 700; letter-spacing: -0.01em; }
.nc-client-links { display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-8); margin-top: var(--space-2); }
.nc-client-tel, .nc-client-mail {
  display: inline-flex; align-items: center; gap: 6px; min-height: 28px;
  font-size: 13px; font-weight: 600; color: var(--brand); text-decoration: none; overflow-wrap: anywhere;
}
.nc-client-tel:hover, .nc-client-mail:hover { text-decoration: underline; }
.nc-client-facts { margin-top: var(--space-3); }
/* Retained files: a compact overview, then one full-width working surface.
   auto-fit releases empty tracks when there is only one retained file. */
#notary-retained-list {
  grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr));
  grid-auto-rows: auto;
  align-items: stretch;
}
#notary-retained-list:has(> .is-expanded) { grid-template-columns: minmax(0, 1fr); }
#notary-retained-list .nc-card { min-width: 0; container-type: inline-size; }
#notary-retained-list .nc-card.is-expanded { grid-column: 1 / -1; }
#notary-retained-list .nc-card:hover { transform: none; }
.nc-retained-summary, .nc-retained-overview, .nc-retained-file { min-width: 0; }
.nc-retained-summary .nc-card-head { flex-wrap: wrap; }
.nc-retained-summary .nc-card-title { flex: 1 1 170px; overflow-wrap: anywhere; }
.nc-retained-summary .nc-client-links > * { min-width: 0; overflow-wrap: anywhere; }
.nc-retained-summary .nc-client-links svg { flex: 0 0 auto; }
.nc-retained-summary .nc-card-facts > * { max-width: 100%; white-space: normal; overflow-wrap: anywhere; }
.nc-retained-actions { margin-top: auto; padding-bottom: 0; }
.nc-retained-buttons { display: flex; flex-wrap: wrap; gap: 8px; width: 100%; }
.nc-retained-buttons > .btn { flex: 1 1 150px; }
.nc-retained-workspace {
  display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px;
  margin-top: 20px; padding-top: 20px; border-top: 1px solid var(--border);
}
.nc-retained-workspace[hidden] { display: none; }
.nc-retained-workspace > .nc-chat, .nc-retained-file > .nc-dossier { margin-top: 0; padding-top: 0; border-top: 0; min-width: 0; }
.nc-retained-workspace .chat-bubble, .nc-retained-workspace .nc-kv dd { overflow-wrap: anywhere; }
.nc-retained-workspace .chat-row { flex-wrap: wrap; }
.nc-retained-workspace .chat-input { min-width: 0; flex-basis: 180px; }
.nc-retained-workspace .nc-card-more { flex-wrap: wrap; }
.nc-retained-workspace .nc-release-open { white-space: normal; text-align: left; min-height: 44px; }
@container (min-width: 720px) {
  .nc-retained-summary { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 24px; }
  .nc-retained-summary .nc-client { margin: 0; padding: 0 0 0 24px; border-top: 0; border-left: 1px solid var(--border); }
  .nc-retained-actions { justify-content: space-between; padding-top: 20px; }
  .nc-retained-buttons { width: auto; }
  .nc-retained-buttons > .btn { flex: 0 1 auto; }
  .nc-retained-workspace { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 24px; }
  .nc-retained-file { border-left: 1px solid var(--border); padding-left: 24px; }
}
/* Unread: a filled square badge on the card head and in the heading. */
.nc-unread {
  display: inline-flex; align-items: center; gap: 4px; vertical-align: middle;
  font-size: 11px; font-weight: 800; padding: 2px 8px; white-space: nowrap;
  border-radius: var(--radius-sm); background: var(--brand); color: var(--brand-ink);
}
.nc-card-head .nc-unread { margin: 0 auto 0 var(--space-4); }
/* The console's own composer (used until the shared one ships): the counter
   under the box, the refusal under the row. */
.nc-composer { display: flex; flex-direction: column; gap: 4px; }
.nc-composer-main { flex: 1 1 auto; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.nc-composer .chat-input { resize: none; overflow-y: auto; max-height: 180px; }
.nc-chat-count { align-self: flex-end; font-size: 11px; color: var(--ink-muted); font-variant-numeric: tabular-nums; }
.nc-chat-count, .nc-chat-err { min-height: 1.5em; }
.nc-chat-err { margin: 0; font-size: 12.5px; color: var(--danger); }
/* A deep-linked card (« #notaires&acte=… ») flashes once, then rests. */
.nc-card.is-flash { animation: ncFlash 1.6s ease-out both; }
/* The client's offer band flashes the same way when the bell or a deep link lands on it. */
.my-offer-detail.is-flash { animation: ncFlash 1.6s ease-out both; }
@keyframes ncFlash {
  0% { box-shadow: 0 0 0 4px var(--focus-ring); border-color: var(--brand); }
  100% { box-shadow: none; }
}
@media (prefers-reduced-motion: reduce) { .nc-card.is-flash { animation: none; border-color: var(--brand); } }
/* The Retenir sheet: a wider dialog (it reads back a whole engagement), the
   retained card's key/value register, left-rule sections for the terms. */
.nc-retenir-dialog { max-width: 880px; max-height: calc(100dvh - 32px); }
.nc-retenir-dialog[open] { display: flex; flex-direction: column; overflow: hidden; }
.nc-retenir-dialog > .nc-retenir { overflow-y: auto; min-height: 0; overscroll-behavior: contain; }
.nc-retenir-dialog .nc-retenir > h3 { padding-right: 24px; }
.nc-retenir-act { display: flex; flex-direction: column; gap: 4px; margin-bottom: 12px; }
.nc-retenir-svc { font-size: 19px; font-weight: 700; }
.nc-retenir-date { font-size: 13px; color: var(--ink-muted); }
.nc-retenir-date::first-letter { text-transform: uppercase; }
.nc-retenir-signals { margin: 0 0 20px; }
.nc-retenir-columns { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; }
.nc-retenir-section { min-width: 0; padding: 18px 0; border-top: 1px solid var(--border); overflow-wrap: anywhere; }
.nc-retenir-section h4 { margin: 0 0 14px; font-size: 15px; font-weight: 700; color: var(--ink); }
.nc-retenir-section h5 { margin: 16px 0 8px; font-size: 13px; font-weight: 700; color: var(--ink); }
.nc-retenir-kv { grid-template-columns: minmax(100px, 35%) minmax(0, 1fr); gap: 12px; margin: 0; }
.nc-retenir-kv [hidden] { display: none; }
.nc-retenir-kv dd { line-height: 1.5; }
#nc-retenir-fee { display: block; font-size: 24px; line-height: 1.2; font-variant-numeric: tabular-nums; color: var(--ink); }
.nc-retenir-kv .nc-deplacement, .nc-retenir-kv .nc-prefixe, .nc-retenir-kv .nc-lender, .nc-retenir-kv .nc-distance {
  display: inline; padding: 0; border: 0; background: none; font-size: 13px; font-weight: 600; color: var(--ink); white-space: normal;
}
.nc-retenir-sub { color: var(--ink-muted); font-weight: 400; }
.nc-retenir-missing { margin-top: 12px; padding: 12px 14px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-inset); }
.nc-retenir-missing h5 { margin-top: 0; }
.nc-retenir-count { display: inline-block; margin-left: 8px; font-size: 12px; color: var(--ink-muted); font-variant-numeric: tabular-nums; }
.nc-retenir-checklist, .nc-retenir-factor-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px 24px; margin: 0; padding-left: 18px; font-size: 13px; line-height: 1.55; }
.nc-retenir-checklist li, .nc-retenir-factor-list li { padding-left: 2px; }
.nc-retenir-checklist li::marker { color: var(--ink-muted); }
.nc-retenir-details { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 24px; margin: 0; }
.nc-retenir-detail { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--border); font-size: 13px; line-height: 1.5; }
.nc-retenir-detail dt { color: var(--ink-muted); }
.nc-retenir-detail dd { margin: 0; font-weight: 600; }
.nc-retenir-more { margin-top: 6px; }
.nc-retenir-footer { flex: none; padding: 12px 22px; border-top: 1px solid var(--border); background: var(--surface); }
.nc-retenir-footer .btn { min-height: 44px; min-width: 0; }
.nc-retenir-error { margin: 0 0 10px; color: var(--danger); font-size: 13px; }
.nc-retenir-sec { margin: 0 0 var(--space-6); padding: 2px 0 2px 10px; border-left: 2px solid var(--border-strong); }
.nc-retenir-sec[hidden] { display: none; }
.nc-retenir-h { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-muted); margin-bottom: 4px; }
.nc-retenir .nc-retenir-p { margin: 0; font-size: 13px; line-height: 1.55; color: var(--ink-muted); }
.nc-retenir .nc-retenir-readiness, .nc-retenir .nc-retenir-appointment { margin: 10px 0 0; }
.nc-retenir .nc-retenir-contact { margin: 0; }
.nc-retenir-bareme { list-style: none; margin: 0 0 var(--space-2); padding: 0; font-size: 13px; }
.nc-bareme-row { display: flex; flex-wrap: wrap; gap: 0 4px; padding: 2px 0; }
.nc-bareme-days { font-weight: 700; font-variant-numeric: tabular-nums; }
.nc-bareme-rate { font-weight: 700; color: var(--ink); }
.nc-bareme-amt { font-weight: 800; color: var(--brand); }
.nc-bareme-free .nc-bareme-rate { color: var(--ok); }
.nc-retenir-dialog .dialog-actions .btn-primary { flex: 1 1 auto; flex-wrap: wrap; }
.nc-retenir-go-amt { white-space: nowrap; }
@media (max-width: 640px) {
  .nc-retenir-columns, .nc-retenir-checklist, .nc-retenir-factor-list, .nc-retenir-details { grid-template-columns: minmax(0, 1fr); }
  .nc-retenir-columns { gap: 0; }
  .nc-retenir-dialog > .nc-retenir { padding: 20px 16px; }
  .nc-retenir-footer { padding: 12px 16px; }
  .nc-retenir-footer .dialog-actions { gap: 8px; }
  .nc-retenir-footer .btn { padding: 10px 12px; }
}
.nc-pay { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--border); }
.nc-pay .btn { margin-top: 4px; }
/* Notary earnings roll-up: realised value, the price the CLIENT paid for the
   Nota service, and what the notary keeps — never a cut of their fees. */
.nc-earn { margin-top: 6px; }
.nc-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
.nc-stat { border: 1px solid var(--border); border-radius: var(--radius); padding: 12px 14px; background: var(--surface); }
.nc-stat-v { font-size: 22px; font-weight: 800; letter-spacing: -0.02em; color: var(--ink); }
.nc-stat-k { font-size: 12px; font-weight: 600; color: var(--ink-muted); margin-top: 3px; }
.nc-stat-net { border-color: var(--brand); }
.nc-stat-net .nc-stat-v { color: var(--brand); }
/* Kill the default <p> margins so the empty state + the money facts read as
   one quiet block, not three floating paragraphs. */
.nc-earn .help { margin: 8px 0 0; }

/* --- « Votre cote » (ADR 0028) -------------------------------------------
   The measure of the SERVICE, published whole — since ADR 0031 it decides no
   dollar: the notary keeps 100 % of their fees. The number leads at display
   size; the axes are the arithmetic under it. Square register throughout —
   no pill, no circle; every colour is a token. */
.nc-cote { margin-top: var(--space-3); }
.nc-cote-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--space-3) var(--space-8); }
.nc-cote-n {
  display: inline-flex; align-items: baseline; gap: var(--space-1);
  padding: var(--space-2) var(--space-6);
  border: 1px solid var(--brand); border-radius: var(--radius);
  background: var(--brand-tint-solid); color: var(--brand);
}
.nc-cote-v { font-size: var(--type-h2); font-weight: 800; letter-spacing: -0.03em; line-height: 1.1; }
.nc-cote-max { font-size: 14px; font-weight: 600; color: var(--ink-muted); }
.nc-cote-head .help { margin: 0; flex: 1 1 240px; }

.nc-cote-axes { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); gap: var(--space-5); margin-top: var(--space-6); }
.nc-cote-axe { border: 1px solid var(--border); border-radius: var(--radius); padding: var(--space-5) var(--space-6); background: var(--surface); }
.nc-cote-axe-h { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-4); }
.nc-cote-axe-nom { font-size: 13px; font-weight: 600; color: var(--ink); }
.nc-cote-axe-pts { font-size: 13px; font-weight: 700; color: var(--brand); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* A thin bar, not a gauge: it ranks the four axes at a glance, the figures
   below carry the truth. --radius-xs keeps it in the square register. */
.nc-cote-bar { height: 5px; margin-top: var(--space-3); border-radius: var(--radius-xs); background: var(--surface-inset); overflow: hidden; }
.nc-cote-bar-fill { display: block; height: 100%; border-radius: var(--radius-xs); background: var(--brand-bright); }
.nc-cote-detail { margin-top: var(--space-3); font-size: 12px; line-height: 1.6; color: var(--ink-muted); font-variant-numeric: tabular-nums; }
/* The separator is CSS, never a text node: the figures stay translatable
   fragment by fragment. */
.nc-cote-f + .nc-cote-f::before { content: ' · '; color: var(--border-strong); }

.nc-cote-next { margin: var(--space-6) 0 0; font-weight: 600; color: var(--ink); }
.nc-bareme { margin-top: var(--space-6); border-top: 1px solid var(--border); padding-top: var(--space-5); }
.nc-bareme-h { font-size: 12px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-muted); }
.nc-bareme-row {
  margin-top: var(--space-3); padding: var(--space-2) var(--space-5);
  border-left: 2px solid var(--border); border-radius: var(--radius-xs);
  font-size: 13px; color: var(--ink-muted); font-variant-numeric: tabular-nums;
}
.nc-bareme-row.is-current { border-left-color: var(--brand); background: var(--brand-tint-solid); color: var(--ink); font-weight: 600; }

/* The per-service record, inside « Vos évaluations ». */
.nc-svc { margin-top: var(--space-6); border-top: 1px solid var(--border); padding-top: var(--space-5); }
.nc-svc-h { font-size: 12px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-muted); }
.nc-svc-row { display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--space-3) var(--space-6); margin-top: var(--space-4); }
.nc-svc-nom { font-size: 13px; font-weight: 600; color: var(--ink); }
.nc-svc-actes { font-size: 12.5px; color: var(--ink-muted); font-variant-numeric: tabular-nums; }
.nc-svc-none { font-size: 12.5px; color: var(--ink-muted); font-style: italic; }

/* The act-by-act statement: the full disclosure, act by act. Wide content
   scrolls inside its own box — the console never scrolls sideways. */
.nc-actes { margin-top: var(--space-5); overflow-x: auto; }
.nc-actes-table { width: 100%; border-collapse: collapse; font-size: 12.5px; font-variant-numeric: tabular-nums; }
.nc-actes-table th, .nc-actes-table td { padding: var(--space-3) var(--space-5); text-align: left; border-bottom: 1px solid var(--border); white-space: nowrap; }
.nc-actes-table thead th { font-size: 11px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-muted); }
.nc-acte-num { text-align: right; }
.nc-acte-net { font-weight: 700; color: var(--brand); }
.nc-acte-total th, .nc-acte-total td { border-bottom: 0; border-top: 2px solid var(--border-strong); font-weight: 700; color: var(--ink); }
/* ADR 0029 — a line settled OFF the platform. The money never reached Nota and
   the service fee is still owed, so the net must not read as money banked: the
   figure drops out of brand ink into the quiet register the rest of the row
   speaks in. No new shape, no new colour — the same weight, one tone down. */
.nc-actes-table .nc-acte-row[data-paye='false'] .nc-acte-net { color: var(--ink-muted); }
/* The marker stacks UNDER the act's name inside a `white-space: nowrap` cell,
   so it has to opt back into wrapping and take a measure of its own — without
   one it sets the column's width and pushes the money columns off the box. */
.nc-acte-etat { white-space: normal; max-width: 30ch; }
/* « Frais de service à percevoir » is a total that has NOT been settled. It
   keeps the totals row's geometry but steps down twice — a hairline instead of
   the strong rule, muted instead of full ink — so the eye reads it as an
   appendix to the settled totals rather than a sixth column of takings. */
.nc-acte-du th, .nc-acte-du td { border-top: 1px solid var(--border); color: var(--ink-muted); }
.nc-actes .help { margin: var(--space-4) 0 0; }

/* --- Demonstration data, declared ---------------------------------------
   store.listMonth falls back to domain fixtures when the API is unreachable.
   That is legitimate; being indistinguishable from the real market is not.
   The register is deliberately NOT an alarm — --warn carries "read this",
   --danger would carry "something broke". Square, tokens only. */
.demo-banner {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-2) var(--space-5);
  margin: var(--space-5) auto 0; width: min(1200px, calc(100% - var(--space-12)));
  padding: var(--space-4) var(--space-7);
  border: 1px solid var(--border); border-left: 3px solid var(--warn);
  border-radius: var(--radius); background: var(--surface-inset);
}
.demo-banner[hidden] { display: none; }
.demo-banner-t { font-size: 12.5px; font-weight: 800; letter-spacing: 0.02em; color: var(--warn); }
.demo-banner-b { font-size: 12.5px; line-height: 1.5; color: var(--ink-muted); }

/* The per-region mark: an aggregate figure is never bare. Small, quiet, and
   right where the numbers are. */
.demo-mark {
  display: inline-block; padding: 0 var(--space-3);
  border: 1px solid var(--warn); border-radius: var(--radius-sm);
  font-size: 10.5px; font-weight: 800; letter-spacing: 0.04em;
  line-height: 16px; white-space: nowrap; vertical-align: middle;
  color: var(--warn); background: var(--surface);
}

/* Mark slots: they take no room until a mark lands in them. */
.nc-live-head:empty, .onb-live-host:empty { display: none; }
.nc-live-head, .onb-live-host { margin: 0 0 var(--space-4); }
.day-head .demo-mark { margin-left: var(--space-4); }

/* The offline "publication" note: nothing left the device. */
.demo-note {
  margin: var(--space-4) 0 0; padding: var(--space-4) var(--space-5);
  border-left: 3px solid var(--warn); border-radius: var(--radius-xs);
  background: var(--surface-inset);
  font-size: 12.5px; line-height: 1.55; color: var(--ink-muted);
}

/* --- Privacy (Law 25) list ---------------------------------------------- */
/* Two-column on wide screens so the long-form list fills the panel width
   (readable measure per item) instead of leaving a big blank right side. */
.privacy-list { list-style: none; margin: 4px 0 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(330px, 100%), 1fr)); gap: 12px 32px; align-content: start; }
.privacy-list li { position: relative; padding-left: 20px; font-size: 14px; line-height: 1.5; color: var(--ink-muted); }
.privacy-list li strong { color: var(--ink); }
.privacy-list li::before {
  content: ''; position: absolute; left: 0; top: 8px; width: 8px; height: 8px;
  border-radius: var(--radius-xs); background: var(--brand);
}
/* --- Security and compliance -------------------------------------------
   A quiet trust block: one outer surface, with no stack of nested borders or
   certification-looking badges. The wording deliberately distinguishes an
   active programme from a completed audit. */
.compliance-section {
  margin-top: var(--space-8); padding: clamp(20px, 3vw, 28px);
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--surface-inset);
}
.compliance-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 20px;
}
.compliance-head .eyebrow { display: block; margin-bottom: 6px; }
.compliance-head h2 { max-width: 680px; margin: 0; }
.compliance-head p { max-width: 760px; margin: 10px 0 0; color: var(--ink-muted); font-size: 14px; line-height: 1.55; }
.compliance-status {
  flex: none; display: inline-flex; align-items: center; min-height: 32px;
  padding: 6px 11px; border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--brand) 12%, var(--surface));
  color: var(--brand); font-size: 12px; font-weight: 800;
  white-space: nowrap;
}
.compliance-grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px; margin-top: 20px;
}
.compliance-card {
  display: flex; flex-direction: column; justify-content: center; gap: 4px;
  min-width: 0; min-height: 70px; padding: 14px 16px;
  border-radius: var(--radius); background: var(--surface);
}
.compliance-card strong { color: var(--ink); font-size: 15px; line-height: 1.25; overflow-wrap: anywhere; }
.compliance-card span { color: var(--ink-muted); font-size: 13px; line-height: 1.3; }
.compliance-note { margin: 16px 0 0; color: var(--ink-muted); font-size: 12px; line-height: 1.5; }
@media (max-width: 680px) {
  .compliance-head { display: block; }
  .compliance-status { margin-top: 14px; }
  .compliance-grid { grid-template-columns: 1fr; gap: 8px; }
  .compliance-card { min-height: 0; }
}
/* The legal panes' version line: an unreviewed draft says so, and when it changed. */
.legal-stamp { margin: var(--space-4) 0 0; font-size: 12px; font-weight: 600; letter-spacing: .01em; color: var(--ink-muted); }

/* Notary cards cascade in like agenda rows; disabled under reduced-motion */
.nc-card { animation: rowIn .2s ease both; }

@media (max-width: 480px) {
  .nc-kv { grid-template-columns: 1fr; gap: 1px 0; }
  .nc-kv dd { margin-bottom: 6px; }
}

/* Le tapis général. Il est !important, donc toute LIGNE TENUE (registre plus
   haut) doit répondre !important elle aussi — c'est le seul endroit du
   registre où c'est inévitable, et un test le vérifie. */
.hidden, [hidden] { display: none !important; }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }

.tab-pane { display: none; }
.tab-pane.is-active { display: block; animation: paneInForward var(--motion-ui) var(--ease-ui) both; }
.tab-pane.is-active > .wrap, .tab-pane.is-active > .layout { will-change: transform, opacity; }
html[data-nav-direction='back'] .tab-pane.is-active { animation-name: paneInBack; }

/* ==========================================================================
   Motion — subtle micro-interactions. All disabled under reduced-motion.
   ========================================================================== */
@keyframes paneIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes paneInForward { from { opacity: 0; transform: translateX(6px); } to { opacity: 1; transform: none; } }
@keyframes paneInBack { from { opacity: 0; transform: translateX(-6px); } to { opacity: 1; transform: none; } }
@keyframes navIndicatorIn { from { opacity: 0; transform: scaleX(.45); } to { opacity: 1; transform: scaleX(1); } }
@keyframes dialogIn { from { opacity: 0; transform: translateY(10px) scale(.97); } to { opacity: 1; transform: none; } }
@keyframes backdropIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes rowIn { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
@keyframes pop { 0% { transform: scale(.9); } 60% { transform: scale(1.04); } 100% { transform: scale(1); } }
@keyframes sheetUp { from { transform: translateY(100%); } to { transform: translateY(0); } }

dialog[open] { animation: dialogIn .2s cubic-bezier(.2, .8, .2, 1) both; }
dialog[open]::backdrop { animation: backdropIn .2s ease both; }
.bid-row { animation: rowIn .2s ease both; }
.gauge-fill { transition: width .35s cubic-bezier(.2, .8, .2, 1); }
.dossier-bar > span { transition: width .35s cubic-bezier(.2, .8, .2, 1); }
.dossier-check { transition: background .15s, border-color .15s, transform .15s; }
.dossier-check[data-on='true'] { animation: pop .2s ease; }
.btn, .nav-tab, .icon-btn, .cal-cell, .pill { transition: background .14s, border-color .14s, color .14s, transform .1s, box-shadow .14s; }
.card { transition: transform .14s, box-shadow .14s, border-color .14s; }
.card:hover { transform: translateY(-2px); border-color: var(--border-strong); box-shadow: var(--shadow); }

/* Layered entrance — the landing plays like the brand films: the headline
   cascades in with a breath of blur, the market card pops with overshoot,
   feed rows stack in, reward amounts glow once. Panes are display:none when
   inactive, so the sequence replays on each door the visitor walks through.
   Inside .intro--hero the cascade must run on .intro-main's CHILDREN (the
   eyebrow/h1/p live one level down), so the column itself stays still. */
@keyframes fadeUp { from { opacity: 0; transform: translateY(7px); } to { opacity: 1; transform: none; } }
@keyframes heroIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes cardPop { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes amtGlow { 0%, 100% { text-shadow: none; } 50% { text-shadow: 0 0 7px color-mix(in srgb, var(--brand-bright) 22%, transparent); } }
.intro > *, .intro--hero .intro-main > * { animation: heroIn .42s cubic-bezier(.2, .7, .2, 1) both; }
.intro--hero > .intro-main { animation: none; }
.intro .eyebrow { animation-delay: .04s; }
.intro h1 { animation-delay: .12s; }
.intro p { animation-delay: .24s; }
.intro .hero-cta { animation-delay: .36s; }
/* The market pulse is the films' demand card: it pops, then its rows stack. */
.intro--hero .pulse { animation: cardPop .46s cubic-bezier(.2, .9, .3, 1.12) .32s both; }
.pulse-rows > * { animation: fadeUp .32s cubic-bezier(.2, .8, .2, 1) both; }
.pulse-rows > *:nth-child(2) { animation-delay: .08s; }
.pulse-rows > *:nth-child(3) { animation-delay: .16s; }
.pulse-rows > *:nth-child(4) { animation-delay: .24s; }
/* Notaires: the live open demands stagger in like the film's feed. */
.nc-live-grid > * { animation: fadeUp .36s cubic-bezier(.2, .8, .2, 1) both; }
.nc-live-grid > *:nth-child(2) { animation-delay: .09s; }
.nc-live-grid > *:nth-child(3) { animation-delay: .18s; }
.nc-live-grid > *:nth-child(4) { animation-delay: .27s; }
/* Partenaires: the two reward cards enter in sequence; amounts stay still. */
.pr-rewards .pr-card { animation: cardPop .42s cubic-bezier(.2, .9, .3, 1.12) .3s both; }
.pr-rewards .pr-card--notaire { animation-delay: .5s; }
.pr-amount { animation: none; }
.cards .card { animation: fadeUp .42s cubic-bezier(.2, .8, .2, 1) both; }
.cards .card:nth-child(2) { animation-delay: .08s; }
.cards .card:nth-child(3) { animation-delay: .16s; }
@media (prefers-reduced-motion: reduce) {
  .tab-pane.is-active, .intro > *, .intro--hero .intro-main > *, .intro--hero .pulse,
  .pulse-rows > *, .nc-live-grid > *, .pr-rewards .pr-card, .pr-amount, .cards .card { animation: none; }
  html { scroll-behavior: auto; }
}

/* More hover micro-interactions across client surfaces */
.bid-row { transition: background-color .14s ease; }
.bid-row:hover { background: var(--surface-inset); }
.dossier-item { transition: background-color .14s ease; }
.dossier-item:hover { background: var(--surface-inset); }
.legend-item { transition: color .14s ease; }
.brand-mark img, .brand-mark-svg { transition: transform .2s cubic-bezier(.2, .8, .2, 1); }
.brand:hover .brand-mark img, .brand:hover .brand-mark-svg { transform: translateY(-1px); }

/* Subscribe card — borderless floating panel (white surface, soft shadow):
   the "Le carnet dans votre agenda" band on the Notaires page. */
.sub-card {
  background: var(--surface-veil);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: var(--pad-card-lg);
}
.sub-card-head { display: flex; align-items: center; gap: 11px; }
.sub-card-logo { flex: none; display: grid; place-items: center; }
.sub-card-logo img { display: block; }
.sub-card-kicker { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; color: var(--subtitle-ink); margin-bottom: 3px; }
.sub-card-title { font-weight: 700; font-size: 13.5px; line-height: 1.2; }
.sub-card-sub { font-size: 12px; color: var(--ink-muted); margin-top: 2px; line-height: 1.45; }
.calendar-subscription-field { display: grid; gap: 6px; margin: 10px 0; }
.calendar-subscription-field input { width: 100%; min-width: 0; }
.calendar-subscription-field .btn { justify-self: start; }
.sub-card-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.sub-card-actions .btn { flex: 1 1 auto; gap: 6px; padding-left: 10px; padding-right: 10px; }
.brand-ic { flex: none; display: block; }

/* Link subscription is a deliberate secondary action, not a native details
   disclosure. The old summary inherited browser marker/focus treatment and
   made the long URL instructions read like a broken form on narrow rails. */
.sub-link-toggle {
  appearance: none; display: flex; align-items: center; gap: 9px; width: 100%;
  margin-top: 12px; padding: 10px 0 0; border: 0; border-top: 1px solid var(--border);
  background: transparent; color: var(--ink); font: inherit; font-size: 12.5px;
  font-weight: 700; text-align: left; cursor: pointer;
}
.sub-link-toggle:disabled { cursor: not-allowed; opacity: .55; }
.sub-link-toggle:not(:disabled):hover { color: var(--brand-on-surface); }
.sub-link-toggle:focus-visible { outline: 3px solid var(--ring); outline-offset: 3px; border-radius: var(--radius-sm); }
.sub-link-toggle-main { display: inline-flex; align-items: center; gap: 7px; min-width: 0; }
.sub-link-icon { width: 16px; height: 16px; flex: none; color: var(--brand); }
.sub-link-toggle-hint { margin-left: auto; color: var(--ink-muted); font-size: 11px; font-weight: 600; white-space: nowrap; }
.sub-link-chevron { flex: none; color: var(--brand); font-size: 16px; line-height: 1; transform: translateY(-1px); transition: transform .15s ease; }
.sub-link-toggle[aria-expanded='true'] .sub-link-chevron { transform: rotate(180deg) translateY(1px); }
.sub-link-panel { margin-top: 9px; padding: 11px 12px 12px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-inset); }
.sub-link-panel[hidden] { display: none; }
.sub-link-panel-copy { display: grid; gap: 2px; }
.sub-link-panel-copy strong { font-size: 12.5px; line-height: 1.3; }
.sub-link-panel-copy span { color: var(--ink-muted); font-size: 11.5px; line-height: 1.4; }
.sub-link-panel .calendar-subscription-field { margin: 11px 0 0; }
.sub-link-panel label { color: var(--ink-muted); font-size: 11px; font-weight: 700; }
.subscription-input-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 8px; }
.subscription-input-row input { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.subscription-input-row .btn { justify-self: stretch; white-space: nowrap; }
.sub-card-footnote { margin: 12px 0 0; padding-top: 10px; border-top: 1px solid var(--border); }

@media (max-width: 520px) {
  .sub-card-actions { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .sub-card-actions .btn { min-width: 0; }
}
@media (max-width: 400px) {
  .subscription-input-row { grid-template-columns: 1fr; }
  .subscription-input-row .btn { width: 100%; }
  .sub-link-toggle-hint { display: none; }
}
/* Sits under the footer tagline now (no auto margin — the grid places it). */
.footer-contact { display: flex; align-items: center; gap: 2px; margin-top: 8px; }
.footer-contact .mini-btn { border: 0; }
.nc-card-actions .mini-btn { margin-left: auto; }
/* Compact card everywhere: on the signed-out landing the grid places it in
   the right column under the gate; signed-in it keeps this small step down. */
.notary-carnet { margin-top: 12px; }
/* Borderless notification bell in the header. */

/* Calendar loading: an indeterminate top bar while the carnet fetches (real
   latency on the live API). Scoped to the carnet panel; overlay only. */
#carnet-panel { position: relative; }
#carnet-panel.is-loading { pointer-events: none; }
#carnet-panel.is-loading::after {
  content: ''; position: absolute; top: 0; left: -40%; height: 2px; width: 40%;
  background: var(--brand-bright); border-radius: var(--radius-xs);
  box-shadow: 0 0 8px var(--brand-bright);
  animation: loadbar 1.05s ease-in-out infinite;
}
#carnet-panel.is-loading #cal-grid, #carnet-panel.is-loading #agenda { opacity: .55; transition: opacity .2s; }
@keyframes loadbar { 0% { left: -40%; } 55% { left: 62%; } 100% { left: 100%; } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; scroll-behavior: auto !important; }
}

/* ==========================================================================
   Responsive — mobile / tablet / desktop, no horizontal overflow anywhere.
   ========================================================================== */
@media (max-width: 900px) {
  /* 14 top / 4 bottom inverted the desktop asymmetry and let the market copy
     nearly touch the calendar card. */
  .intro { padding-block: var(--space-7); }
}
/* THE HERO'S TWO-COLUMN THRESHOLD, and everything that follows from it.
   Below this the market panel cannot sit beside the copy, so it stacks under
   it. 768px is where two columns still leave the pulse ~340px: enough for the
   act name, its two fr-CA amounts ("1 250 $ · 1 950 $") AND the volume bar on
   one row. At 720–767 a column is ~300px, and the amounts painted over the
   bar and each other — prices must never jam, so the hero stacks instead.

   Below it the pitch is trimmed: the eyebrow goes (the h1, the tagline and
   the two CTAs still say what this is) and the market panel keeps its
   FIGURES and drops its counts caption, so the carnet lands near the fold. */
/* 768–900 — the copy still holds two columns; the market strip beside it does
   not. The threshold below was measured in English: in French a half-column at
   768 leaves the strip ~330px, and « repère du mois » over « 2 279 $ » ran 19px
   under the book arrow while the kicker painted over the month. So the strip
   takes the WHOLE width under the copy from 900 down, which is what the rules
   two blocks up have claimed since they were written. Everything else stays
   desktop here — the eyebrow, the gauges, the counts caption; the phone's
   two-card strip still starts below 768. */
@media (min-width: 768px) and (max-width: 899.98px) {
  .intro--hero { grid-template-columns: 1fr; gap: clamp(18px, 3vw, 26px); }
}
@media (max-width: 767.98px) {
  .intro--hero { grid-template-columns: 1fr; gap: clamp(18px, 3vw, 26px); }
  /* The tagline (and the notary lede) IS the phone copy; only the eyebrow goes. */
  .intro .eyebrow { display: none; }
  .pr-hero .eyebrow { display: none; }
  /* Side by side rather than stacked. */
  .hero-cta { flex-direction: row; }
  /* flex:1 alone still refuses to go under min-content, so two btn-lg wrapped
     to two rows and the pair cost 114px instead of 44px. */
  .hero-cta .btn { flex: 1 1 0; min-width: 0; }
  /* THE PHONE MARKET STRIP (owner, 2026-08-27: « pour la version mobile,
     financing et refinancing, on peut utiliser un autre UI — le but c'est de
     focusser sur les availabilities et le calendrier »). The stacked rows
     cost ~300px of the first screen and pushed the calendar under the fold;
     the two acts now sit SIDE BY SIDE as a pair of compact cards — the act's
     name over its two captioned figures. The volume bar and the counts
     caption stay desktop-only (market colour, not a booking decision), and
     the per-row book arrow goes: the hero CTA right above already books.
     Same DOM as the desktop rows — a card still filters the carnet below,
     and the active act keeps .is-on, indicated by its underlined name. */
  .pulse-rows { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); }
  /* The item wrapper dissolves so each ROW is the grid child; its book arrow
     is display:none, so nothing else surfaces from the wrapper. */
  .pulse-item { display: contents; }
  .pulse-item .mini-btn { display: none; }
  /* Compact filters retain their own spacing on phones. */
  .pulse-item .pulse-row { padding: 10px 12px; margin: 0; }
  .pulse-row {
    display: flex; flex-direction: column; align-items: stretch; gap: 7px;
  }
  .pulse-svc { font-size: clamp(12px, 3.5vw, 13.5px); }
  /* The captions STAY: two bare amounts stacked read as one confusing price.
     Each figure takes a full line of its card — caption left, amount right. */
  .pulse-figs { flex-direction: column; align-items: stretch; gap: 3px; }
  /* « repère du mois » + a five-figure amount do not fit one 115px line at
     320px: let the amount drop under its caption instead of past the card. */
  .pulse-fig { flex-direction: row; flex-wrap: nowrap; justify-content: space-between; align-items: baseline; gap: 8px; min-width: 0; }
  .pulse-fig-k { font-size: 10.5px; }
  .pulse-fig-v { font-size: 14px; }
  .pulse-bar, .pulse-meta { display: none; }
  /* The floating « Comment ça marche » bubble goes on phones (owner,
     2026-08-27: « remove this ») — it sat over the calendar tiles on the
     very screen the phone now centres on. The guide keeps its phone doors:
     the first-visit onboarding and the footer link. Desktop keeps the
     bubble, one tap from anywhere. */
  .guide-fab { display: none; }
}

/* At phone widths, give the offering strip one calm reading column. Two
   narrow cards force both the service name and the caption/value pair onto
   extra lines (especially « Power of attorney » and « month’s reference »).
   One wider card keeps each fact on one line and lets the four acts scan as a
   consistent list without clipping or ellipses. */
@media (max-width: 480px) {
  .pulse-head {
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
  }

  .pulse-rows { grid-template-columns: minmax(0, 1fr); }
  .pulse-fig { flex-wrap: nowrap; }
  .pulse-head { display: flex; }
  .pulse-svc { white-space: nowrap; }
}
/* The DRAWER threshold is 900: above it the header carries the full control
   set (compact band 900–1099.98); below it everything hands off to the
   hamburger — the narrow header is brand → avatar → burger. Theme and language
   keep their drawer rows (#mnav-theme / #mnav-lang), so hiding them here
   loses nothing; the guide « ? » is the fixed bubble on desktop and the
   footer link / first-visit guide on phones (see ux-nav.test.mjs). */
@media (max-width: 899.98px) {
  .nav-burger { display: grid; }
  .nav-tabs, .header-auth, #theme-toggle { display: none; }
  #lang-toggle { display: none; }
  /* Both controls moved to the drawer: an empty strip is not a control. */
  .header-tools { display: none; }
}

/* ==========================================================================
   Quiet arrival refinement
   The first decision should feel like a calm welcome: the mark carries the
   identity, the two paths remain obvious, and the surrounding motion stays
   peripheral. Language detection remains active in i18n.js; only its chrome
   is removed from the visual layout.
   ========================================================================== */
@keyframes igChooserReveal {
  from { opacity: 0; transform: translateY(12px) scale(.985); }
  to { opacity: 1; transform: none; }
}
@keyframes igLogoReveal {
  from { opacity: 0; transform: translateY(8px) scale(.96); }
  to { opacity: 1; transform: none; }
}
.ig:not(.ig-out) .ig-chooser { animation: igChooserReveal .62s cubic-bezier(.2, .75, .2, 1) both; }
.ig:not(.ig-out) .ig-chooser > .ig-wordmark { animation: igLogoReveal .7s cubic-bezier(.2, .75, .2, 1) .06s both; }
.ig:not(.ig-out) .ig-chooser > .ig-title { animation: fadeUp .42s ease .12s both; }
.ig:not(.ig-out) .ig-chooser > .ig-lede { animation: fadeUp .42s ease .18s both; }
.ig:not(.ig-out) .ig-chooser > .ig-doors { animation: fadeUp .42s ease .24s both; }
.ig:not(.ig-out) .ig-chooser > .ig-enter { animation: fadeUp .42s ease .3s both; }

.ig-chooser {
  background: var(--surface-veil);
  box-shadow: var(--shadow), 0 18px 48px -28px rgb(var(--nota-blue-700-rgb) / .28);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
}
.ig-enter {
  color: var(--brand);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding-inline: 16px;
  transition: border-color .18s ease, background-color .18s ease, transform .18s ease;
}
.ig-enter:hover { color: var(--brand-on-surface); border-color: var(--border-strong); background: var(--surface-inset); transform: translateY(-1px); }

/* Keep the language API, URL override and keyboard coverage intact while the
   product presents one quiet browser-selected language by default. */
.language-control { opacity: 0 !important; pointer-events: auto !important; }
#lang-toggle.language-control {
  position: relative !important;
  top: auto; right: auto; width: 1px; height: 1px;
  margin: 0; padding: 0; overflow: visible; border: 0;
  z-index: 1;
}
.ig-chooser > .language-control { width: 1px; height: 1px; overflow: visible; }
.ig-controls > .language-control {
  position: absolute !important; inset: 0 auto auto 0;
  width: 1px; height: 1px; margin: 0; padding: 0; overflow: visible;
}
.mnav-pref.language-control {
  min-height: 1px; height: 1px; margin-block: -1px !important; overflow: visible;
}

@media (min-width: 1080px) {
  .ig-chooser > .ig-wordmark,
  .ig-chooser > .ig-title,
  .ig-chooser > .ig-lede,
  .ig-chooser > .ig-doors,
  .ig-chooser > .ig-enter { grid-area: auto; }
  .ig-doors { flex-direction: row; gap: 14px; }
  .ig-enter { justify-self: auto; }
}

/* Consent is still explicit, but reads as a small preference notice instead
   of a dominant bottom panel. */
.analytics-consent {
  left: 50%; right: auto; bottom: 16px;
  width: min(560px, calc(100vw - 32px)); max-width: none;
  padding: 12px 14px;
  transform: translateX(-50%);
  background: var(--surface);
  border-color: var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.analytics-consent p { margin-bottom: 8px; font-size: 12px; line-height: 1.45; }
.analytics-consent button, #analytics-preferences:not(.footer-link) { padding: 7px 10px; margin-right: 4px; font-size: 12px; }
.analytics-consent a { font-size: 12px; }

/* The transient toast follows the same low-contrast language as the consent
   notice and never competes with a form or a confirmation action. */
.toast {
  bottom: 18px;
  padding: 10px 14px;
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
  font-size: 13px;
}

/* Intro gate feedback pass: let the Nota field participate in the chooser,
   make the full N + OTA lockup unmistakable, and give the two decisions a
   confident bit of motion without moving the page around. */
.ig-chooser {
  background: linear-gradient(145deg,
    color-mix(in srgb, var(--surface) 64%, transparent),
    color-mix(in srgb, var(--surface) 78%, transparent));
  border-color: color-mix(in srgb, var(--border-strong) 72%, transparent);
  box-shadow: var(--shadow), 0 22px 56px -30px rgb(var(--nota-blue-700-rgb) / .36);
  -webkit-backdrop-filter: blur(18px) saturate(1.08);
  backdrop-filter: blur(18px) saturate(1.08);
}
.mark-drift--intro { opacity: .86; }
.mark-drift--intro i { opacity: calc(var(--o, .025) * 1.18); }

/* --- Nota signature identity -------------------------------------------
   The signature beta is Nota's clearest brand moment: calm institutional
   blue, an editorial display face, and one precise piece of interface art.
   Keep the atmosphere on the page and the surfaces solid so the mark remains
   legible when the language or theme changes. */
#pane-beta {
  --beta-ink: var(--nota-blue-900);
  --beta-shadow: 0 26px 64px -34px rgb(var(--nota-blue-700-rgb) / .56);
  position: relative;
  isolation: isolate;
  overflow: clip;
  background:
    radial-gradient(42% 32% at 76% 18%, rgb(var(--nota-blue-400-rgb) / .1), transparent 72%),
    linear-gradient(180deg, rgb(var(--nota-blue-400-rgb) / .045), transparent 440px);
}

#pane-beta .beta-page { position: relative; }

#pane-beta .beta-page {
  max-width: 1884px;
  padding-top: clamp(64px, 6.2vw, 128px);
}

#pane-beta .beta-intro {
  position: relative;
  padding-top: clamp(32px, 4.8vw, 88px);
}

/* No accent rule beside the headline: this was the only door of the four
   that opened with a decoration, and it carried the title 13px off the line
   the other three start on. */

#pane-beta .beta-intro h1 {
  color: var(--beta-ink);
}

#pane-beta .beta-eyebrow {
  color: var(--subtitle-ink);
}

#pane-beta .beta-dot {
  box-shadow: 0 0 0 4px rgb(var(--nota-blue-400-rgb) / .12);
}

#pane-beta .beta-preview {
  width: min(100%, 760px);
  border-color: color-mix(in srgb, var(--brand) 24%, var(--border));
  box-shadow: var(--beta-shadow);
  transform: translateY(-2px);
}

#pane-beta .beta-preview-scene {
  min-height: clamp(290px, 22vw, 370px);
}

#pane-beta .beta-preview-top > span:first-child {
  color: var(--beta-ink);
  font-family: var(--font-display);
  font-weight: 800;
  letter-spacing: -.055em;
}

#pane-beta .beta-preview-tag {
  color: var(--brand);
  border-color: color-mix(in srgb, var(--brand) 30%, var(--border));
  font-weight: 700;
}

#pane-beta .beta-preview-person {
  border-color: color-mix(in srgb, var(--brand) 26%, var(--border-strong));
}

#pane-beta .beta-preview-paper {
  border-color: color-mix(in srgb, var(--brand) 34%, var(--border-strong));
  box-shadow: 10px 16px 28px -18px rgb(var(--nota-blue-700-rgb) / .7);
}

#pane-beta .beta-preview-steps {
  color: var(--beta-ink);
}

#pane-beta .beta-preview-steps li:not(:last-child)::after {
  border-color: var(--brand-bright);
}

#pane-beta .beta-boundary {
  background: color-mix(in srgb, var(--surface) 94%, var(--brand));
  box-shadow: 0 12px 28px -24px rgb(var(--nota-blue-700-rgb) / .75);
}

#pane-beta .beta-section-heading h2,
#pane-beta .beta-access-grid h2 {
  color: var(--beta-ink);
}

@media (max-width: 820px) {
  #pane-beta .beta-page {
    padding-top: 38px;
    padding-bottom: 44px;
  }
    #pane-beta .beta-intro { padding-top: 0; }
    #pane-beta .beta-preview { transform: none; }
}

/* --- Signature beta: editorial visual pass ------------------------------
   The beta is the one public pane that sells a new experience. Keep its
   content model and copy stable, but give the story a distinct stage: an
   atmospheric canvas, a confident headline, and a preview that feels like a
   real product surface instead of two adjacent boxes. */
#pane-beta {
  position: relative;
  isolation: isolate;
  overflow: clip;
}

#pane-beta::before {
  content: '';
  position: absolute;
  z-index: -1;
  top: -180px;
  right: -8%;
  width: 72%;
  height: 720px;
  pointer-events: none;
  background: radial-gradient(ellipse at 50% 42%, rgb(var(--nota-blue-400-rgb) / .13), transparent 68%);
}

#pane-beta .beta-page {
  max-width: 1600px;
  padding-top: clamp(48px, 5.5vw, 88px);
  padding-bottom: clamp(56px, 6vw, 96px);
}

#pane-beta .beta-hero {
  grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr);
  gap: clamp(48px, 6vw, 96px);
  align-items: start;
}

#pane-beta .beta-intro {
  padding-top: clamp(32px, 4.8vw, 72px);
}

#pane-beta .beta-eyebrow {
  color: var(--subtitle-ink);
}

#pane-beta .beta-intro h1 {
  max-width: 12ch;
  margin-bottom: 22px;
}

#pane-beta .beta-actions {
  gap: 16px;
  margin-top: 30px;
}

#pane-beta .beta-actions .btn-primary {
  padding-inline: 18px;
  box-shadow: 0 9px 20px -12px rgb(var(--nota-blue-700-rgb) / .8);
}

#pane-beta #beta-preview::after {
  content: '↗';
  margin-left: 4px;
  font-size: 15px;
  line-height: 1;
}

#pane-beta .beta-caption {
  max-width: 44ch;
  margin-top: 18px;
  font-size: 12.5px;
}

#pane-beta .beta-preview {
  position: relative;
  width: min(100%, 640px);
  padding: clamp(26px, 3vw, 36px);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: 0 24px 60px -28px rgb(var(--nota-blue-700-rgb) / .5);
  overflow: hidden;
}

#pane-beta .beta-preview::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 44%;
  height: 4px;
  background: linear-gradient(90deg, var(--brand), var(--brand-bright));
}

#pane-beta .beta-preview::after {
  content: '';
  position: absolute;
  top: -90px;
  right: -90px;
  width: 230px;
  height: 230px;
  border: 1px solid var(--border);
  border-radius: 50%;
  box-shadow: 0 0 0 22px rgb(var(--nota-blue-400-rgb) / .035), 0 0 0 44px rgb(var(--nota-blue-400-rgb) / .022);
  pointer-events: none;
}

#pane-beta .beta-preview-top {
  position: relative;
  z-index: 1;
  font-size: 16px;
  letter-spacing: -.02em;
}

#pane-beta .beta-preview-tag {
  padding: 7px 10px;
  font-size: 11px;
  background: var(--surface-inset);
}

#pane-beta .beta-preview-scene {
  position: relative;
  z-index: 1;
  gap: clamp(18px, 2.6vw, 28px);
  margin: 30px 0 26px;
  min-height: clamp(250px, 19vw, 300px);
}

#pane-beta .beta-preview-person {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius);
  background: linear-gradient(145deg, var(--surface-inset), color-mix(in srgb, var(--brand) 7%, var(--surface-inset)));
  box-shadow: inset 0 1px 0 var(--sheen);
}

#pane-beta .beta-preview-person::before {
  content: '';
  position: absolute;
  inset: 0;
  opacity: .55;
  background: linear-gradient(rgb(var(--nota-blue-400-rgb) / .1) 1px, transparent 1px), linear-gradient(90deg, rgb(var(--nota-blue-400-rgb) / .1) 1px, transparent 1px);
  background-size: 32px 32px;
  mask-image: linear-gradient(to bottom, transparent, black 22%, black 78%, transparent);
}

#pane-beta .beta-preview-person::after {
  content: '';
  position: absolute;
  width: 46%;
  aspect-ratio: 1;
  top: 13%;
  left: 20%;
  border-radius: 50%;
  background: rgb(var(--nota-blue-400-rgb) / .13);
  filter: blur(22px);
}

#pane-beta .beta-preview-person svg {
  position: relative;
  z-index: 1;
  width: 68%;
  stroke: var(--nota-blue-400);
}

#pane-beta .beta-preview-paper {
  position: relative;
  z-index: 1;
  border-radius: var(--radius-sm);
  padding: 25px 20px;
  transform: rotate(3deg) translateY(2px);
  box-shadow: 8px 12px 22px -15px rgb(var(--nota-blue-700-rgb) / .65);
}

#pane-beta .beta-preview-paper::before {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  width: 34px;
  height: 34px;
  background: linear-gradient(135deg, transparent 49%, var(--surface-inset) 50%);
  opacity: .8;
}

#pane-beta .beta-preview-paper i {
  height: 5px;
  margin: 12px 0;
  border-radius: var(--radius-xs);
}

#pane-beta .beta-preview-paper svg {
  position: relative;
  z-index: 1;
  margin-top: 22px;
  stroke-width: 1.9;
}

#pane-beta .beta-preview-steps {
  position: relative;
  z-index: 1;
  padding-top: 18px;
  font-size: 12px;
  letter-spacing: .01em;
}

#pane-beta .beta-boundary {
  grid-template-columns: minmax(220px, 270px) 1fr;
  gap: clamp(24px, 4vw, 56px);
  margin-top: clamp(42px, 5vw, 68px);
  padding: 23px 28px;
  border-left-width: 4px;
  border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
  background: color-mix(in srgb, var(--surface) 96%, var(--brand));
}

#pane-beta .beta-boundary strong {
  color: var(--ink);
  font-size: 14px;
  line-height: 1.4;
}

#pane-beta .beta-boundary p {
  max-width: 92ch;
  font-size: 13px;
}

#pane-beta .beta-experience {
  margin-top: clamp(48px, 6vw, 84px);
}

#pane-beta .beta-section-heading {
  display: grid;
  grid-template-columns: minmax(180px, 220px) 1fr;
  gap: 24px;
  align-items: baseline;
  padding-bottom: 17px;
  border-bottom: 1px solid var(--border);
}

#pane-beta .beta-section-heading .beta-eyebrow {
  margin: 0;
}

#pane-beta .beta-section-heading h2 {
  margin: 0;
}

#pane-beta .beta-features {
  gap: 18px;
  margin-top: 20px;
}

#pane-beta .beta-features li {
  position: relative;
  padding: 23px 24px 25px;
  border-top-width: 4px;
  border-radius: 0 0 var(--radius) var(--radius);
  transition: transform .18s ease, border-color .18s ease, box-shadow .18s ease;
}

#pane-beta .beta-features li:hover,
#pane-beta .beta-features li:focus-within {
  transform: translateY(-4px);
  border-color: var(--border-strong);
  border-top-color: var(--brand);
  box-shadow: var(--shadow);
}

#pane-beta .beta-features h3 {
  margin-top: 13px;
}

#pane-beta .beta-features p {
  font-size: 13.5px;
  line-height: 1.65;
}

#pane-beta .beta-access-grid {
  gap: 18px;
  margin-top: clamp(40px, 5vw, 64px);
}

#pane-beta .beta-access,
#pane-beta .beta-upcoming {
  padding: clamp(24px, 3vw, 34px);
  border-radius: var(--radius);
}

@media (max-width: 980px) {
  #pane-beta .beta-hero {
    gap: 40px;
  }

  #pane-beta .beta-preview {
    width: 100%;
  }

  #pane-beta .beta-intro h1 {
    max-width: 14ch;
  }
}

@media (max-width: 820px) {
  #pane-beta .beta-page {
    padding-top: 38px;
  }

  #pane-beta .beta-hero {
    grid-template-columns: 1fr;
    gap: 34px;
  }

  #pane-beta .beta-intro {
    padding-top: 0;
  }

  #pane-beta .beta-intro h1 {
    max-width: 14ch;
    font-size: var(--type-h1-compact);
  }

  #pane-beta .beta-preview {
    justify-self: start;
    max-width: 640px;
  }

  #pane-beta .beta-section-heading {
    grid-template-columns: 1fr;
    gap: 8px;
  }

  #pane-beta .beta-boundary {
    grid-template-columns: 1fr;
    gap: 9px;
  }

  /* One column: the preview is a small portrait beside the paper, not a tile
     stretched to the paper's height, and the cards keep their text close to
     their edges — no strip the eye reads as blank (layout lens, 320/390). */
  #pane-beta .beta-preview-scene { min-height: 0; align-items: start; gap: 14px; margin: 16px 0 8px; }
  #pane-beta .beta-preview-person { aspect-ratio: 4 / 5; align-self: start; }
  #pane-beta .beta-preview-paper { padding: 18px 14px 14px; }
  #pane-beta .beta-preview-paper svg { margin-top: 14px; }
  #pane-beta .beta-preview-steps { padding-top: 10px; }
  #pane-beta .beta-features li { padding: 18px 18px 18px; }
  #pane-beta .beta-features h3 { margin-top: 4px; }
}

@media (prefers-reduced-motion: reduce) {
  #pane-beta .beta-features li { transition: none; }
}
/* Above the drawer threshold the drawer can never appear, open class or not. */
@media (min-width: 900px) {
  .mnav, .mnav-scrim { display: none; }
}

@media (max-width: 680px) {
  /* THE LEGEND WAS ONE CRAMMED PARAGRAPH. Everything lived in a single
     wrapping flex row, so "SERVICE" landed mid-line right after "Extreme 8x"
     with a vertical rule in front of it, reading as one run-on block. Each
     label now takes its own line and its keys wrap underneath it, and the rows
     get room to breathe. */
  .legend { gap: var(--space-4) var(--space-5); }
  .legend-label { flex: 1 0 100%; margin-top: var(--space-2); }
  /* The rule and the indent only make sense inline, which it no longer is. */
  .legend-label--sep { margin-left: 0; padding-left: 0; border-left: 0; }
  /* Four lines restating what the cell already prints, on the screen with the
     least room for it. */
  .legend-note { display: none; }

  /* Longhand: a shorthand would reset .layout's vertical padding to 0 and the
     carnet would butt against the hero and against the footer. */
  .wrap { padding-inline: var(--space-8); }
  .site-header .wrap { gap: 8px; } /* height follows --header-h below */
  /* The header shrinks here, so the scroll offset it feeds must shrink with it,
     or a scrolled-to cell lands under the header instead of below the gap. */
  :root { --header-h: 48px; --sticky-top: 68px; }
  .brand-sub { display: none; }
  .brand { font-size: 17px; }
  .nav-tab { padding: 6px 9px; font-size: 13px; }
  .intro h1, .pr-hero h1 { font-size: var(--type-h1-compact); }
  /* No padding here. The cal container queries own cell padding, and a
     viewport rule this late in the file silently outranks all of them. */
  /* No min-height: @container cal owns cell sizing, and a viewport rule this
     far down the file outranks it at equal specificity. */
  /* .cal-avg deliberately has NO font-size here. The container query compacts it
     by zeroing the font and reprinting attr(data-compact) from ::after; a
     viewport rule that restores a visible size cannot remove the ::after, so the
     two used to print together as "3 285 $3,3k". Sizing belongs to the container
     queries, which is what this cell's content responds to anyway. */
    /* Sides stay at 14 so the grid lines up with the toolbar, filter bar and
     legend that bracket it inside the same card. */
  /* Padding only. gap:4px here outranked the 3-column reflow's own gap, so
     the phone grid packed 2px tighter than the token chose. */
  .cal-grid { padding: var(--space-4) var(--space-7) var(--space-6); }

  .cal-row { gap: 4px; }
  .cal-dow { font-size: 10px; }
  .filters { padding: 10px 14px; gap: 8px; }
  .field { flex: 1 1 40%; }
  /* :not(.visually-hidden): this attribute selector outranks the class, and a
     full-width HIDDEN date input was silently widening the booking sheet's
     scroll box by 16px on phones. */
  select:not(.visually-hidden), input[type='text'], input[type='email'], input[type='tel'], input[type='number'], input[type='date']:not(.visually-hidden) { min-width: 0; width: 100%; }
  /* Phone: the lender dropdown stretches with its sheet like every other field. */
  .crit-row .nselect { max-width: none; }
  .cards { grid-template-columns: 1fr; }
  .section { padding: 28px 0; }
  #day-dialog, dialog { width: 96vw; }
  /* The day-booking dialog becomes a bottom sheet on phones (thumb-reachable,
     slides up). Ordered after the 96vw rule so width:100% wins. */
  #day-dialog { margin: 0; inset: auto 0 0 0; width: 100%; max-width: 100%; max-height: 92dvh; border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
  #day-dialog[open] { animation: sheetUp .28s cubic-bezier(.2, .8, .2, 1) both; }
  .day-head { padding: 16px 60px 10px 16px; }
  /* The offer rows shrink with the bands that bracket them; the 2px difference
     compensates .bid-row's own left border. */
  .day-bids .bid-row { padding-left: 14px; padding-right: var(--space-8); }
  .day-bids-count { padding-left: var(--space-8); padding-right: var(--space-8); }
  .day-book { padding: 14px 16px 18px; }
  /* The day dialog becomes a full-width sheet on phones, so its rows are as tight
     as the list cards — give them the same two-line treatment. */
  .day-bids .bid-row { flex-wrap: wrap; row-gap: 3px; }
  .day-bids .bid-amount { order: 1; }
  .day-bids .pill, .day-bids .status-chip { order: 2; }
  .day-bids .bid-meta { order: 4; flex: 1 0 100%; }
  .day-bids .status-chip { max-width: none; }
  /* Explainer stacks the badge over the text on narrow screens. */
  .hero-cta { gap: 8px; }
  .hero-cta .btn-lg { flex: 1 1 auto; }
  /* (Auth buttons left the narrow header entirely — they live in the
     hamburger drawer below 900px.) */
}
/* (The theme toggle leaves the header with the tabs at 899.98px — it lives in
   the hamburger drawer on phones, so it stays reachable at every width.) */
/* Smallest phones (320-360): the header wordmark yields to the logo mark, which
   stays the home affordance. Scoped to the header — the footer reuses
   .brand-word and has room for it. */
@media (max-width: 360px) {
  .site-header .brand-word { display: none; }
}
/* Comfortable touch targets on phones (>=44px), gated to coarse pointers so the
   desktop density is untouched. */
/* Comfortable 44px touch targets on ANY coarse pointer (phones AND tablets, e.g.
   iPad portrait at 768) — not width-gated. Fine pointers (mouse/trackpad) keep the
   desktop density untouched. Includes the smaller controls that were being missed. */
@media (pointer: coarse) {
  .btn, .nav-tab, .chip, .seg-btn, .acct-item, .acct-legal-link, input[type='range'], .nselect-btn { min-height: 44px; }
  /* Le sélecteur FR|EN et l'interrupteur de thème (.mini-seg-btn) manquaient à
     l'appel (2026-09-06) : sur téléphone l'en-tête les range dans le tiroir, et
     ils y tenaient 35 × 24 px — sous la cible tactile, pour le seul geste qui
     change la langue de tout le site. La piste garde sa hauteur d'origine à la
     souris ; au doigt, les deux boutons montent à 44. */
  .mini-seg-btn { min-height: 44px; }
  /* Et la piste suit : à 28 px de haut elle laissait ses propres boutons
     dépasser de 8 px en haut et en bas. 44 + les deux marges de 2. */
  .mini-seg { height: 48px; }
  .nselect-opt { min-height: 44px; display: flex; align-items: center; }
  /* Repeated at .header-auth .btn specificity: the ≤680px header rule sets a
     32px floor on the SAME selector, and on a phone (coarse + narrow) it was
     out-ranking the plain .btn floor above — leaving the only sign-up button
     under the 44px touch target. */
  .header-auth .btn { min-height: 44px; }
  /* Clickable notification rows and their dismiss ✕ join the 44px floor; the
     row's right padding grows so text never slides under the bigger target. */
  .notif-item[role='button'] { min-height: 44px; }
  .notif-item { padding-right: 48px; }
  .notif-x { width: 44px; height: 44px; top: 2px; right: 0; }
  /* Footer links and the brand are plain <a>s (~20px tall) — they need the same
     thumb-sized hit area as the buttons above. inline-flex so the gap-based
     footer row keeps its alignment. */
  .site-footer a, .brand { min-height: 44px; display: inline-flex; align-items: center; }
  /* « Comment ça marche » is a BUTTON among those links (it opens the guide
     dialog), so the rule above never reached it — and on a phone, where the
     « ? » bubble is deliberately absent (ADR 0022), the footer is the only
     door left to the guide. It was 26px tall. */
  .site-footer .footer-link { min-height: 44px; display: inline-flex; align-items: center; }
  /* A text field is a touch target like any other: the pane's own inputs came
     out 42px from their padding alone, two short of the promise. */
  input[type='text'], input[type='email'], input[type='tel'], input[type='number'],
  input[type='search'], input[type='password'], input[type='date'], textarea { min-height: 44px; }
  .mini-btn { width: 44px; height: 44px; }
  .cal-nav .btn { min-width: 44px; }
  /* flex:none — in the drawer head the lockup grew and squeezed the close
     button to 32px wide (android lens, 2026-09-11); a thumb target does not shrink. */
  .icon-btn { width: 44px; height: 44px; flex: none; }
  /* « Offrir autant · N $ » is a 26px text button on the booking sheet; it only
     appears when the day already has an offer, which is why the lens caught it
     in CI and not locally. A thumb target is 44px whatever the data. */
  .day-beat { min-height: 44px; }
}
@media (max-width: 420px) {
  .nav-tabs { gap: 0; }
  .nav-tab { padding: 6px 7px; font-size: 12px; }
  /* .cal-cell and .cal-daynum are sized by @container cal, not from here. */
}

/* Never let the page scroll sideways */
html { max-width: 100%; overflow-x: hidden; overflow-x: clip; }
body { max-width: 100%; overflow-x: hidden; overflow-x: clip; }
/* Smooth scrolling centralized in CSS (so the reduced-motion reset above wins),
   and every anchored/focus/programmatic scroll stops BELOW the sticky header. */
html { scroll-behavior: smooth; scroll-padding-top: var(--sticky-top); }

/* ==========================================================================
   Carnet view switcher (Calendrier · Liste)
   ========================================================================== */
.view-panel { min-width: 0; }
.view-panel[hidden] { display: none; }


/* ==========================================================================
   Phone compaction — calendar toolbar and filter bar (≤680px).
   Last in the file on purpose: these reflow rules must outrank the component
   defaults above at equal specificity.
   ========================================================================== */
@media (max-width: 680px) {
  /* THE TOOLBAR WAS A TOWER. Every control wrapped to its own line — nav row,
     title row, dispo pill row, count row, Filtres row — ~230px of chrome
     before the first date. Three tight rows instead: [nav … Filtres],
     [title], [dispo … count]. */
  .cal-toolbar { padding: var(--space-5) var(--space-7) var(--space-3); row-gap: var(--space-3); }
  /* The spacer goes back to being a spacer (the 680px rule above turns it
     into a row break; here the break comes from the title's own 100% basis). */
  .cal-toolbar .header-spacer { flex: 1 1 auto; height: auto; order: 2; }
  .cal-nav { order: 1; }
  #filters-toggle { order: 3; }
  .cal-title { order: 4; flex: 1 0 100%; font-size: 14px; }
  .cal-avail { order: 5; padding-block: 2px; }
  .result-count { order: 6; margin-left: auto; }

  /* THE FILTER BAR SPRAWLED OVER SIX RAGGED ROWS. Two single-line rows now:
     the act chips, then statut + montant + tri together — each row scrolls
     sideways instead of wrapping, bled to the card edge so the scroll reaches
     the viewport like the calendar grid does. */
  .filterbar { padding: var(--space-5) var(--space-7); gap: var(--space-4); }
  .filterbar > .chip-group, .filterbar-row {
    flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    margin-inline: calc(-1 * var(--space-7)); padding-inline: var(--space-7);
  }
  .filterbar > .chip-group::-webkit-scrollbar, .filterbar-row::-webkit-scrollbar { display: none; }
  /* Nothing inside a scroll row may shrink or wrap — the row scrolls instead. */
  .filterbar .chip, .filterbar .seg, .filterbar .seg-btn, .filterbar-row .btn { flex: none; }
  .filterbar-row { gap: var(--space-4); }
  /* The nested montant group rides the row's scroll — one scroll container. */
  .filterbar-row .chip-group { flex-wrap: nowrap; margin-inline: 0; padding-inline: 0; }
  /* A flexible spacer is meaningless inside a scroll row. */
  .filterbar-row .header-spacer { display: none; }
}

/* ==========================================================================
   Intro gate — the first-arrival pitch films (four scenes, 20 seconds each film).
   Fully token-driven so it follows both themes; every animation lives under
   .run so a film restarts cleanly; the whole gate is inert under
   prefers-reduced-motion (the app never shows it there).
   ========================================================================== */
.ig {
  position: fixed; inset: 0; z-index: 200;
  background: var(--bg);
  --bg: var(--intro-bg);
  --surface: var(--intro-surface);
  --surface-inset: var(--intro-surface-inset);
  --surface-hover: var(--intro-surface-hover);
  --surface-veil: var(--intro-surface-veil);
  --surface-hover-veil: color-mix(in srgb, var(--intro-surface-hover) 90%, transparent);
  --ink: var(--intro-ink);
  --ink-muted: var(--intro-ink-muted);
  --border: var(--intro-border);
  --border-strong: var(--intro-border-strong);
  --brand: var(--nota-blue-700);
  --brand-bright: var(--nota-blue-500);
  /* Le film garde un sol CLAIR même quand la page est en nuit : un jeton qui
     contient var() se fige sur l'élément qui le déclare, donc sans cette
     ligne le film hériterait de l'encre d'état de la page. */
  --brand-on-surface: var(--brand);
  --brand-word-ink: var(--ink);
  --brand-tint: var(--intro-tint);
  --brand-tint-solid: var(--intro-surface-inset);
  --ring: var(--nota-blue-600);
  --shadow-lg: var(--shadow);
  background-image: radial-gradient(60% 70% at 50% 8%, var(--brand-tint), transparent 72%);
  display: flex; align-items: center; align-items: safe center; justify-content: center;
  padding: 14px; overflow-y: auto;
}
.ig::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: .2;
  background:
    radial-gradient(42% 34% at 10% 18%, rgb(var(--nota-blue-400-rgb) / .22), transparent 78%),
    radial-gradient(38% 34% at 88% 78%, rgb(var(--nota-blue-500-rgb) / .18), transparent 80%),
    radial-gradient(26% 28% at 58% 44%, var(--brand-tint), transparent 76%),
    linear-gradient(115deg, transparent 30%, rgb(var(--nota-blue-400-rgb) / .05) 48%, transparent 66%);
  filter: blur(22px); transform: scale(1.08); animation: igLightDrift 26s ease-in-out infinite alternate;
}
@keyframes igLightDrift {
  from { transform: scale(1.08) translate3d(-2%, -1%, 0) rotate(-1deg); opacity: .55; }
  to { transform: scale(1.16) translate3d(2%, 1%, 0) rotate(1deg); opacity: .9; }
}
.ig::before {
  content: ""; position: absolute; inset: -20%; pointer-events: none;
  background:
    radial-gradient(34% 38% at 18% 18%, var(--brand-tint), transparent 72%),
    radial-gradient(42% 46% at 84% 78%, var(--brand-tint), transparent 74%);
  opacity: .36; animation: igAura 22s ease-in-out infinite alternate;
}
@keyframes igAura {
  from { transform: translate3d(-2%, -1%, 0) scale(1); }
  to { transform: translate3d(2%, 1%, 0) scale(1.05); }
}
.ig.ig-out { opacity: 0; transition: opacity 0.3s ease; }
html.ig-open, body.ig-open { overflow: hidden; }
/* Ambient mark drift — the Nota logo, twenty-four times, adrift far behind the
   site content (app.js driftBuild deals each copy its place and tempo). One
   fixed site-wide layer (#site-bg) rides behind ALL panes — no band boundary
   ever slices a mark again. The arrival chooser stays clear; the gate's
   animated aura supplies motion without a second field of cubes. */
.mark-drift { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
/* Behind everything, edge to edge, and it arrives smoothly — a slow fade-in
   so the scene breathes into place instead of popping. */
.mark-drift--site { display: block; opacity: .42; }
.mark-drift--intro { display: block; opacity: .72; }
@keyframes mark-fade { from { opacity: 0; } to { opacity: 1; } }
/* Two clocks per mark, both endless and seamless: the wrapper wanders a
   closed loop through two waypoints (out, across, home — never retracing
   itself) while the mark itself tumbles like a thrown die — one full, even
   turn around its own random 3D axis (linear — a roll has no resting point
   to ease toward). Splitting them keeps both loops smooth. Depth (app.js:
   one draw per mark) sets the size, the weight (--o), the softness (--blur)
   and how far it roams — near marks glide boldly in front of small,
   blurred, barely-stirring distant ones: parallax from a single random
   number. */
.mark-drift i {
  position: absolute; left: var(--x); top: var(--y);
  width: var(--s); height: var(--s);
  /* Half the die's edge — every face folds out to this depth. */
  --h: calc(var(--s) / 2);
  opacity: var(--o, 0.025);
  filter: blur(var(--blur, 0px));
  /* The stage depth that turns the tumble from a flat spin into a die
     rolling toward and away from the eye. */
  perspective: 400px;
  animation: mark-wander var(--d) ease-in-out var(--dl) infinite;
}
/* The die's body: six faces folded into a cube, tumbling as one. Hidden
   backfaces keep it reading as a solid object, not layered glass. */
.mark-drift .cube {
  position: absolute; inset: 0;
  transform-style: preserve-3d;
  animation: mark-tumble var(--sd) linear var(--dl) infinite;
}
.mark-drift .cube svg {
  position: absolute; inset: 0; width: 100%; height: 100%;
  backface-visibility: hidden;
}
.mark-drift .cube svg:nth-child(1) { transform: translateZ(var(--h)); }
.mark-drift .cube svg:nth-child(2) { transform: rotateY(180deg) translateZ(var(--h)); }
.mark-drift .cube svg:nth-child(3) { transform: rotateY(90deg) translateZ(var(--h)); }
.mark-drift .cube svg:nth-child(4) { transform: rotateY(-90deg) translateZ(var(--h)); }
.mark-drift .cube svg:nth-child(5) { transform: rotateX(90deg) translateZ(var(--h)); }
.mark-drift .cube svg:nth-child(6) { transform: rotateX(-90deg) translateZ(var(--h)); }
@keyframes mark-wander {
  0%, 100% { transform: translate(0, 0); }
  33% { transform: translate(var(--dx1), var(--dy1)); }
  66% { transform: translate(var(--dx2), var(--dy2)); }
}
@keyframes mark-tumble {
  from { transform: rotate3d(var(--ax), var(--ay), var(--az), 0); }
  to { transform: rotate3d(var(--ax), var(--ay), var(--az), var(--spin)); }
}
@media (prefers-reduced-motion: reduce) { .mark-drift i, .mark-drift .cube { animation: none; } }
/* The in-flow column hosts only the CHOOSER (the film frame is its own
   fixed, full-viewport layer) — a plain centred measure is enough. */
.ig-inner { flex: none; position: relative; z-index: 1; width: min(1040px, 96vw); display: flex; flex-direction: column; align-items: center; }

/* The introduction's lockup is the same parametric drawing as the header's,
   sized in em so one font-size scales the whole thing: the tile is .9em and
   the word, the gap and the centring follow from the five lockup properties. */
.ig-wordmark { --lockup-tile: .9em; display: inline-flex; align-items: center; justify-content: center; gap: var(--lockup-gap); color: var(--brand); font-size: 32px; line-height: 1; }
.ig-wordmark .ig-mark { display: block; width: var(--lockup-tile); height: var(--lockup-tile); flex: none; }
.ig-wordmark .ig-word { display: inline-flex; align-items: center; width: calc(var(--lockup-word) * 91.8 / 28); height: var(--lockup-word); color: var(--brand-word-ink); line-height: 1; }
.ig-wordmark .brand-word-svg { width: 100%; height: 100%; }
.ig-signature { position: relative; font-size: clamp(64px, 9vw, 112px); filter: drop-shadow(0 14px 24px rgb(var(--nota-blue-700-rgb) / .2)); }
.ig-signature::before {
  content: ""; position: absolute; z-index: -1; width: 1.34em; height: 1.34em;
  border: 1px solid var(--brand-tint); border-radius: 50%;
  box-shadow: 0 0 0 14px rgb(var(--nota-blue-500-rgb) / .035), 0 0 0 28px rgb(var(--nota-blue-500-rgb) / .02);
  animation: igOrbit 8s ease-in-out infinite;
}
@keyframes igOrbit {
  0%, 100% { transform: scale(.94) rotate(-3deg); opacity: .55; }
  50% { transform: scale(1.04) rotate(3deg); opacity: 1; }
}
/* L'ARRIVÉE MONTRE LE CARNET (propriétaire, 2026-09-12) — « je trouve
   l'expérience très simple et basique […] on peut faire beaucoup mieux ».
   La porte ne promet plus, elle démontre : la marque et les deux publics sur
   une seule ligne, la promesse en titre, puis de VRAIES dates à leur prix
   total. Une seule colonne de lecture à toutes les largeurs ; seule la bande
   des dates se répartit sur la largeur disponible. */
.ig-chooser {
  position: relative; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: end; gap: 36px;
  text-align: left; max-width: 1040px; width: 100%;
  padding: clamp(24px, 3.5vw, 40px);
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: linear-gradient(145deg, var(--surface-veil), var(--surface)); box-shadow: var(--shadow-lg);
  backdrop-filter: blur(18px);
}
.ig-chooser::before {
  content: ""; position: absolute; top: -1px; left: 15%; right: 15%; height: 2px;
  border-radius: var(--radius-xs); background: linear-gradient(90deg, transparent, var(--brand-bright), transparent);
  opacity: .8;
}
/* .ig [data-set-lang] below gives these buttons a 44px touch target, so the
   track has to grow to match — at the base 28px/2px it clipped the active
   button's own highlight by 8px top and bottom. */
.ig-chooser > .mini-seg { position: absolute; top: 20px; right: 24px; height: 44px; padding: 0; gap: 0; margin: 0; border: 1px solid var(--border); }
/* La marque et le choix du public tiennent la même ligne : le visiteur n'a
   plus à se déclarer avant de voir quoi que ce soit. */
.ig-arrival-top { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.ig-title { max-width: 22ch; color: var(--ink); font-size: var(--type-h1); letter-spacing: var(--type-h1-ls); line-height: var(--type-h1-lh); font-weight: var(--weight-display); margin: 0; text-wrap: balance; }
.ig-lede { color: var(--ink-muted); font-size: var(--type-lead); line-height: var(--type-lead-lh); margin: -12px 0 0; max-width: 46ch; }
.ig-doors { display: flex; gap: 8px; flex-wrap: wrap; }
/* Deux invitations, pas deux affiches : contour, encre, et la marque qui ne
   sert qu'à signaler l'état survolé (aucun aplat — registre du 2026-09-12). */
.ig-door {
  position: relative; font: inherit; cursor: pointer; text-align: left;
  display: inline-flex; align-items: center; min-height: 44px;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 10px 14px;
  transition: border-color .15s, color .15s, background-color .15s;
}
.ig-door:hover { border-color: var(--brand); background: var(--surface-hover); }
.ig-door:hover .ig-door-t { color: var(--ink); }
.ig-door:focus-visible { outline: 3px solid var(--ring); outline-offset: 2px; }
.ig-door-t { color: var(--ink); font-size: var(--type-h4); font-weight: 650; line-height: 1.2; }
.ig-arrival-copy { display: flex; flex-direction: column; align-items: stretch; gap: 20px; min-width: 0; }
.ig-arrival-top { justify-content: flex-start; }
.ig-arrival-top > .ig-wordmark { --lockup-tile: clamp(44px, 5vw, 56px); }
.ig-arrival-copy .ig-title { margin-top: 10px; max-width: 14ch; }
.ig-arrival-copy .ig-lede { font-size: var(--type-body); line-height: var(--type-body-lh); margin: -8px 0 0; max-width: 32ch; }
.ig-arrival-copy .ig-doors { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; width: 100%; }
.ig-arrival-copy .ig-door { flex-direction: column; align-items: flex-start; justify-content: center; gap: 5px; min-width: 0; padding: 14px 42px 14px 16px; }
.ig-arrival-copy .ig-door::after { content: '→'; position: absolute; right: 16px; top: 50%; transform: translateY(-50%); color: var(--brand-on-surface); }
.ig-arrival-copy #ig-door-client { border-color: var(--brand); background: var(--brand-tint-solid); }
.ig-door-sub { color: var(--ink-muted); font-size: var(--type-control); line-height: 1.4; }
.ig-arrival-market { min-width: 0; display: flex; flex-direction: column; gap: 14px; padding: 24px; margin-top: 36px; background: var(--brand-tint-solid); border: 1px solid var(--border); border-radius: var(--radius); }
.ig-arrival-market .ig-cal { border-top: 0; padding-top: 0; }
.ig-arrival-market .ig-cal-head { margin-bottom: 16px; }
.ig-arrival-market .ig-cal-row { grid-template-columns: minmax(0, 1fr); }
.ig-arrival-market .ig-cal-cell { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: 'when price' 'tier price'; align-items: center; gap: 6px 12px; padding: 12px 14px; }
.ig-arrival-market .ig-cal-when { grid-area: when; }
.ig-arrival-market .ig-cal-price { grid-area: price; white-space: nowrap; }
.ig-arrival-market .ig-cal-tier { grid-area: tier; }
.ig-arrival-market .ig-enter { align-self: stretch; text-align: left; padding: 10px 0 0; border: 0; border-top: 1px solid var(--border); border-radius: 0; background: transparent; color: var(--brand-on-surface); box-shadow: none; }

/* LA BANDE DES DATES — une tuile par palier d'avis du domaine, dans l'ordre
   des dates. Le prix est un montant : il est le seul bleu de la tuile, le
   nombre du jour reste de l'encre (registre du 2026-09-12). */
.ig-cal { border-top: 1px solid var(--border); padding-top: 16px; }
.ig-cal-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.ig-cal-lbl {
  font-size: var(--type-eyebrow); letter-spacing: var(--type-eyebrow-ls); text-transform: uppercase;
  font-weight: var(--weight-display); color: var(--subtitle-ink);
}
.ig-cal-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(116px, 1fr)); gap: 8px; }
.ig-cal-cell {
  font: inherit; cursor: pointer; text-align: left;
  display: flex; flex-direction: column; gap: 7px;
  min-height: 44px; padding: 12px;
  color: var(--ink); background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius);
  transition: border-color .15s, transform .15s, box-shadow .15s;
}
.ig-cal-cell:hover { border-color: var(--brand); transform: translateY(-2px); box-shadow: var(--shadow-sm); }
.ig-cal-cell:focus-visible { outline: 3px solid var(--ring); outline-offset: 2px; }
/* La date calme : celle que le reste du site ouvre par défaut. Un cadre de
   marque la désigne — jamais un aplat, jamais un mot de plus. */
.ig-cal-cell[data-anchor="true"] { border-color: var(--brand); box-shadow: inset 0 0 0 1px var(--brand-tint); }
.ig-cal-when { display: flex; align-items: baseline; gap: 5px; }
.ig-cal-dow, .ig-cal-month {
  font-size: var(--type-eyebrow); letter-spacing: var(--type-eyebrow-ls);
  text-transform: uppercase; color: var(--ink-muted);
}
.ig-cal-day { font-size: var(--type-h3); line-height: 1; font-weight: var(--weight-display); color: var(--ink); }
.ig-cal-price { font-size: var(--type-h4); font-weight: 700; line-height: 1.2; color: var(--brand-on-surface); }
.ig-cal-tier { font-size: var(--type-eyebrow); color: var(--ink-muted); }

.ig-enter { font: inherit; cursor: pointer; background: none; border: none; color: var(--ink-muted); font-size: 16px; font-weight: 600; padding: 10px; min-height: 44px; align-self: start; }
.ig-enter:hover { color: var(--ink); }
.ig-enter:focus-visible { outline: 3px solid var(--ring); outline-offset: 2px; border-radius: var(--radius); }

/* Full viewport film. Playback controls stay in normal flow below the stage. */
.ig-frame { position: fixed; inset: 0; display: flex; flex-direction: column; align-items: center; background: var(--surface); }
.ig-frame[hidden] { display: none; }
.ig-stage {
  container-type: size; flex: 1; min-height: 0; width: 100%;
  background: var(--surface); position: relative; overflow: hidden;
}
.ig-stage::before {
  content: ""; position: absolute; z-index: 0; pointer-events: none;
  width: clamp(220px, 34vw, 560px); height: clamp(220px, 34vw, 560px);
  left: -9%; top: 42%; border: 1px solid var(--border); border-radius: 50%;
  box-shadow: 0 0 90px var(--brand-tint); opacity: .5;
  transform-style: preserve-3d; animation: igStageOrbit 20s ease-in-out infinite alternate;
}
.ig-stage::after { content: ""; position: absolute; inset: 0; pointer-events: none; background: radial-gradient(ellipse at 85% 10%, var(--brand-tint), transparent 65%); }
.ig-masthead {
  position: absolute; z-index: 2; top: 0; left: 0; right: 0;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: max(24px, env(safe-area-inset-top)) max(32px, env(safe-area-inset-right)) 20px max(32px, env(safe-area-inset-left));
}
.ig-masthead .ig-wordmark { padding: 0; }
.ig-audience { color: var(--ink-muted); font-size: 16px; font-weight: 500; line-height: 1.4; text-align: right; }
.ig-scene {
  position: absolute; inset: 88px 0 0; z-index: 1;
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; justify-content: safe center; overflow-y: auto;
  text-align: center; gap: clamp(20px, 3cqh, 32px);
  padding: 24px max(24px, env(safe-area-inset-right)) 48px max(24px, env(safe-area-inset-left));
  opacity: 0; visibility: hidden;
}
.ig-scene .ig-signature { font-size: clamp(64px, 9cqw, 112px); margin-bottom: 8px; }
.ig-h {
  color: var(--ink); font-size: clamp(28px, 4.5cqw, 56px); font-weight: 700;
  letter-spacing: -.035em; line-height: 1.08; margin: 0;
  text-wrap: balance; max-width: 19ch;
}
.ig-sub { font-size: clamp(16px, 2cqw, 22px); font-weight: 500; line-height: 1.45; color: var(--ink-muted); margin: 0; max-width: 43ch; text-wrap: balance; }
.ig-note { font-size: 16px; line-height: 1.5; color: var(--ink-muted); margin: 0; max-width: 44ch; text-wrap: balance; }
.ig-story-symbol { display: grid; place-items: center; width: clamp(72px, 10cqw, 120px); height: clamp(72px, 10cqw, 120px); flex: none; border-radius: var(--radius-lg); background: var(--brand-tint-solid); color: var(--brand); box-shadow: var(--shadow-sm); }
.ig-story-icon { width: 58%; height: 58%; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.ig-client-calendar {
  position: absolute; z-index: 1; width: min(48%, 82cqh); right: max(5%, calc(29% - 41cqh)); top: 50%; transform: translateY(-50%);
  padding: clamp(16px, 2.5vw, 32px); border: 1px solid var(--border);
  border-radius: var(--radius); background: var(--surface);
}
.ig-client-calendar-head { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 12px; margin-bottom: 20px; }
.ig-client-brand { font-size: 42px; }
.ig-client-month { margin: 0; font-size: var(--type-h4); font-weight: 600; color: var(--ink-muted); }
.ig-client-dates { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
.ig-client-weekday { padding-block: 8px; text-align: center; font-size: 12px; color: var(--ink-muted); }
.ig-client-date {
  display: grid; place-items: center; aspect-ratio: 1; min-width: 0;
  border: 1px solid var(--border); border-radius: var(--radius-xs);
  background: var(--surface); position: relative;
}
.ig-client-date strong { font-size: clamp(14px, 1.8vw, 22px); color: var(--ink); font-weight: 500; }
.ig-client-outside { opacity: .4; }
.ig-client-picked { border-color: var(--brand); background: var(--brand-tint-solid); }
.ig-client-picked::after {
  content: '↖'; position: absolute; right: -12px; bottom: -16px;
  font-size: 42px; color: var(--brand-on-surface); line-height: 1;
}
.ig-client-example { width: min(340px, 100%); display: grid; gap: 10px; font-size: 16px; }
.ig-client-choice { padding: 12px 16px; border: 1px solid var(--brand); border-radius: var(--radius); color: var(--brand-on-surface); background: var(--brand-tint-solid); font-weight: 600; }
.ig-client-field { display: flex; justify-content: space-between; gap: 20px; text-align: left; padding: 8px 4px; border-bottom: 1px solid var(--border); }
.ig-client-field > span, .ig-client-posted { color: var(--brand-on-surface); }
.run .ig-client-picked::after { animation: igClientClick .7s ease calc(.8s - var(--ig-seek-offset, 0ms)) both; }
.run .ig-client-posted { animation: igIn .3s ease calc(var(--ig-at) + .7s - var(--ig-seek-offset, 0ms)) both; }
.ig-client-market-offer { display: flex; flex-wrap: wrap; gap: 6px 20px; margin-top: 16px; color: var(--brand-on-surface); font-size: 14px; opacity: 0; }
.run .ig-client-market-offer { animation: igIn .3s ease calc(11.2s - var(--ig-seek-offset, 0ms)) both; }
#ig-stage-client::before, #ig-stage-client::after { display: none; }
#ig-stage-client .ig-scene { inset: 0 57% 0 5%; padding: 24px 0; align-items: flex-start; text-align: left; gap: clamp(14px, 2cqh, 24px); }
#ig-stage-client .ig-h { font-size: clamp(28px, 3.5cqw, 48px); }
#ig-stage-client .ig-sub { font-size: clamp(16px, 1.65cqw, 21px); }
@media (max-width: 700px) and (orientation: portrait) {
  .ig-client-calendar { display: flex; flex-direction: column; width: auto; inset: 20px 20px 52%; transform: none; padding: 16px; }
  .ig-client-calendar-head { gap: 8px; margin-bottom: 8px; }
  .ig-client-calendar-head .ig-client-brand { font-size: 32px; }
  .ig-client-month { font-size: 14px; }
  .ig-client-dates { flex: 1; min-height: 0; grid-auto-rows: minmax(0, 1fr); }
  .ig-client-date { aspect-ratio: auto; height: auto; }
  .ig-client-weekday { padding-block: 4px; }
  .ig-client-picked::after { font-size: 30px; right: -6px; bottom: -8px; }
  .ig-client-market-offer { margin-top: 10px; font-size: 12px; }
  #ig-stage-client .ig-scene { inset: calc(48% + 8px) 20px 18px; padding: 12px 0; gap: 12px; }
  #ig-stage-client .ig-client-example { gap: 6px; font-size: 14px; }
  #ig-stage-client .ig-client-choice { padding: 8px 12px; }
  #ig-stage-client .ig-client-field { padding-block: 5px; }
}
@media (max-width: 700px) and (orientation: portrait) and (max-height: 700px) {
  .ig-client-calendar { bottom: 56%; }
  #ig-stage-client .ig-scene { inset-block-start: calc(44% + 8px); gap: 8px; }
  #ig-stage-client .ig-h { font-size: 24px; }
  #ig-stage-client .ig-note { font-size: 14px; }
  #ig-stage-client .ig-client-publish { display: none; }
}
@media (max-height: 500px) and (min-width: 500px) {
  .ig-client-calendar { width: 42%; right: 6%; padding: 12px; }
  .ig-client-calendar-head { gap: 8px; margin-bottom: 4px; }
  .ig-client-calendar-head .ig-client-brand { font-size: 28px; }
  .ig-client-month { font-size: 14px; }
  .ig-client-date { aspect-ratio: auto; height: 26px; }
  .ig-client-weekday { padding-block: 2px; }
  .ig-client-market-offer { margin-top: 8px; font-size: 12px; }
  #ig-stage-client .ig-scene { gap: 8px; }
  #ig-stage-client .ig-client-example { gap: 4px; font-size: 14px; }
  #ig-stage-client .ig-client-choice { padding-block: 8px; }
}
@keyframes igClientClick { from { opacity: 0; transform: translate(18px, 16px); } to { opacity: 1; transform: none; } }
.ig-progress-track { position: absolute; z-index: 5; bottom: 0; left: 0; width: 100%; height: 18px; }
.ig-progress { position: absolute; inset: auto 0 7px; height: 4px; background: var(--brand-bright); width: 100%; transform: scaleX(0); transform-origin: left center; pointer-events: none; }
.ig-progress-seek { position: absolute; inset: 0; width: 100%; height: 18px; margin: 0; appearance: none; background: transparent; cursor: pointer; opacity: .14; }
.ig-progress-seek::-webkit-slider-runnable-track { height: 18px; background: transparent; }
.ig-progress-seek::-moz-range-track { height: 18px; background: transparent; }
.ig-progress-seek::-webkit-slider-thumb { width: 18px; height: 18px; appearance: none; border: 0; border-radius: 50%; background: var(--brand-bright); }
.ig-progress-seek::-moz-range-thumb { width: 18px; height: 18px; border: 0; border-radius: 50%; background: var(--brand-bright); }
.ig-progress-seek:focus-visible { opacity: 1; outline: 3px solid var(--ring); outline-offset: 3px; }
.ig-controls {
  display: flex; align-items: center; gap: 12px; width: 100%; flex: none;
  padding: 12px max(24px, env(safe-area-inset-right)) max(12px, env(safe-area-inset-bottom)) max(24px, env(safe-area-inset-left));
  background: var(--surface); border-top: 1px solid var(--border);
}
.ig-controls > .mini-seg { height: 48px; padding: 2px; flex: none; }
.ig-skip {
  display: block; margin-left: auto;
  font: inherit; font-size: 16px; font-weight: 700; cursor: pointer;
  color: var(--ink); background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius); padding: 10px 16px; min-height: 44px;
}
.ig-pause { font: inherit; font-size: 16px; font-weight: 700; cursor: pointer; color: var(--ink); background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 10px 12px; min-height: 44px; }
.ig-cta { font: inherit; font-size: clamp(17px, 2cqw, 21px); line-height: 1.3; font-weight: 700; color: var(--brand-on-surface); background: transparent; border: 1px solid var(--brand); border-radius: var(--radius); cursor: pointer; min-height: 46px; padding: 11px 22px; }
.ig-cta:hover { background: var(--brand-tint-solid); border-color: var(--brand-hover); color: var(--brand-on-surface); box-shadow: var(--shadow); }
.ig [data-set-lang] { min-width: 44px; min-height: 44px; font-size: 16px; }
.ig-skip:focus-visible, .ig-pause:focus-visible, .ig-cta:focus-visible { outline: 3px solid var(--ring); outline-offset: 3px; }
.ig-stage.is-paused, .ig-stage.is-paused *, .ig-stage.is-paused *::before, .ig-stage.is-paused *::after { animation-play-state: paused !important; }
@media (max-width: 600px) and (orientation: portrait) {
  .ig-controls { display: grid; grid-template-columns: 1fr auto; gap: 8px; padding-inline: max(16px, env(safe-area-inset-left)); }
  .ig-controls .ig-skip { grid-column: 1 / -1; grid-row: 1; width: 100%; margin-left: 0; }
  .ig-controls .ig-pause { grid-column: 1; grid-row: 2; justify-self: start; }
  .ig-controls > .mini-seg { grid-column: 2; grid-row: 2; justify-self: end; }
  .ig-scene .ig-cta { display: none; }
}
@keyframes igIn { from { opacity: 0; visibility: hidden; transform: translate3d(0, 14px, 0) scale(.985); filter: blur(2px); } 65% { opacity: 1; filter: blur(0); } to { opacity: 1; visibility: visible; transform: none; filter: blur(0); } }
@keyframes igOut { from { opacity: 1; visibility: visible; transform: none; filter: blur(0); } to { opacity: 0; visibility: hidden; transform: translate3d(0, -8px, 0) scale(1.01); filter: blur(1px); } }
@keyframes igBarAnim { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes igStageOrbit { 0% { transform: translate3d(0, 0, 0) rotateX(66deg) rotateZ(-18deg); } 100% { transform: translate3d(15vw, -8vh, 120px) rotateX(72deg) rotateZ(28deg); } }
.run .ig-progress { animation: igBarAnim 14s linear calc(-1 * var(--ig-seek-offset, 0ms)) both; }
/* Four distinct beats, 3.5s apiece (was 5s — felt sluggish). Text settles in
   0.3 seconds, leaving time to read. */
.run .ig-scene { animation: igIn .38s cubic-bezier(.2, .8, .2, 1) calc(var(--ig-at) - var(--ig-seek-offset, 0ms)) both, igOut .32s ease calc(var(--ig-at) + 3.18s - var(--ig-seek-offset, 0ms)) forwards; }
.run .ig-c4, .run .ig-n4 { animation: igIn .3s ease calc(var(--ig-at) - var(--ig-seek-offset, 0ms)) both; }
.ig-c1, .ig-n1 { --ig-at: 0s; }
.ig-c2, .ig-n2 { --ig-at: 3.5s; }
.ig-c3, .ig-n3 { --ig-at: 7s; }
.ig-c4, .ig-n4 { --ig-at: 10.5s; }
.run .ig-story-icon path { stroke-dasharray: 1; animation: igSketch .7s ease var(--ig-at) both; }
@keyframes igSketch { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@media (max-width: 640px) {
  .ig { padding: 20px; }
  .ig-inner { width: 100%; }
  .ig-chooser { display: flex; }
  .ig-chooser { gap: 18px; border-radius: var(--radius-lg); }
  .ig-chooser > .mini-seg { top: 16px; right: 16px; }
  .ig-doors { gap: 8px; }
  .ig-door { flex: 1; justify-content: center; }
  .ig-masthead { padding: max(20px, env(safe-area-inset-top)) 20px 16px; }
  .ig-wordmark { font-size: 28px; }
  .ig-signature { font-size: 72px; }
  .ig-audience { font-size: 14px; max-width: 15ch; }
  .ig-scene { inset-block-start: 72px; padding: 20px 24px 40px; }
  .ig-controls { gap: 6px; padding-inline: 12px; }
  .ig-pause { padding-inline: 8px; }
  .ig-skip { white-space: nowrap; padding-inline: 12px; }
}
@media (max-width: 640px) and (max-height: 700px) {
  .ig-chooser { gap: 12px; padding: 72px 10px 14px; }
  .ig-chooser > .mini-seg { top: 14px; right: 14px; }
  .ig-chooser .ig-signature { font-size: 52px; }
  .ig-title { font-size: var(--type-h2); line-height: var(--type-h2-lh); letter-spacing: var(--type-h2-ls); margin-top: 0; } /* short phone: the h2 rung is the nearest */
  .ig-lede { margin: 0; font-size: 16px; }
  .ig-doors { gap: 8px; }
  .ig-door { padding: 10px 12px; }
  .ig-enter { font-size: 14px; padding-block: 6px; }
  .ig-scene { gap: 16px; padding: 16px 20px 24px; }
  .ig-scene .ig-signature { font-size: 56px; margin-bottom: 0; }
  .ig-cta { padding-block: 12px; min-height: 48px; }
}
@media (max-height: 500px) and (min-width: 500px) {
  .ig-chooser { gap: 8px; }
  .ig-doors { gap: 8px; }
  .ig-chooser > .mini-seg { position: absolute; top: 0; right: 0; }
  .ig-chooser .ig-signature { font-size: 48px; }
  .ig-title { font-size: var(--type-h2); line-height: var(--type-h2-lh); letter-spacing: var(--type-h2-ls); margin-top: 0; }
  .ig-lede { font-size: 18px; margin: 0; }
  .ig-door { padding: 10px 12px; }
  .ig-masthead { padding-block: 16px; }
  .ig-scene { inset-block-start: 64px; gap: 12px; padding-block: 12px; }
  .ig-scene .ig-signature { font-size: 40px; margin-bottom: 0; }
  .ig-h { font-size: 32px; max-width: 30ch; }
  .ig-sub { font-size: 18px; max-width: 60ch; }
  .ig-story-symbol { width: 56px; height: 56px; }
  .ig-cta { font-size: 18px; min-height: 44px; padding: 10px 24px; }
  .ig-note { font-size: 16px; }
}
/* On the shortest landscape phones the masthead carries the brand, leaving
   the reading area and final action fully visible. */
@media (max-height: 380px) and (min-width: 500px) {
  .ig-scene { gap: 8px; padding: 8px 20px; }
  .ig-scene .ig-signature { display: none; }
}
/* The arrival calendar must reserve real line-height for every date, even
   above a two-row action bar on the smallest phones. */
@media (max-width: 700px) and (orientation: portrait) {
  .ig-client-calendar { min-height: 212px; padding: 12px; }
  .ig-client-dates { gap: 2px; }
  .ig-client-weekday { padding: 0; line-height: 1.2; font-size: 11px; }
  .ig-client-date { min-height: 0; }
  .ig-client-date strong { font-size: 12px; line-height: 1; }
  .ig-client-market-offer { position: absolute; right: 12px; bottom: 8px; padding: 4px 6px; margin: 0; background: var(--surface); }
}
@media (max-width: 700px) and (orientation: portrait) and (max-height: 700px) {
  #ig-stage-client .ig-scene { inset-block-start: max(244px, calc(44% + 8px)); padding-block: 8px; }
  #ig-stage-client .ig-client-example, #ig-stage-client .ig-cta { display: none; }
}
@media (max-height: 380px) and (min-width: 500px) {
  .ig-client-date { height: 20px; }
  .ig-client-date strong { font-size: 12px; line-height: 1; }
  #ig-stage-client .ig-client-example, #ig-stage-client .ig-cta { display: none; }
}
@media (prefers-reduced-motion: reduce) { .ig { display: none; } }

/* ==========================================================================
   Conformité (ADR 0033 §5 · ADR 0031) — the notary landing's compliance block.
   Detailed articles stay under the sign-in gate, outside the short film.
   Folds away with the gate: signed in, the console is a workspace.
   ========================================================================== */
.nc-conformite { margin-top: var(--space-16); padding-top: var(--space-12); border-top: 1px solid var(--border); max-width: 440px; }
/* Signed in, the console is a workspace and the compliance band folds away
   with the gate. The band is no longer the form's next sibling (it sits in the
   pane's grid, one level up), so the fold reads the gate through the wrap. */
#pane-notaires > .wrap:has(#notary-auth-form[hidden]) #nc-conformite { display: none; }
.nc-conformite-kicker { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; color: var(--subtitle-ink); margin-bottom: var(--space-3); }
.nc-conformite-h { font-size: var(--type-h4); line-height: var(--type-h4-lh); letter-spacing: var(--type-h4-ls); color: var(--subtitle-ink); margin: 0 0 var(--space-5); }
.nc-conformite-tiles { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-4); }
.nc-conformite-tile {
  display: grid; grid-template-columns: auto 1fr; column-gap: var(--space-5); row-gap: var(--space-1); align-items: start;
  padding: var(--space-5) var(--space-6);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
}
.nc-conformite-ic {
  grid-row: 1 / span 2; width: 30px; height: 30px; border-radius: var(--radius-sm);
  display: grid; place-items: center; color: var(--brand); background: var(--brand-tint);
}
.nc-conformite-ic svg { width: 18px; height: 18px; }
.nc-conformite-art { font-size: 11px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--subtitle-ink); }
.nc-conformite-txt { font-size: 13px; line-height: 1.45; color: var(--ink); }
.nc-conformite-order { margin: var(--space-5) 0 0; font-size: 12.5px; font-weight: 700; color: var(--ink-muted); }
.nc-conformite-link { display: inline-block; margin-top: var(--space-3); font-size: 13px; font-weight: 700; color: var(--brand); }

/* ==========================================================================
   Les promesses du notaire (ADR 0052 §A) — le bloc qui dit, avant le compte,
   ce que Nota donne : l'agenda, les trous comblés, ce que l'urgence paie, la
   fiche complète. Même registre que la bande Conformité plus bas (kicker,
   sur-titre, tuiles carrées sur --surface) : deux blocs d'annonce, un seul
   dessin. Le titre d'une tuile est de l'encre, jamais du bleu (registre
   d'encre) ; le bleu ne porte ici que le glyphe et le MONTANT.
   ========================================================================== */
.nc-promesses { margin: var(--space-8) 0 var(--space-10); }
/* Signé, la console est un plan de travail : le bloc se replie avec la porte,
   exactement comme #nc-conformite (il lit la porte à travers le wrap). */
#pane-notaires > .wrap:has(#notary-auth-form[hidden]) #nc-promesses { display: none; }
.nc-promesses-kicker { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; color: var(--subtitle-ink); margin-bottom: var(--space-3); }
.nc-promesses-h { font-size: var(--type-h4); line-height: var(--type-h4-lh); letter-spacing: var(--type-h4-ls); color: var(--subtitle-ink); margin: 0 0 var(--space-5); }
.nc-promesses-tiles {
  list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-4);
  grid-template-columns: minmax(0, 1fr);
}
/* Quatre promesses veulent un carré 2×2, jamais trois et une orpheline : un
   auto-fit donnait 3 + 1 dès que le rail passait 900px (constaté au
   navigateur, 2026-09-12). Deux colonnes fixes dès qu'il y a la place. */
@media (min-width: 620px) {
  .nc-promesses-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.nc-promesse {
  display: grid; grid-template-columns: auto 1fr; column-gap: var(--space-5); row-gap: var(--space-2); align-items: start;
  padding: var(--space-5) var(--space-6);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
}
.nc-promesse-ic {
  grid-row: 1 / span 2; width: 30px; height: 30px; border-radius: var(--radius-sm);
  display: grid; place-items: center; color: var(--brand); background: var(--brand-tint);
}
.nc-promesse-ic svg { width: 18px; height: 18px; }
.nc-promesse-t { font-size: 13.5px; font-weight: 800; line-height: 1.3; color: var(--ink); }
.nc-promesse-p { font-size: 13px; line-height: 1.45; color: var(--ink-muted); }
/* Le chiffre de l'urgence : la seule chose bleue de la tuile, parce que c'est
   un montant. Vide tant que app.js ne l'a pas écrit — la phrase qui suit se
   tient seule, elle ne commence pas par une espace orpheline. */
/* Le chiffre de l'urgence ouvre la phrase, en encre : c'est une PHRASE, pas un
   montant isolé, et le registre d'encre réserve le bleu à une information qui
   se montre seule (un montant, un lien, une pastille). Une phrase entière en
   bleu se lisait comme un lien. */
.nc-promesse-chiffre { font-weight: 800; color: var(--ink); }
.nc-promesse-chiffre:not(:empty)::after { content: ' '; }

/* ==========================================================================
   Live support chat (ADR 0026 · ADR 0033 §5) — the floating question door.
   Its own `sup-*` namespace: the retained-act `.chat-*` rules (a flex column,
   start-aligned) once reached in and dropped the visitor's bubbles on the
   wrong side. Same square scale as every control; brand blue only on the
   trigger and the visitor's own bubbles. Fixed above everything, footer
   included — and STACKED above the guide « ? » bubble on desktop: bottom
   70px clears the bubble's 16px + 42px (ux-nav.test.mjs pins the sum).
   Phones drop the fab (the drawer's « Messagerie » row opens the panel),
   so the calendar corner ADR 0022 cleared stays clear.
   ========================================================================== */
.sup-wrap { position: fixed; right: 16px; bottom: 70px; z-index: 60; display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }
.sup-fab {
  appearance: none; font: inherit; border: 1px solid var(--brand); cursor: pointer; position: relative;
  width: 48px; height: 48px; border-radius: var(--radius);
  background: transparent; color: var(--brand);
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: none;
}
.sup-fab:hover { background: transparent; border-color: var(--brand-hover); color: var(--brand-hover); }
.sup-fab:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 2px; }
/* The unread mark — the one round thing here: an 8px dot, as the register allows. */
.sup-fab-dot { position: absolute; top: 6px; right: 6px; width: 8px; height: 8px; border-radius: 50%; background: var(--danger); box-shadow: 0 0 0 2px var(--brand); }
.sup-panel {
  width: min(380px, calc(100vw - 32px));
  max-height: calc(100dvh - 28px); overflow-y: auto;
  display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg); overflow-x: hidden; overflow-y: auto;
}
.sup-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-4); padding: var(--space-6) var(--space-6) var(--space-5) var(--space-8); border-bottom: 1px solid var(--border); }
.sup-title { font-weight: 800; letter-spacing: -0.01em; }
.sup-sub { margin: 2px 0 0; font-size: 12.5px; line-height: 1.4; color: var(--ink-muted); max-width: 30ch; }
/* La fermeture est une icône carrée du registre, pas un caractère posé dans le
   texte : même gabarit que les autres boutons-icônes, et une cible de 28 px. */
.sup-close {
  appearance: none; border: 1px solid var(--border); background: transparent; color: var(--ink-muted);
  font: inherit; font-size: 14px; line-height: 1; cursor: pointer; flex: none;
  width: 28px; height: 28px; display: inline-grid; place-items: center; border-radius: var(--radius-sm);
}
.sup-close:hover { background: transparent; border-color: var(--brand); color: var(--ink); }
.sup-close:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
/* ADR 0046 — le journal ne réserve plus 96 px de vide. Un fil neuf n'a rien à
   montrer : ce sont les questions d'amorce, juste dessous, qui occupent la
   place, et elles, elles mènent quelque part. Le journal ne prend donc de la
   hauteur qu'une fois qu'il porte des bulles. */
.sup-log { max-height: 300px; overflow-y: auto; padding: var(--space-7) var(--space-8); display: flex; flex-direction: column; justify-content: flex-end; gap: var(--space-5); }
.sup-log:empty { padding: 0; }
.sup-log-op { min-height: 80px; max-height: 240px; border: 1px solid var(--border); border-radius: var(--radius); margin-bottom: 10px; }
.sup-empty { font-size: 13px; line-height: 1.5; color: var(--ink-muted); }
/* A message is a column — the bubble, then its « who · when » line — on the
   end side for the reader's own, the start side for the other. */
.sup-msg { display: flex; flex-direction: column; align-items: flex-start; gap: 3px; }
.sup-msg.is-mine { align-items: flex-end; }
.sup-bubble {
  max-width: 85%; padding: 7px 10px; font-size: 13.5px; line-height: 1.4;
  border-radius: var(--radius); white-space: pre-wrap; word-break: break-word;
  background: var(--surface-inset); color: var(--ink); border: 1px solid var(--border);
}
.sup-msg.is-mine .sup-bubble { background: var(--brand); color: var(--brand-ink); border-color: transparent; }
/* L'assistant a SA bulle : le même registre que celle de Nota, avec un filet
   de marque à gauche qui dit d'un coup d'œil que c'est la machine qui a
   répondu — jamais un déguisement en personne. */
.sup-msg[data-de='assistant'] .sup-bubble { border-left: 2px solid var(--brand); }
/* « L'assistant écrit… » : trois points qui respirent, du côté de l'assistant.
   La bulle garde la hauteur d'une ligne pour que le fil ne saute pas quand la
   vraie réponse la remplace. */
.sup-bubble-typing { display: inline-flex; align-items: center; gap: 4px; min-height: 20px; }
.sup-dot { width: 5px; height: 5px; border-radius: 50%; background: var(--ink-muted); opacity: 0.35; animation: sup-pulse 1.2s ease-in-out infinite; }
.sup-dot:nth-child(2) { animation-delay: 0.15s; }
.sup-dot:nth-child(3) { animation-delay: 0.3s; }
@keyframes sup-pulse { 0%, 60%, 100% { opacity: 0.25; } 30% { opacity: 0.9; } }
@media (prefers-reduced-motion: reduce) { .sup-dot { animation: none; opacity: 0.5; } }
/* Les questions d'amorce — des cibles, pas de la décoration : elles occupent
   le vide qu'ouvrait le journal et disent ce que l'assistant sait traiter. */
.sup-suggest { display: flex; flex-wrap: wrap; gap: var(--space-3); padding: var(--space-6) var(--space-8) 0; }
.sup-chip {
  appearance: none; cursor: pointer; font: inherit; font-size: 12.5px; line-height: 1.3;
  padding: var(--space-4) var(--space-5); border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: var(--surface-inset); color: var(--ink);
}
.sup-chip:hover { border-color: var(--border-strong); background: var(--surface); }
.sup-chip:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
/* L'escalade se lit — même registre que « conversation terminée », en marque. */
.sup-escalade { margin: 0; padding: 8px 14px; font-size: 12.5px; line-height: 1.45; color: var(--ink-muted); border-top: 1px dashed var(--border); }
.sup-meta { display: flex; gap: var(--space-3); font-size: 11.5px; color: var(--ink-muted); padding: 0 2px; }
.sup-who { font-weight: 700; }
/* Un bloc, pas une liste de fiches : deux messages de suite du même côté se
   serrent, et la signature « qui · quand » ne se pose qu'au PIED du bloc —
   une conversation de six lignes cesse d'être six fois « Vous · 15:33 ». */
.sup-log .sup-msg.is-cont { margin-top: calc(var(--space-5) * -1 + var(--space-2)); }
.sup-msg.is-mid .sup-meta { display: none; }
.sup-ended { margin: 0; padding: 8px 14px; font-size: 12.5px; color: var(--ink-muted); border-top: 1px dashed var(--border); }
.sup-form { padding: var(--space-6) var(--space-8) var(--space-7); border-top: 1px solid var(--border); display: flex; flex-direction: column; gap: var(--space-4); }
/* Le composeur est UN champ, pas deux boîtes côte à côte : la rangée porte le
   cadre et l'anneau de focus, le champ et le bouton vivent dedans. */
.sup-row {
  display: flex; align-items: flex-end; gap: var(--space-3);
  padding: var(--space-3) var(--space-3) var(--space-3) var(--space-5);
  border: 1px solid var(--border-strong); border-radius: var(--radius); background: var(--surface);
}
.sup-row:focus-within { border-color: var(--ring); box-shadow: 0 0 0 3px var(--focus-ring); }
/* Grows with the text (field-sizing where the browser has it, app.js
   otherwise), capped so the log keeps its room. */
.sup-text {
  flex: 1; resize: none; min-height: 26px; max-height: 160px; overflow-y: auto; field-sizing: content;
  min-width: 0; padding: var(--space-3) 0; border: 0; border-radius: 0; background: transparent;
}
.sup-text:focus { border: 0; outline: none; box-shadow: none; }
.sup-send { flex: none; padding: var(--space-4) var(--space-6); font-size: 13px; }
.sup-count { margin: 0; min-height: 1.5em; font-size: 12px; color: var(--ink-muted); text-align: right; font-variant-numeric: tabular-nums; }
.sup-error { margin: 0; font-size: 13px; color: var(--danger); }
/* La porte du courriel : un lien discret tant qu'il ne sert pas. Elle ne prend
   qu'une ligne, et le champ n'apparaît qu'une fois ouverte. */
.sup-mail-open {
  appearance: none; border: 0; background: transparent; padding: 0; font: inherit;
  font-size: 12px; color: var(--ink-muted); text-align: left; cursor: pointer;
  text-decoration: underline; text-underline-offset: 2px; align-self: flex-start;
}
.sup-mail-open:hover { color: var(--ink); }
.sup-mail-open:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: var(--radius-xs); }
.sup-mail-open[aria-expanded='true'] { display: none; }
/* The optional courriel, one line under the composer: label · field, help beneath. */
.sup-courriel-row { display: flex; flex-direction: column; gap: var(--space-2); }
.sup-courriel-lbl { font-size: 12px; font-weight: 600; color: var(--ink-muted); }
.sup-opt { font-weight: 500; }
.sup-courriel { width: 100%; min-width: 0; padding: var(--space-4) var(--space-5); font-size: 13px; }
.sup-courriel-help { margin: 0; font-size: 12px; }
.sup-reply-courriel { margin: 0 0 8px; min-height: 1.5em; }
#chat-reply-error, #chat-reply-sent { min-height: 1.5em; }
#chat-reply-dialog textarea { width: 100%; resize: vertical; }
@media (max-width: 767.98px) {
  /* The guide « ? » left phones (ADR 0022) so the calendar owns its corner —
     the chat fab must not take its place. The panel still opens from the
     drawer's « Messagerie » row and from an emailed #messagerie link. */
  .sup-fab { display: none; }
  .sup-wrap { right: 10px; bottom: 10px; left: 10px; align-items: flex-end; }
  .sup-panel { width: 100%; }
}

/* --- Les documents de la conversation (ADR 0032) --------------------------
   Sous le fil, au même endroit des deux côtés : ce que l'un envoie, l'autre le
   lit là. Aucune couleur d'accent — un document n'est ni une alerte ni une
   récompense, c'est une pièce du dossier. L'état de l'envoi se dit en mots
   (aria-live), parce qu'une barre de progression sans phrase ne dit pas ce qui
   se passe quand elle s'arrête. */
.chat-docs { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border); }
.chat-doc-count { margin-bottom: 8px; }
.chat-doc-list { list-style: none; margin: 0 0 8px; padding: 0; display: grid; gap: 4px; }
.chat-doc { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; font-size: 13px; }
.chat-doc-open {
  font: inherit; padding: 0; border: 0; background: none; color: var(--brand);
  text-decoration: underline; cursor: pointer; text-align: left;
}
.chat-doc-open:hover { text-decoration: none; }
.chat-doc-meta { color: var(--ink-muted); font-size: 11.5px; }
.chat-doc-vide { color: var(--ink-muted); font-size: 12.5px; }
.chat-doc-input { display: none; }
.chat-doc-etat { margin: 6px 0 0; font-size: 12px; color: var(--ink-muted); min-height: 1em; }
.chat-doc-etat[data-etat="erreur"] { color: var(--danger); }
/* The act's checklist inside the document block (ADR 0032 × audit 2.1): one
   row per expected piece, its own Joindre, marked sent once confirmed. */
.chat-doc-checklist { list-style: none; margin: 0 0 8px; padding: 0; display: grid; gap: 6px; }
.chat-doc-item { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 13px; }
.chat-doc-item-name { font-weight: 600; }
.chat-doc-item[data-sent='true'] .chat-doc-item-name::before { content: '✓ '; color: var(--ok); }
.chat-doc-item .chat-doc-etat { margin: 0; flex-basis: 100%; }
.chat-doc-free { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 13px; margin-top: 4px; }
.chat-doc-free-lbl { color: var(--ink-muted); }
/* Back from Stripe (audit 2.2): the success card the redirect skipped. */
.checkout-success { margin-top: 10px; padding: 12px 16px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
.checkout-success-h { font-weight: 700; font-size: 14px; display: flex; flex-wrap: wrap; gap: 4px 8px; align-items: baseline; }
.checkout-success-h .money { color: var(--brand); }
.checkout-success .dossier-next { margin-top: 10px; }
.checkout-success .actions-inline { margin-top: 10px; }

/* =============================================================================
   Print. Paper is white: the light canvas tokens are restated for the dark
   theme and the system-dark media block (both outrank :root), the fixed
   chrome goes — header, drawer, bubbles, backdrop dice, footer nav, gate,
   dialogs — and the active pane keeps its content. The demo banner STAYS: a
   printed fictional carnet must still say so. Only canvas tokens are
   restated; the brand ramp is shared, everything else follows.
   ========================================================================== */
@media print {
  :root, :root[data-theme='dark'], :root:not([data-theme='light']) {
    color-scheme: light;
    --brand: var(--nota-blue-700); --brand-bright: var(--nota-blue-500); --brand-ink: var(--paper); --brand-hover: var(--nota-blue-800);
    --brand-on-surface: var(--brand); /* sur papier, l'état reprend la marque elle-même */
    --brand-word-ink: var(--ink);
    --bg: var(--paper); --surface: var(--paper); --surface-inset: var(--nota-blue-50); --surface-hover: var(--canvas-surface-hover);
    --ink: var(--nota-blue-950); --ink-muted: var(--canvas-ink-muted); --border: var(--canvas-border); --border-strong: var(--canvas-border-strong); --ring: var(--nota-blue-600);
    --subtitle-ink: var(--canvas-subtitle-ink);
    --shadow-sm: none; --shadow: none; --shadow-lg: none; --shadow-brand: none;
  }
  .site-header, .site-footer nav, .guide-fab, .sup-wrap, .mark-drift, .mnav, .mnav-scrim,
  .toast, .skip, .nav-burger, #intro-gate, dialog { display: none !important; }
  body { background: var(--bg); color: var(--ink); }
  * { box-shadow: none !important; text-shadow: none !important; -webkit-backdrop-filter: none !important; backdrop-filter: none !important; }
  .wrap { max-width: none; padding: 0; }
  .tab-pane[hidden] { display: none !important; }
}

/* ADR 0041 — l'acte annulé par le client, en attente de la décision du notaire
   sur l'indemnité : une carte à part, sans client ni fil, avec sa réclamation. */
.pill-annulee { background: transparent; color: var(--ink-muted); border: 1px solid var(--border); }
.nc-card.is-annulee { border-style: dashed; }
.nc-indemnite { margin-top: 10px; padding-top: 8px; border-top: 1px dashed var(--border); }
.nc-indemnite-form { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.nc-indemnite-amt { max-width: 160px; }
.nc-indemnite-just { resize: vertical; min-height: 56px; }
.nc-indemnite-err { color: var(--danger, var(--ink)); }
.devis-annulation { margin: 6px 0 0; }

.coverage-note { grid-column: 1 / -1; padding: 1rem; border: 1px solid currentColor; border-radius: var(--radius); max-width: 100%; }
.coverage-note .help { margin: 0 0 .75rem; }

/* Email preferences use the same surface and controls as the profile. */
#email-preferences-dialog {
  width: min(640px, calc(100vw - 32px));
  max-height: calc(100dvh - 48px);
  overflow-y: auto;
  padding: 24px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  color: var(--ink);
}
#email-preferences-dialog .check-row { display: flex; align-items: center; gap: 12px; min-height: 44px; }
#email-preferences-dialog input { width: 18px; height: 18px; accent-color: var(--brand); }
#email-preferences-dialog button { margin-block: 12px; }

/* Final booking step: keep the contact form readable on wide screens. */
.day-book[data-at='4'] {
  width: 100%; max-width: 1120px; margin-inline: auto; box-sizing: border-box;
  gap: 20px;
}
.day-book[data-at='4'] #o-where-step { padding: 20px; }
.day-book[data-at='4'] #prefix-row { margin-bottom: 0; }
.day-book[data-at='4'] #prefix-row > .coverage-note { grid-column: 1 / -1; }
.day-book[data-at='4'] .book-identity {
  margin-top: 0; padding-top: 20px;
  grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px;
}
.day-book[data-at='4'] .book-identity .form-row { min-width: 0; }
.day-book[data-at='4'] .book-identity .form-row:has(#o-sms) { grid-column: 1 / -1; }
.day-book[data-at='4'] .book-identity .form-row:has(#o-sms) .check-line { align-items: flex-start; max-width: 760px; }
.day-book[data-at='4'] #identity-rows input { width: 100%; max-width: none; box-sizing: border-box; }
.day-book[data-at='4'] .book-identity .help { font-size: 13px; line-height: 1.5; }
.day-book[data-at='4'] .offer-hint { margin: 0; }
.day-book[data-at='4'] .consent-line { margin: 0; font-size: 12px; line-height: 1.5; }
.day-book[data-at='4'] .book-nav { margin-top: 4px; }
@media (max-width: 760px) {
  .day-book[data-at='4'] .book-identity { grid-template-columns: minmax(0, 1fr); }
  .day-book[data-at='4'] #o-where-step { padding: 16px; }
}
/* Inactive validation messages must not reserve a flex row or its gap. */
.day-book[data-at] > [data-screen][hidden] { display: none !important; }

/* One tour surface for both account roles; native dialog contains keyboard focus. */
.account-tour {
  position: fixed; inset: auto 20px 20px auto; margin: 0;
  width: min(460px, calc(100vw - 32px)); max-height: min(50dvh, 420px);
  box-sizing: border-box; overflow: auto; padding: 24px;
  color: var(--ink); background: var(--surface); border: 1px solid var(--brand);
  border-radius: var(--radius); box-shadow: var(--shadow-lg);
}
.account-tour[open] { animation: account-tour-in .2s ease-out; }
.account-tour::backdrop { background: var(--backdrop-soft); }
.account-tour h2 { margin: 10px 0; }
.account-tour p { margin: 0 0 20px; line-height: 1.6; }
.account-tour-progress { color: var(--brand); font-size: 12px; font-weight: 700; }
.account-tour-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; }
.account-tour-actions .btn { min-height: 44px; }
.account-tour-actions .btn:first-child { margin-right: auto; }
.account-tour-target { outline: 3px solid var(--brand); outline-offset: 5px; scroll-margin-top: 110px; }
.account-tour-replay { justify-self: start; margin-bottom: 16px; }
@keyframes account-tour-in { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }
@media (max-width: 560px) { .account-tour { inset: auto 16px 16px; padding: 18px; } }
@media (prefers-reduced-motion: reduce) { .account-tour[open] { animation: none; } }
.account-tour::backdrop { backdrop-filter: none; -webkit-backdrop-filter: none; }
.account-tour h2 { animation: account-tour-in .2s ease-out; }
@media (prefers-reduced-motion: reduce) { .account-tour h2 { animation: none; } }

/* The client guide follows the live form and leaves every control usable. */
.client-walk {
  position: fixed; z-index: 90; right: 20px; bottom: 20px;
  width: min(360px, calc(100vw - 32px)); box-sizing: border-box;
  max-height: calc(100dvh - 96px); overflow-y: auto; overscroll-behavior: contain;
  padding: 12px 16px 16px; border: 1px solid var(--border-strong);
  border-radius: var(--radius); background: var(--surface); color: var(--ink);
  box-shadow: var(--shadow-lg);
}
.client-walk-top { display: flex; position: sticky; top: -12px; z-index: 2; align-items: center; justify-content: space-between; gap: 8px; background: var(--surface); }
.client-walk-progress { color: var(--brand-on-surface); font-size: 12px; font-weight: 700; }
.client-walk-skip, .client-walk-toggle, .client-walk-link {
  border: 0; background: transparent; color: var(--ink-muted); cursor: pointer;
  font: inherit; font-size: 13px; min-height: 44px; padding: 4px 8px;
}
.client-walk-skip { text-decoration: underline; }
.client-walk-toggle, .client-walk-link { color: var(--brand-on-surface); font-weight: 600; }
.client-walk button:focus-visible, .client-walk summary:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.client-walk h2 { font-size: var(--type-h3); line-height: var(--type-h3-lh); margin: 4px 0 8px; }
.client-walk p { font-size: 14px; line-height: 1.5; margin: 0 0 12px; }
.client-walk .btn { min-height: 44px; }
.client-walk-actions { display: flex; flex-wrap: wrap; gap: 4px 8px; align-items: center; }
.client-walk-actions .btn { flex: 1; }
.client-walk-date-field { display: grid; gap: 6px; margin: 0 0 12px; font-size: 13px; font-weight: 600; }
.client-walk-date-field input { width: 100%; min-width: 0; min-height: 44px; box-sizing: border-box; font: inherit; padding: 8px 12px; border: 1px solid var(--border-strong); border-radius: var(--radius-sm); background: var(--surface); color: var(--ink); }
.client-walk-body[hidden], .client-walk-date-field[hidden], .client-walk-link[hidden] { display: none; }
.client-walk.is-minimized { width: auto; max-width: calc(100vw - 32px); padding-block: 4px; }
.client-walk.is-minimized .client-walk-top { position: static; gap: 16px; }
.client-walk.is-minimized .client-walk-progress, .client-walk.is-minimized .client-walk-toggle { white-space: nowrap; flex: none; }
.client-walk-target { outline: 2px solid var(--brand); outline-offset: 4px; scroll-margin-block: 280px 40px; }
#cal-grid .client-walk-target { scroll-margin-block: 90px 360px; }
#day-dialog > .client-walk {
  position: sticky; top: 0; bottom: auto; right: auto; z-index: 6;
  width: auto; margin: 0 20px 12px; padding: 4px 16px 12px; max-height: min(360px, 58dvh);
}
#day-dialog > .client-walk.is-minimized { padding-block: 4px; }
#day-dialog:has(> .client-walk) .day-head { position: relative; }
#day-dialog > .client-walk h2 { margin-bottom: 4px; }
#day-dialog > .client-walk p { margin-bottom: 10px; }
.client-walk-animation { margin-top: 10px; border-top: 1px solid var(--border); }
.client-walk-animation > summary { min-height: 44px; box-sizing: border-box; padding-block: 12px; font-size: 13px; cursor: pointer; color: var(--brand-on-surface); }
.client-walk-demo { border-radius: var(--radius-sm); padding: 12px; background: var(--surface-inset); }
.client-walk-demo .client-walk-demo-caption { font-size: 11px; color: var(--ink-muted); margin-bottom: 8px; }
.client-walk-demo-view { min-height: 178px; display: grid; align-items: center; }
.client-walk-demo .ig-client-calendar { position: static; inset: auto; display: block; width: 100%; min-height: 0; padding: 0; transform: none; background: transparent; border: 0; box-shadow: none; }
.client-walk-demo .ig-client-calendar-head { margin-bottom: 6px; }
.client-walk-demo .ig-client-month { font-size: 13px; margin: 0; }
.client-walk-demo .ig-client-dates { gap: 2px; grid-auto-rows: auto; }
.client-walk-demo .ig-client-date { height: 18px; min-height: 0; aspect-ratio: auto; border-radius: var(--radius-xs); }
.client-walk-demo .ig-client-date strong { font-size: 11px; line-height: 1; }
.client-walk-demo .ig-client-weekday { font-size: 10px; padding: 2px 0; }
.client-walk-demo .ig-client-picked::after { display: none; }
.client-walk-demo .ig-client-market-offer { display: none; }
.client-walk-demo-view[data-scene='3'] .ig-client-market-offer { display: flex; position: static; opacity: 1; font-size: 12px; margin-top: 6px; padding: 0; }
.client-walk-demo .ig-client-example { width: 100%; min-width: 0; font-size: 13px; gap: 8px; }
.client-walk-demo .ig-client-choice { padding: 10px; }
.client-walk-demo .ig-client-field { gap: 12px; padding-block: 6px; }
.client-walk-demo .client-walk-demo-heading { font-weight: 600; margin: 10px 0 0; font-size: 13px; min-height: 3em; }
.client-walk-demo-controls { display: flex; justify-content: space-between; align-items: center; font-size: 12px; color: var(--ink-muted); }
.client-walk-demo-view.is-playing[data-scene='0'] .ig-client-picked { animation: client-walk-date 1s ease .4s; }
@keyframes client-walk-date { 50% { box-shadow: 0 0 0 4px var(--brand-tint); transform: scale(1.12); } }
@media (prefers-reduced-motion: reduce) { .client-walk-demo-view.is-playing .ig-client-picked { animation: none; } }
@media (max-width: 560px) {
  .client-walk { right: 16px; bottom: max(16px, env(safe-area-inset-bottom)); }
  #day-dialog > .client-walk { margin-inline: 12px; }
}

/* Shared help affordance: visible hit area, readable copy, both themes. */
.itip { vertical-align: middle; margin-left: 8px; }
.itip-btn {
  width: 32px; height: 32px; min-height: 32px; padding: 0;
  border: 1px solid var(--border-strong); border-radius: 50%;
  background: var(--surface-inset); color: var(--brand);
}
.itip-btn svg { width: 18px; height: 18px; }
.itip-btn::after { inset: 0; }
.itip-btn:hover, .itip[data-open='true'] .itip-btn {
  color: var(--brand-on-surface); border-color: currentColor; background: var(--surface-hover);
}
.itip[data-tone='warn'] .itip-btn { color: var(--warn); }
.itip-pop {
  box-sizing: border-box; width: 360px; max-width: calc(100vw - 32px);
  padding: 16px 18px; font-size: 14px; line-height: 1.6; font-weight: 400;
  border-radius: var(--radius); overflow-y: auto; overflow-wrap: anywhere;
  pointer-events: auto;
}
.itip[data-dismissed='true'] > .itip-pop { display: none; }
@media (pointer: coarse) {
  .itip-btn { width: 44px; height: 44px; min-height: 44px; }
}

/* Profile fields share an input baseline; supporting text sits below it. */
.profil-fields { align-items: start; gap: 20px; }
.profil-fields .form-row { min-width: 0; }
.profil-fields .help { margin: 6px 0 0; font-size: 13px; line-height: 1.5; }
@media (max-width: 860px) {
  /* An offer summary and its detail row form one card, never adjacent cards. */
  .my-offers tbody { grid-template-columns: minmax(0, 1fr); }
  .my-offers .c-acte, .my-offers .c-date, .my-offers .c-montant, .my-offers .c-statut {
    width: auto; min-width: 0;
  }
  .my-offers .c-statut { justify-self: stretch; }
  .my-offers .my-offer-status { display: inline-block; max-width: 100%; box-sizing: border-box; }
}

/* Shared questionnaire cards, including the dossier and optional details. */
#day-dialog:has(.day-book[data-at='2']) { width: min(96vw, 1040px); max-width: 1040px; }
.day-book[data-at='2'] { padding: 20px; gap: 16px; }
.day-book[data-at='2'] .book-rail { margin-bottom: 4px; }
.o-criteria .crit-sec { padding: 16px; gap: 16px; background: var(--surface); }
.o-criteria .crit-sec-h {
  margin: -16px -16px 0; padding: 14px 16px;
  gap: 8px 12px;
}
.o-criteria .crit-sec-grid { gap: 12px; }
.o-criteria .crit-sec-grid > .crit-row {
  padding: 12px; border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface-inset); min-width: 0;
}
.o-criteria .crit-head { margin-bottom: 8px; }
/* Le « $ » entre DANS le champ (2026-09-12) : posé à côté, il repoussait le
   cadre du montant de dix pixels vers l'intérieur — deux champs l'un sous
   l'autre, « Montant du nouveau prêt » et « Prêteur hypothécaire », ne
   finissaient donc pas sur la même verticale. Le champ va jusqu'au rail, comme
   la liste, et l'unité se lit dans sa marge droite. */
.o-criteria .crit-unit-wrap { display: flex; position: relative; width: 100%; }
.o-criteria .crit-unit-wrap input[type='number'] { width: 100%; max-width: none; min-width: 0; padding-right: 28px; }
.o-criteria .crit-unit-wrap > .crit-unit {
  position: absolute; top: 0; right: 12px; height: 100%;
  display: inline-flex; align-items: center; pointer-events: none;
}
.o-criteria .crit-row .nselect { width: 100%; max-width: none; }
.o-criteria .crit-sec-grid > .crit-row .seg-btn { flex: 1 1 0; max-width: none; min-height: 44px; }
.o-criteria .crit-row .seg.seg-stack .seg-btn { flex: auto; }
.o-criteria .crit-more { margin-top: 0; }
.o-criteria .crit-sec[data-fold='true'] { padding-bottom: 0; gap: 0; }
@media (max-width: 600px) {
  #day-dialog:has(.day-book[data-at='2']) { width: 100%; max-width: 100%; }
  .day-book[data-at='2'] { padding: 14px; }
  .o-criteria .crit-sec-grid { grid-template-columns: minmax(0, 1fr); }
  .o-criteria .crit-sec-grid > .crit-row { grid-column: 1 / -1; grid-row: auto; }
}
.o-criteria .crit-row .nselect { min-width: 100%; align-self: stretch; box-sizing: border-box; }

/* Additional text belongs below its choice, with the same usable width. */
.o-criteria .crit-row:has(> .crit-other) { flex-direction: column; flex-wrap: nowrap; gap: 8px; }
.o-criteria .crit-row:has(> .crit-other) > :is(.crit-head, .crit-effet, .nselect, .help, .crit-other) {
  flex: none; width: 100%; min-width: 0; box-sizing: border-box;
}
.o-criteria .crit-other input[type='text'] { width: 100%; max-width: none; box-sizing: border-box; }
/* The optional rows share the same question rails as their section's required
   rows. Keep the vertical separation, but do not add a second horizontal
   inset inside the disclosure. */
.o-criteria .crit-sec > .crit-more .crit-sec-grid { padding: var(--space-6) 0 0; }
/* UN SEUL RAIL POUR TOUTE LA SECTION (2026-09-12, retour du propriétaire :
   « a lot of fields in the form that are not aligned »). Le volet des
   précisions portait son propre cadre AUTOUR des rangs : sa bordure d'un pixel
   poussait chaque question facultative d'un pixel vers la droite et lui coupait
   un pixel à droite — deux questions de la même section ne commençaient donc
   pas sur la même verticale, et les deux colonnes de la grille intérieure
   tombaient à côté de celles du dessus. Le cadre passe sur la BARRE, qui
   devient une carte de la même famille que les questions ; le volet, lui, ne
   pèse plus rien dans la mise en page. */
.o-criteria .crit-sec > .crit-more { border: 0; border-radius: 0; background: none; }
.o-criteria .crit-more > summary {
  padding: 12px; min-height: 44px; box-sizing: border-box;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface-inset);
}
.o-criteria .crit-more > summary:hover { border-color: var(--border-strong); }
.o-criteria .crit-sec-grid > .crit-row { margin: 0; }

/* Keep every questionnaire track inside its card. Without an explicit
   shrinkable width, a nested flex track can preserve its intrinsic content
   width at browser zoom and pull the right-hand choices away from the shared
   rail. */
.o-criteria .crit-sec-grid,
.o-criteria .crit-row,
.o-criteria .crit-dep,
.o-criteria .crit-dep .seg {
  width: 100%;
  max-width: 100%;
  min-width: 0;
  box-sizing: border-box;
}

/* Postal lookup: a compact input followed by a clear geographic result. */
#o-where-step .coverage-note { background: var(--surface-inset); border-color: var(--border); padding: 16px; }
#o-where-step .coverage-note[data-state='none'] { border-left: 3px solid var(--warn); }
#o-where-step .coverage-note[data-state='covered'] { border-left: 3px solid var(--brand); }
.coverage-summary { display: flex; align-items: center; gap: 16px; margin-bottom: 12px; }
.coverage-count { font-size: var(--type-h2); line-height: 1; color: var(--brand); font-variant-numeric: tabular-nums; }
.coverage-caption { display: grid; gap: 4px; min-width: 0; }
.coverage-caption > span { font-size: 13px; color: var(--ink-muted); }
#o-where-step #prefix-row { gap: 10px 16px; }

/* The confirmed referral is a shared workspace above the signup and FAQ. */
.pr-grid > .partner-share-panel {
  grid-column: 1 / -1; margin: 0; padding: clamp(18px, 2vw, 24px);
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(20px, 3vw, 40px); background: var(--surface);
  border-color: var(--brand); scroll-margin-top: var(--sticky-top);
}
.pr-grid > .partner-share-panel[hidden] { display: none; }
.partner-share-panel > * { min-width: 0; }
.partner-share-panel .partner-msg { margin: 0; padding: 0 0 0 var(--space-6); border-top: 0; border-left: 1px solid var(--border); }
.partner-share-panel .partner-link-row code { flex-basis: 100%; padding: 14px; font-size: 15px; }
.partner-share-panel .partner-msg-text { margin: 12px 0; padding: 16px; font-size: 14px; line-height: 1.65; }
.partner-share-panel .btn { min-height: 44px; }
@media (max-width: 700px) {
  .pr-grid > .partner-share-panel { grid-template-columns: minmax(0, 1fr); }
  .partner-share-panel .partner-msg { padding: 20px 0 0; border-left: 0; border-top: 1px solid var(--border); }
}

/* Equal-weight, nonblocking analytics choice. Token-driven so it follows
   both themes instead of forcing a white card onto a dark canvas. */
.analytics-consent { position: fixed; inset: auto 16px 16px; z-index: 10000; max-width: 680px; margin: auto; padding: 18px; background: var(--surface); color: var(--ink); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); }
.analytics-consent[hidden] { display: none; }
.analytics-consent p { margin: 0 0 12px; font-size: 14px; line-height: 1.5; }
.analytics-consent button, #analytics-preferences:not(.footer-link) { font: inherit; cursor: pointer; padding: 8px 12px; border: 1px solid var(--border-strong); border-radius: var(--radius-sm); background: var(--surface); color: var(--ink); margin-right: 8px; }
.analytics-consent button:hover, #analytics-preferences:not(.footer-link):hover { background: var(--surface-hover); }

/* Help discovery remains available without crowding the conversation. */
.sup-topics { padding: 6px 14px; font-size: 12.5px; flex-shrink: 0; }
.sup-topics summary { cursor: pointer; color: var(--ink); padding: 8px 0; font-weight: 600; }
.sup-topics summary:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.sup-topic-list { display: flex; flex-wrap: wrap; gap: 6px; max-height: 150px; overflow-y: auto; padding: 8px 2px; }
.sup-privacy { margin: 0; padding: 8px 14px; font-size: 12px; line-height: 1.4; color: var(--ink-muted); }

/* Search and delivery recovery stay inside the dependency-free messenger. */
.sup-topic-search { width: 100%; margin-top: 6px; min-height: 36px; }
.sup-topic-empty { margin: 6px 0; color: var(--ink-muted); }

/* --- Booking component consistency --------------------------------------
   One header pattern for every criterion: the label owns the left rail, the
   information affordance owns the top-right rail, and answer effects own a
   separate right rail. The question card itself is a surface, not another
   outlined box inside the outlined section. */
#day-dialog .o-criteria .crit-head,
#day-dialog .o-criteria .crit-text {
  position: relative;
  min-width: 0;
  min-height: 44px;
  padding-right: 52px;
  align-items: center;
}

#day-dialog .o-criteria .crit-head > .itip,
#day-dialog .o-criteria .crit-text > .itip,
#day-dialog .o-criteria .crit-sec-h > .itip {
  position: absolute;
  top: 0;
  right: 0;
  margin: 0;
  transform: none;
}

#day-dialog .o-criteria .crit-sec-h:has(> .itip) {
  position: relative;
  padding-right: 52px;
}

#day-dialog .o-criteria .crit-head > .crit-label,
#day-dialog .o-criteria .crit-text > .crit-label {
  min-width: 0;
  overflow-wrap: anywhere;
  line-height: 1.35;
}

#day-dialog .o-criteria .crit-req {
  max-width: 100%;
  margin-left: 8px;
  white-space: normal;
}

#day-dialog .o-criteria .crit-flag { align-items: center; }
#day-dialog .o-criteria .crit-flag input { margin-top: 0; }

/* Labels and prices are separate flex items. This keeps « Pas encore
   demandée » and « +200 $ » readable at every width. */
#day-dialog .o-criteria .crit-row .seg-btn {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  min-width: 0;
  min-height: 44px;
  line-height: 1.35;
  text-align: left;
  overflow-wrap: anywhere;
}

#day-dialog .o-criteria .crit-row .seg-btn .crit-add {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
  margin-left: auto;
  padding-left: 12px;
  white-space: nowrap;
}

/* Keep controls readable without adding another visual frame around the
   question: the section is the grouping boundary, the surface is the row. */
#day-dialog .o-criteria .crit-sec-grid > .crit-row {
  border: 0;
  background: var(--surface);
}

#day-dialog .o-criteria .crit-sec {
  /* A confident blue wash separates each subsection from the white answer
     surfaces without adding another outline around the question. */
  background: color-mix(in srgb, var(--brand-bright) 20%, var(--surface));
}

/* Dans le dialogue, une question ne porte pas de cadre : la section est la
   frontière, la surface EST le rang. La barre des précisions suit ce registre
   — même surface, mêmes rails, aucun trait de plus — sinon elle se lisait
   comme un contrôle d'une autre famille, posé un pixel à côté des questions
   qu'elle ouvre. */
#day-dialog .o-criteria .crit-more > summary {
  border: 0;
  background: none;
}
#day-dialog .o-criteria .crit-more > summary:hover { color: var(--ink); }
#day-dialog .o-criteria .crit-more[open] > summary { margin-bottom: 0; }

/* Three-choice rows have no safe inline layout below tablet width. A single
   full-width answer per line preserves the left label rail and the right
   price rail instead of allowing a 2+1 wrap. */
@media (max-width: 900px) {
  #day-dialog .o-criteria .crit-row .seg {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-3);
  }

  #day-dialog .o-criteria .crit-row .seg-btn {
    width: 100%;
    max-width: none;
    flex: 1 1 auto;
  }
}

/* Offer sections: the white parent is the deliberate separator. The tinted
   cards remain part of the Nota palette, but their spacing is now a real gap
   instead of blue meeting blue at a border. */
#day-dialog .book-step-offer,
#day-dialog .o-criteria {
  background: var(--surface);
}

#day-dialog .book-step-offer {
  gap: var(--space-12);
}

/* The offer step is intentionally allowed to remain a block in the base
   layout; use a sibling margin as well so the white separator survives that
   cascade and remains visible between each tinted section. */
#day-dialog .book-step-offer > .offer-sec + .offer-sec {
  margin-top: var(--space-12);
}

#day-dialog .o-criteria {
  gap: var(--space-12);
}

#day-dialog .offer-sec,
#day-dialog .o-criteria .crit-sec {
  background: var(--surface-inset);
}

#day-dialog .offer-sec .crit-sec-h,
#day-dialog .o-criteria .crit-sec-h {
  background: var(--surface);
}

/* Section pictograms are brand signals, not controls: no enclosing border or
   tint, including after the section is completed. */
#day-dialog .crit-sec-ic {
  border: 0;
  background: transparent;
  color: var(--brand);
  transition: color .15s;
}

.sup-msg[data-delivery='unconfirmed'] .sup-bubble { border: 1px dashed var(--border-strong); }
.sup-delivery { color: var(--ink-muted); font-size: 12px; }
.sup-recover { font: inherit; font-size: 12px; padding: 6px 8px; color: var(--ink); background: var(--surface); border: 1px solid var(--border); cursor: pointer; }
.sup-recover:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
#chat-reply-recovery .help { white-space: pre-wrap; overflow-wrap: anywhere; }

/* ==========================================================================
   LA SALLE DE SIGNATURE — ADR 0047

   Plein écran, et volontairement sombre : une cérémonie n'est pas une page du
   site. Ce qui doit rester lisible à distance d'un écran — la chaîne
   d'authentification, l'état des quatre portes, le texte de conduite — l'est
   avant tout le reste. Le bandeau bêta est au-dessus de tout et ne se cache
   jamais.
   ========================================================================== */
.salle { position: fixed; inset: 0; z-index: 11000; display: flex; flex-direction: column; background: var(--nota-blue-950); color: var(--midnight-ink); }
.salle[hidden] { display: none; }
/* Le fond de la page ne défile plus derrière la salle. */
body.salle-ouverte { overflow: hidden; }

/* Le bandeau. Aucune règle ne le masque, aucun rendu ne le touche. */
.salle-beta { margin: 0; padding: 10px 16px; text-align: center; font-size: 13px; line-height: 1.45; background: var(--warn); color: var(--on-warn); }
.salle-beta strong { font-weight: 700; }

.salle-scene { flex: 1; display: grid; grid-template-columns: minmax(0, 1fr) 380px; min-height: 0; }

.salle-videos { position: relative; min-height: 0; background: var(--midnight-matte); }
.salle-video { display: block; width: 100%; height: 100%; object-fit: cover; background: var(--midnight-matte); }
.salle-video-distant { width: 100%; height: 100%; }
/* La vignette locale : assez grande pour se vérifier, assez petite pour ne pas
   voler l'attention de la personne d'en face. */
.salle-video-local { position: absolute; right: 16px; bottom: 16px; width: 22%; min-width: 140px; max-width: 260px; height: auto; aspect-ratio: 4 / 3; border: 1px solid var(--border-strong); border-radius: var(--radius); box-shadow: var(--shadow-lg); }

.salle-rail { display: flex; flex-direction: column; gap: 14px; padding: 18px; overflow-y: auto; background: var(--nota-blue-900); border-left: 1px solid var(--nota-blue-800); }
.salle-bloc { padding: 14px; background: var(--midnight-veil-soft); border: 1px solid var(--nota-blue-800); border-radius: var(--radius); }
.salle-etape-nom { margin: 0 0 8px; font-size: var(--type-h3); line-height: var(--type-h3-lh); letter-spacing: var(--type-h3-ls); }
.salle-etape-conduite { margin: 0 0 8px; font-size: 15px; line-height: 1.5; }
.salle-etape-constat { margin: 0; font-size: 13px; line-height: 1.45; color: var(--nota-blue-300); }

/* La chaîne d'authentification. C'est la ligne qu'on lit à voix haute : elle a
   droit à la plus grosse typographie de l'écran, en chasse fixe pour que S et 5
   ne se confondent pas. */
.salle-bloc-sas { text-align: center; }
.salle-sas-titre { margin: 0 0 6px; font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--midnight-ink); }
.salle-sas { margin: 0; font-family: var(--font-mono); font-size: var(--type-h2); font-weight: 700; letter-spacing: 0.12em; }
.salle-sas.is-confirme { color: var(--nota-blue-400); }
.salle-sas-aide { margin: 6px 0 0; font-size: 12px; line-height: 1.4; color: var(--nota-blue-300); }

.salle-portes-titre { margin: 0 0 8px; font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--midnight-ink); }
.salle-portes { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 8px; }
.salle-porte { display: grid; grid-template-columns: 20px minmax(0, 1fr); gap: 4px 8px; font-size: 14px; line-height: 1.4; }
.salle-porte-marque { color: var(--warn); font-weight: 700; }
.salle-porte.is-ouverte .salle-porte-marque { color: var(--nota-blue-400); }
.salle-porte-nom { font-weight: 600; }
/* Une porte fermée DIT pourquoi. Le motif s'aligne sous le nom, pas sous la
   marque : c'est une phrase, pas une puce. */
.salle-porte-motif { grid-column: 2; margin: 0; font-size: 13px; line-height: 1.4; color: var(--nota-blue-200); }

.salle-statut { display: flex; flex-direction: column; gap: 8px; }
.salle-statut-ligne { margin: 0; font-size: 13px; line-height: 1.45; color: var(--nota-blue-200); }
.salle-statut-ligne.is-alerte { padding: 10px; background: var(--danger-wash); border: 1px solid var(--danger); border-radius: var(--radius-sm); color: var(--danger-pale); }
.salle-statut-ligne.is-enregistre { color: var(--warn); font-weight: 600; }
.salle-empreinte { display: block; overflow-wrap: anywhere; font-family: ui-monospace, "SFMono-Regular", "Menlo", "Consolas", monospace; font-size: 11px; line-height: 1.5; color: var(--nota-blue-300); }

.salle-refus { display: flex; flex-direction: column; gap: 6px; padding: 10px; background: var(--danger-wash); border: 1px solid var(--danger); border-radius: var(--radius-sm); }
.salle-refus[hidden] { display: none; }
.salle-refus-ligne { margin: 0; font-size: 13px; line-height: 1.45; color: var(--danger-pale); }

.salle-actions { display: flex; flex-direction: column; gap: 8px; }
.salle-btn { font: inherit; font-size: 14px; font-weight: 600; padding: 11px 14px; cursor: pointer; text-align: left; color: var(--midnight-ink); background: var(--midnight-veil); border: 1px solid var(--nota-blue-700); border-radius: var(--radius-sm); }
.salle-btn:hover:not(:disabled) { background: var(--midnight-veil-strong); }
.salle-btn.is-primaire { background: var(--midnight-veil); border-color: var(--nota-blue-400); color: var(--midnight-ink); font-weight: 700; }
.salle-btn.is-primaire:hover:not(:disabled) { background: var(--midnight-veil); border-color: var(--nota-blue-300); }
.salle-btn.is-discret { background: transparent; font-weight: 500; }
.salle-btn:disabled { opacity: 0.45; cursor: not-allowed; }
.salle-quitter { margin-top: auto; }

/* Sur un téléphone la vidéo passe au-dessus et le rail dessous : le notaire
   conduit rarement depuis un téléphone, le client souvent. */
@media (max-width: 860px) {
  .salle-scene { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(180px, 40vh) minmax(0, 1fr); }
  .salle-rail { border-left: 0; border-top: 1px solid var(--nota-blue-800); }
  .salle-sas { font-size: 28px; }
}

/* L'annonce, dans le carnet et dans l'espace notaire. */
/* Coins carrés comme tout le reste : la marque a tranché contre l'arrondi, et
   une pastille en pilule ferait une exception que rien ne justifie ici. */
.salle-annonce-pastille { display: inline-block; margin: 0 0 8px; padding: 3px 10px; font-size: 12px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--brand-ink); background: var(--brand); border-radius: var(--radius-xs); }
.salle-annonce-actions { margin-top: 14px; display: flex; flex-wrap: wrap; gap: 8px; }

/* Beta: an explicit home for experiments, but still part of the public site.
   It shares the carnet's open canvas, measure and editorial rhythm; the beta
   is a feature of Nota, not a separate branded microsite. */
.beta-page { max-width: var(--maxw); padding-top: clamp(28px, 3.2vw, 48px); padding-bottom: clamp(40px, 5vw, 72px); }
.beta-hero { display: grid; grid-template-columns: minmax(0, .94fr) minmax(0, 1.06fr); gap: clamp(32px, 5vw, 72px); align-items: center; }
.beta-eyebrow { display: flex; align-items: center; gap: 9px; margin: 0 0 16px; font-size: var(--type-eyebrow); font-weight: var(--weight-display); letter-spacing: var(--type-eyebrow-ls); text-transform: uppercase; color: var(--subtitle-ink); }
.beta-dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.beta-intro h1 { max-width: 560px; margin: 0 0 16px; }
.beta-lead { max-width: 47ch; color: var(--ink-muted); font-size: var(--type-lead); line-height: var(--type-lead-lh); }
.beta-actions { display: flex; flex-wrap: wrap; gap: var(--space-6); align-items: center; margin-top: var(--space-10); }
.beta-actions .btn { min-height: 44px; white-space: normal; text-align: center; }
.beta-actions .btn-lg { padding-inline: 17px; }
.beta-caption { margin: var(--space-6) 0 0; max-width: 56ch; color: var(--ink-muted); font-size: 12px; line-height: 1.55; }
.beta-preview { width: min(100%, 600px); justify-self: end; border: 1px solid var(--border); border-radius: var(--radius-lg); padding: clamp(20px, 2.4vw, 30px); background: var(--surface); box-shadow: var(--shadow-sm); }
.beta-preview-top { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; justify-content: space-between; font-weight: 700; }
.beta-preview-tag { font-size: 11px; color: var(--ink-muted); background: transparent; border: 1px solid var(--border); padding: 6px 9px; border-radius: var(--radius-xs); }
.beta-preview-scene { display: grid; grid-template-columns: .9fr 1fr; gap: clamp(14px, 2vw, 22px); margin: 22px 0 20px; min-height: 228px; }
.beta-preview-person { display: flex; align-items: center; justify-content: center; background: var(--surface-inset); border: 1px solid var(--border-strong); border-radius: var(--radius); }
.beta-preview-person svg { width: 80%; stroke: var(--nota-blue-300); stroke-width: 1.5; }
.beta-preview-paper { min-width: 0; border: 1px solid var(--border-strong); border-radius: var(--radius-sm); padding: 22px 16px; transform: rotate(3deg); background: var(--surface); box-shadow: var(--shadow-sm); }
.beta-paper-brand { display: block; color: var(--ink-muted); font-size: 13px; font-weight: 700; margin-bottom: 25px; }
.beta-preview-paper i { display: block; height: 4px; background: var(--border); margin: 11px 0; }
.beta-preview-paper i:nth-of-type(2) { width: 80%; }
.beta-preview-paper i:nth-of-type(4) { width: 60%; }
.beta-preview-paper svg { display: block; width: 100%; margin-top: 16px; stroke: var(--brand); stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.beta-preview-steps { list-style: none; display: flex; flex-wrap: wrap; justify-content: space-between; gap: 12px; padding: 16px 0 0; margin: 0; border-top: 1px solid var(--border); font-size: 11px; color: var(--ink-muted); }
.beta-preview-steps li { flex: 1 1 0; }
.beta-preview-steps li:not(:last-child) { position: relative; }
.beta-preview-steps li:not(:last-child)::after { content: ''; position: absolute; top: .65em; right: 8px; width: 18px; border-top: 1px solid var(--border-strong); transform: translateX(50%); }
.beta-boundary { display: grid; grid-template-columns: minmax(180px, 220px) 1fr; gap: clamp(20px, 3vw, 36px); align-items: start; margin-top: clamp(28px, 3.5vw, 40px); padding: 20px 24px; border: 1px solid var(--border); border-left: 3px solid var(--brand); background: var(--surface); border-radius: 0 var(--radius) var(--radius) 0; font-size: 14px; line-height: 1.65; box-shadow: var(--shadow-sm); }
.beta-boundary p { margin: 0; color: var(--ink-muted); }
.beta-experience { margin-top: clamp(32px, 4vw, 52px); }
.beta-section-heading h2, .beta-access-grid h2 { margin: 0 0 16px; }
.beta-features { list-style: none; display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(16px, 2.5vw, 28px); margin: 16px 0 0; padding: 0; }
.beta-features li { min-width: 0; padding: 18px 18px 18px; border: 1px solid var(--border); border-top: 3px solid var(--brand); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow-sm); }
.beta-step { display: block; line-height: 1.2; margin-bottom: 6px; font-size: 13px; font-weight: 700; color: var(--ink-muted); }
.beta-features h3 { margin: 4px 0 6px; }
.beta-features li p { margin: 0; }
.beta-features p, .beta-access-grid p, .beta-demo p { font-size: 14px; color: var(--ink-muted); line-height: 1.7; }
/* La section « Confiance et hébergement » et la note d'infrastructure : le
   balisage existait, la feuille ne les connaissait PAS. Trois articles et un
   aside s'empilaient donc en blocs pleine largeur — 1 540 px pour trois
   phrases, d'où le grand vide vu par le propriétaire le 2026-09-12. Elles
   reprennent la langue des cartes d'étapes juste au-dessus : même filet de
   marque en tête, même mesure, même rythme. */
.beta-security-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(16px, 2.5vw, 28px); margin: 18px 0 0; }
.beta-security-card { min-width: 0; padding: 18px 18px 20px; border: 1px solid var(--border); border-top: 3px solid var(--brand); border-radius: 0 0 var(--radius) var(--radius); background: var(--surface); box-shadow: var(--shadow-sm); }
.beta-security-icon { display: block; line-height: 1.2; margin-bottom: 6px; font-size: 13px; font-weight: 700; color: var(--ink-muted); }
.beta-security-card h3 { margin: 4px 0 6px; }
.beta-security-card p { margin: 0; font-size: 14px; color: var(--ink-muted); line-height: 1.7; }
.beta-security-card .beta-eyebrow { margin: 0 0 2px; }
/* La note d'infrastructure partage la grille de la portée : un intitulé à
   gauche, la phrase à droite, et un filet qui la rattache au récit. */
aside.beta-security { display: grid; grid-template-columns: minmax(180px, 220px) 1fr; gap: clamp(20px, 3vw, 36px); align-items: baseline; margin-top: clamp(24px, 3vw, 36px); padding-top: 18px; border-top: 1px solid var(--border); font-size: 14px; line-height: 1.65; }
aside.beta-security p { margin: 0; color: var(--ink-muted); }
section.beta-security { margin-top: clamp(32px, 4vw, 52px); }
.beta-access-grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(18px, 3vw, 32px); margin-top: clamp(20px, 2.5vw, 32px); }
.beta-access, .beta-upcoming { min-width: 0; border: 1px solid var(--border); background: var(--surface); padding: clamp(20px, 2.5vw, 26px); border-radius: var(--radius); box-shadow: var(--shadow-sm); }
.beta-upcoming { background: var(--surface-inset); }
.beta-access-grid .beta-eyebrow { color: var(--subtitle-ink); font-size: 12px; }
.beta-access-grid .btn { margin-top: 12px; min-height: 44px; white-space: normal; text-align: center; }
.beta-upcoming ul { padding-left: 20px; color: var(--ink-muted); font-size: 14px; line-height: 1.7; }
.beta-upcoming li + li { margin-top: 12px; }
.beta-demo { border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); margin-top: clamp(24px, 3vw, 36px); padding: 16px 0; }
.beta-demo summary { cursor: pointer; padding: 4px 0; min-height: 32px; font-size: 15px; font-weight: 650; }
.beta-demo summary:focus-visible { outline: 2px solid var(--ring); outline-offset: 5px; }
.beta-demo p { max-width: 850px; }
@media (max-width: 980px) {
  .beta-hero { gap: 32px; }
  .beta-security-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .beta-preview { padding: 20px; }
  .beta-preview-scene { min-height: 190px; gap: 10px; }
}
@media (max-width: 720px) {
  .beta-page { padding-top: 30px; padding-bottom: 44px; }
  .beta-hero { grid-template-columns: 1fr; gap: 30px; }
  .beta-preview { max-width: 480px; width: 100%; box-sizing: border-box; }
  .beta-preview-scene { min-height: 0; align-items: start; margin: 16px 0 8px; }
  .beta-preview-paper { padding: 18px 14px 14px; }
  .beta-preview-steps { padding-top: 10px; }
  .beta-preview-person { aspect-ratio: 4 / 5; align-self: start; }
  .beta-preview-person svg { width: 62%; }
  .beta-boundary { grid-template-columns: 1fr; gap: 8px; margin-top: 28px; padding: 20px; }
  aside.beta-security { grid-template-columns: 1fr; gap: 8px; }
  .beta-experience { margin-top: 40px; }
  .beta-features, .beta-access-grid, .beta-security-grid { grid-template-columns: 1fr; gap: 16px; }
  .beta-features h3 { margin-top: 4px; }
  .beta-access, .beta-upcoming { padding: 24px; }
  .beta-access-grid { margin-top: 20px; }
  .beta-lead { font-size: 16px; }
}

/* --- Notary landing polish ----------------------------------------------
   The door opens on the SAME surface the Carnet opens on (owner, 2026-09-12:
   « Carnet est vraiment ce que Nota doit dégager… s'assurer que l'espace
   notaire, partenaire, signature » suivent). No filled box, no side padding
   that moves the headline off the wrap's left edge, and the ink is the page's
   ink — --brand-ink is the inverted ink that belongs ON a brand fill, and with
   the fill gone it read white on a pale tint. */
#pane-notaires .intro--hero {
  margin-top: var(--space-4);
  padding-block: var(--space-9);
  border: 0;
}

#pane-notaires .intro--hero h1 {
  color: var(--ink);
  animation: none;
}

#pane-notaires .intro--hero p {
  color: var(--ink-muted);
  animation: none;
}

#pane-notaires .intro--hero .eyebrow {
  color: var(--subtitle-ink);
  animation: none;
}

#pane-notaires .nc-live-head {
  padding-inline: var(--space-2);
}

/* A heading is ink on every other surface — including this pane's own
   « Conformité » heading. Blue is for an informational mention (an amount, a
   link, a badge), never for the label a section is read by. */
#pane-notaires .nc-live-h,
#pane-notaires #notary-console .h-sub {
  color: var(--ink);
}

#pane-notaires .nc-live-card {
  border-color: var(--border);
  border-radius: var(--radius);
  background: var(--nota-blue-50);
}

#pane-notaires .nc-live-card:hover {
  border-color: var(--brand);
  background: var(--surface-hover);
}

/* The act's name stays ink — the base rule says so in as many words, and the
   same grammar runs the carnet's own strip. Only the amount is blue. */
#pane-notaires .nc-live-amt {
  color: var(--brand-hover);
}

#pane-notaires .nc-live-amt {
  font-weight: 700;
}

#pane-notaires .nc-live-meta {
  color: var(--ink-muted);
}

#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-console {
  border-radius: var(--radius);
  border: 1px solid var(--border-strong);
  background: var(--surface);
  box-shadow: var(--shadow-lg);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

#pane-notaires .nc-auth-cta {
  background: transparent;
  border-color: var(--brand);
  color: var(--brand-on-surface);
}

#pane-notaires .nc-auth-cta:hover {
  background: var(--brand-tint-solid);
  border-color: var(--brand-hover);
  color: var(--brand-on-surface);
}

#pane-notaires .nc-signup-open {
  color: var(--brand);
}

@media (max-width: 640px) {
  #pane-notaires .intro--hero {
    margin-top: var(--space-4);
    padding-block: var(--space-9);
  }

  #pane-notaires .intro--hero h1 {
    font-size: var(--type-h1-compact);
  }

  #pane-notaires .nc-live {
    padding: var(--space-5);
  }
}

/* Final notary landing surface: keep the compact, square-edged Nota system
   last in the cascade so legacy treatments cannot reintroduce a side rail or
   white floating cards. */
/* (The hero keeps the page's own surface — see the landing block above.) */
#pane-notaires .intro--hero p { color: var(--ink-muted); opacity: 1; }
#pane-notaires .intro--hero .eyebrow { color: var(--subtitle-ink); opacity: 1; }
#pane-notaires .nc-live-card {
  border-radius: var(--radius);
  background: var(--surface-inset);
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-console {
  border-radius: var(--radius);
  background: linear-gradient(145deg, var(--surface-inset) 0%, var(--brand-tint-solid) 100%);
}

/* --- Partenaires: same Nota surface language as Carnet / Espace notaire ---
   The partner page is a conversion surface, not a loose collection of
   outlined boxes. The hero groups the value, the story and claim form then
   share the same compact rhythm. */
/* The hero is NOT re-boxed here. The block above records the owner's own ask
   (2026-08-27: « add some gradient… no corner… smooth for the eyes », and
   « move to left ») and this layer had put the box back: side padding that
   pushed the h1 16–24px off the Carnet's left edge at every width, a hairline
   radius, a shadow and an opaque fill, where Carnet's hero is one continuous
   chromeless surface. Only the alignment survives. */
#pane-partenaires .pr-hero {
  align-items: start;
}
#pane-partenaires .pr-hero-copy > p { max-width: 58ch; }
#pane-partenaires .pr-rewards { gap: var(--space-5); }
/* Both cards sit on ONE green register (owner, 2026-08-27 evening: strong tint
   for the 250 $, REGULAR tint for the 50 $). The 50 $ card had been given the
   veil instead of the tint, so it carried no green at all and the pair read as
   two different objects. --radius-lg, like every large surface on Carnet. */
#pane-partenaires .pr-card {
  min-height: 0;
  padding: var(--space-8) var(--space-9);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  background: var(--surface-veil);
  box-shadow: var(--shadow-sm);
}
#pane-partenaires .pr-card--notaire {
  border-color: var(--brand);
  background: var(--surface-veil);
}
#pane-partenaires .pr-amount { color: var(--brand-hover); }
#pane-partenaires .pr-grid { margin-top: var(--space-8); gap: var(--space-10); }
/* A large panel carries the veil AND its blur — the register is a pair, and
   this one had the veil replaced by an opaque gradient and the blur explicitly
   cancelled, which is the one thing the register forbids. */
#pane-partenaires .pr-form-panel {
  padding: var(--space-9);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  background: var(--surface-veil);
  box-shadow: var(--shadow-lg);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}
#pane-notaires .nc-auth-cta {
  background: transparent;
  border-color: var(--brand);
  color: var(--brand-on-surface);
  box-shadow: none;
}
#pane-notaires .nc-auth-cta:hover {
  background: var(--brand-tint-solid);
  border-color: var(--brand-hover);
  color: var(--brand-on-surface);
}

@media (prefers-reduced-motion: no-preference) {
  #pane-partenaires .pr-hero-copy > *,
  #pane-partenaires .pr-grid > * {
    animation: fadeUp .42s cubic-bezier(.2, .8, .2, 1) both;
  }
  #pane-partenaires .pr-hero-copy > *:nth-child(2) { animation-delay: .06s; }
  #pane-partenaires .pr-hero-copy > *:nth-child(3) { animation-delay: .12s; }
  #pane-partenaires .pr-hero-copy > *:nth-child(4) { animation-delay: .18s; }
  #pane-partenaires .pr-hero-copy > *:nth-child(5) { animation-delay: .24s; }
  #pane-partenaires .pr-grid > *:nth-child(2) { animation-delay: .1s; }
}


@media (max-width: 900px) {
  /* No side padding here either: the wrap already holds the page's gutter, and
     16px on top of it pushed this door's headline off the line every other
     door starts on. */
  #pane-partenaires .pr-form-panel { padding: var(--space-8); }
}

/* --- Notary landing: focused split --------------------------------------
   The landing has two jobs: show the week on the left and open the notary
   door on the right. Keep the split compact and let the page background do
   the framing; large outlined slabs made the previous version feel wider
   than it was. The beta announcement remains available from its own tab, but
   is not part of this acquisition path. */
.notary-landing-left {
  grid-area: left;
  min-width: 0;
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) {
  /* The house measure, not a private one: at 1920 this door was 160px
     narrower than the Carnet beside it, so the two panes did not share a
     left edge on the widest screens. */
  width: min(100%, var(--maxw));
  grid-template-columns: minmax(0, 1.55fr) minmax(300px, .75fr);
  grid-template-areas:
    "left       right"
    "conformite conformite"
    "guarantee  guarantee";
  column-gap: clamp(24px, 3vw, 48px);
}

#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-landing-right {
  grid-area: right;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  min-width: 0;
}

#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-ai-beta-note {
  display: none;
}

#pane-notaires .intro--hero {
  margin-top: var(--space-6);
  padding: var(--space-10) 0 var(--space-8);
  background: transparent;
  box-shadow: none;
}

#pane-notaires .intro--hero p {
  max-width: 58ch;
  color: var(--ink-muted);
}

#pane-notaires .nc-live-head {
  padding-inline: 0;
  margin-top: var(--space-2);
}

/* The page canvas continues between offers. Only individual cards need a
   surface; a second panel behind the inventory creates empty white rails. */
#pane-notaires .nc-live {
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  box-shadow: none;
}

#pane-notaires .nc-live-grid {
  gap: var(--space-5);
}

#pane-notaires .nc-live-card {
  background: var(--nc-offer-surface);
}

#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-console {
  align-self: start;
  width: 100%;
  margin: var(--space-6) 0 0;
  padding: clamp(22px, 3vw, 36px);
  border: 0;
  border-radius: var(--radius-lg);
  background: color-mix(in srgb, var(--brand-bright) 11%, var(--surface));
  box-shadow: none;
}

#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-landing-right #notary-console {
  order: 1;
  margin-top: var(--space-6);
}

#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-console .nc-gate {
  max-width: none;
}

#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-carnet {
  order: 2;
  margin: var(--space-6) 0 0;
  padding: 0;
  border-top: 0;
}

#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-carnet .sub-card {
  padding: 0;
  background: transparent;
  box-shadow: none;
}

.beta-teaser-info {
  background: transparent;
}

.beta-teaser-info:hover {
  background: transparent;
}

.guide-fab {
  background: transparent;
  box-shadow: none;
}

.guide-fab:hover {
  background: transparent;
  box-shadow: none;
  border-color: var(--brand);
}

@media (max-width: 899.98px) {
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) {
    width: 100%;
    display: flex;
    flex-direction: column;
    grid-template-columns: minmax(0, 1fr);
    row-gap: 0;
  }

  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-landing-left,
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-landing-right {
    display: contents;
  }

  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .intro--hero { order: 1; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-console { order: 2; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .nc-live-head { order: 3; width: 100%; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .nc-live { order: 4; width: 100%; align-self: stretch; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-carnet { order: 5; width: 100%; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #nc-conformite { order: 6; width: 100%; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .nota-guarantee { order: 7; width: 100%; }

  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-console {
    margin-top: 0;
  }

  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .nc-live-head {
    margin-top: var(--space-12);
  }

  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-carnet {
    margin-top: var(--space-10);
  }
}

@media (max-width: 560px) {
  #pane-notaires .intro--hero {
    margin-top: var(--space-4);
    padding-block: var(--space-8) var(--space-7);
  }

  #pane-notaires .intro--hero h1 {
    font-size: var(--type-h1-compact);
  }

  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-console {
    padding: var(--space-8);
  }
}

/* Final landing geometry: keep the public proof and the access door in one
   reading order at every breakpoint. The responsive contract uses the hero as
   the desktop alignment line, and the inventory as the mobile hand-off. */
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-landing-right #notary-console {
  margin-top: 0;
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-ai-beta-note {
  display: block;
}
@media (max-width: 899.98px) {
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-ai-beta-note { order: 2; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-landing-right #notary-console { order: 5; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-carnet { order: 6; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #nc-conformite { order: 7; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .nota-guarantee { order: 8; }
}

/* Tablets keep the desktop header but use the same honest one-column landing
   as phones: the inventory must finish before the access gate begins. */
@media (min-width: 900px) and (max-width: 1200px) {
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) {
    display: flex;
    flex-direction: column;
    width: 100%;
  }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-landing-left,
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-landing-right { display: contents; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .intro--hero { order: 1; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-ai-beta-note { order: 2; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .nc-live-head { order: 3; width: 100%; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .nc-live { order: 4; width: 100%; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-landing-right #notary-console { order: 5; margin-top: 0; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-carnet { order: 6; width: 100%; margin-top: var(--space-10); }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #nc-conformite { order: 7; width: 100%; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .nota-guarantee { order: 8; width: 100%; }
}

/* Sous 1200px, le rail des notaires n'est plus une grille nommée mais une
   COLONNE FLEX dont chaque bloc porte son `order` — un bloc sans order tombe
   donc à 0, c'est-à-dire tout en haut, au-dessus du titre (constaté au
   navigateur, 2026-09-12). Les promesses partagent l'ordre du héros : elles le
   suivent dans le balisage, donc elles le suivent à l'écran. */
@media (max-width: 1200px) {
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .nc-promesses { order: 1; width: 100%; }
}

/* Empty inventory keeps the same footprint as the six quiet slots behind it,
   so the empty message does not collapse or create a layout jump. */
.nc-live-grid--empty { position: relative; }
.nc-live-grid--empty .nc-live-empty {
  position: absolute; inset: 0; z-index: 1; display: grid; place-items: center;
  min-height: 100%; padding: var(--space-8); box-sizing: border-box;
  color: var(--ink-muted); text-align: center; pointer-events: none;
}

/* --- Account menu refinement ---------------------------------------------
   Keep the account hub calm and flat: the shadow separates it from the page,
   while the identity row remains part of the menu instead of becoming a card
   inside another card. */
.acct-panel {
  width: min(368px, calc(100vw - 24px));
  padding: 10px;
  border: 0;
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow-lg);
}
.acct-panel-head {
  align-items: center;
  gap: 8px;
  padding: 2px;
}
.acct-panel-head .acct-head {
  gap: 11px;
  padding: 10px;
  border: 0;
  background: transparent;
}
.acct-panel-head .acct-head:hover,
.acct-panel-head .acct-head:focus-visible {
  background: var(--surface-hover);
}
.acct-avatar {
  width: 40px;
  height: 40px;
  background: var(--surface);
  border-color: var(--border-strong);
}
.acct-item-title { font-size: 15px; letter-spacing: -0.01em; }
.acct-item-sub { font-size: 12px; line-height: 1.35; }
.acct-role { margin-top: 3px; padding: 2px 7px; background: transparent; }
.acct-close {
  width: 34px;
  height: 34px;
  border: 1px solid transparent;
  border-radius: var(--radius);
}
.acct-close:hover,
.acct-close:focus-visible {
  border-color: var(--border);
  background: var(--surface-hover);
}
.acct-sep { margin: 8px 4px; background: color-mix(in srgb, var(--border-strong) 70%, transparent); }
.acct-actions { gap: 3px; padding: 1px 2px; }
.acct-action {
  min-height: 42px;
  padding: 8px 10px;
  border: 1px solid transparent;
  transition: background-color .16s ease, border-color .16s ease, transform .16s ease;
}
.acct-action svg {
  width: 18px;
  height: 18px;
  color: var(--brand);
}
.acct-action:hover,
.acct-action:focus-visible {
  border-color: var(--border);
  background: var(--surface-hover);
}
.acct-action:hover { transform: translateX(2px); }
.acct-action:last-child {
  margin-top: 4px;
  border-top-color: var(--border);
  color: var(--ink-muted);
}
.acct-action:last-child svg { color: var(--ink-muted); }
.acct-notifs { margin-top: 2px; }
.acct-panel .notif-head {
  padding: 5px 10px 4px;
  color: var(--ink-muted);
}
.acct-panel .notif-list {
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-veil);
}
.acct-panel .notif-item {
  padding: 9px 34px 9px 10px;
  border-bottom-color: var(--border);
}
.acct-panel .notif-item:last-child { border-bottom: 0; }
.acct-panel .notif-item.is-unread { background: var(--surface-hover); }
.acct-legal {
  gap: 2px;
  padding: 0 2px 1px;
}
.acct-legal-link { padding: 5px 7px; }

@media (max-width: 899.98px) {
  .acct-panel {
    position: fixed;
    top: calc(var(--header-h) + 8px);
    right: 8px;
    width: min(360px, calc(100vw - 16px));
  }
}

/* Final visual pass: these rules intentionally sit after the responsive intro
   rules so the calm chooser treatment wins at every viewport size. */
#pane-beta {
  --beta-heading: var(--ink); /* the same ink the Carnet's headline reads in */
}

/* Both dark paths, like every other token pair in this file: the explicit
   toggle AND the system preference. With only the toggle branch, a visitor on
   system dark read a near-black heading on the near-black pane. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) #pane-beta { --beta-heading: var(--ink); }
}

html[data-theme='dark'] #pane-beta {
  --beta-heading: var(--ink);
}

#pane-beta .beta-intro h1,
#pane-beta .beta-section-heading h2,
#pane-beta .beta-access-grid h2 {
  color: var(--beta-heading);
}

#pane-beta .beta-eyebrow { color: var(--subtitle-ink); }

#pane-beta .beta-experience { margin-top: clamp(32px, 4vw, 52px); }
#pane-beta .beta-access-grid { margin-top: clamp(20px, 2.5vw, 32px); }
#pane-beta .beta-demo { margin-top: clamp(24px, 3vw, 36px); }

#pane-beta .beta-preview,
#pane-beta .beta-features li,
#pane-beta .beta-access,
#pane-beta .beta-upcoming,
#pane-beta .beta-actions .btn {
  transition: transform .28s cubic-bezier(.2, .8, .2, 1),
    box-shadow .28s ease, border-color .2s ease, background-color .2s ease;
}

#pane-beta .beta-preview:hover,
#pane-beta .beta-preview:focus-within {
  transform: translateY(-7px);
  box-shadow: 0 30px 64px -30px rgb(var(--nota-blue-700-rgb) / .6);
}

#pane-beta .beta-preview-paper {
  transition: transform .35s cubic-bezier(.2, .8, .2, 1);
}

#pane-beta .beta-preview:hover .beta-preview-paper,
#pane-beta .beta-preview:focus-within .beta-preview-paper {
  transform: rotate(1.2deg) translateY(-4px);
}

#pane-beta .beta-actions .btn:hover,
#pane-beta .beta-actions .btn:focus-visible {
  transform: translateY(-2px);
}

@keyframes beta-brand-rise {
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: translateY(0); }
}

#pane-beta .beta-intro { animation: beta-brand-rise .55s cubic-bezier(.2, .8, .2, 1) both; }
#pane-beta .beta-preview { animation: beta-brand-rise .65s .06s cubic-bezier(.2, .8, .2, 1) both; }

@media (prefers-reduced-motion: reduce) {
  #pane-beta .beta-intro,
  #pane-beta .beta-preview { animation: none; }
  #pane-beta .beta-preview,
  #pane-beta .beta-preview-paper,
  #pane-beta .beta-features li,
  #pane-beta .beta-access,
  #pane-beta .beta-upcoming,
  #pane-beta .beta-actions .btn { transition: none; }
}

.ig-chooser {
  /* Let the ambient marks pass through as one soft field. The foreground
     stays crisp; only the background is blurred, which visually joins the
     N block and OTA without washing out the lettering. */
  background: linear-gradient(145deg,
    color-mix(in srgb, var(--surface) 64%, transparent),
    color-mix(in srgb, var(--surface) 78%, transparent));
  border-color: color-mix(in srgb, var(--border-strong) 72%, transparent);
  box-shadow: var(--shadow), 0 22px 56px -30px rgb(var(--nota-blue-700-rgb) / .36);
  -webkit-backdrop-filter: blur(18px) saturate(1.08);
  backdrop-filter: blur(18px) saturate(1.08);
}
.mark-drift--intro { opacity: .86; }
.mark-drift--intro i { opacity: calc(var(--o, .025) * 1.18); }
.ig-enter {
  color: var(--brand);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding-inline: 16px;
  transition: border-color .18s ease, background-color .18s ease, transform .18s ease;
}
.ig-enter:hover { color: var(--brand-on-surface); border-color: var(--border-strong); background: var(--surface-inset); transform: translateY(-1px); }
.language-control { opacity: 0 !important; pointer-events: auto !important; }
#lang-toggle.language-control {
  position: relative !important;
  top: auto; right: auto; width: 1px; height: 1px;
  margin: 0; padding: 0; overflow: visible; border: 0;
  z-index: 1;
}
.ig-chooser > .language-control { width: 1px; height: 1px; overflow: visible; }
.ig-controls > .language-control {
  position: absolute !important; inset: 0 auto auto 0;
  width: 1px; height: 1px; margin: 0; padding: 0; overflow: visible;
}
.mnav-pref.language-control {
  min-height: 1px; height: 1px; margin-block: -1px !important; overflow: visible;
}
#lang-toggle.language-control { min-width: 0 !important; }
@media (min-width: 1080px) {
  .ig-chooser {
    display: flex;
    width: min(920px, 94vw);
    max-width: 920px;
    padding-inline: clamp(48px, 7vw, 88px);
  }
  .ig-chooser > .ig-wordmark,
  .ig-chooser > .ig-title,
  .ig-chooser > .ig-lede,
  .ig-chooser > .ig-doors,
  .ig-chooser > .ig-enter { grid-area: auto; }
  .ig-doors { flex-direction: row; gap: 14px; }
}
.analytics-consent {
  left: 50%; right: auto; bottom: 16px;
  width: min(560px, calc(100vw - 32px)); max-width: none;
  padding: 12px 14px;
  transform: translateX(-50%);
  background: var(--surface);
  border-color: var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.analytics-consent p { margin-bottom: 8px; font-size: 12px; line-height: 1.45; }
.analytics-consent button, #analytics-preferences:not(.footer-link) { padding: 7px 10px; margin-right: 4px; font-size: 12px; }
.analytics-consent a { font-size: 12px; }
.toast {
  bottom: 18px;
  padding: 10px 14px;
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
  font-size: 13px;
}

/* Keep the locale control discoverable in the real header and mobile drawer.
   The arrival-film copies remain intentionally quiet, but the application
   shell must always expose the FR | EN choice promised by the product. */
.language-control {
  opacity: 1 !important;
  pointer-events: auto !important;
}

#lang-toggle.language-control {
  position: relative !important;
  width: auto;
  height: auto;
  min-width: auto !important;
  margin: 0;
  padding: 2px;
  overflow: visible;
}

.mnav-pref.language-control {
  min-height: 0;
  height: auto;
  margin-block: 0 !important;
  overflow: visible;
}

.ig-chooser > .language-control,
.ig-controls > .language-control {
  opacity: 1 !important;
  pointer-events: auto !important;
}
#ig-chooser > .language-control { width: auto; height: 44px; top: 16px; right: 20px; overflow: hidden; }
.ig-controls > .language-control { position: relative !important; inset: auto; width: auto; height: 44px; margin: 0; }
@media (max-width: 760px) {
  .ig-chooser { display: flex; flex-direction: column; align-items: stretch; gap: 24px; padding: 24px 20px; }
  .ig-arrival-copy { gap: 16px; }
  .ig-arrival-copy .ig-title { margin-top: 4px; max-width: none; }
  .ig-arrival-top { min-height: 44px; padding-right: 96px; }
  .ig-arrival-top > .ig-wordmark { --lockup-tile: 40px; }
  .ig-arrival-market { margin-top: 0; padding: 18px; }
}
@media (max-width: 380px) {
  .ig { padding: 12px; }
  .ig-chooser { padding: 20px 16px; }
  .ig-arrival-market { padding: 14px; }
  .ig-arrival-market .ig-cal-cell { padding: 10px; gap: 6px 8px; }
  .ig-arrival-market .ig-cal-price { font-size: var(--type-control); }
}

/* The section tint should whisper blue against the white card. The white
   parent and the 24 px sibling margin are the visual separator. */
#day-dialog .offer-sec,
#day-dialog .o-criteria .crit-sec {
  background: color-mix(in srgb, var(--brand-bright) 6%, var(--surface));
}

/* Information is an affordance, but the glyph itself is not another boxed
   card: keep it brand-coloured and remove the enclosing ring. */
#day-dialog .itip-btn,
#day-dialog .itip-btn:hover,
#day-dialog .itip[data-open='true'] .itip-btn {
  border: 0;
  background: transparent;
  color: var(--brand);
}

/* The beta note is a signed-out discovery cue; an authenticated notary gets
   the account-scoped preparation card instead. */
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-ai-beta-note { display: block; }

/* Lead with calendar subscription; account access follows it in the rail. */
@media (min-width: 1200.01px) {
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) {
    display: grid;
    grid-template-columns: minmax(0, 1.55fr) minmax(300px, .75fr);
    grid-template-areas:
      "left carnet"
      "left console"
      "conformite conformite"
      "guarantee guarantee";
    column-gap: clamp(24px, 3vw, 48px);
    row-gap: 0;
    align-items: start;
  }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-landing-right { display: contents; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-console { grid-area: console; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-carnet {
    grid-area: carnet;
    margin-top: var(--space-10);
  }

}

/* Touch targets apply at every width; keep these outside the wide-only
   authenticated landing layout above. */
.nc-conformite-link,
.sup-mail-open {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}
.sup-text { min-height: 44px; }

@media (max-width: 899.98px) {
  /* The compact phone inventory is followed immediately by its calendar
     subscription rail; the previous 40px margin plus 48px inset created a
     conspicuous dead band after a one-column sparse grid. */
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-carnet {
    margin-top: var(--space-6);
    padding-top: var(--space-6);
  }
}

@media (max-width: 640px) {
  /* On a one-column phone inventory the overflow tile follows the last real
     card. Top-aligning its message keeps the tile useful without a centered
     dead pocket between two consecutive demand rows. */
  #pane-notaires .nc-live-more { justify-content: flex-start; }
}

/* Signing entry: a compact room preview, with trial limits beside each other.
   This is an illustration, not a simulated call or an interactive toolbar. */
#pane-beta .beta-page { max-width: 1280px; padding-top: clamp(28px, 4vw, 48px); padding-bottom: 64px; }
#pane-beta .beta-hero { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(32px, 4vw, 56px); align-items: center; }
#pane-beta .beta-intro { padding-top: 0; }
#pane-beta .beta-intro h1 { max-width: 18ch; margin-bottom: 20px; text-wrap: balance; }
#pane-beta .beta-lead { max-width: 48ch; }
#pane-beta .beta-caption { max-width: 48ch; margin-top: 16px; }
#pane-beta #beta-preview::after { content: none; }
#pane-beta .beta-actions .btn-primary { box-shadow: none; }
#pane-beta .beta-preview {
  width: 100%; max-width: 600px; justify-self: end; padding: 0;
  background: var(--surface-hover-veil); backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px); border-color: var(--border-strong);
  box-shadow: var(--shadow);
}
#pane-beta .beta-preview::before, #pane-beta .beta-preview::after { content: none; }
#pane-beta .beta-preview-top { padding: 14px 20px; border-bottom: 1px solid var(--border); color: var(--ink); font-size: 13px; letter-spacing: 0; }
#pane-beta .beta-preview-top > .beta-room-title:first-child { display: inline-flex; align-items: center; gap: 9px; color: var(--ink); font: inherit; letter-spacing: 0; }
.beta-room-title svg { color: var(--brand-on-surface); flex: none; }
#pane-beta .beta-preview-tag { padding: 3px 8px; background: transparent; color: var(--ink-muted); font-size: 11px; letter-spacing: .02em; }
#pane-beta .beta-preview-steps {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px;
  padding: 14px 20px; margin: 0; border: 0; color: var(--ink-muted); font-size: 11px; letter-spacing: 0;
}
#pane-beta .beta-preview-steps li { display: flex; align-items: center; gap: 7px; line-height: 1.4; }
#pane-beta .beta-preview-steps li::after { content: none; }
.beta-preview-steps li > span { color: var(--brand-on-surface); font-size: 10px; font-weight: 700; font-variant-numeric: tabular-nums; }
#pane-beta .beta-preview-scene { display: grid; grid-template-columns: minmax(0, 1fr) 96px; gap: 12px; min-height: 0; margin: 0; padding: 4px 20px 18px; }
.beta-document-stage { min-width: 0; padding: 10px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-inset); }
#pane-beta .beta-preview-paper { padding: 18px; transform: none; box-shadow: var(--shadow-sm); border-color: var(--border); }
#pane-beta .beta-preview-paper::before { content: none; }
.beta-paper-heading { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 6px; }
#pane-beta .beta-paper-brand { margin: 0; font-size: 14px; letter-spacing: -.04em; color: var(--ink); }
.beta-paper-label { font-size: 10px; color: var(--ink-muted); }
.beta-document-title { display: block; max-width: 20ch; margin: 18px 0 14px; font-size: 14px; line-height: 1.5; }
#pane-beta .beta-document-lines i { height: 3px; margin: 8px 0; }
#pane-beta .beta-document-lines i:last-child { width: 72%; }
.beta-signature-field { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 20px; padding: 10px 12px; border: 1px dashed var(--border-strong); border-radius: var(--radius-xs); color: var(--ink-muted); font-size: 10px; }
#pane-beta .beta-signature-field svg { width: 86px; flex: none; margin: 0; stroke: var(--brand-on-surface); }
.beta-preview-video { display: flex; flex-direction: column; gap: 12px; }
#pane-beta .beta-preview-person { flex: 1; min-width: 0; min-height: 110px; aspect-ratio: auto; align-self: stretch; flex-direction: column; gap: 10px; padding: 12px 8px; text-align: center; border-color: var(--border); box-shadow: none; }
#pane-beta .beta-preview-person::before, #pane-beta .beta-preview-person::after { content: none; }
#pane-beta .beta-preview-person svg { width: 58px; height: 58px; stroke: var(--brand-on-surface); }
.beta-preview-person span { position: relative; font-size: 11px; line-height: 1.4; color: var(--ink-muted); }
#pane-beta .beta-preview-self { min-height: 90px; background: var(--surface); }
#pane-beta .beta-preview-self svg { width: 23px; height: 23px; stroke: var(--ink-muted); }
.beta-preview-footnote { display: flex; align-items: center; gap: 8px; margin: 0; padding: 11px 20px; border-top: 1px solid var(--border); font-size: 11px; line-height: 1.5; color: var(--ink-muted); }
.beta-preview-footnote .beta-dot { flex: none; width: 5px; height: 5px; color: var(--brand-on-surface); }
.beta-trust-row { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(32px, 4vw, 56px); margin-top: 32px; padding: 24px 0; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
#pane-beta .beta-trust-row > aside { display: block; margin: 0; padding: 0; border: 0; background: none; box-shadow: none; border-radius: 0; }
#pane-beta .beta-trust-row > aside + aside { position: relative; }
#pane-beta .beta-trust-row > aside + aside::before { content: ''; position: absolute; top: 0; bottom: 0; left: calc(clamp(32px, 4vw, 56px) / -2); border-left: 1px solid var(--border); }
#pane-beta .beta-trust-row strong { display: block; margin-bottom: 7px; font-size: 13px; }
#pane-beta .beta-trust-row p { max-width: 65ch; font-size: 13px; line-height: 1.65; margin: 0; }
.beta-scope-details { margin-top: 8px; color: var(--ink-muted); font-size: 12px; }
.beta-scope-details summary { width: fit-content; padding-block: 6px; cursor: pointer; color: var(--brand-on-surface); }
.beta-scope-details[open] summary { margin-bottom: 4px; }
@media (max-width: 1100px) and (min-width: 981px) {
  #pane-beta .beta-preview-scene { grid-template-columns: minmax(0, 1fr) 84px; gap: 8px; padding-inline: 14px; }
  .beta-document-stage { padding: 10px; }
  #pane-beta .beta-preview-paper { padding: 14px; }
  .beta-signature-field { flex-direction: column; align-items: flex-start; }
}
@media (max-width: 980px) {
  #pane-beta .beta-hero { grid-template-columns: 1fr; gap: 32px; }
  #pane-beta .beta-intro { max-width: 600px; width: 100%; justify-self: start; }
  #pane-beta .beta-intro h1 { max-width: 22ch; }
  #pane-beta .beta-preview { justify-self: center; }
  #pane-beta .beta-caption { max-width: 56ch; }
}
@media (max-width: 480px) {
  #pane-beta .beta-page { padding-top: 28px; }
  #pane-beta .beta-actions { display: grid; grid-template-columns: 1fr; gap: 4px; margin-top: 22px; }
  #pane-beta .beta-preview-top { padding: 14px; }
  #pane-beta .beta-preview-steps { padding: 14px; gap: 8px; font-size: 10px; }
  #pane-beta .beta-preview-steps li { flex-direction: column; align-items: flex-start; gap: 4px; }
  #pane-beta .beta-preview-scene { grid-template-columns: minmax(0, 1fr); padding: 0 14px 14px; gap: 12px; }
  .beta-document-stage { padding: 14px; }
  #pane-beta .beta-preview-paper { padding: 18px; }
  .beta-preview-video { flex-direction: row; gap: 8px; }
  #pane-beta .beta-preview-person { min-height: 48px; aspect-ratio: auto; flex-direction: row; padding: 10px 8px; gap: 6px; align-items: center; align-self: stretch; }
  #pane-beta .beta-preview-person svg { width: 26px; height: 26px; flex: none; }
  .beta-preview-footnote { padding: 12px 14px; }
  .beta-trust-row { grid-template-columns: 1fr; gap: 18px; margin-top: 24px; padding-block: 20px; }
  #pane-beta .beta-trust-row > aside + aside { padding: 18px 0 0; border-top: 1px solid var(--border); }
  #pane-beta .beta-trust-row > aside + aside::before { content: none; }
  .beta-scope-details summary { min-height: 44px; display: list-item; align-content: center; }
}

/* Calendar subscription is the first action on compact notary landings. */
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-carnet .sub-card {
  display: block;
  min-width: 0;
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-carnet .sub-card-actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin-top: var(--space-6);
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-carnet .sub-card > .help:last-child {
  margin-top: var(--space-6);
}
@media (max-width: 1200px) {
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .intro--hero { order: 0; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-carnet { order: 1; margin-top: 0; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .nc-promesses { order: 2; }
}

/* The public notary landing leads with the calendar and available offers.
   Keep these rules scoped to the signed-out state; the working console retains
   its full-width layout after authentication. */
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) {
  display: flex;
  flex-direction: column;
  gap: 0;
  max-width: var(--maxw);
  padding-top: 0;
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-landing-left {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr);
  grid-template-rows: min-content minmax(min-content, 1fr);
  gap: var(--space-12) clamp(24px, 3vw, 40px);
  align-items: start;
  order: 0;
  width: 100%;
  padding: var(--intro-pad-top) 0 var(--space-12);
  border-bottom: 1px solid var(--border);
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-landing-right {
  display: contents;
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .intro--hero {
  order: 0;
  width: 100%;
  align-self: stretch;
  margin: 0;
  padding: 0;
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-carnet {
  display: grid;
  grid-template-columns: subgrid;
  grid-template-rows: subgrid;
  grid-column: 1 / -1;
  grid-row: 1 / span 2;
  order: 1;
  width: 100%;
  max-width: none;
  margin: 0;
  padding: 0;
  border: 0;
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-carnet .sub-card {
  display: contents;
}
.nc-calendar-guide { min-width: 0; }
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .nc-calendar-guide {
  display: grid; grid-template-columns: minmax(0, 1fr);
  grid-column: 1; grid-row: 2;
  align-items: start; align-content: start; align-self: start; gap: var(--space-6);
}
.nc-calendar-connect { min-width: 0; }
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-carnet .sub-card-head { margin: 0; text-align: left; }
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-carnet .nc-calendar-title {
  font-family: var(--font-display); font-size: var(--type-h3); line-height: var(--type-h3-lh); margin: 0;
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-carnet .sub-card-kicker {
  grid-column: 1 / -1; margin: 0;
  font-size: 12px; font-weight: 500; letter-spacing: 0; text-transform: none; color: var(--subtitle-ink);
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-carnet .sub-card-sub {
  display: block; max-width: 52ch; margin-top: var(--space-4); font-size: 13px; line-height: 1.6; text-wrap: balance;
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-carnet .sub-card-actions {
  display: flex; flex-wrap: wrap; gap: var(--space-4); margin: var(--space-6) 0 0;
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-carnet .sub-card-actions .sub-btn {
  flex: 0 0 auto; min-height: 44px; padding: 8px 12px; justify-content: center; font-size: 13px; gap: 7px;
  border-color: var(--border-strong); background: var(--nc-offer-surface); box-shadow: none; color: var(--ink-muted);
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-carnet .sub-card-actions .sub-btn:hover {
  color: var(--ink); background: var(--nc-offer-hover); border-color: var(--brand);
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-carnet .sub-card-actions .brand-ic { width: 13px; height: 13px; }
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #sub-subscription-toggle {
  width: fit-content; min-height: 44px; margin: var(--space-4) 0 0; padding: 4px 0;
  border: 0; font-size: 12px; gap: 8px;
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #sub-subscription-toggle .sub-link-toggle-hint { display: none; }
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #sub-subscription-panel { width: 100%; margin-top: var(--space-6); }
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .nc-calendar-preview {
  display: grid; min-width: 0; gap: var(--space-14);
  grid-column: 2; grid-row: 1 / span 2; align-self: start;
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #nc-calendar-teaser {
  width: 100%; max-width: none; margin: 0; justify-self: stretch; align-self: start;
}
.nc-calendar-note h3 { margin: 0; }
.nc-calendar-note p { max-width: 52ch; margin: var(--space-4) 0 0; font-size: 13px; line-height: 1.6; color: var(--ink-muted); text-wrap: balance; }
.nc-calendar-guide > .nc-calendar-note { margin-top: var(--space-4); padding-top: var(--space-8); border-top: 1px solid var(--border); }
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .nc-week-total,
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .nc-week-note { display: none; }
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-carnet .sub-card-footnote {
  margin: 0; padding: 0; border: 0; font-size: 11px; text-align: left; color: var(--ink-muted);
  grid-column: 1 / -1;
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .nc-landing-head { order: 2; margin: var(--space-10) 0 var(--space-8); }
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-live { order: 3; width: 100%; margin: 0 0 16px; }
/* Render offers together: staggered fades left temporary holes on refresh. */
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-live-grid > * { animation: none; }
.nc-calendar-secondary { min-width: 0; }
.nc-calendar-secondary > summary {
  cursor: pointer;
  padding: 18px 0;
  font-weight: 600;
  color: var(--ink);
}
.nc-calendar-secondary > summary:focus-visible { outline: 2px solid currentColor; outline-offset: 4px; }
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-calendar-explore {
  order: 5;
  border-bottom: 1px solid var(--border);
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-landing-right #notary-console {
  order: 4;
  width: 100%;
  padding: 0;
  margin: 0;
  background: transparent;
  border: 0;
  box-shadow: none;
  border-bottom: 1px solid var(--border);
}
#notary-calendar-access[open] > form { margin: 0 0 24px; max-width: 560px; }
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-calendar-obligations { order: 6; }
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) > .nota-guarantee { display: none; }
#pane-notaires > .wrap:has(#notary-authed:not([hidden])) #notary-calendar-explore,
#pane-notaires > .wrap:has(#notary-authed:not([hidden])) #notary-calendar-obligations { display: none; }
#pane-notaires > .wrap:has(#notary-authed:not([hidden])) .notary-landing-left,
#pane-notaires > .wrap:has(#notary-authed:not([hidden])) .notary-landing-right { display: contents; }
/* Keep the pane's navigation target available to assistive technology while
   letting the work start immediately below the navigation bar. */
#pane-notaires > .wrap:has(#notary-authed:not([hidden])) .intro--hero {
  position: absolute;
  width: 1px;
  height: 1px;
  min-height: 0;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
#pane-notaires > .wrap:has(#notary-authed:not([hidden])) #notary-console {
  width: 100%;
  margin: 0;
  padding: var(--space-7) 0 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  box-shadow: none;
}
#pane-notaires .nc-card,
#pane-notaires .nc-live-card {
  background: var(--nc-offer-surface);
  box-shadow: var(--shadow-sm);
  animation: none;
  transition: background-color var(--motion-fast) ease, border-color var(--motion-fast) ease, box-shadow var(--motion-fast) ease;
}
#pane-notaires .nc-card:hover,
#pane-notaires .nc-live-card:hover {
  transform: none;
  background: var(--nc-offer-hover);
  border-color: var(--border-strong);
  box-shadow: var(--shadow-sm);
}
@media (max-width: 960px) {
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-landing-left {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto auto;
    gap: var(--space-10);
  }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-carnet {
    grid-row: 2 / span 2;
  }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .nc-calendar-guide {
    grid-row: 1;
  }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .nc-calendar-preview {
    grid-column: 1; grid-row: 2;
  }
}
@media (max-width: 900px) {
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-landing-left { padding-top: var(--space-4); }
}
@media (pointer: coarse) {
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-carnet .sub-card-actions .sub-btn,
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #sub-subscription-toggle,
  .nc-calendar-teaser .nc-calendar-play { min-height: 44px; }
}

/* Human handoff is a chat action with the same inset as the topic browser. */
.sup-panel > #chat-human { margin-inline: 14px; align-self: flex-start; }

/* Quiet subscription choices accompany the unchanged calendar film. */
.nc-calendar-teaser { margin: 20px auto; width: 100%; max-width: 1100px; min-width: 0; align-self: center; border: 1px solid var(--border); border-radius: var(--radius-lg); overflow: hidden; }
.nc-calendar-video { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; background: var(--bg); }
.nc-calendar-teaser figcaption { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 12px; font-size: 11px; color: var(--ink-muted); border-top: 1px solid var(--border); }
.nc-calendar-play { min-height: 32px; border: 0; padding: 4px 8px; color: var(--ink); background: transparent; font: inherit; cursor: pointer; }
.nc-calendar-play:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* The phone calendar keeps its month readable; the offer gets its own row
   instead of shrinking the desktop film's text into seven tiny columns. */
.nc-calendar-mobile { display: none; padding: 16px; background: var(--surface); color: var(--ink); line-height: 1.4; text-align: left; }
.nc-calendar-teaser.is-mobile .nc-calendar-video { display: none; }
.nc-calendar-teaser.is-mobile .nc-calendar-mobile { display: block; }
.nc-mobile-progress { display: flex; gap: 5px; margin-top: 16px; }
.nc-mobile-progress span { height: 3px; flex: 1; border-radius: var(--radius-xs); background: var(--border); }
.nc-mobile-progress .is-current, .nc-mobile-progress .is-complete { background: var(--ink-muted); }
.nc-mobile-canvas { display: grid; }
.nc-mobile-month-view, .nc-mobile-details { grid-area: 1 / 1; min-width: 0; }
.nc-mobile-month-view.is-hidden, .nc-mobile-details.is-hidden { visibility: hidden; pointer-events: none; }
.nc-mobile-month-view { display: grid; align-content: start; }
.nc-calendar-mobile:not(.is-playing) *, .nc-calendar-mobile:not(.is-playing) *::after { animation-play-state: paused !important; }
.nc-calendar-mobile[data-step='0'] .nc-mobile-offer { animation: nc-mobile-arrival .4s ease both; }
.nc-mobile-details { display: flex; flex-direction: column; justify-content: center; align-items: flex-start; padding: 20px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-inset); }
.nc-mobile-detail-status { font-size: 12px; color: var(--ink-muted); margin-bottom: 16px; }
.nc-mobile-detail-service { font-family: var(--font-display); font-size: 22px; }
.nc-mobile-detail-date { font-size: 13px; color: var(--ink-muted); margin-top: 6px; }
.nc-mobile-detail-amount { font-size: 30px; margin-top: 16px; font-variant-numeric: tabular-nums; }
.nc-mobile-detail-note { margin: 12px 0 0; min-height: 4.5em; font-size: 14px; line-height: 1.5; }
.nc-mobile-outcome { align-self: stretch; min-height: calc(3em + 13px); border-top: 1px solid var(--border); margin-top: 20px; padding-top: 12px; font-size: 13px; font-weight: 600; line-height: 1.5; }
.nc-calendar-mobile[data-step='2'] .nc-mobile-detail-status::before { content: '✓ '; }
@keyframes nc-mobile-arrival { from { transform: translateY(-6px); } to { transform: none; } }
@media (prefers-reduced-motion: reduce) { .nc-calendar-mobile *, .nc-calendar-mobile *::after { animation: none !important; } }
.nc-mobile-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.nc-mobile-month { font-family: var(--font-display); font-size: 18px; line-height: 1.4; }
.nc-mobile-legend { display: flex; align-items: center; gap: 6px; margin: 6px 0 12px; font-size: 12px; color: var(--ink-muted); }
.nc-mobile-legend::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: var(--ink-muted); }
.nc-mobile-week, .nc-mobile-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); }
.nc-mobile-week { padding-bottom: 6px; color: var(--ink-muted); font-size: 11px; text-align: center; }
.nc-mobile-grid { gap: 2px 0; }
.nc-mobile-day { display: grid; place-items: center; align-content: center; gap: 3px; height: 32px; font-size: 12px; font-variant-numeric: tabular-nums; border: 1px solid transparent; border-radius: var(--radius-sm); }
.nc-mobile-day::after { content: ''; width: 4px; height: 4px; border-radius: 50%; background: transparent; }
.nc-mobile-day.has-request::after { background: var(--ink-muted); }
.nc-mobile-day.is-outside { color: var(--ink-muted); opacity: .5; }
.nc-mobile-day.is-selected { font-weight: 700; border-color: var(--border-strong); background: var(--surface-inset); }
.nc-mobile-offer { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 6px 12px; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); }
.nc-mobile-date { grid-column: 1 / -1; font-size: 12px; color: var(--ink-muted); }
.nc-mobile-date::first-letter { text-transform: uppercase; }
.nc-mobile-service { align-self: center; font-size: 14px; font-weight: 600; overflow-wrap: anywhere; }
.nc-mobile-amount { align-self: center; font-size: 21px; font-variant-numeric: tabular-nums; white-space: nowrap; }

@media (max-width: 600px) {
  /* One reading order: introduction, subscribe, calendar, supporting details.
     Flatten only the guide wrapper so its notes can follow the calendar. */
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-landing-left { display: flex; flex-direction: column; gap: 12px; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-carnet { display: block; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-carnet .sub-card { display: flex; flex-direction: column; align-items: stretch; gap: 0; padding: 0; border: 0; background: transparent; box-shadow: none; text-align: left; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .nc-calendar-guide { display: contents; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-carnet .sub-card-kicker { order: 0; margin-bottom: 4px; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .nc-calendar-connect { order: 1; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-carnet .sub-card-actions { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-top: 0; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-carnet .sub-card-actions .sub-btn { min-width: 0; padding-inline: 6px; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .nc-calendar-preview { order: 2; width: 100%; gap: 20px; margin-top: 0; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #nc-calendar-teaser { order: 0; }
  .nc-calendar-preview > .nc-calendar-note { order: 1; }
  .nc-calendar-guide > .nc-calendar-note { order: 3; margin-top: 16px; padding-top: 0; border: 0; }
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) #notary-carnet .sub-card-footnote { order: 4; margin-top: 12px; font-size: 12px; line-height: 1.5; }
  #pane-notaires .nc-calendar-note h3 { font-size: var(--type-h3); line-height: var(--type-h3-lh); }
  #pane-notaires .nc-calendar-note p { margin-top: 6px; font-size: 14px; line-height: 1.5; text-wrap: pretty; }
  #pane-notaires #notary-live-grid { grid-template-columns: minmax(0, 1fr); grid-auto-rows: auto; gap: 8px; }
  #pane-notaires .nc-live-card { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: 'svc amt' 'meta pill'; align-items: center; align-content: center; gap: 8px 12px; padding: 14px; }
  #pane-notaires .nc-live-card .nc-live-svc-name { font-size: 14px; white-space: normal; overflow: visible; }
  #pane-notaires .nc-live-card .nc-live-amt { justify-self: end; font-size: 20px; }
  #pane-notaires .nc-live-card .nc-live-meta { font-size: 12px; }
  #pane-notaires .nc-live-more { min-height: 76px; }
}

/* One header layout for the three public entry points. The copy starts at
   the same top-left position, independent of the content in the other column. */
#pane-carnet .landing-hero,
#pane-partenaires .landing-hero,
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .landing-hero {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(20px, 4vw, 48px);
  align-items: start;
  min-height: 0;
  margin: 0;
  padding: var(--intro-pad-top) 0;
  text-align: left;
}
#pane-carnet .landing-copy,
#pane-partenaires .landing-copy,
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .landing-copy {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  min-width: 0;
  width: 100%;
  max-width: none;
}
#pane-carnet .landing-copy > .eyebrow,
#pane-partenaires .landing-copy > .eyebrow,
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .landing-copy > .eyebrow { margin: 0 0 var(--space-8); }
#pane-carnet .landing-copy > h1,
#pane-partenaires .landing-copy > h1,
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .landing-copy > h1 {
  width: 100%;
  max-width: none;
  margin: 4px 0 0;
  font-size: var(--type-h1);
  line-height: var(--type-h1-lh);
  text-wrap: balance;
}
#pane-carnet .landing-copy > .landing-lede,
#pane-partenaires .landing-copy > .landing-lede,
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .landing-copy > .landing-lede {
  width: 100%;
  max-width: 47ch;
  margin: var(--space-8) 0 0;
  font-size: var(--type-lead);
  line-height: var(--type-lead-lh);
  color: var(--ink-muted);
  text-wrap: pretty;
}
/* Let the carnet copy breathe and share the four service rows' full height.
   Keep the usual minimum gaps; spread only the spare room on wide screens. */
#pane-carnet .landing-copy {
  --type-h1-lh: 1.25;
  --type-lead-lh: 1.75;
}
@media (min-width: 901px) {
  #pane-carnet .landing-copy {
    align-self: stretch;
    justify-content: space-between;
  }
}
@media (max-width: 900px) {
  #pane-carnet .landing-hero,
  #pane-partenaires .landing-hero,
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .landing-hero {
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(18px, 3vw, 26px);
    padding-block: var(--space-7);
  }
}
@media (max-width: 680px) {
  #pane-carnet .landing-copy > h1,
  #pane-partenaires .landing-copy > h1,
  #pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .landing-copy > h1 { font-size: var(--type-h1-compact); }
}

/* The header and subscription share the left column; the film starts beside
   the header. A shared grid avoids reserving an empty title row above it. */
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .notary-landing-left > .landing-hero {
  display: block;
  grid-column: 1;
  grid-row: 1;
  padding: 0;
}
#pane-notaires > .wrap:has(#notary-auth-form:not([hidden])) .landing-copy > .nc-lede { text-wrap: balance; }

/* Profile workspace: a quiet navigation rail and readable, consistent sections. */
#pane-profil > .wrap { max-width: 1280px; }
#pane-profil .profil-intro { margin-bottom: 28px; }
#pane-profil .profil-intro h1 { font-size: var(--type-h1-compact); }
#pane-profil .profil-intro p { max-width: 58ch; }
.profil-layout { display: grid; grid-template-columns: 204px minmax(0, 1fr); gap: 32px; align-items: start; }
.profil-nav { position: sticky; top: calc(var(--sticky-top) + 16px); display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.profil-nav > .eyebrow { margin: 0 0 12px 12px; font-size: 10px; }
.profil-nav-item {
  display: flex; align-items: center; gap: 10px; width: 100%; min-height: 48px; padding: 8px 12px;
  border: 1px solid transparent; border-radius: var(--radius-sm); background: transparent;
  font: inherit; font-size: 14px; font-weight: 600; text-align: left; color: var(--ink-muted); cursor: pointer;
}
.profil-nav-item .profil-card-ic { background: transparent; color: inherit; }
.profil-nav-item:hover, .profil-nav-item:focus-visible { background: var(--brand-tint-solid); color: var(--brand-on-surface); border-color: var(--border-strong); }
.profil-nav .account-tour-replay { order: 1; margin-top: 20px; white-space: normal; align-self: stretch; }
#pane-profil .profil-stack { gap: 24px; min-width: 0; }
#pane-profil .profil-card {
  min-width: 0; padding: clamp(18px, 2.5vw, 28px); gap: 20px;
  border-radius: var(--radius-lg); background: var(--surface-veil);
  scroll-margin-top: calc(var(--sticky-top) + 20px);
}
#pane-profil .profil-card:focus { outline: 2px solid var(--brand); outline-offset: 4px; }
#pane-profil .profil-card-head { display: grid; grid-template-columns: 36px minmax(0, 1fr); gap: 4px 12px; }
#pane-profil .profil-card-head > .profil-card-ic { grid-row: 1 / span 2; width: 36px; height: 36px; background: var(--brand-tint-solid); }
#pane-profil .profil-card-title { font-size: var(--type-h3); line-height: var(--type-h3-lh); letter-spacing: var(--type-h3-ls); }
#pane-profil .profil-card-sub { grid-column: 2; max-width: 64ch; font-size: 13px; line-height: 1.55; }
#pane-profil .profil-fields { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 22px; }
#pane-profil .profil-fields input { min-height: 46px; background: var(--surface); }
#pane-profil .profil-fields .help { font-size: 12px; }
.profil-save-status { padding-top: 14px; border-top: 1px solid var(--border); font-size: 12px; color: var(--ink-muted); }
.profil-save-status::before { content: '✓'; margin-right: 8px; color: var(--ok); }
.profil-fields .profil-field-error { color: var(--danger); }
.profil-fields input[aria-invalid='true'] { border-color: var(--danger); }
#pane-profil .profil-switches { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 24px; }
#pane-profil .switch-row { min-height: 62px; padding: 12px 0; border-bottom: 1px solid var(--border); gap: 12px; }
#pane-profil .switch-title { flex: 1; margin: 0; font-size: 13px; line-height: 1.45; cursor: pointer; }
#pane-profil .switch { flex-shrink: 0; }
.profil-email-prefs { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 20px; }
.profil-email-prefs > p { flex: 1 1 240px; max-width: 52ch; }
.profil-email-prefs .btn { min-height: 44px; }
#pane-profil .profil-empty { gap: 20px; padding: 18px; background: var(--surface-inset); border: 1px solid var(--border); }
#pane-profil .profil-empty-text { max-width: 48ch; line-height: 1.6; }
#pane-profil .profil-empty .btn { flex-shrink: 0; min-height: 44px; white-space: normal; }
#pane-profil .profil-doc-chips { gap: 8px; margin: 0; }
#pane-profil .profil-doc-chips .chip { min-height: 42px; white-space: normal; text-align: left; }
#pane-profil .doc-summary { padding: 14px; background: var(--surface-inset); border: 1px solid var(--border); }
#pane-profil .my-offers { margin: 0; }
#pane-profil .profil-referral { border-color: var(--border-strong); }
.profil-rewards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); border: 1px solid var(--border-strong); background: var(--brand-tint-solid); }
.profil-reward { display: grid; gap: 8px; padding: 20px; min-width: 0; }
.profil-reward + .profil-reward { border-left: 1px solid var(--border-strong); background: var(--brand-tint-solid-strong); }
.profil-reward-label { font-size: 12px; font-weight: 600; color: var(--ink-muted); }
.profil-reward-amount { font-family: var(--font-mono); font-size: var(--type-h2); line-height: 1.2; letter-spacing: -.04em; color: var(--brand-on-surface); }
.profil-reward .help { font-size: 12px; line-height: 1.5; }
.profil-referral .parr-code-row { flex-wrap: wrap; gap: 8px 14px; }
.profil-referral .parr-code { font-size: 24px; overflow-wrap: anywhere; }
.profil-status { display: inline-flex; align-items: center; gap: 6px; padding: 4px 8px; width: fit-content; font-size: 11px; font-weight: 700; color: var(--ink); background: var(--surface-inset); border: 1px solid var(--border); }
.profil-status::before { content: ''; width: 5px; height: 5px; background: currentColor; border-radius: 50%; }
.profil-referral .partner-link-row { margin: 0; gap: 10px; }
.profil-referral .partner-link-row code { flex: 1 1 100%; min-width: 0; padding: 14px 16px; font-size: 14px; user-select: all; }
.profil-referral .btn { min-height: 44px; }
.profil-message { padding: 16px 0; border-block: 1px solid var(--border); }
.profil-message > summary { min-height: 28px; font-size: 14px; font-weight: 600; cursor: pointer; color: var(--ink); }
.profil-message .partner-msg-text { margin-top: 16px; font-size: 14px; line-height: 1.65; }
.profil-referral-followup { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; }
.profil-referral-followup .help { flex-basis: 100%; margin: 0; }
.profil-referral-email { flex: 1 1 180px; font-size: 13px; overflow-wrap: anywhere; color: var(--ink-muted); }

/* Une seule colonne sous le héros (2026-09-12) : le formulaire, puis la
   mention du prix du client. La colonne « histoire » qui tenait la moitié
   droite est partie avec son texte. */
#pane-partenaires .pr-grid { grid-template-columns: minmax(0, 560px); gap: 28px; }
#pane-partenaires .pr-form-panel { padding: 24px; box-shadow: none; }
/* Le résumé du dépliant EST le titre du panneau : il en prend la voix, pas
   celle d'un sous-titre replié. */
.partner-details > summary { font-size: var(--type-h3); line-height: var(--type-h3-lh); letter-spacing: var(--type-h3-ls); font-family: var(--font-display); font-weight: var(--weight-display); cursor: pointer; padding: 0 0 10px; color: var(--ink); }
.partner-details[open] > summary { margin-bottom: 14px; border-bottom: 1px solid var(--border); }
/* Le bouton se dimensionne sur son libellé (même retour que la feuille de
   réservation) : dans une colonne de 560 px, un aplat pleine largeur pour six
   mots se lit comme une bande. */
.partner-details #partner-submit { min-height: 48px; }
.partner-details .partner-rappel-line { margin: 16px 0 0; line-height: 1.6; }
.partner-details .partner-rappel-line .btn { margin-top: 8px; white-space: normal; }
.partner-active-code { margin: 10px 0 14px; font-family: var(--font-mono); font-size: clamp(20px, 2.2vw, 26px); font-weight: 700; letter-spacing: .03em; overflow-wrap: anywhere; }
#pane-partenaires .partner-share-panel { border-color: var(--border-strong); background: var(--surface-veil); }
#pane-partenaires .partner-share-panel .partner-link-row code { user-select: all; }
#pane-partenaires[data-partner-state='confirmed'] .pr-hero { grid-template-rows: auto; }
#pane-partenaires[data-partner-state='confirmed'] .pr-hero-copy { grid-row: auto; }
/* Une fois le code confirmé, la grille s'élargit pour le panneau de partage,
   et le formulaire replié ne garde que la hauteur de son titre — il n'a plus
   qu'un seul enfant, alors la grille à deux colonnes qu'il portait laissait
   une moitié vide sous le résumé. */
#pane-partenaires[data-partner-state='confirmed'] .pr-grid { grid-template-columns: minmax(0, 1fr); }
#pane-partenaires[data-partner-state='confirmed'] .pr-form-panel { padding: var(--space-7) var(--space-8); }
#pane-partenaires[data-partner-state='confirmed'] .partner-details:not([open]) > summary { padding-bottom: 0; }
@media (max-width: 900px) {
  .profil-layout { grid-template-columns: minmax(0, 1fr); gap: 18px; }
  .profil-nav { position: static; flex-direction: row; flex-wrap: wrap; gap: 6px; padding-bottom: 18px; border-bottom: 1px solid var(--border); }
  .profil-nav > .eyebrow { flex-basis: 100%; margin: 0 0 6px; }
  .profil-nav-item { width: auto; min-height: 44px; padding: 6px 10px; border-color: var(--border); background: var(--surface-inset); font-size: 12px; }
  .profil-nav-item .profil-card-ic { width: 18px; height: 18px; }
  .profil-nav .account-tour-replay { margin: 0; min-height: 44px; }
  #pane-partenaires .pr-grid { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 560px) {
  #pane-profil .profil-intro { margin-bottom: 20px; }
  #pane-profil .profil-card { gap: 18px; padding: 18px 16px; }
  #pane-profil .profil-fields, #pane-profil .profil-switches { grid-template-columns: minmax(0, 1fr); }
  #pane-profil .profil-empty { flex-direction: column; align-items: stretch; padding: 16px; }
  #pane-profil .profil-card-head { grid-template-columns: 30px minmax(0, 1fr); gap: 8px 10px; }
  #pane-profil .profil-card-head > .profil-card-ic { width: 30px; height: 30px; grid-row: 1; }
  #pane-profil .profil-card-sub { grid-column: 1 / -1; }
  .profil-reward { padding: 14px 12px; }
  .profil-email-prefs .btn { width: 100%; }
  .profil-referral .partner-link-row .btn { flex: 1; }
  .profil-referral .partner-link-row code { font-size: 12px; }
}

/* Calm depth and responsive feedback across the public experience.
   Only the panel paint is translucent; readable text and inputs stay solid. */
.sub-card, .nc-card, .pr-form-panel,
.partner-share-panel, #pane-profil .profil-card {
  box-shadow: var(--shadow);
  transition: border-color var(--motion-ui) ease, box-shadow var(--motion-ui) ease;
}
#pane-partenaires .pr-card, #pane-partenaires .pr-form-panel,
#pane-partenaires .partner-share-panel {
  border-color: var(--panel-border); box-shadow: var(--shadow);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
}
#pane-partenaires .pr-card--notaire { border-color: var(--border-strong); }
#pane-partenaires .pr-form-panel:focus-within, .sub-card:focus-within,
#pane-profil .profil-card:focus-within { border-color: var(--border-strong); box-shadow: var(--shadow-lg); }
.partner-share-panel .partner-msg-text { background: var(--surface-soft-veil); border-color: var(--panel-border); }
.partner-share-panel .partner-link-row code { font-size: 13px; line-height: 1.6; padding: 10px 12px; }
#pane-partenaires .partner-share-panel .help { font-size: 13px; line-height: 1.55; }
h1, h2, h3 { text-wrap: balance; }
@media (prefers-reduced-motion: no-preference) {
  .btn, .sub-btn, .profil-nav-item {
    transition: background-color var(--motion-fast) ease, border-color var(--motion-fast) ease,
      color var(--motion-fast) ease, box-shadow var(--motion-ui) ease, transform var(--motion-fast) var(--ease-ui);
  }
  #pane-profil.is-active .profil-card { animation: heroIn var(--motion-enter) var(--ease-ui) both; }
  #pane-profil.is-active .profil-card:nth-child(2) { animation-delay: 50ms; }
  #pane-profil.is-active .profil-card:nth-child(3) { animation-delay: 100ms; }
  .partner-share-panel:not([hidden]) { animation: heroIn var(--motion-enter) var(--ease-ui) both; }
}
/* Partner experience: Nota's ink, signal and action colours distinguish
   rewards, selected choices and the next step. Existing grids stay intact. */
#pane-partenaires .pr-hero .eyebrow::before {
  content: ''; display: inline-block; width: 7px; height: 7px;
  margin-right: var(--space-4); background: var(--brand-bright);
}
#pane-partenaires .pr-card { background: var(--surface); }
#pane-partenaires .pr-card--notaire {
  background: var(--brand-tint-solid); border-color: var(--brand);
}
#pane-partenaires .pr-card .pr-amount { color: var(--brand-on-surface); }
#pane-partenaires .pr-freq { background: var(--brand-tint-solid); border-color: var(--border-strong); }
#pane-partenaires .pr-form-panel { background: var(--surface); border-top-color: var(--brand); }
#pane-partenaires .pr-form-panel:focus-within { border-color: var(--brand); }
#pane-partenaires #partner-submit:not(:disabled) {
  box-shadow: inset 0 -2px 0 var(--brand);
}
/* The partner pitch has a content-sized column. Equal landing columns
   leave hundreds of empty pixels between its short headline and the offer. */
@media (min-width: 901px) {
  #pane-partenaires .pr-hero {
    grid-template-columns: minmax(0, clamp(360px, 30vw, 480px)) minmax(0, 1fr);
    gap: var(--space-12);
  }
}
.partner-form-intro { margin: 0 0 var(--space-8); color: var(--ink-muted); font-size: 13px; line-height: 1.6; }
.partner-next-step { padding-left: var(--space-5); border-left: 2px solid var(--border-strong); line-height: 1.6; }
.partner-next-step[data-ready='true'] { border-color: var(--brand); color: var(--brand-on-surface); }
.partner-pending-to { font-size: 14px; line-height: 1.6; overflow-wrap: anywhere; }
#partner-pending-email { display: block; color: var(--ink); }
#partner-pending { border-color: var(--brand); }
#partner-email-edit { min-height: 44px; margin-top: var(--space-4); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
  .brand:hover .brand-mark img, .brand:hover .brand-mark-svg { transform: none; }
}

/* Calendar controls and dates share the hero’s left rail. */
#carnet-panel :is(.cal-toolbar, .cal-grid, .filterbar, .legend) { padding-inline: 0; }
