Aller au contenu

Style de l'interface utilisateur ​

CSS Cours ​

Wrapper principal de l'interface utilisateur ​

  • .pivotick – Le conteneur principal de l'interface utilisateur pivotick.

    • .pvt-mainheader – Barre supérieure (recherche/filtre/notes).
    • .pvt-sidebar – Panneau de gauche pour la sélection actuelle (propriétés, facettes, voisins) et les actions groupées.
    • .pvt-canvas – La zone où le graphique est rendu.
      • svg – Zone de canevas intérieure (pour le type de rendu SVG).
    • .pvt-moderail – Rail de mode gauche (Sélectionner/Créer/Afficher/Physique).
    • .pvt-toolpanel – Panneau d'outils contextuel pour le mode actif.
    • .pvt-flyout – Emplacement contenant les menus déroulants des paramètres ; chaque panneau est un .pvt-flyout-panel (.pvt-flyout-view pour les commutateurs grille/canevas, .pvt-flyout-physics pour la mise en page et la simulation).
    • .pvt-graphnavigation – Commandes de la fenêtre d'affichage (ajustement et centrage, zoom, paramètres, plein écran).
  • .pvt-tooltip – Conteneur d'info-bulle pour les nœuds ou les arêtes.

  • .pvt-contextmenu – Conteneur de menu contextuel pour les actions par clic droit.

Classes de nœuds ​

  • .pvt-node – Nœuds individuels dans le graphique.

Classes de pointe ​

  • .pvt-edge-group – Conteneur de groupe pour les bords.
    • path – Le chemin SVG représentant le bord.
    • .label-container – Conteneur pour l'étiquette de bord.

conseil

Ce sont les classes principales que vous pouvez remplacer. Pour voir toutes les classes disponibles, ouvrez simplement les outils de développement de votre navigateur et inspectez l'élément.

CSS Variables ​

Un autre moyen simple de styliser Pivotick consiste à remplacer les variables par défaut CSS. Vous pouvez tous les trouver here.

Afficher toutes les variables
scss
@use "sass:map";
@use 'utils';


//
// LIGHT THEME
//

$light-vibrant-color-palette: (
    vibrant-blue: #007acc,
    vibrant-indigo: #7000cc,
    vibrant-lobster: #f0636a,
    vibrant-green: #81dd18,
    vibrant-amaranth: #eb2e53,
);

$light-bg-color-palette-1: (
    pvt-bg-color-0: #fff,
    pvt-bg-color-1: #fafafa,
    pvt-bg-color-2: #f3f3f3,
    pvt-bg-color-3: #ededed,
    pvt-bg-color-4: #e6e6e6,
    pvt-bg-color-5: #e0e0e0,
    pvt-bg-color-6: #d6d6d6,
    pvt-bg-color-7: #cccccc,
    pvt-bg-color-8: #c2c2c2,
);

