/* =====================================================================================
   PieceDesk « Ardoise » : design tokens, the single source of truth (2026-10-24).
   Read DIRECTION.md first. Every colour that a page or a screen uses lives here and
   only here (rule S11): components read ROLE tokens (--site-*, --app-*, --paper-*),
   never the primitives (--pd-ink, --pd-l-*, ...) and never a raw hex.

   Scopes
   - .pd-site            the public site, dark first (ink canvas).
   - .pd-site[data-theme="light"]  fallback only, if Kevin refuses a dark site.
   - .pd-app             the software, light by default (rule S1).
   - .pd-app[data-theme="dark"]    the software's dark theme, by the person's choice only.
   - .pd-paper           documents (quote, invoice, QR-bill, receipt): white in every theme.
   A software frame shown on the site carries .pd-app inside .pd-site; nothing leaks.

   Font files: brand/fonts/ (static cuts, no variable font: Playwright WebKit drew the
   variable Instrument Sans with collided letters in all four concepts). Paths below are
   relative to this file; copy the folder next to your build and keep the names.
   Contrast of every text pair is measured in DIRECTION.md section 3.4.
   ===================================================================================== */

@font-face { font-family: "PD Display"; src: url("brand/fonts/instrument-sans-display-w78-600.woff2") format("woff2"); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: "PD Title";   src: url("brand/fonts/instrument-sans-title-w90-600.woff2") format("woff2");   font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: "PD Text";    src: url("brand/fonts/instrument-sans-400.woff2") format("woff2");             font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "PD Text";    src: url("brand/fonts/instrument-sans-500.woff2") format("woff2");             font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: "PD Text";    src: url("brand/fonts/instrument-sans-600.woff2") format("woff2");             font-weight: 600 700; font-style: normal; font-display: swap; }
@font-face { font-family: "PD Mono";    src: url("brand/fonts/fragment-mono-400.woff2") format("woff2");               font-weight: 400; font-style: normal; font-display: swap; }

