@stratametriq/id-card-designer 1.1.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -9,15 +9,16 @@ Whether you are building an **Educational ERP / Student Information System**, **
9
9
  ## 🌟 Features
10
10
 
11
11
  - **🎨 Turnkey All-In-One Dashboard (`<IdCardManager />`):** Drop in a complete, ready-to-use workspace containing department tabs, live vector stage, batch A4 print setup, and roster selection table.
12
- - **✨ Interactive Visual Studio Canvas:** Drag-and-drop element positioning (`react-draggable`), real-time zoom controls (`80% - 200%`), grid snapping (`1mm / 5mm`), and Z-index layering.
13
- - **📏 Technical Precision Rulers & Grid Overlay:** Toggleable millimeter measurement rulers (`0mm - 86mm`) and radial matrix grid overlays for exact PVC card alignment.
12
+ - **📁 Multiple Card Templates:** Full support for multiple pre-configured category layouts (*Student ID Cards*, *Faculty & Admin*, *Corporate HR*, *Hospital Portal*) and multi-orientation presets (*Vertical 54×86mm* and *Horizontal 86×54mm*).
13
+ - **🔳 QR Code & Barcode Generation:** Built-in deterministic, high-resolution vector 1D Barcode (`<Barcode />`) and 2D QR Code (`<QrCode />`) generation with live database key binding.
14
+ - **🏷️ Variable Placeholders (`{{name}}`, `{{employeeId}}`):** Seamless handlebar/mustache syntax interpolation across text labels, custom formulas, prefixes, and suffixes (`e.g., ID: {{admissionNo}} - {{studentName}}`).
15
+ - **📥 Batch Generation from CSV or Excel (`.csv`):** One-click spreadsheet import instantly parses rows, maps headers, and populates hundreds of roster cards in real time.
16
+ - **🖼️ High-Resolution PDF & PNG Export:** Dual production output options: Batch A4 multi-page PDF sheets (`html2canvas` + `jspdf` with hardware cut marks) alongside standalone high-resolution **300 DPI PNG export**.
14
17
  - **🔄 Undo & Redo History Control:** Full history stack tracking (`Ctrl+Z` / `Cmd+Z` to undo, `Ctrl+Y` / `Cmd+Shift+Z` to redo) alongside keyboard arrow key precision nudging (`1px` or `5px` with Shift).
15
- - **📝 Signature & Image File Uploads:** Upload Principal/Director signatures, employee photos, or organization logos (`PNG/JPG`) directly from the property inspector with live base64 conversion.
16
- - **🔄 Multi-Orientation Support:** Seamless switching between standard PVC card dimensions: **Vertical (54×86 mm)** and **Horizontal (86×54 mm)**.
17
- - **⚡ Professional Built-in Presets:** Starter templates including *Classic Traditional*, *Minimalist Modern*, *Sage Table Banner*, *Corporate Executive*, and *Medical Staff Pass*.
18
- - **🧩 Universal Element Types:** Dynamic text fields, static labels, custom shapes/dividers, profile photos, organization logos, signature slots, and visual barcodes/QRs.
19
- - **🔍 Inspector Panel & Property Editor:** Fine-grained styling for font family, size, weight, text alignment, text casing (`uppercase`, `lowercase`, `capitalize`, `togglecase`), background/border colors, radii, and prefixes/suffixes.
20
- - **📄 High-Resolution Batch PDF Export Engine:** Built-in multi-page A4 / Letter grid layout calculation with toggleable hardware guillotine cut marks, perimeter outlines, and registration headers (`html2canvas` + `jspdf`).
18
+ - **📏 Grid Snapping & Alignment Guides:** Toggleable millimeter measurement rulers (`0mm - 86mm`), radial grid overlay with snap-to-grid accuracy (`1mm / 5mm`), and multi-element alignment guides (`Align Left, Center, Right`).
19
+ - **🖼️ Dedicated Image Property Inspector:** Fine-grained controls for image elements including **Replace Image / Data Binding**, **Crop / Object Fit** (`cover`, `contain`, `fill`, `none`, `scale-down`), **Corner Radius** (`Circle` avatars or custom px), **Border** styling, **Opacity**, and **Box Shadow**.
20
+ - **🔤 Advanced Text & Typography Inspector:** Complete control over **Font Family**, **Font Size**, **Font Weight**, **Text Color**, **Letter Spacing**, **Line Height**, **Text Alignment** (`Left`, `Center`, `Right`), **Rotation (°)**, **Opacity**, **Padding**, **Border & Divider Lines**, and **Box Shadow**.
21
+ - **🔍 Instant Roster Search & Status Filters:** Real-time search bar across names, ID numbers, departments, and phone numbers, plus quick status filter pill tabs (`All | Selected | Unselected`).
21
22
 