$light-theme: (
    // #region core-variables
    pvt-bg: var(--pvt-bg-color-0),
    pvt-ui-bg: var(--pvt-bg-color-0),
    pvt-border-color: var(--pvt-bg-color-7),
    // Floating chrome surface (rails / pills / panels). Kept light here so it
    // doesn't read heavy on the white canvas; see the dark map for the dark tone.
    pvt-chrome-bg: var(--pvt-bg-color-3),
    pvt-chrome-border: #dcdcdc,
    pvt-chrome-shadow: "0 2px 6px rgba(0, 0, 0, 0.10)",

    pvt-theme-primary: map.get($light-vibrant-color-palette, vibrant-amaranth),
    pvt-theme-secondary: #f2f2f2,
    pvt-theme-info: #25B6EB,
    pvt-theme-warning: #F59E0B,
    pvt-theme-danger: #DC2626,
    pvt-theme-success: #16A34A,

    pvt-font-family: "system-ui, sans-serif",
    // #endregion core-variables

    pvt-text-color-0: #fff,
    pvt-text-color-1: #e0e0e0,
    pvt-text-color-2: #bbb,
    pvt-text-color-3: #999,
    pvt-text-color-4: #666,
    pvt-text-color-5: #333,
    pvt-text-color-6: #000,
    pvt-text-color-primary: color-mix(in srgb, var(--pvt-bg-color-primary), black 50%),
    pvt-text-color-secondary: color-mix(in srgb, var(--pvt-bg-color-secondary), black 50%),
    pvt-text-color-info: color-mix(in srgb, var(--pvt-bg-color-info), black 50%),
    pvt-text-color-warning: color-mix(in srgb, var(--pvt-bg-color-warning), black 50%),
    pvt-text-color-danger: color-mix(in srgb, var(--pvt-bg-color-danger), black 50%),
    pvt-text-color-success: color-mix(in srgb, var(--pvt-bg-color-success), black 50%),

    pvt-bg-color-primary: var(--pvt-theme-primary),
    pvt-bg-color-secondary: var(--pvt-theme-secondary),
    pvt-bg-color-info: var(--pvt-theme-info),
    pvt-bg-color-warning: var(--pvt-theme-warning),
    pvt-bg-color-danger: var(--pvt-theme-danger),
    pvt-bg-color-success: var(--pvt-theme-success),
    pvt-text-color-for-primary: #fff,
    pvt-text-color-for-secondary: #000,
    pvt-text-color-for-info: #fff,
    pvt-text-color-for-warning: #fff,
    pvt-text-color-for-danger: #fff,
    pvt-text-color-for-success: #fff,

    pvt-box-shadow-light: "rgba(0, 0, 0, 0.25) 0px 1px 2px 0px",
    pvt-box-shadow-medium: "rgba(0, 0, 0, 0.1) 0px 4px 6px -1px, rgba(0, 0, 0, 0.06) 0px 2px 4px -1px",
    pvt-box-shadow-strong: "rgba(0, 0, 0, 0.16) 0px 3px 6px, rgba(0, 0, 0, 0.23) 0px 3px 6px",
    pvt-box-shadow-color-strong: "#aaaaaa55",

    /* Scrollbar (thumb tracks the ink colour so it adapts to the theme) */
    pvt-scrollbar-size: 10px,
    pvt-scrollbar-track: transparent,
    pvt-scrollbar-thumb: color-mix(in srgb, var(--pvt-text-color-6) 22%, transparent),
    pvt-scrollbar-thumb-hover: color-mix(in srgb, var(--pvt-text-color-6) 40%, transparent),


    /* Sidebar */
    pvt-sidebar-bg: var(--pvt-bg-color-0),
    pvt-sidebar-mainpanelheader-bg: var(--pvt-bg-color-1),
    pvt-sidebar-panelheader-bg: var(--pvt-bg-color-4),
    pvt-sidebar-panelbody-bg: var(--pvt-bg-color-0),
    pvt-sidebar-panel-border: 1px solid var(--pvt-text-color-1),
    pvt-sidebar-subpanelheader-bg: var(--pvt-bg-color-2),
    pvt-mainheader-nodepreview-bg: var(--pvt-bg-color-0),
    pvt-sidebar-layout-shadow-right: "rgba(0, 0, 0, 0.07) 2px 0px 3px 0px, rgba(0, 0, 0, 0.04) 3px 0px 2px 0px",
    pvt-sidebar-layout-shadow-left: "rgba(0, 0, 0, 0.07) -2px 0px 3px 0px, rgba(0, 0, 0, 0.04) -3px 0px 2px 0px",
    pvt-sidebar-layout-shadow-bottom: "rgba(0, 0, 0, 0.07) 3px 2px 3px 0px, rgba(0, 0, 0, 0.04) 2px 3px 2px 0px",
    pvt-sidebar-layout-shadow-top: "rgba(0, 0, 0, 0.07) 3px -2px 3px 0px, rgba(0, 0, 0, 0.04) 2px -3px 2px 0px",
    pvt-sidebar-collapse-bg: var(--pvt-bg),
    pvt-sidebar-collapse-color: var(--pvt-text-color-4),
    pvt-sidebar-collapse-border-color: var(--pvt-border-color),
    pvt-sidebar-collapse-shadow: var(--pvt-box-shadow-strong),

    /* Tooltip */
    pvt-tooltip-floating-bg-color: var(--pvt-bg-color-6),
    pvt-tooltip-property-list: var(--pvt-bg-color-2),

    /* Menu */
    pvt-menu-bg-color: var(--pvt-bg-color-1),
    pvt-menu-border-color: var(--pvt-text-color-1),
    pvt-menu-shadow: var(--pvt-sidebar-layout-shadow-right),
    pvt-action-container-shadow: "inset 0 1px 2px rgba(255, 255, 255, 0.12), inset 0 -1px 2px rgba(0, 0, 0, 0.18), rgba(0, 0, 0, 0.09) 0 -1px 2px",

    /* Modal */
    pvt-modal-bg: var(--pvt-bg-color-0),
    pvt-modal-text-color: var(--pvt-text-color-5),
    pvt-modal-overlay-bg: rgba(0, 0, 0, 0.45),
    pvt-modal-shadow: "0 20px 40px rgba(0, 0, 0, 0.25), 0 4px 12px rgba(0, 0, 0, 0.15)",


    /* Graph notification */
    pvt-toast-bg-color-primary: color-mix(in srgb, var(--pvt-bg-color-primary) 40%, white),
    pvt-toast-bg-color-secondary: color-mix(in srgb, var(--pvt-bg-color-secondary) 40%, white),
    pvt-toast-bg-color-info: color-mix(in srgb, var(--pvt-bg-color-info) 40%, white),
    pvt-toast-bg-color-warning: color-mix(in srgb, var(--pvt-bg-color-warning) 40%, white),
    pvt-toast-bg-color-danger: color-mix(in srgb, var(--pvt-bg-color-danger) 40%, white),
    pvt-toast-bg-color-success: color-mix(in srgb, var(--pvt-bg-color-success) 40%, white),

    pvt-toast-text-color-primary: color-mix(in srgb, var(--pvt-bg-color-primary) 70%, black),
    pvt-toast-text-color-secondary: color-mix(in srgb, var(--pvt-bg-color-secondary) 70%, black),
    pvt-toast-text-color-info: color-mix(in srgb, var(--pvt-bg-color-info) 70%, black),
    pvt-toast-text-color-warning: color-mix(in srgb, var(--pvt-bg-color-warning) 70%, black),
    pvt-toast-text-color-danger: color-mix(in srgb, var(--pvt-bg-color-danger) 70%, black),
    pvt-toast-text-color-success: color-mix(in srgb, var(--pvt-bg-color-success) 70%, black),

    /* Graph canvas */
    // #region canvas
    pvt-graph-grid-color: var(--pvt-bg-color-2),
    pvt-graph-navigation-control-container-shadow:
        "rgba(0, 0, 0, 0.22) 0px 0px 4px,"
        "rgba(0, 0, 0, 0.30) 0px 1px 2px",
    // #endregion canvas

    pvt-selection-color: map.get($light-vibrant-color-palette, vibrant-lobster),
    pvt-selection-stroke-color: map.get($light-vibrant-color-palette, vibrant-lobster),
    pvt-selection-rectangle-fill: color-mix(in srgb, var(--pvt-selection-color) 20%, #ffffff00),
    pvt-selection-rectangle-stroke: color-mix(in srgb, var(--pvt-selection-color) 80%, #ffffff00),

    // #region node
    /* Node defaults */
    pvt-node-color: map.get($light-vibrant-color-palette, vibrant-blue),
    pvt-node-stroke: #fff,
    pvt-node-stroke-width: 2,
    pvt-node-text-color: #fff,
    pvt-node-icon-font-family: '"Font Awesome 7 Free"',
    pvt-node-icon-font-weight: 900,

    /* Node rim badges */
    pvt-badge-color: map.get($light-vibrant-color-palette, vibrant-lobster),
    pvt-badge-text-color: #fff,
    pvt-badge-stroke: var(--pvt-bg),
    // Mid-slate in both themes: the secondary background is near-white in light mode, which
    // leaves a white-on-white badge. Neutral chrome, so it borrows no single badge's colour.
    pvt-badge-overflow-color: #64748b,

    // How much thicker than its own border a node's or edge's state ring is drawn. The
    // widths below are floors, not fixed sizes: a stroke already thicker than the floor
    // grows by this instead, so decorating it can never make it thinner.
    pvt-state-stroke-boost: 1,

    /* Node selected state */
    pvt-node-selected-color: map.get($light-vibrant-color-palette, vibrant-lobster),
    pvt-node-selected-stroke: var(--pvt-selection-stroke-color),
    // The pulse animates stroke-width 3 -> 5 -> 3 and an animated declaration wins, so this
    // only matters where the animation is off. Match its resting frame.
    pvt-node-selected-stroke-width: 3,
    pvt-node-selected-stroke-opacity: 1,
    pvt-node-selected-filter: drop-shadow(0 0 2px var(--pvt-node-selected-color)),
    pvt-node-selected-animation: glowPulseSelected 1.5s infinite,
    pvt-node-selected-big-animation: glowPulseBigSelected 1.5s infinite,

    /* Node highlighted state */
    pvt-node-highlighted-stroke: map.get($light-vibrant-color-palette, vibrant-blue),
    pvt-node-highlighted-stroke-width: 2,
    pvt-node-highlighted-filter: drop-shadow(0 0 2px var(--pvt-node-highlighted-stroke)),
    pvt-node-highlighted-opacity: 1,
    pvt-node-highlighted-animation: glowPulseHighlighted 1.5s infinite,
    // #endregion node

    /* Node cluster */
    pvt-node-dash-stroke: #333,
    pvt-node-cluster-fill: #00000010,
    pvt-node-cluster-stroke: color-mix(in srgb, var(--pvt-node-dash-stroke) 60%, #fff),

    // #region edge
    /* Edge defaults */
    pvt-edge-stroke: color-mix(in srgb, map.get($light-vibrant-color-palette, vibrant-blue) 50%, #fff),
    pvt-edge-stroke-width: 2,
    pvt-edge-stroke-opacity: 1,
    pvt-edge-stroke-dasharray: "6, 4",
    pvt-edge-animation: dashmove-edge 1s linear infinite,
    pvt-edge-filter: none,
    pvt-edge-label-bg: var(--pvt-bg-color-4),
    pvt-edge-label-font-family: "system-ui, sans-serif",
    pvt-edge-label-font-size: 12px,
    pvt-edge-label-color: var(--pvt-text-color-6),
    pvt-edge-label-stroke: none,
    pvt-edge-label-stroke-width: 1,

    /* Edge highlighted state — its own, because a node's highlight width is animated and an
       edge's is not: a 0 there is overridden on a node and simply erases an edge. */
    pvt-edge-highlighted-stroke: var(--pvt-node-highlighted-stroke),
    pvt-edge-highlighted-stroke-width: 3,
    pvt-edge-highlighted-filter: drop-shadow(0 0 2px var(--pvt-edge-highlighted-stroke)),

    /* Edge selected state */
    pvt-edge-selected-stroke: var(--pvt-selection-color),
    pvt-edge-selected-stroke-width: 5,
    pvt-edge-selected-stroke-opacity: 0.8,
    pvt-edge-selected-filter: drop-shadow(0 0 1px var(--pvt-selection-color)),
    pvt-edge-label-selected-stroke: var(--pvt-selection-color),
    pvt-edge-label-selected-stroke-width: 2,
    pvt-edge-label-selected-color: var(--pvt-edge-label-color),
    pvt-edge-label-selected-font-size: var(--pvt-edge-label-font-size),
    pvt-edge-label-selected-bg: var(--pvt-bg-color-4),
    // #endregion edge

    /* Note */
    pvt-note-node-reference-dot-default: #007acc,
    pvt-note-node-reference-text-color: #333,
    // Terminal note surface — a neutral, theme-aware panel (light canvas: white
    // card, dark ink). The colour is only an accent (top hairline + prompt); the
    // jewel surface needs no vars (it is always a deep card).
    pvt-note-term-bg: #ffffff,
    pvt-note-term-border: #e6e8ec,
    pvt-note-term-text: #1c2026,
    pvt-note-term-text-dim: #61666e,

    /* Component */
    pvt-inline-bar-bg: var(--pvt-bg-color-2),
    pvt-inline-bar-fill-bg: "linear-gradient("
        "90deg,"
        "color-mix(in srgb, var(--pvt-bg-color-primary) 20%, #fff) 0%,"
        "var(--pvt-bg-color-primary) 70%,"
        "color-mix(in srgb, var(--pvt-bg-color-primary) 80%, #000) 100%"
    ")",
    pvt-inline-bar-height: 0.5rem,
    pvt-inline-bar-width: 80px,
    pvt-inline-bar-shadow: "color-mix(in srgb, var(--pvt-text-color-6) 15%, transparent) 0px 1px 1px 0px,"
        "color-mix(in srgb, var(--pvt-text-color-6) 10%, transparent) 0px 0px 2px 0px,"
        "inset 0 1px 2px rgba(0, 0, 0, 0.05)",

    pvt-json-background: var(--pvt-bg-color-3),
    pvt-json-border: var(--pvt-bg-color-7),
    pvt-json-key: oklch(0.50 0.15 255),
    pvt-json-string: oklch(0.55 0.17 25),
    pvt-json-number: oklch(0.52 0.14 145),
    pvt-json-boolean: #7a3e9d,
    pvt-json-null: #98a2b3,
    pvt-json-bracket: var(--pvt-text-color-3),
);


//
// DARK THEME
//

$dark-vibrant-color-palette: (
    vibrant-blue: #7EA2FB,
    vibrant-indigo: #A666F4,
    vibrant-lobster: #F2545B,
    vibrant-green: #85CB33,
    vibrant-amaranth: #eb2e53,
);

$dark-bg-color-palette-1: (
    pvt-bg-color-0: #050e15,
    pvt-bg-color-1: #05141f,
    pvt-bg-color-2: #071d2d,
    pvt-bg-color-3: #082032,
    pvt-bg-color-4: #2c394b,
    pvt-bg-color-5: #334756,
    pvt-bg-color-6: #465865,
    pvt-bg-color-7: #576773,
    pvt-bg-color-8: #667580,
    pvt-bg-color-9: #78848d,
);

$dark-bg-color-palette-2: (
    pvt-bg-color-0: #0F0F10,
    pvt-bg-color-1: #131314,
    pvt-bg-color-2: #171719,
    pvt-bg-color-3: #1A1A1D,
    pvt-bg-color-4: #1D1D20,
    pvt-bg-color-5: #202023,
    pvt-bg-color-6: #252528,
    pvt-bg-color-7: #343437,
    pvt-bg-color-8: #464649,
    pvt-bg-color-9: #565658,
);

$dark-bg-color-palette-3: (
    pvt-bg-color-0: hsl(240, 0%, 6%),
    pvt-bg-color-1: hsl(240, 0%, 8%),
    pvt-bg-color-2: hsl(240, 0%, 9%),
    pvt-bg-color-3: hsl(240, 0%, 11%),
    pvt-bg-color-4: hsl(240, 0%, 12%),
    pvt-bg-color-5: hsl(240, 0%, 13%),
    pvt-bg-color-6: hsl(240, 0%, 15%),
    pvt-bg-color-7: hsl(240, 0%, 21%),
    pvt-bg-color-8: hsl(240, 0%, 28%),
    pvt-bg-color-9: hsl(240, 0%, 35%),
);

$dark-theme: (
    pvt-bg: var(--pvt-bg-color-2),
    // Docked panels (sidebar + slide panels) sit on the chrome tone (bg-6);
    // borders track the chrome's border tone (bg-7) so panels read as one family.
    pvt-ui-bg: var(--pvt-bg-color-6),
    pvt-border-color: var(--pvt-bg-color-7),
    // Floating chrome surface (rails / pills / panels) — the graphite tone.
    pvt-chrome-bg: var(--pvt-bg-color-6),
    pvt-chrome-border: var(--pvt-bg-color-7),
    pvt-chrome-shadow: "0 3px 8px rgba(0, 0, 0, 0.30)",

    // pvt-theme-primary: #730ff0,
    pvt-theme-primary: map.get($dark-vibrant-color-palette, vibrant-amaranth),
    pvt-theme-secondary: #666666,
    pvt-theme-info: #2E67F8,
    pvt-theme-warning: #ff8000,
    pvt-theme-danger: #EB212E,
    pvt-theme-success: #22b91a,

    pvt-font-family: "system-ui, sans-serif",

    pvt-text-color-0: #000,
    pvt-text-color-1: #333,
    pvt-text-color-2: #666,
    pvt-text-color-3: #999,
    pvt-text-color-4: #bbb,
    pvt-text-color-5: #e0e0e0,
    pvt-text-color-6: #fff,
    pvt-text-color-primary: color-mix(in srgb, var(--pvt-bg-color-primary), white 50%),
    pvt-text-color-secondary: color-mix(in srgb, var(--pvt-bg-color-secondary), white 50%),
    pvt-text-color-info: color-mix(in srgb, var(--pvt-bg-color-info), white 50%),
    pvt-text-color-warning: color-mix(in srgb, var(--pvt-bg-color-warning), white 50%),
    pvt-text-color-danger: color-mix(in srgb, var(--pvt-bg-color-danger), white 50%),
    pvt-text-color-success: color-mix(in srgb, var(--pvt-bg-color-success), white 50%),

    pvt-bg-color-primary: var(--pvt-theme-primary),
    pvt-bg-color-secondary: var(--pvt-theme-secondary),
    pvt-bg-color-info: var(--pvt-theme-info),
    pvt-bg-color-warning: var(--pvt-theme-warning),
    pvt-bg-color-danger: var(--pvt-theme-danger),
    pvt-bg-color-success: var(--pvt-theme-success),
    pvt-text-color-for-primary: #fff,
    pvt-text-color-for-secondary: #fff,
    pvt-text-color-for-info: #fff,
    pvt-text-color-for-warning: #fff,
    pvt-text-color-for-danger: #fff,
    pvt-text-color-for-success: #000,

    pvt-box-shadow-light: "rgba(0, 0, 0, 0.25) 0px 1px 2px 0px",
    pvt-box-shadow-medium: "rgba(0, 0, 0, 0.1) 0px 4px 6px -1px, rgba(0, 0, 0, 0.06) 0px 2px 4px -1px",
    pvt-box-shadow-strong: "rgba(0, 0, 0, 0.16) 0px 3px 6px, rgba(0, 0, 0, 0.23) 0px 3px 6px",
    pvt-box-shadow-color-strong: "#00000055",

    /* Scrollbar (thumb tracks the ink colour so it adapts to the theme) */
    pvt-scrollbar-size: 10px,
    pvt-scrollbar-track: transparent,
    pvt-scrollbar-thumb: color-mix(in srgb, var(--pvt-text-color-6) 18%, transparent),
    pvt-scrollbar-thumb-hover: color-mix(in srgb, var(--pvt-text-color-6) 34%, transparent),


    /* Sidebar */
    pvt-sidebar-mainpanelheader-bg: transparent,
    pvt-sidebar-panelheader-bg: var(--pvt-bg-color-4),
    pvt-sidebar-panelbody-bg: var(--pvt-bg-color-0),
    pvt-sidebar-panel-border: 1px solid var(--pvt-text-color-1),
    pvt-sidebar-subpanelheader-bg: var(--pvt-bg-color-2),
    pvt-mainheader-nodepreview-bg: var(--pvt-bg-color-6),
    pvt-sidebar-layout-shadow-right: "rgba(0, 0, 0, 0.07) 2px 0px 3px 0px, rgba(0, 0, 0, 0.04) 3px 0px 2px 0px",
    pvt-sidebar-layout-shadow-left: "rgba(0, 0, 0, 0.07) -2px 0px 3px 0px, rgba(0, 0, 0, 0.04) -3px 0px 2px 0px",
    pvt-sidebar-layout-shadow-bottom: "rgba(0, 0, 0, 0.07) 3px 2px 3px 0px, rgba(0, 0, 0, 0.04) 2px 3px 2px 0px",
    pvt-sidebar-collapse-bg: var(--pvt-bg),
    pvt-sidebar-collapse-color: var(--pvt-text-color-4),
    pvt-sidebar-collapse-border-color: var(--pvt-border-color),
    pvt-sidebar-collapse-shadow: var(--pvt-box-shadow-strong),

    /* Tooltip */
    pvt-tooltip-floating-bg-color: var(--pvt-bg-color-7),
    pvt-tooltip-property-list: var(--pvt-bg-color-6),

    /* Menu */
    // Overlays (menu/tooltip/modal) sit one notch above the chrome tone.
    pvt-menu-bg-color: #2E2E31,
    pvt-menu-border-color: var(--pvt-bg-color-2),
    pvt-menu-shadow: var(--pvt-sidebar-layout-shadow-right),
    pvt-action-container-shadow: "inset 0 1px 2px rgba(255, 255, 255, 0.12), inset 0 -1px 2px rgba(0, 0, 0, 0.18)",

    /* Modal */
    pvt-modal-bg: #2E2E31,
    pvt-modal-text-color: var(--pvt-text-color-5),
    pvt-modal-overlay-bg: rgba(0, 0, 0, 0.45),
    pvt-modal-shadow: "0 20px 40px rgba(0, 0, 0, 0.25), 0 4px 12px rgba(0, 0, 0, 0.15)",

    /* Graph notification */
    pvt-toast-bg-color-primary: color-mix(in srgb, var(--pvt-bg-color-primary) 40%, white),
    pvt-toast-bg-color-secondary: color-mix(in srgb, var(--pvt-bg-color-secondary) 40%, white),
    pvt-toast-bg-color-info: color-mix(in srgb, var(--pvt-bg-color-info) 40%, white),
    pvt-toast-bg-color-warning: color-mix(in srgb, var(--pvt-bg-color-warning) 40%, white),
    pvt-toast-bg-color-danger: color-mix(in srgb, var(--pvt-bg-color-danger) 40%, white),
    pvt-toast-bg-color-success: color-mix(in srgb, var(--pvt-bg-color-success) 40%, white),

    pvt-toast-text-color-primary: color-mix(in srgb, var(--pvt-bg-color-primary) 70%, black),
    pvt-toast-text-color-secondary: color-mix(in srgb, var(--pvt-bg-color-secondary) 70%, black),
    pvt-toast-text-color-info: color-mix(in srgb, var(--pvt-bg-color-info) 70%, black),
    pvt-toast-text-color-warning: color-mix(in srgb, var(--pvt-bg-color-warning) 70%, black),
    pvt-toast-text-color-danger: color-mix(in srgb, var(--pvt-bg-color-danger) 70%, black),
    pvt-toast-text-color-success: color-mix(in srgb, var(--pvt-bg-color-success) 70%, black),

    /* Graph canvas */
    pvt-graph-grid-color: var(--pvt-bg-color-4),
    pvt-graph-navigation-control-container-shadow: "rgba(255, 255, 255, 0.15) 0px 0px 4px"
    "rgba(255, 255, 255, 0.10) 0px 1px 2px",

    pvt-selection-color: map.get($dark-vibrant-color-palette, vibrant-lobster),
    pvt-selection-stroke-color: map.get($dark-vibrant-color-palette, vibrant-lobster),
    pvt-selection-rectangle-fill: color-mix(in srgb, var(--pvt-selection-color) 20%, #ffffff00),
    pvt-selection-rectangle-stroke: color-mix(in srgb, var(--pvt-selection-color) 80%, #ffffff00),


    /* Node defaults */
    pvt-node-color: map.get($dark-vibrant-color-palette, vibrant-blue),
    pvt-node-stroke: #fff,
    pvt-node-stroke-width: 0,
    pvt-node-text-color: #fff,
    pvt-node-icon-font-family: '"Font Awesome 7 Free"',
    pvt-node-icon-font-weight: 900,

    /* Node rim badges */
    pvt-badge-color: map.get($dark-vibrant-color-palette, vibrant-lobster),
    pvt-badge-text-color: #fff,
    pvt-badge-stroke: var(--pvt-bg),
    // Mid-slate in both themes: the secondary background is near-white in light mode, which
    // leaves a white-on-white badge. Neutral chrome, so it borrows no single badge's colour.
    pvt-badge-overflow-color: #64748b,

    // See the light theme's note: the state widths are floors, not fixed sizes.
    pvt-state-stroke-boost: 1,

    /* Node selected state */
    pvt-node-selected-color: var(--pvt-selection-color),
    pvt-node-selected-stroke: var(--pvt-selection-stroke-color),
    // The pulse animates stroke-width 3 -> 5 -> 3 and an animated declaration wins, so this
    // only matters where the animation is off. Match its resting frame.
    pvt-node-selected-stroke-width: 3,
    pvt-node-selected-stroke-opacity: 1,
    pvt-node-selected-filter: drop-shadow(0 0 2px var(--pvt-node-selected-color)),
    pvt-node-selected-animation: glowPulseSelected 1.5s infinite,

    /* Node highlighted state */
    pvt-node-highlighted-stroke: map.get($dark-vibrant-color-palette, vibrant-blue),
    pvt-node-highlighted-stroke-width: 0,
    pvt-node-highlighted-filter: drop-shadow(0 0 2px var(--pvt-node-highlighted-stroke)),
    pvt-node-highlighted-opacity: 1,
    pvt-node-highlighted-animation: glowPulseHighlighted 1.5s infinite,

    /* Node cluster */
    pvt-node-dash-stroke: #fff,
    pvt-node-cluster-fill: #ffffff06,
    pvt-node-cluster-stroke: color-mix(in srgb, var(--pvt-node-dash-stroke) 60%, #000),

    /* Edge defaults */
    pvt-edge-stroke: color-mix(in srgb, map.get($dark-vibrant-color-palette, vibrant-blue) 50%, #000),
    pvt-edge-stroke-width: 2,
    pvt-edge-stroke-opacity: 1,
    pvt-edge-stroke-dasharray: "6, 4",
    pvt-edge-animation: dashmove-edge 1s linear infinite,
    pvt-edge-filter: none,
    pvt-edge-label-bg: var(--pvt-bg-color-5),
    pvt-edge-label-font-family: "system-ui, sans-serif",
    pvt-edge-label-font-size: 12px,
    pvt-edge-label-color: var(--pvt-text-color-5),
    pvt-edge-label-stroke: none,
    pvt-edge-label-stroke-width: 1,

    /* Edge highlighted state — see the light theme's note. */
    pvt-edge-highlighted-stroke: var(--pvt-node-highlighted-stroke),
    pvt-edge-highlighted-stroke-width: 3,
    pvt-edge-highlighted-filter: drop-shadow(0 0 2px var(--pvt-edge-highlighted-stroke)),

    /* Edge selected state */
    pvt-edge-selected-stroke: var(--pvt-selection-color),
    pvt-edge-selected-stroke-width: 5,
    pvt-edge-selected-stroke-opacity: 0.8,
    pvt-edge-selected-filter: drop-shadow(0 0 1px var(--pvt-selection-color)),
    pvt-edge-label-selected-stroke: var(--pvt-selection-color),
    pvt-edge-label-selected-stroke-width: 2,
    pvt-edge-label-selected-color:  var(--pvt-text-color-5),
    pvt-edge-label-selected-font-size: var(--pvt-edge-label-font-size),
    pvt-edge-label-selected-bg: var(--pvt-bg-color-5),

    /* Note */
    pvt-note-node-reference-dot-default: #007acc,
    pvt-note-node-reference-text-color: #333,
    // Terminal note surface — a neutral, theme-aware panel (dark canvas: near-
    // black card, light ink). The colour is only an accent (top hairline +
    // prompt); the jewel surface needs no vars (it is always a deep card).
    pvt-note-term-bg: #1a1a1e,
    pvt-note-term-border: #2a2b31,
    pvt-note-term-text: #e8eaed,
    pvt-note-term-text-dim: #a7abb2,

    /* Component */
    pvt-inline-bar-bg: var(--pvt-bg-color-6),
    pvt-inline-bar-fill-bg: "linear-gradient("
    "90deg,"
    "color-mix(in srgb, var(--pvt-bg-color-primary) 90%, #000) 0%,"
    "var(--pvt-bg-color-primary) 60%,"
    "color-mix(in srgb, var(--pvt-bg-color-primary) 60%, #fff) 80%,"
    "color-mix(in srgb, var(--pvt-bg-color-primary) 30%, #fff) 100%"
    ")",
    pvt-inline-bar-height: 0.5rem,
    pvt-inline-bar-width: 80px,
    pvt-inline-bar-shadow: inset 0 1px 2px var(--pvt-bg-color-0),

    pvt-json-background: var(--pvt-bg-color-5),
    pvt-json-border: var(--pvt-bg-color-7),
    pvt-json-key: oklch(0.74 0.10 255),
    pvt-json-string: oklch(0.74 0.11 25),
    pvt-json-number: oklch(0.78 0.13 145),
    pvt-json-boolean: #9564b2,
    pvt-json-null: #98a2b3,
    pvt-json-bracket: var(--pvt-text-color-3),
);


$dark-theme: map.merge($dark-theme,
        $dark-bg-color-palette-2);

@each $name, $value in $dark-vibrant-color-palette {
    $dark-theme: map.merge($dark-theme,
            (pvt-#{$name}: $value));
}


$light-theme: map.merge($light-theme,
        $light-bg-color-palette-1);

@each $name, $value in $light-vibrant-color-palette {
    $light-theme: map.merge($light-theme,
            (pvt-#{$name}: $value));
}

Principales variables ​

scss
pvt-bg: var(--pvt-bg-color-0),
pvt-ui-bg: var(--pvt-bg-color-0),
pvt-border-color: var(--pvt-bg-color-7),
// Floating chrome surface (rails / pills / panels). Kept light here so it
// doesn't read heavy on the white canvas; see the dark map for the dark tone.
pvt-chrome-bg: var(--pvt-bg-color-3),
pvt-chrome-border: #dcdcdc,
pvt-chrome-shadow: "0 2px 6px rgba(0, 0, 0, 0.10)",

pvt-theme-primary: map.get($light-vibrant-color-palette, vibrant-amaranth),
pvt-theme-secondary: #f2f2f2,
pvt-theme-info: #25B6EB,
pvt-theme-warning: #F59E0B,
pvt-theme-danger: #DC2626,
pvt-theme-success: #16A34A,

pvt-font-family: "system-ui, sans-serif",
scss
pvt-graph-grid-color: var(--pvt-bg-color-2),
pvt-graph-navigation-control-container-shadow:
    "rgba(0, 0, 0, 0.22) 0px 0px 4px,"
    "rgba(0, 0, 0, 0.30) 0px 1px 2px",

Variables de nœud et de bord ​

scss
/* Node defaults */
pvt-node-color: map.get($light-vibrant-color-palette, vibrant-blue),
pvt-node-stroke: #fff,
pvt-node-stroke-width: 2,
pvt-node-text-color: #fff,
pvt-node-icon-font-family: '"Font Awesome 7 Free"',
pvt-node-icon-font-weight: 900,

/* Node rim badges */
pvt-badge-color: map.get($light-vibrant-color-palette, vibrant-lobster),
pvt-badge-text-color: #fff,
pvt-badge-stroke: var(--pvt-bg),
// Mid-slate in both themes: the secondary background is near-white in light mode, which
// leaves a white-on-white badge. Neutral chrome, so it borrows no single badge's colour.
pvt-badge-overflow-color: #64748b,

// How much thicker than its own border a node's or edge's state ring is drawn. The
// widths below are floors, not fixed sizes: a stroke already thicker than the floor
// grows by this instead, so decorating it can never make it thinner.
pvt-state-stroke-boost: 1,

/* Node selected state */
pvt-node-selected-color: map.get($light-vibrant-color-palette, vibrant-lobster),
pvt-node-selected-stroke: var(--pvt-selection-stroke-color),
// The pulse animates stroke-width 3 -> 5 -> 3 and an animated declaration wins, so this
// only matters where the animation is off. Match its resting frame.
pvt-node-selected-stroke-width: 3,
pvt-node-selected-stroke-opacity: 1,
pvt-node-selected-filter: drop-shadow(0 0 2px var(--pvt-node-selected-color)),
pvt-node-selected-animation: glowPulseSelected 1.5s infinite,
pvt-node-selected-big-animation: glowPulseBigSelected 1.5s infinite,

/* Node highlighted state */
pvt-node-highlighted-stroke: map.get($light-vibrant-color-palette, vibrant-blue),
pvt-node-highlighted-stroke-width: 2,
pvt-node-highlighted-filter: drop-shadow(0 0 2px var(--pvt-node-highlighted-stroke)),
pvt-node-highlighted-opacity: 1,
pvt-node-highlighted-animation: glowPulseHighlighted 1.5s infinite,
scss
/* Edge defaults */
pvt-edge-stroke: color-mix(in srgb, map.get($light-vibrant-color-palette, vibrant-blue) 50%, #fff),
pvt-edge-stroke-width: 2,
pvt-edge-stroke-opacity: 1,
pvt-edge-stroke-dasharray: "6, 4",
pvt-edge-animation: dashmove-edge 1s linear infinite,
pvt-edge-filter: none,
pvt-edge-label-bg: var(--pvt-bg-color-4),
pvt-edge-label-font-family: "system-ui, sans-serif",
pvt-edge-label-font-size: 12px,
pvt-edge-label-color: var(--pvt-text-color-6),
pvt-edge-label-stroke: none,
pvt-edge-label-stroke-width: 1,

/* Edge highlighted state — its own, because a node's highlight width is animated and an
   edge's is not: a 0 there is overridden on a node and simply erases an edge. */
pvt-edge-highlighted-stroke: var(--pvt-node-highlighted-stroke),
pvt-edge-highlighted-stroke-width: 3,
pvt-edge-highlighted-filter: drop-shadow(0 0 2px var(--pvt-edge-highlighted-stroke)),

/* Edge selected state */
pvt-edge-selected-stroke: var(--pvt-selection-color),
pvt-edge-selected-stroke-width: 5,
pvt-edge-selected-stroke-opacity: 0.8,
pvt-edge-selected-filter: drop-shadow(0 0 1px var(--pvt-selection-color)),
pvt-edge-label-selected-stroke: var(--pvt-selection-color),
pvt-edge-label-selected-stroke-width: 2,
pvt-edge-label-selected-color: var(--pvt-edge-label-color),
pvt-edge-label-selected-font-size: var(--pvt-edge-label-font-size),
pvt-edge-label-selected-bg: var(--pvt-bg-color-4),

Exemple ​

html
<style>
  :root {
    --pvt-node-color: #FDDA24;
    --pvt-node-stroke: #000000;
    --pvt-edge-stroke: #EF3340;
  }
</style>

Thème ​