:root {
  /* ---------- 1. Primitives: the ramp, as given (never used directly by components) */
  --pd-ink:   #06141B;
  --pd-deep:  #11212D;
  --pd-slate: #253745;
  --pd-steel: #4A5C6A;
  --pd-mist:  #9BA8AB;
  --pd-fog:   #CCD0CF;
  --pd-white: #FFFFFF;
  --pd-black: #000000;            /* QR-bill payment part only (SIX: black) */

  /* derived dark steps, same hue band (OKLCH hue 231 to 242) */
  --pd-d-050: #0A1820;            /* software dark: side menu */
  --pd-d-075: #0B1A23;            /* software dark: canvas */
  --pd-d-100: #0D1B24;            /* site slate tone 1 */
  --pd-d-125: #12232E;            /* site slate tone 2 */
  --pd-d-175: #172935;            /* hover on deep; dark surface-2 */
  --pd-d-200: #182A36;            /* site slate tone 3 */
  --pd-d-225: #1A2C38;            /* dark hover */
  --pd-d-300: #1F313E;            /* site slate tone 4; dark block */
  --pd-d-350: #223543;            /* site dark slate hover */
  --pd-d-disabled: #6F7E88;       /* disabled text and icons on dark */
  --pd-d-edge: #6D7D88;           /* control border on dark (4.40:1 on ink) */
  --pd-d-mist-hi: #AAB6B9;        /* secondary text on deep and darker (7.90:1 on deep) */
  --pd-d-text: #E5E8EA;           /* software dark: primary text */
  --pd-paper-white: #EEF1F1;      /* display type on ink (16.45:1) */

  /* derived light steps */
  --pd-l-050: #F4F6F7;            /* software canvas */
  --pd-l-100: #EBEFF0;            /* sunken surface, hover on canvas, quoted message */
  --pd-l-125: #F2F5F6;            /* hover on white */
  --pd-l-150: #E1E7EA;            /* selected, done block in a time bar */
  --pd-l-200: #D9DEDF;            /* site light slate (what belongs to one business) */
  --pd-l-225: #E3E8E9;            /* site light slate hover */
  --pd-l-line: #D5DBDD;           /* separator between two regions (decorative, 1.4:1) */
  --pd-l-border: #7A8992;         /* control border on light (3.61:1 on white, 3.33 on canvas) */
  --pd-l-text-3: #3E505D;         /* meta text on light (8.37:1 on white) */
  --pd-l-disabled: #8A979E;       /* disabled text and icons (exempt, still 3.0:1 on white) */

  /* status primitives: muted, equal lightness; glyphs first, text only where named */
  --pd-good-l: #2A7449;   --pd-good-d: #82CB9B;
  --pd-warn-l: #8A5600;   --pd-warn-d: #E1AD63;
  --pd-crit-l: #A43B35;   --pd-crit-d: #FB9890;
  --pd-crit-ink-l: #8E2F2A;       /* overdue amounts and true minus on light (8.11:1 on white) */
  --pd-crit-ink-l-hover: #7A2823; /* destructive button hover, light */
  --pd-crit-d-hover: #FDB1AA;     /* destructive button hover, dark */
  --pd-proto-bg: #F3E6CC;         /* « Prototype » banner (ink on it 15.13:1) */
  --pd-proto-edge: #DCC9A2;       /* the line between the banner and the app below it */

  /* demo tenants' accents (rule S29: a tenant changes only its accent, logo, names) */
  --pd-tenant-lambert: #06141B;   /* Lambert Sanitaire: the neutral preset */
  --pd-tenant-claire:  #7B3F5E;   /* Atelier Claire (white on it 7.74:1) */
  --pd-tenant-leman:   #245A52;   /* Net Léman Services (white on it 7.90:1) */

  /* ---------- 2. Type */
  --pd-font-display: "PD Display", "Instrument Sans", "Arial Narrow", Arial, sans-serif;  /* width 78, 600 */
  --pd-font-title:   "PD Title", "Instrument Sans", Arial, sans-serif;                    /* width 90, 600 */
  --pd-font-text:    "PD Text", "Instrument Sans", "Helvetica Neue", Arial, sans-serif;   /* width 100, 400 500 600 */
  --pd-font-mono:    "PD Mono", "Fragment Mono", ui-monospace, Menlo, Consolas, monospace;
  --pd-font-bill:    Arial, "Liberation Sans", Helvetica, sans-serif;                     /* QR-bill receipt and payment part */

  /* site scale (size / line height / tracking) */
  --pd-site-hero-size: clamp(54px, 4.19vw + 39.7px, 100px);  --pd-site-hero-lh: 0.95;  --pd-site-hero-track: -0.035em;
  --pd-site-h2-size: clamp(34px, 1.143vw + 29.5px, 46px);     --pd-site-h2-lh: 1.04;    --pd-site-h2-track: -0.025em;
  --pd-site-figure-size: clamp(38px, 0.762vw + 35px, 46px);   --pd-site-figure-lh: 1.08;
  --pd-site-text-size: 18px;      --pd-site-text-lh: 28px;    /* phone: 17 / 26 */
  --pd-site-small-size: 15px;     --pd-site-small-lh: 22px;
  --pd-site-caption-size: 13px;   --pd-site-caption-lh: 20px;
  --pd-site-mono-size: 13px;      --pd-site-mono-lh: 20px;
  --pd-site-btn-size: 17px;

  /* software scale */
  --pd-app-h1-size: 28px;         --pd-app-h1-lh: 34px;       --pd-app-h1-track: -0.015em;   /* phone: 24 / 30 */
  --pd-app-money-size: 30px;      --pd-app-money-lh: 36px;    /* the one big figure of a card */
  --pd-app-title-size: 16px;      --pd-app-title-lh: 22px;    /* card and dialog titles, 600 */
  --pd-app-body-size: 15px;       --pd-app-body-lh: 22px;
  --pd-app-input-size: 16px;      --pd-app-input-lh: 24px;    /* never less: stops iOS zoom (S8) */
  --pd-app-label-size: 14px;      --pd-app-label-lh: 20px;
  --pd-app-meta-size: 13px;       --pd-app-meta-lh: 18px;
  --pd-app-mono-size: 13px;       --pd-app-mono-lh: 18px;     /* never under 12 */
  --pd-app-tab-size: 11px;        --pd-app-tab-lh: 14px;      /* phone tab bar and count digits only: the 11 px floor (S9) */

  /* ---------- 3. Space: 8 px grid with 4 px half steps */
  --pd-s-0: 0px;    --pd-s-05: 4px;   --pd-s-1: 8px;    --pd-s-15: 12px;  --pd-s-2: 16px;
  --pd-s-25: 20px;  --pd-s-3: 24px;   --pd-s-4: 32px;   --pd-s-5: 40px;   --pd-s-6: 48px;
  --pd-s-7: 56px;   --pd-s-8: 64px;   --pd-s-10: 80px;  --pd-s-12: 96px;  --pd-s-14: 112px;
  --pd-s-16: 128px; --pd-s-21: 168px;

  --pd-container: 1280px;
  --pd-gutter: clamp(16px, 5vw, 80px);
  --pd-col-gap: 24px;             /* one text line */
  --pd-section-top: clamp(112px, 8vw + 80px, 168px);   /* sections on one background pad the top only (H8) */

  /* sizes */
  --pd-control-h: 44px;           /* software controls, every one (S7) */
  --pd-control-h-compact: 32px;   /* desktop table rows and dispatcher only, by a per-table toggle */
  --pd-control-h-site: 52px;      /* site buttons and fields */
  --pd-row-h: 48px;               /* software table row, comfortable */
  --pd-topbar-h: 56px;  --pd-topbar-h-phone: 48px;
  --pd-tabbar-h: 56px;            /* plus env(safe-area-inset-bottom) */
  --pd-sidebar-w: 256px; --pd-rail-w: 64px;
  --pd-fab: 56px;
  --pd-icon: 20px; --pd-icon-tab: 24px; --pd-icon-sm: 16px;
  --pd-glyph: 10px;               /* status glyph inside a 16 px box */

  /* ---------- 4. Radii: square first, never a stadium (H1) */
  --pd-r-0: 0px;                  /* slates (their shape is the cut corner), paper */
  --pd-r-1: 2px;                  /* site buttons and fields, tags, keycaps, bars */
  --pd-r-2: 4px;                  /* software buttons, inputs, cards, menu entries */
  --pd-r-3: 6px;                  /* dialogs, popovers, a software frame shown on the site */
  --pd-r-4: 8px;                  /* tenant square at 40 px */
  --pd-r-round: 50%;              /* true circles only: avatar, status disc, radio */
  --pd-chamfer: 12px;             /* site slate foot cut */
  --pd-chamfer-sm: 9px;           /* small site slates (phone roof) */
  --pd-chamfer-app: 8px;          /* slates inside the software (screen of pieces, Réglages > Pièces) */
  --pd-joint: 6px;                /* gap between two slates of a course */
  --pd-lap: 24px;                 /* how far an upper course covers the one below */
  --pd-slate-edge: 3px;           /* the hard edge a slate throws, no blur (4px on the hero) */

  /* ---------- 5. Layers */
  --pd-z-base: 0; --pd-z-raised: 1; --pd-z-sticky: 100; --pd-z-dropdown: 200; --pd-z-popover: 300;
  --pd-z-scrim: 400; --pd-z-dialog: 410; --pd-z-toast: 500; --pd-z-skip: 600;

  /* ---------- 6. Motion */
  --pd-dur-1: 80ms;               /* software: press, small state */
  --pd-dur-2: 160ms;              /* software: menus, popovers, hover */
  --pd-dur-3: 240ms;              /* software: dialogs, toasts; site: button tone */
  --pd-dur-4: 320ms;              /* software: sheets, one bar fill */
  --pd-dur-pop: 640ms;            /* site: an element pops into place */
  --pd-dur-lay: 700ms;            /* site: a slate is set down */
  --pd-dur-fill: 1100ms;          /* site only: a progress fill (H11) */
  --pd-stagger: 70ms;             /* between siblings, left to right */
  --pd-course-gap: 330ms;         /* between two courses of the roof */
  --pd-ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --pd-ease-in: cubic-bezier(0.55, 0, 1, 0.45);
  --pd-ease-std: cubic-bezier(0.2, 0, 0, 1);
  /* damped spring, damping 0.7, 6.7 % overshoot (from concept A) */
  --pd-spring: linear(0, 0.167 3.3%, 0.329 6.7%, 0.478 10%, 0.611 13.3%, 0.724 16.7%, 0.819 20%, 0.895 23.3%, 0.955 26.7%, 0.999 30%, 1.03 33.3%, 1.05 36.7%, 1.061 40%, 1.066 43.3%, 1.066 46.7%, 1.063 50%, 1.057 53.3%, 1.05 56.7%, 1.042 60%, 1.035 63.3%, 1.027 66.7%, 1.021 70%, 1.015 73.3%, 1.01 76.7%, 1.006 80%, 1.003 83.3%, 1.001 86.7%, 0.999 90%, 0.998 93.3%, 0.997 96.7%, 1);

  font-synthesis: none;           /* never a fake bold or oblique */
}
@supports not (transition-timing-function: linear(0, 1)) {
  :root { --pd-spring: cubic-bezier(0.3, 1.35, 0.55, 1); }
}
@media (prefers-reduced-motion: reduce) {
  :root {
    --pd-dur-1: 80ms; --pd-dur-2: 80ms; --pd-dur-3: 80ms; --pd-dur-4: 80ms;
    --pd-dur-pop: 0ms; --pd-dur-lay: 0ms; --pd-dur-fill: 0ms; --pd-stagger: 0ms; --pd-course-gap: 0ms;
  }
}