22
23
  ---
23
24
 
@@ -37,6 +38,136 @@ import "@stratametriq/id-card-designer/dist/index.css";
37
38
 
38
39
  ---
39
40
 
41
+ ## 💼 Commercial & Enterprise Licensing
42
+
43
+ `@stratametriq/id-card-designer` is dual-licensed to support both open-source developers and commercial enterprises:
44
+
45
+ 1. **Community / Open Source Tier (MIT License):**
46
+ Free for non-commercial evaluation, personal open-source projects, and rendering standalone static preview widgets (`<IdCardPreview />`).
47
+ 2. **Commercial / Enterprise Tier (Commercial License):**
48
+ Required for commercial SaaS applications, School ERP platforms, HR suites, and institutions using the **Turnkey Dashboard (`<IdCardManager />`)**, **CSV/Excel Bulk Import Parser**, or **Batch A4/Letter Multi-Page Print Engine (`generateIdCardsPdf`)** in commercial production.
49
+
50
+ 👉 **[Purchase a Commercial Enterprise License ($399 - $1,499) to Unlock Production Usage, White-Labeling & Priority Support](https://your-gumroad-or-lemonsqueezy-link.com)**
51
+
52
+ ---
53
+
54
+ ## 🚀 Sweet & Simple Guide: How to Use with Real Data & Features
55
+
56
+ Whether you want a **1-Minute Turnkey Dashboard** (`<IdCardManager />`) or want to build your own **Custom Portal** using individual modular features (`<IdCardPreview />`, `<IdCardDesignerModal />`, `generateIdCardsPdf`), connecting your real database or API data is effortless!
57
+
58
+ ### Option 1: Turnkey All-In-One Dashboard (`<IdCardManager />`)
59
+
60
+ By default, rendering `<IdCardManager />` without props opens our full interactive demo screen. To connect your **real API or database records**, simply pass them into the `sampleRecords` prop:
61
+
62
+ ```jsx
63
+ import React, { useState, useEffect } from 'react';
64
+ import { IdCardManager } from '@stratametriq/id-card-designer';
65
+ import '@stratametriq/id-card-designer/dist/index.css';
66
+
67
+ export default function SchoolPortal() {
68
+ const [dbRecords, setDbRecords] = useState({ student: [], staff: [] });
69
+
70
+ // 1. Fetch real students/employees from your backend (Node.js, Laravel, Supabase, etc.)
71
+ useEffect(() => {
72
+ fetch('https://api.yourschool.com/students')
73
+ .then(res => res.json())
74
+ .then(data => setDbRecords({ student: data }));
75
+ }, []);
76
+
77
+ // 2. Pass your live data right into <IdCardManager />!
78
+ return (
79
+ <IdCardManager
80
+ sampleRecords={dbRecords}
81
+
82
+ // Save customized card designs back to your database
83
+ onSaveCategoryTemplate={(category, templateSchema) => {
84
+ console.log(`Saving ${category} template to DB:`, templateSchema);
85
+ }}
86
+
87
+ // Listen when batch PDF export completes
88
+ onBatchExportComplete={(category, exportedRecords) => {
89
+ console.log(`Generated A4 PDF for ${exportedRecords.length} records!`);
90
+ }}
91
+ />
92
+ );
93
+ }
94
+ ```
95
+
96
+ ---
97
+
98
+ ### Option 2: Building Custom Screens (Using Modular Features)
99
+
100
+ If you don't want our full dashboard and instead want to embed specific ID card features directly into your own custom pages, tables, or profile screens, use our **standalone building blocks**:
101
+
102
+ #### A. Show a Live ID Card on a Student Profile Page (`<IdCardPreview />`)
103
+ ```jsx
104
+ import { IdCardPreview } from '@stratametriq/id-card-designer';
105
+
106
+ function StudentProfilePage({ realStudentData, savedTemplateJson }) {
107
+ return (
108
+ <div className="profile-card-widget">
109
+ <h3>Student ID Card</h3>
110
+
111
+ {/* Automatically binds realStudentData fields into the template */}
112
+ <IdCardPreview
113
+ templateSchema={savedTemplateJson}
114
+ data={realStudentData} // e.g. { studentName: 'Aarav Patel', admissionNo: 'ADM-101', profilePhoto: '...' }
115
+ orientation="vertical"
116
+ zoom={1.2}
117
+ />
118
+ </div>
119
+ );
120
+ }
121
+ ```
122
+
123
+ #### B. Trigger Batch A4 PDF Export from Your Own Custom Button (`generateIdCardsPdf`)
124
+ ```jsx
125
+ import { generateIdCardsPdf } from '@stratametriq/id-card-designer';
126
+
127
+ function CustomRosterTable({ selectedStudents, activeTemplate }) {
128
+ const handlePrint = async () => {
129
+ // Generate high-resolution A4 multi-page PDF directly from your data array
130
+ await generateIdCardsPdf({
131
+ records: selectedStudents,
132
+ templateSchema: activeTemplate,
133
+ orientation: 'vertical',
134
+ fileName: `Student_Cards_Batch_${new Date().toISOString().slice(0,10)}.pdf`,
135
+ pageOptions: { format: 'a4', showCropMarks: true }
136
+ });
137
+ };
138
+
139
+ return <button onClick={handlePrint}>Download A4 Print Sheet ({selectedStudents.length} Cards)</button>;
140
+ }
141
+ ```
142
+
143
+ #### C. Open the Drag-and-Drop Studio inside Your Own Modal (`<IdCardDesignerModal />`)
144
+ ```jsx
145
+ import { IdCardDesignerModal } from '@stratametriq/id-card-designer';
146
+
147
+ function DesignButton({ currentTemplate, onSaveToDatabase }) {
148
+ const [isOpen, setIsOpen] = useState(false);
149
+
150
+ return (
151
+ <>
152
+ <button onClick={() => setIsOpen(true)}>✨ Design Card Layout</button>
153
+
154
+ <IdCardDesignerModal
155
+ show={isOpen}
156
+ onHide={() => setIsOpen(false)}
157
+ initialTemplate={currentTemplate}
158
+ sampleData={[{ studentName: 'Sample Student', admissionNo: '101' }]}
159
+ onSaveTemplate={(newTemplate) => {
160
+ onSaveToDatabase(newTemplate);
161
+ setIsOpen(false);
162
+ }}
163
+ />
164
+ </>
165
+ );
166
+ }
167
+ ```
168
+
169
+ ---
170
+
40
171
  ## 🌐 Multi-Framework & Vanilla JS Support (`Vue`, `Angular`, `Svelte`, `Next.js` & `HTML`)
41
172
 
42
173
  While the visual UI components (`<IdCardManager />` and `<IdCardDesignerModal />`) are built with React hooks and drag-and-drop vector canvas state (`react-draggable`), **this npm package can be used across any frontend framework or vanilla JavaScript project**:
@@ -129,7 +260,7 @@ When users open `<IdCardManager />`, they interact with a unified, professional
129
260
  | **Step 1** | **Select Department / Organization Category** | A clean 4-card header grid showing your configured organization categories (e.g., *Student IDs*, *Faculty & Admin*, *Corporate HR*, *Hospital Portal*). Each card displays the number of bound data fields (`{fieldDefinitions.length} fields`) and template layouts (`{templateCount} template`). Clicking any card instantly switches the active category, isolating state, templates, and roster tables cleanly. |
130
261
  | **Step 2** | **Live Stage Preview & Studio Launcher** | A high-resolution vector canvas preview displaying the currently selected person's ID card in real-time. Includes:<br>• **Interactive Zoom Controls (`80% - 150%`)** alongside instant reset buttons.<br>• **Toggleable Grid & Measurement Rulers (`0-80mm`)** for visual precision inspection.<br>• **Launch Studio Canvas Button:** Opens our popup drag-and-drop design studio modal where operators can add new text fields, upload background textures, bind database keys, and drag elements around with snap-to-grid accuracy. |
131
262
  | **Step 3** | **Batch A4 Print Engine (`⚡ Live Sheet Matrix`)** | A commercial print-engine sidebar that calculates and exports production-ready multi-page grid sheets:<br>• **⚡ Live Sheet Matrix Calculation Box:** Dynamically computes physical sheet mathematics in real-time right before your eyes! When you toggle **Paper Sheet Size (`A4` vs `US Letter`)**, **Orientation (`Portrait` vs `Landscape` Sheet)**, or **Card Cut Size (`86×54mm Standard ID-1`, `90×50mm Business Card`, `100×70mm Event Badge`)**, the matrix immediately recalculates the exact column × row capacity (`e.g., 3 Cols × 3 Rows = 9 cards/page`) and total job pages required.<br>• **Hardware Cut Guides Checkboxes:** Toggle corner crosshair cut marks (`0.35mm stroke`), card perimeter cut outline guides, and technical registration headers (`PRECISION CUT SHEET — JOB SPECIFICATIONS`) for print shop operators. |
132
- | **Step 4** | **Live Roster Directory Table** | Displays a dynamic, paginated table of all people in that department. Columns automatically reflect your category's database fields (`studentName`, `admissionNo`, `classSec`, etc.). Check or uncheck individual records to include them in the Batch A4 Print Engine, or click any row to preview their rendered card live in Step 2! |
263
+ | **Step 4** | **Live Roster Directory Table & Instant Search** | Displays an interactive data table of all records in that department equipped with:<br>• **🔍 Instant Search Input:** Type any name, admission/employee number, department, or phone number to instantly filter records right before your eyes.<br>• **🏷️ Quick Status Filter Pills (`All \| Selected \| Unselected`):** Isolate checked vs unchecked records instantly before batch printing.<br>• **⚡ Smart Batch Selection:** Clicking **Select Shown / Unselect Shown** smartly checks or unchecks *only the records matching your current search or filter* without disrupting unrelated records outside your filter! Clicking any row previews their rendered card live on stage in Step 2. |
133
264
 
134
265
  ---
135
266
 
@@ -347,6 +478,156 @@ const CATEGORY_CONFIGS = {
347
478
 
348
479
  ---
349
480
 
481
+ ## 🏗️ Recommended Consumer App Architecture (`my-consumer-app/`)
482
+
483
+ When integrating `@stratametriq/id-card-designer` into an enterprise or institutional web application (e.g., School Management System, Hospital Portal, or Corporate HR Suite), we recommend structuring your project with clean separation of concerns:
484
+
485
+ ```text
486
+ my-consumer-app/
487
+ ├── src/
488
+ │ ├── config/
489
+ │ │ └── idCardFields.js # 1. Centralized field definitions & mappings across categories
490
+ │ │
491
+ │ ├── services/
492
+ │ │ └── idCardApi.js # 2. API helper methods to load/save JSON templates & records from backend
493
+ │ │
494
+ │ ├── components/
495
+ │ │ └── id-cards/
496
+ │ │ ├── CardTemplateStudio.jsx # 3. Admin component wrapping <IdCardDesignerModal />
497
+ │ │ ├── CardPreviewBadge.jsx # 4. Reusable UI component wrapping <IdCardPreview />
498
+ │ │ └── BatchPrintActions.jsx # 5. Component managing high-DPI PDF generation & progress (`generateIdCardsPdf`)
499
+ │ │
500
+ │ ├── pages/
501
+ │ │ ├── AdminSettingsPage.jsx # Uses <CardTemplateStudio /> for administrators to design ID cards
502
+ │ │ └── StaffDirectoryPage.jsx # Uses <CardPreviewBadge /> and <BatchPrintActions /> for staff/student rosters
503
+ │ └── main.jsx # Imports global "@stratametriq/id-card-designer/dist/index.css"
504
+ ```
505
+
506
+ ### 🗂️ Explanation of Key Architectural Components
507
+
508
+ 1. **`src/config/idCardFields.js` (Centralized Configuration)**
509
+ Maintains all available data fields for each department. By isolating fields in config, adding new custom fields (`bloodGroup`, `busRoute`, `rfidTag`) never requires modifying UI components:
510
+ ```javascript
511
+ export const ID_CARD_FIELDS = {
512
+ student: [
513
+ { key: "studentName", label: "Student Full Name" },
514
+ { key: "admissionNo", label: "Admission Number" },
515
+ { key: "bloodGroup", label: "Blood Group" }
516
+ ],
517
+ staff: [
518
+ { key: "staffName", label: "Staff Member Name" },
519
+ { key: "designation", label: "Job Title / Role" }
520
+ ]
521
+ };
522
+ ```
523
+
524
+ 2. **`src/services/idCardApi.js` (API & Storage Layer)**
525
+ Handles communicating with your backend server or local storage to persist the JSON template schemas (`templateSchema`) saved by administrators:
526
+ ```javascript
527
+ export async function fetchCategoryTemplate(categoryKey) {
528
+ const res = await fetch(`/api/id-cards/templates/${categoryKey}`);
529
+ return res.json();
530
+ }
531
+
532
+ export async function saveCategoryTemplate(categoryKey, schema) {
533
+ return fetch(`/api/id-cards/templates/${categoryKey}`, {
534
+ method: "POST",
535
+ headers: { "Content-Type": "application/json" },
536
+ body: JSON.stringify(schema)
537
+ });
538
+ }
539
+ ```
540
+
541
+ 3. **`src/components/id-cards/CardTemplateStudio.jsx` (Admin Studio Wrapper)**
542
+ Wraps `<IdCardDesignerModal />` with your application's custom saving logic and category switcher:
543
+ ```jsx
544
+ import React, { useState } from "react";
545
+ import { IdCardDesignerModal } from "@stratametriq/id-card-designer";
546
+ import { ID_CARD_FIELDS } from "../../config/idCardFields";
547
+ import { saveCategoryTemplate } from "../../services/idCardApi";
548
+
549
+ export function CardTemplateStudio({ categoryKey = "student", initialSchema }) {
550
+ const [showModal, setShowModal] = useState(false);
551
+
552
+ return (
553
+ <div>
554
+ <button onClick={() => setShowModal(true)}>Open ID Card Designer</button>
555
+ <IdCardDesignerModal
556
+ show={showModal}
557
+ onHide={() => setShowModal(false)}
558
+ initialTemplate={initialSchema}
559
+ fieldDefinitions={ID_CARD_FIELDS[categoryKey]}
560
+ onSaveTemplate={async (schema) => {
561
+ await saveCategoryTemplate(categoryKey, schema);
562
+ setShowModal(false);
563
+ }}
564
+ />
565
+ </div>
566
+ );
567
+ }
568
+ ```
569
+
570
+ 4. **`src/components/id-cards/CardPreviewBadge.jsx` (Reusable Live Badge)**
571
+ Wraps `<IdCardPreview />` to render clean vector ID cards in directory listings, profile popups, or student tables:
572
+ ```jsx
573
+ import React from "react";
574
+ import { IdCardPreview } from "@stratametriq/id-card-designer";
575
+
576
+ export function CardPreviewBadge({ recordData, templateSchema }) {
577
+ return (
578
+ <div className="card-preview-wrapper shadow-md rounded-lg overflow-hidden">
579
+ <IdCardPreview
580
+ templateSchema={templateSchema}
581
+ data={recordData}
582
+ zoom={1}
583
+ />
584
+ </div>
585
+ );
586
+ }
587
+ ```
588
+
589
+ 5. **`src/components/id-cards/BatchPrintActions.jsx` (Batch Print Utility Button)**
590
+ Manages batch exporting checked staff or student records into multi-page A4 or Letter sheets:
591
+ ```jsx
592
+ import React, { useState } from "react";
593
+ import { generateIdCardsPdf } from "@stratametriq/id-card-designer";
594
+
595
+ export function BatchPrintActions({ selectedRecords, templateSchema }) {
596
+ const [exporting, setExporting] = useState(false);
597
+
598
+ const handleExport = async () => {
599
+ setExporting(true);
600
+ await generateIdCardsPdf({
601
+ records: selectedRecords,
602
+ templateSchema: templateSchema,
603
+ orientation: templateSchema?.orientation || "vertical",
604
+ fileName: "Batch_ID_Cards_Job.pdf",
605
+ pageOptions: { format: "a4", showCropMarks: true, showCutOutline: true }
606
+ });
607
+ setExporting(false);
608
+ };
609
+
610
+ return (
611
+ <button onClick={handleExport} disabled={exporting || selectedRecords.length === 0}>
612
+ {exporting ? "Generating PDF Sheets..." : `Batch Print (${selectedRecords.length} Cards)`}
613
+ </button>
614
+ );
615
+ }
616
+ ```
617
+
618
+ 6. **`src/main.jsx` (Global Stylesheet Import)**
619
+ Always import the universal stylesheet right at the root entry point of your application:
620
+ ```javascript
621
+ import React from 'react';
622
+ import ReactDOM from 'react-dom/client';
623
+ import App from './App.jsx';
624
+ import "@stratametriq/id-card-designer/dist/index.css";
625
+
626
+ ReactDOM.createRoot(document.getElementById('root')).render(<App />);
627
+ ```
628
+
629
+ ---
630
+
350
631
  ## 📜 License
351
632
 
352
- MIT © Stratametriq
633
+ Dual-licensed under the [MIT License](./LICENSE) (for open-source/non-commercial) and a Commercial Enterprise License (for commercial usage). © Stratametriq
package/dist/index.css CHANGED
@@ -1,17 +1,30 @@
1
1
  /* react-id-card-designer universal styles */
2
- @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Roboto:wght@400;500;700&family=Outfit:wght@400;500;600;700&display=swap');
2
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=Plus+Jakarta+Sans:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap');
3
3
 
4
4
  :root {
5
5
  --ricd-primary: #3b82f6;
6
6
  --ricd-primary-hover: #2563eb;
7
- --ricd-bg: #0f172a;
8
- --ricd-surface: #1e293b;
9
- --ricd-surface-light: #334155;
10
- --ricd-border: #475569;
7
+ --ricd-primary-glow: rgba(59, 130, 246, 0.35);
8
+ --ricd-bg: #060913;
9
+ --ricd-surface: rgba(17, 24, 39, 0.88);
10
+ --ricd-surface-light: rgba(30, 41, 59, 0.82);
11
+ --ricd-border: rgba(255, 255, 255, 0.1);
12
+ --ricd-border-highlight: rgba(59, 130, 246, 0.45);
11
13
  --ricd-text: #f8fafc;
12
14
  --ricd-text-muted: #94a3b8;
13
- --ricd-radius: 0.75rem;
14
- --ricd-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.5), 0 8px 10px -6px rgba(0, 0, 0, 0.3);
15
+ --ricd-radius: 1rem;
16
+ --ricd-shadow: 0 20px 40px -15px rgba(0, 0, 0, 0.6), 0 10px 15px -8px rgba(0, 0, 0, 0.4);
17
+ }
18
+
19
+ * {
20
+ box-sizing: border-box;
21
+ }
22
+
23
+ body, button, input, select, textarea {
24
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
25
+ -webkit-font-smoothing: antialiased;
26
+ -moz-osx-font-smoothing: grayscale;
27
+ text-rendering: optimizeLegibility;
15
28
  }
16
29
 
17
30
  /* Modal Overlay & Wrapper */
@@ -22,11 +35,11 @@
22
35
  display: flex;
23
36
  align-items: center;
24
37
  justify-content: center;
25
- background-color: rgba(15, 23, 42, 0.85);
26
- backdrop-filter: blur(8px);
27
- animation: ricdFadeIn 0.2s ease-out;
38
+ background-color: rgba(6, 9, 19, 0.88);
39
+ backdrop-filter: blur(12px);
40
+ animation: ricdFadeIn 0.2s cubic-bezier(0.16, 1, 0.3, 1);
28
41
  padding: 1.5rem;
29
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
42
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
30
43
  color: var(--ricd-text);
31
44
  box-sizing: border-box;
32
45
  }
