Spaces:
Running
Running
Re-theme demo in National Design Studio editorial style (black/white, Swiss grid, EOB masthead)
Browse files- README.md +4 -4
- index.html +185 -30
README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
| 1 |
---
|
| 2 |
-
title: Rampart
|
| 3 |
emoji: π‘οΈ
|
| 4 |
-
colorFrom:
|
| 5 |
-
colorTo:
|
| 6 |
sdk: static
|
| 7 |
app_file: index.html
|
| 8 |
-
short_description:
|
| 9 |
---
|
| 10 |
|
| 11 |
# Rampart β Client-Side PII Redaction Demo
|
|
|
|
| 1 |
---
|
| 2 |
+
title: Rampart
|
| 3 |
emoji: π‘οΈ
|
| 4 |
+
colorFrom: gray
|
| 5 |
+
colorTo: gray
|
| 6 |
sdk: static
|
| 7 |
app_file: index.html
|
| 8 |
+
short_description: On-device PII redaction by National Design Studio
|
| 9 |
---
|
| 10 |
|
| 11 |
# Rampart β Client-Side PII Redaction Demo
|
index.html
CHANGED
|
@@ -7,21 +7,21 @@
|
|
| 7 |
<meta name="description" content="14.7 MB ONNX model that detects and redacts PII in your browser before it leaves your device. No server, no API, no data sent anywhere.">
|
| 8 |
<style>
|
| 9 |
:root {
|
| 10 |
-
--bg: #
|
| 11 |
-
--bg-elev: #
|
| 12 |
-
--bg-card: #
|
| 13 |
-
--border:
|
| 14 |
-
--border-bright:
|
| 15 |
-
--text: #
|
| 16 |
-
--text-dim:
|
| 17 |
-
--text-dimmer:
|
| 18 |
-
--accent: #
|
| 19 |
-
--accent-dim: #
|
| 20 |
-
--accent-glow: rgba(
|
| 21 |
-
--green: #
|
| 22 |
-
--red: #
|
| 23 |
-
--radius:
|
| 24 |
-
--font:
|
| 25 |
--mono: "SF Mono", "Fira Code", "Fira Mono", "Cascadia Code", Menlo, Consolas, monospace;
|
| 26 |
}
|
| 27 |
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
@@ -564,6 +564,139 @@ textarea.input-box::placeholder { color: var(--text-dimmer); }
|
|
| 564 |
.tooltip .tt-label { font-weight: 700; }
|
| 565 |
.tooltip .tt-original { color: var(--text-dim); margin-top: 2px; }
|
| 566 |
.tooltip .tt-score { color: var(--text-dimmer); margin-top: 2px; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 567 |
</style>
|
| 568 |
</head>
|
| 569 |
<body>
|
|
@@ -578,17 +711,26 @@ textarea.input-box::placeholder { color: var(--text-dimmer); }
|
|
| 578 |
</div>
|
| 579 |
</div>
|
| 580 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 581 |
<!-- HERO -->
|
| 582 |
<div class="hero">
|
| 583 |
<div class="hero-badge">
|
| 584 |
<span class="dot"></span>
|
| 585 |
-
Runs
|
| 586 |
</div>
|
| 587 |
<h1>Rampart</h1>
|
| 588 |
-
<p>A 14.7
|
| 589 |
<div class="hero-stats">
|
| 590 |
<div class="stat">
|
| 591 |
-
<div class="stat-val">14.7<span style="font-size:1rem">MB</span></div>
|
| 592 |
<div class="stat-label">Model Size</div>
|
| 593 |
</div>
|
| 594 |
<div class="stat">
|
|
@@ -601,10 +743,10 @@ textarea.input-box::placeholder { color: var(--text-dimmer); }
|
|
| 601 |
</div>
|
| 602 |
<div class="stat">
|
| 603 |
<div class="stat-val">98.4<span style="font-size:1rem">%</span></div>
|
| 604 |
-
<div class="stat-label">
|
| 605 |
</div>
|
| 606 |
<div class="stat">
|
| 607 |
-
<div class="stat-val">~4<span style="font-size:1rem">ms</span></div>
|
| 608 |
<div class="stat-label">p50 Latency</div>
|
| 609 |
</div>
|
| 610 |
</div>
|
|
@@ -614,7 +756,7 @@ textarea.input-box::placeholder { color: var(--text-dimmer); }
|
|
| 614 |
|
| 615 |
<!-- LIVE REDACTION DEMO -->
|
| 616 |
<div class="section">
|
| 617 |
-
<div class="section-title">
|
| 618 |
<div class="demo-panel">
|
| 619 |
<div class="demo-header">
|
| 620 |
<div class="demo-header-left">
|
|
@@ -656,6 +798,7 @@ textarea.input-box::placeholder { color: var(--text-dimmer); }
|
|
| 656 |
|
| 657 |
<!-- TABS: Examples / Entity Types / Chat Sim / Rehydration -->
|
| 658 |
<div class="section">
|
|
|
|
| 659 |
<div class="tabs">
|
| 660 |
<button class="tab active" onclick="switchTab(event,'examples')">Example Gallery</button>
|
| 661 |
<button class="tab" onclick="switchTab(event,'entities')">Entity Types</button>
|
|
@@ -727,15 +870,27 @@ textarea.input-box::placeholder { color: var(--text-dimmer); }
|
|
| 727 |
</div>
|
| 728 |
|
| 729 |
<!-- FOOTER -->
|
| 730 |
-
<
|
| 731 |
-
<
|
| 732 |
-
<
|
| 733 |
-
<
|
| 734 |
-
|
| 735 |
-
|
| 736 |
-
|
| 737 |
-
|
| 738 |
-
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 739 |
|
| 740 |
<!-- TOOLTIP -->
|
| 741 |
<div class="tooltip" id="tooltip"></div>
|
|
|
|
| 7 |
<meta name="description" content="14.7 MB ONNX model that detects and redacts PII in your browser before it leaves your device. No server, no API, no data sent anywhere.">
|
| 8 |
<style>
|
| 9 |
:root {
|
| 10 |
+
--bg: #000000;
|
| 11 |
+
--bg-elev: #0c0c0c;
|
| 12 |
+
--bg-card: #070707;
|
| 13 |
+
--border: rgba(255,255,255,0.14);
|
| 14 |
+
--border-bright: rgba(255,255,255,0.30);
|
| 15 |
+
--text: #ffffff;
|
| 16 |
+
--text-dim: rgba(255,255,255,0.62);
|
| 17 |
+
--text-dimmer: rgba(255,255,255,0.40);
|
| 18 |
+
--accent: #ffffff;
|
| 19 |
+
--accent-dim: #ffffff;
|
| 20 |
+
--accent-glow: rgba(255,255,255,0.08);
|
| 21 |
+
--green: #5dd39e;
|
| 22 |
+
--red: #ff5d5d;
|
| 23 |
+
--radius: 2px;
|
| 24 |
+
--font: "PP Neue Montreal", "Neue Montreal", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
| 25 |
--mono: "SF Mono", "Fira Code", "Fira Mono", "Cascadia Code", Menlo, Consolas, monospace;
|
| 26 |
}
|
| 27 |
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
|
|
| 564 |
.tooltip .tt-label { font-weight: 700; }
|
| 565 |
.tooltip .tt-original { color: var(--text-dim); margin-top: 2px; }
|
| 566 |
.tooltip .tt-score { color: var(--text-dimmer); margin-top: 2px; }
|
| 567 |
+
|
| 568 |
+
/* ===================================================================== */
|
| 569 |
+
/* National Design Studio editorial theme β black/white, Swiss grid, */
|
| 570 |
+
/* hairline rules, Roman-numeral section markers, arrow affordances. */
|
| 571 |
+
/* ===================================================================== */
|
| 572 |
+
body { line-height: 1.5; letter-spacing: -0.005em; }
|
| 573 |
+
::selection { background: #fff; color: #000; }
|
| 574 |
+
|
| 575 |
+
/* Top nav */
|
| 576 |
+
.nav {
|
| 577 |
+
display: flex; align-items: baseline; justify-content: space-between;
|
| 578 |
+
gap: 16px; padding: 22px 40px; border-bottom: 1px solid var(--border);
|
| 579 |
+
}
|
| 580 |
+
.nav-brand { font-size: 15px; font-weight: 500; letter-spacing: -0.01em; }
|
| 581 |
+
.nav-links { display: flex; gap: 26px; font-size: 14px; }
|
| 582 |
+
.nav-links a { color: var(--text-dim); text-decoration: none; transition: color .15s; }
|
| 583 |
+
.nav-links a:hover { color: #fff; }
|
| 584 |
+
.nav-links a .arr { display: inline-block; transition: transform .2s ease; }
|
| 585 |
+
.nav-links a:hover .arr { transform: translate(2px,-2px); }
|
| 586 |
+
|
| 587 |
+
/* Hero β left-aligned editorial */
|
| 588 |
+
.hero { text-align: left; padding: 80px 40px 56px; overflow: visible; }
|
| 589 |
+
.hero::before { display: none; }
|
| 590 |
+
.hero-badge {
|
| 591 |
+
border: 1px solid var(--border); border-radius: 99px; background: transparent;
|
| 592 |
+
color: var(--text-dim); margin-bottom: 36px; text-transform: none; letter-spacing: 0;
|
| 593 |
+
}
|
| 594 |
+
.hero-badge .dot { background: var(--green); box-shadow: none; }
|
| 595 |
+
.hero h1 {
|
| 596 |
+
font-size: clamp(3rem, 9vw, 6.5rem); font-weight: 500; letter-spacing: -0.04em;
|
| 597 |
+
line-height: 0.95; margin-bottom: 22px;
|
| 598 |
+
background: none; -webkit-text-fill-color: #fff; color: #fff;
|
| 599 |
+
}
|
| 600 |
+
.hero p {
|
| 601 |
+
font-size: clamp(1.15rem, 2.2vw, 1.6rem); color: var(--text); line-height: 1.12;
|
| 602 |
+
max-width: 760px; margin: 0; letter-spacing: -0.02em; font-weight: 400;
|
| 603 |
+
}
|
| 604 |
+
.hero p .muted { color: var(--text-dim); }
|
| 605 |
+
.hero-stats {
|
| 606 |
+
justify-content: flex-start; gap: 0; margin-top: 56px;
|
| 607 |
+
border-top: 1px solid var(--border);
|
| 608 |
+
}
|
| 609 |
+
.stat {
|
| 610 |
+
text-align: left; flex: 1; min-width: 120px; padding: 18px 24px 0 0;
|
| 611 |
+
}
|
| 612 |
+
.stat-val { font-size: 1.9rem; font-weight: 500; letter-spacing: -0.03em; }
|
| 613 |
+
.stat-label {
|
| 614 |
+
text-transform: uppercase; letter-spacing: 0.12em; font-size: 0.66rem;
|
| 615 |
+
color: var(--text-dimmer); margin-top: 4px;
|
| 616 |
+
}
|
| 617 |
+
|
| 618 |
+
/* Layout */
|
| 619 |
+
.container { max-width: 1280px; padding: 0 40px 96px; }
|
| 620 |
+
.section { margin-bottom: 72px; }
|
| 621 |
+
|
| 622 |
+
/* Section header: Roman numeral + label, hairline above */
|
| 623 |
+
.section-title {
|
| 624 |
+
text-transform: none; letter-spacing: -0.01em; font-size: 1.05rem; color: var(--text);
|
| 625 |
+
border-top: 1px solid var(--border); padding-top: 20px; margin-bottom: 28px;
|
| 626 |
+
gap: 22px;
|
| 627 |
+
}
|
| 628 |
+
.section-title::after { display: none; }
|
| 629 |
+
.section-title .rn {
|
| 630 |
+
display: inline-block; width: 2.4em; color: var(--text-dimmer);
|
| 631 |
+
font-variant-numeric: normal; font-feature-settings: normal;
|
| 632 |
+
font-size: 0.85rem; letter-spacing: 0.04em;
|
| 633 |
+
}
|
| 634 |
+
.section-title .lede { color: var(--text-dim); font-size: 0.95rem; margin-left: auto; max-width: 46ch; text-align: right; }
|
| 635 |
+
|
| 636 |
+
/* Panels β square, hairline */
|
| 637 |
+
.demo-panel, .chat-panel { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); }
|
| 638 |
+
.demo-header { padding: 18px 22px; }
|
| 639 |
+
.demo-header-title { font-weight: 400; color: var(--text-dim); font-size: 13px; }
|
| 640 |
+
.model-status { border-radius: 99px; background: transparent; }
|
| 641 |
+
|
| 642 |
+
textarea.input-box, .chat-input, .output-box, .mapping-value, .stat-pill, .legend-item, .example-card {
|
| 643 |
+
border-radius: var(--radius);
|
| 644 |
+
}
|
| 645 |
+
textarea.input-box, .chat-input { background: #000; }
|
| 646 |
+
textarea.input-box:focus, .chat-input:focus { border-color: #fff; }
|
| 647 |
+
.output-box { background: #000; }
|
| 648 |
+
|
| 649 |
+
/* Buttons β square, uppercase micro-label, invert on hover */
|
| 650 |
+
.btn {
|
| 651 |
+
border-radius: var(--radius); background: transparent; color: var(--text-dim);
|
| 652 |
+
text-transform: uppercase; letter-spacing: 0.08em; font-size: 11px; font-weight: 500;
|
| 653 |
+
border: 1px solid var(--border); padding: 8px 14px;
|
| 654 |
+
}
|
| 655 |
+
.btn:hover { border-color: #fff; color: #fff; background: transparent; }
|
| 656 |
+
.btn-primary { background: #fff; border-color: #fff; color: #000; }
|
| 657 |
+
.btn-primary:hover { background: var(--text-dim); border-color: var(--text-dim); color: #000; }
|
| 658 |
+
|
| 659 |
+
/* Tabs β minimal text, underline active */
|
| 660 |
+
.tabs { gap: 28px; }
|
| 661 |
+
.tab {
|
| 662 |
+
text-transform: uppercase; letter-spacing: 0.08em; font-size: 11px; font-weight: 500;
|
| 663 |
+
padding: 12px 0; color: var(--text-dimmer);
|
| 664 |
+
}
|
| 665 |
+
.tab:hover { color: var(--text); }
|
| 666 |
+
.tab.active { color: #fff; border-bottom-color: #fff; }
|
| 667 |
+
|
| 668 |
+
/* Cards */
|
| 669 |
+
.example-card { background: var(--bg-card); }
|
| 670 |
+
.example-card:hover { border-color: #fff; background: var(--bg-elev); }
|
| 671 |
+
.example-card-title { color: #fff; text-transform: none; letter-spacing: 0; }
|
| 672 |
+
.legend-item:hover { border-color: var(--border-bright); }
|
| 673 |
+
.mapping-placeholder { color: #fff; }
|
| 674 |
+
|
| 675 |
+
/* Footer β inverted white block, ND Studio masthead */
|
| 676 |
+
.footer {
|
| 677 |
+
background: #fff; color: #000; text-align: left; border-top: none;
|
| 678 |
+
padding: 56px 40px; display: grid; gap: 32px;
|
| 679 |
+
grid-template-columns: 1.2fr 1fr; align-items: start; font-size: 14px;
|
| 680 |
+
}
|
| 681 |
+
.footer a { color: #000; text-decoration: underline; text-underline-offset: 3px; }
|
| 682 |
+
.footer a:hover { color: #000; opacity: 0.6; }
|
| 683 |
+
.footer .f-mark { font-size: 1.5rem; font-weight: 500; letter-spacing: -0.03em; line-height: 1.05; max-width: 18ch; }
|
| 684 |
+
.footer .f-addr { color: #333; line-height: 1.5; margin-top: 16px; font-size: 13px; }
|
| 685 |
+
.footer .f-links { display: flex; flex-wrap: wrap; gap: 18px 26px; align-content: start; }
|
| 686 |
+
.footer .f-legal { grid-column: 1 / -1; border-top: 1px solid rgba(0,0,0,0.15); padding-top: 20px; color: #444; font-size: 12px; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 8px; }
|
| 687 |
+
|
| 688 |
+
.loading-overlay { background: rgba(0,0,0,0.92); }
|
| 689 |
+
.loading-spinner { border-color: var(--border); border-top-color: #fff; }
|
| 690 |
+
.loading-progress-bar { background: #fff; }
|
| 691 |
+
|
| 692 |
+
@media (max-width: 768px) {
|
| 693 |
+
.nav, .hero, .container, .footer { padding-left: 20px; padding-right: 20px; }
|
| 694 |
+
.hero { padding-top: 48px; }
|
| 695 |
+
.nav-links { gap: 16px; }
|
| 696 |
+
.section-title { flex-wrap: wrap; }
|
| 697 |
+
.section-title .lede { margin-left: 0; text-align: left; max-width: none; }
|
| 698 |
+
.footer { grid-template-columns: 1fr; }
|
| 699 |
+
}
|
| 700 |
</style>
|
| 701 |
</head>
|
| 702 |
<body>
|
|
|
|
| 711 |
</div>
|
| 712 |
</div>
|
| 713 |
|
| 714 |
+
<!-- NAV -->
|
| 715 |
+
<nav class="nav">
|
| 716 |
+
<div class="nav-brand">National Design Studio</div>
|
| 717 |
+
<div class="nav-links">
|
| 718 |
+
<a href="https://huggingface.co/nationaldesignstudio/rampart" target="_blank" rel="noopener">Model <span class="arr">β</span></a>
|
| 719 |
+
<a href="https://ndstudio.gov" target="_blank" rel="noopener">ndstudio.gov <span class="arr">β</span></a>
|
| 720 |
+
</div>
|
| 721 |
+
</nav>
|
| 722 |
+
|
| 723 |
<!-- HERO -->
|
| 724 |
<div class="hero">
|
| 725 |
<div class="hero-badge">
|
| 726 |
<span class="dot"></span>
|
| 727 |
+
Runs entirely in your browser β no data leaves your device
|
| 728 |
</div>
|
| 729 |
<h1>Rampart</h1>
|
| 730 |
+
<p>Personal information, redacted before it ever leaves your device. <span class="muted">A 14.7 MB on-device model that finds and removes PII in real time β no server, no API, no data sent anywhere.</span></p>
|
| 731 |
<div class="hero-stats">
|
| 732 |
<div class="stat">
|
| 733 |
+
<div class="stat-val">14.7<span style="font-size:1rem"> MB</span></div>
|
| 734 |
<div class="stat-label">Model Size</div>
|
| 735 |
</div>
|
| 736 |
<div class="stat">
|
|
|
|
| 743 |
</div>
|
| 744 |
<div class="stat">
|
| 745 |
<div class="stat-val">98.4<span style="font-size:1rem">%</span></div>
|
| 746 |
+
<div class="stat-label">Private-term recall</div>
|
| 747 |
</div>
|
| 748 |
<div class="stat">
|
| 749 |
+
<div class="stat-val">~4<span style="font-size:1rem"> ms</span></div>
|
| 750 |
<div class="stat-label">p50 Latency</div>
|
| 751 |
</div>
|
| 752 |
</div>
|
|
|
|
| 756 |
|
| 757 |
<!-- LIVE REDACTION DEMO -->
|
| 758 |
<div class="section">
|
| 759 |
+
<div class="section-title"><span class="rn">I</span><span>Live Redaction</span><span class="lede">Type or paste text. PII is detected and replaced with stable placeholders, on-device, as you type.</span></div>
|
| 760 |
<div class="demo-panel">
|
| 761 |
<div class="demo-header">
|
| 762 |
<div class="demo-header-left">
|
|
|
|
| 798 |
|
| 799 |
<!-- TABS: Examples / Entity Types / Chat Sim / Rehydration -->
|
| 800 |
<div class="section">
|
| 801 |
+
<div class="section-title"><span class="rn">II</span><span>Reference</span><span class="lede">Examples, the full entity schema, a chat simulation, and the reversible placeholder map.</span></div>
|
| 802 |
<div class="tabs">
|
| 803 |
<button class="tab active" onclick="switchTab(event,'examples')">Example Gallery</button>
|
| 804 |
<button class="tab" onclick="switchTab(event,'entities')">Entity Types</button>
|
|
|
|
| 870 |
</div>
|
| 871 |
|
| 872 |
<!-- FOOTER -->
|
| 873 |
+
<footer class="footer">
|
| 874 |
+
<div>
|
| 875 |
+
<div class="f-mark">National Design Studio</div>
|
| 876 |
+
<div class="f-addr">
|
| 877 |
+
Eisenhower Executive Office Building<br>
|
| 878 |
+
1650 17th St NW,<br>
|
| 879 |
+
Washington, DC 20006
|
| 880 |
+
</div>
|
| 881 |
+
</div>
|
| 882 |
+
<div class="f-links">
|
| 883 |
+
<a href="https://huggingface.co/nationaldesignstudio/rampart" target="_blank" rel="noopener">Rampart Model β</a>
|
| 884 |
+
<a href="https://www.npmjs.com/package/@nationaldesignstudio/rampart" target="_blank" rel="noopener">npm β</a>
|
| 885 |
+
<a href="https://huggingface.co/datasets/ai4privacy/pii-masking-openpii-1.5m" target="_blank" rel="noopener">Training Data β</a>
|
| 886 |
+
<a href="https://huggingface.co/docs/transformers.js" target="_blank" rel="noopener">transformers.js β</a>
|
| 887 |
+
<a href="https://ndstudio.gov" target="_blank" rel="noopener">ndstudio.gov β</a>
|
| 888 |
+
</div>
|
| 889 |
+
<div class="f-legal">
|
| 890 |
+
<span>Rampart model β National Design Studio. CC BY 4.0.</span>
|
| 891 |
+
<span>Demo build by Mike0021. This is America, designed.</span>
|
| 892 |
+
</div>
|
| 893 |
+
</footer>
|
| 894 |
|
| 895 |
<!-- TOOLTIP -->
|
| 896 |
<div class="tooltip" id="tooltip"></div>
|