/* No italic anywhere (S12): roman files only, and reset what browsers slant by default. */
em, i, cite, var, dfn, address { font-style: normal; }
em { font-weight: 600; }

/* =====================================================================================
   SITE (piecedesk.ch): dark first. Depth = the ramp's lightness + one hard slate edge.
   ===================================================================================== */
.pd-site {
  color-scheme: dark;
  --site-bg: var(--pd-ink);                    /* the page */
  --site-bg-raised: var(--pd-deep);            /* a band with a visible edge (prices panel) */
  --site-bg-hover: var(--pd-d-175);            /* row or tile hover on ink and deep */
  --site-line: var(--pd-slate);                /* separates two regions only (1.52:1, decorative) */
  --site-text-display: var(--pd-paper-white);  /* h1, h2, figures */
  --site-text: var(--pd-fog);                  /* body */
  --site-text-2: var(--pd-mist);               /* secondary, on ink ONLY (7.64:1) */
  --site-text-2-raised: var(--pd-d-mist-hi);   /* secondary on deep and on slate tones */
  --site-control-border: var(--pd-d-edge);     /* outline of fields and quiet buttons (4.40:1) */

  --site-btn-bg: var(--pd-fog);                --site-btn-text: var(--pd-ink);
  --site-btn-bg-hover: var(--pd-paper-white);
  --site-btn2-border: var(--pd-d-edge);        --site-btn2-text: var(--pd-paper-white);
  --site-btn2-bg-hover: var(--pd-deep);
  --site-focus: var(--pd-paper-white);         /* 2 px ring, 2 px offset */
  --site-focus-inner: var(--pd-ink);           /* inner ring so the focus reads on fog buttons too */

  /* the slates: dark = a piece every business shares, light = what belongs to one business,
     outlined = a piece « Sur demande » (no code yet). */
  --site-slate-1: var(--pd-d-100);
  --site-slate-2: var(--pd-d-125);
  --site-slate-3: var(--pd-d-200);
  --site-slate-4: var(--pd-d-300);
  --site-slate-hover: var(--pd-d-350);
  --site-slate-text: var(--pd-paper-white);
  --site-slate-text-2: var(--pd-fog);          /* data line on a dark slate (8.61:1 on tone 4) */
  --site-slate-light: var(--pd-l-200);
  --site-slate-light-hover: var(--pd-l-225);
  --site-slate-light-text: var(--pd-ink);      /* 13.76:1 */
  --site-slate-light-text-2: var(--pd-slate);  /* 9.04:1 */
  --site-slate-outline: var(--pd-d-edge);      /* the outline of a « Sur demande » slate */
  --site-slate-edge: var(--pd-ink);            /* the hard 3 px edge under a slate */

  --site-good: var(--pd-good-d);
  --site-warn: var(--pd-warn-d);               /* also the « à confirmer » text (9.22:1 on ink) */
  --site-crit: var(--pd-crit-d);
  --site-frame-ring: var(--pd-slate);          /* 1 px around a software frame shown on the site */
  --site-scrim: rgb(6 20 27 / 0.72);

  background: var(--site-bg);
  color: var(--site-text);
}