@@ -994,4 +1007,149 @@
994
1007
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.25);
995
1008
  }
996
1009
 
1010
+ /* =========================================================
1011
+ * ID CARD MANAGER THEME
1012
+ * The manager used to pass its theme only to the studio modal.
1013
+ * These rules apply the same selection to the complete dashboard.
1014
+ * ========================================================= */
1015
+ .pg-theme-enterprise {
1016
+ background-color: #eef4fb;
1017
+ background-image:
1018
+ radial-gradient(circle at 50% 0%, rgba(59, 130, 246, 0.16) 0%, transparent 58%),
1019
+ radial-gradient(circle at 85% 30%, rgba(14, 165, 233, 0.08) 0%, transparent 48%);
1020
+ color: #1e293b;
1021
+ }
1022
+
1023
+ .pg-theme-enterprise .pg-master-header {
1024
+ background: linear-gradient(135deg, #ffffff 0%, #f1f6fc 100%);
1025
+ border-color: rgba(37, 99, 235, 0.24);
1026
+ box-shadow: 0 15px 35px -10px rgba(30, 64, 175, 0.18), inset 0 1px 0 #ffffff;
1027
+ }
1028
+
1029
+ .pg-theme-enterprise .pg-title {
1030
+ background: linear-gradient(to right, #172554 30%, #334155);
1031
+ -webkit-background-clip: text;
1032
+ }
1033
+
1034
+ .pg-theme-enterprise .pg-subtitle,
1035
+ .pg-theme-enterprise .pg-section-subtitle,
1036
+ .pg-theme-enterprise .pg-toggle-label {
1037
+ color: #64748b;
1038
+ }
1039
+
1040
+ .pg-theme-enterprise .pg-section-title {
1041
+ color: #1e293b;
1042
+ }
1043
+
1044
+ .pg-theme-enterprise .pg-card {
1045
+ background: rgba(255, 255, 255, 0.88) !important;
1046
+ border-color: #dbe5f0 !important;
1047
+ box-shadow: 0 12px 28px -18px rgba(15, 23, 42, 0.35);
1048
+ }
1049
+
1050
+ .pg-theme-enterprise .pg-category-card {
1051
+ background: #ffffff !important;
1052
+ border-color: #dbe5f0 !important;
1053
+ box-shadow: 0 8px 20px -16px rgba(15, 23, 42, 0.4);
1054
+ }
1055
+
1056
+ .pg-theme-enterprise .pg-category-card:hover {
1057
+ border-color: #93c5fd !important;
1058
+ transform: translateY(-2px);
1059
+ }
1060
+
1061
+ .pg-theme-enterprise .pg-category-card--active {
1062
+ background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%) !important;
1063
+ border-color: #3b82f6 !important;
1064
+ box-shadow: 0 10px 25px -12px rgba(37, 99, 235, 0.4) !important;
1065
+ }
1066
+
1067
+ .pg-theme-enterprise .pg-category-card > div > div > div[style*="color"] {
1068
+ color: #1e293b !important;
1069
+ }
1070
+
1071
+ .pg-theme-enterprise .pg-category-card--active > div > div > div:first-child {
1072
+ color: #ffffff !important;
1073
+ }
1074
+
1075
+ .pg-theme-enterprise .pg-stage-toolbar,
1076
+ .pg-theme-enterprise .pg-tip-banner,
1077
+ .pg-theme-enterprise .pg-export-summary,
1078
+ .pg-theme-enterprise .pg-sheet-matrix,
1079
+ .pg-theme-enterprise .pg-cut-guides {
1080
+ background: #f8fbff !important;
1081
+ border-color: #d7e3f0 !important;
1082
+ }
1083
+
1084
+ .pg-theme-enterprise .pg-preview-stage {
1085
+ background-color: #edf3f8 !important;
1086
+ }
1087
+
1088
+ .pg-theme-enterprise .pg-btn-sm-glass {
1089
+ background: #ffffff;
1090
+ border: 1px solid #cbd5e1;
1091
+ color: #334155;
1092
+ }
1093
+
1094
+ .pg-theme-enterprise .pg-btn-sm-glass:hover {
1095
+ background: #eff6ff;
1096
+ border-color: #60a5fa;
1097
+ color: #1d4ed8;
1098
+ }
1099
+
1100
+ .pg-theme-enterprise .pg-select,
1101
+ .pg-theme-enterprise .pg-stage-toolbar select {
1102
+ background: #ffffff !important;
1103
+ border-color: #cbd5e1 !important;
1104
+ color: #1e293b !important;
1105
+ }
1106
+
1107
+ .pg-theme-enterprise .pg-table-wrapper {
1108
+ background: #ffffff;
1109
+ border-color: #dbe5f0;
1110
+ }
1111
+
1112
+ .pg-theme-enterprise .pg-table th {
1113
+ background: #f1f5f9;
1114
+ border-color: #dbe5f0;
1115
+ color: #475569;
1116
+ }
1117
+
1118
+ .pg-theme-enterprise .pg-table td {
1119
+ border-color: #e2e8f0;
1120
+ color: #334155;
1121
+ }
1122
+
1123
+ .pg-theme-enterprise .pg-table tr:hover td {
1124
+ background: #eff6ff;
1125
+ }
1126
+
1127
+ /* Inline dashboard styles use the dark palette. Keep the component API intact
1128
+ * while translating those semantic dark surfaces and text tokens in light mode. */
1129
+ .pg-theme-enterprise [style*="background: rgba(15, 23, 42"],
1130
+ .pg-theme-enterprise [style*="background: rgba(30, 41, 59"],
1131
+ .pg-theme-enterprise [style*="background-color: rgba(15, 23, 42"],
1132
+ .pg-theme-enterprise [style*="background-color: rgb(11, 15, 25)"] {
1133
+ background-color: #f8fafc !important;
1134
+ background: #f8fafc !important;
1135
+ }
1136
+
1137
+ .pg-theme-enterprise [style*="color: rgb(255, 255, 255)"],
1138
+ .pg-theme-enterprise [style*="color: #fff"],
1139
+ .pg-theme-enterprise [style*="color: rgb(248, 250, 252)"],
1140
+ .pg-theme-enterprise [style*="color: #f8fafc"] {
1141
+ color: #1e293b !important;
1142
+ }
1143
+
1144
+ .pg-theme-enterprise [style*="color: rgb(226, 232, 240)"],
1145
+ .pg-theme-enterprise [style*="color: #e2e8f0"],
1146
+ .pg-theme-enterprise [style*="color: rgb(203, 213, 225)"],
1147
+ .pg-theme-enterprise [style*="color: #cbd5e1"] {
1148
+ color: #475569 !important;
1149
+ }
1150
+
1151
+ .pg-theme-enterprise [style*="color: rgb(148, 163, 184)"],
1152
+ .pg-theme-enterprise [style*="color: #94a3b8"] {
1153
+ color: #64748b !important;
1154
+ }
997
1155