/* Fallback if the site must be light (open decision, DIRECTION.md 0). Same roles. */
.pd-site[data-theme="light"] {
  color-scheme: light;
  --site-bg: var(--pd-l-050);
  --site-bg-raised: var(--pd-white);
  --site-bg-hover: var(--pd-l-100);
  --site-line: var(--pd-l-line);
  --site-text-display: var(--pd-ink);
  --site-text: var(--pd-ink);
  --site-text-2: var(--pd-slate);
  --site-text-2-raised: var(--pd-slate);
  --site-control-border: var(--pd-l-border);
  --site-btn-bg: var(--pd-ink);                --site-btn-text: var(--pd-white);
  --site-btn-bg-hover: var(--pd-slate);
  --site-btn2-border: var(--pd-l-border);      --site-btn2-text: var(--pd-ink);
  --site-btn2-bg-hover: var(--pd-l-100);
  --site-focus: var(--pd-ink);                 --site-focus-inner: var(--pd-white);
  --site-good: var(--pd-good-l); --site-warn: var(--pd-warn-l); --site-crit: var(--pd-crit-l);
  --site-frame-ring: var(--pd-l-line);
  /* slates keep their own colours in light: the roof stays a slate roof */
}

/* =====================================================================================
   SOFTWARE (app.piecedesk.ch and every tenant): light by default, dark side menu in both.
   ===================================================================================== */
.pd-app {
  color-scheme: light;
  --app-bg: var(--pd-l-050);                   /* canvas */
  --app-surface: var(--pd-white);              /* cards, tables, dialogs */
  --app-surface-2: var(--pd-l-100);            /* sunken: quoted message, closed hours, track */
  --app-hover: var(--pd-l-125);                /* row hover on white */
  --app-hover-canvas: var(--pd-l-100);         /* hover on the canvas */
  --app-selected: var(--pd-l-150);             /* selected row, pressed segment, done block */
  --app-line: var(--pd-l-line);                /* separates two regions (rows, card edges) */
  --app-border: var(--pd-l-border);            /* control outline, 3:1 on white, canvas, surface-2 */
  --app-text: var(--pd-ink);                   /* 18.69:1 on white */
  --app-text-2: var(--pd-slate);               /* secondary (12.27:1 on white, 9.83 on selected) */
  --app-text-3: var(--pd-l-text-3);            /* meta, never on --app-selected (6.70) */
  --app-text-disabled: var(--pd-l-disabled);
  --app-solid: var(--pd-ink);                  /* primary button, now label, count chip */
  --app-solid-hover: var(--pd-slate);
  --app-on-solid: var(--pd-white);
  --app-danger: var(--pd-crit-ink-l);          /* destructive button fill (white on it 8.11:1) */
  --app-danger-hover: var(--pd-crit-ink-l-hover);
  --app-on-danger: var(--pd-white);

  --app-chrome-bg: var(--pd-deep);             /* side menu, both themes keep a dark chrome */
  --app-chrome-text: var(--pd-d-text);         /* 13.34:1 on deep */
  --app-chrome-text-2: var(--pd-d-mist-hi);    /* group labels (7.90:1) */
  --app-chrome-hover: var(--pd-d-225);
  --app-chrome-active: var(--pd-slate);        /* active entry fill, white text 12.27:1 */
  --app-chrome-active-text: var(--pd-white);
  --app-chrome-line: var(--pd-slate);
  --app-chrome-count-bg: var(--pd-fog);        /* count square on the menu */
  --app-chrome-count-text: var(--pd-ink);

  --app-focus: var(--pd-ink);                  /* 2 px ring at 2 px offset, never removed (S15) */
  --app-focus-inner: var(--pd-white);
  --app-now: var(--pd-ink);                    /* the now line and its mono label */
  --app-scrim: rgb(6 20 27 / 0.48);            /* behind a dialog, no blur */
  --app-shadow-pop: 0 1px 2px rgb(6 20 27 / 0.08), 0 12px 32px -12px rgb(6 20 27 / 0.24);  /* menus, popovers, toasts */
  --app-shadow-dialog: 0 2px 4px rgb(6 20 27 / 0.08), 0 32px 64px -24px rgb(6 20 27 / 0.32);
  /* cards and bars carry NO shadow; hover never adds one (S15) */

  --app-good: var(--pd-good-l);                /* glyphs; 5.69:1 */
  --app-warn: var(--pd-warn-l);                /* glyphs; never a text colour (S24) */
  --app-crit: var(--pd-crit-l);                /* glyphs; 6.45:1 */
  --app-crit-ink: var(--pd-crit-ink-l);        /* text: overdue amount, true minus (8.11:1) */
  --app-proto-bg: var(--pd-proto-bg);  --app-proto-text: var(--pd-ink);  --app-proto-edge: var(--pd-proto-edge);

  --app-chart-1: var(--pd-ink);                /* series 1 */
  --app-chart-2: var(--pd-steel);              /* series 2 (6.93:1) */
  --app-chart-3: var(--pd-l-border);           /* series 3 (3.61:1) */
  --app-chart-track: var(--pd-l-150);          /* empty part of a bar */
  /* a 4th series is --app-chart-2 hatched; never a status hue as a series (S24) */

  --app-accent: var(--pd-tenant-lambert);      /* set per tenant at runtime by the theme engine */
  --app-on-accent: var(--pd-white);

  background: var(--app-bg);
  color: var(--app-text);
}

.pd-app[data-theme="dark"] {
  color-scheme: dark;
  --app-bg: var(--pd-d-075);
  --app-surface: var(--pd-deep);
  --app-surface-2: var(--pd-d-175);
  --app-hover: var(--pd-d-175);
  --app-hover-canvas: var(--pd-deep);
  --app-selected: var(--pd-slate);
  --app-line: var(--pd-slate);
  --app-border: var(--pd-d-edge);              /* 3.86:1 on deep */
  --app-text: var(--pd-d-text);                /* 13.34:1 on deep */
  --app-text-2: var(--pd-fog);                 /* 10.55:1 on deep */
  --app-text-3: var(--pd-d-mist-hi);           /* 7.90:1 on deep, never on --app-selected */
  --app-text-disabled: var(--pd-d-disabled);
  --app-solid: var(--pd-fog);
  --app-solid-hover: var(--pd-d-text);
  --app-on-solid: var(--pd-ink);
  --app-danger: var(--pd-crit-d);
  --app-danger-hover: var(--pd-crit-d-hover);
  --app-on-danger: var(--pd-ink);

  --app-chrome-bg: var(--pd-d-050);
  --app-chrome-hover: var(--pd-d-175);
  --app-chrome-active: var(--pd-slate);

  --app-focus: var(--pd-paper-white);
  --app-focus-inner: var(--pd-ink);
  --app-now: var(--pd-fog);
  --app-scrim: rgb(3 10 14 / 0.64);
  --app-shadow-pop: 0 0 0 1px var(--pd-slate); /* dark: no shadow, an edge */
  --app-shadow-dialog: 0 0 0 1px var(--pd-slate);

  --app-good: var(--pd-good-d);
  --app-warn: var(--pd-warn-d);
  --app-crit: var(--pd-crit-d);
  --app-crit-ink: var(--pd-crit-d);            /* 7.81:1 on deep */

  --app-chart-1: var(--pd-fog);
  --app-chart-2: var(--pd-mist);
  --app-chart-3: var(--pd-d-edge);
  --app-chart-track: var(--pd-slate);
  --app-on-accent: var(--pd-white);
}

/* =====================================================================================
   PAPER: quotes, invoices, receipts, PDFs. White in every theme and on the site.
   ===================================================================================== */
.pd-paper {
  color-scheme: light;
  --paper-bg: var(--pd-white);
  --paper-text: var(--pd-ink);
  --paper-text-2: var(--pd-slate);
  --paper-line: var(--pd-l-line);
  --paper-rule-total: var(--pd-ink);           /* the 2 px rule above a total */
  --paper-bill-text: var(--pd-black);          /* receipt and payment part: black Arial (SIX) */
  --paper-bill-line: var(--pd-black);          /* the perforation, dashed, with the scissors */
  background: var(--paper-bg);
  color: var(--paper-text);
}
