Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
172 changes: 169 additions & 3 deletions sec_certs_page/static/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@
--sidebar-width: 250px;
}

/* Skip to main content link - accessible but visually hidden until focused */
.skip-link {
position: absolute;
top: -40px;
left: 0;
background: #000;
color: white;
padding: 8px;
text-decoration: none;
z-index: 100;
}

.skip-link:focus {
top: 0;
}

.nav-button {
margin-right: 0.5rem !important;
margin-left: 0.5rem !important;
Expand Down Expand Up @@ -94,7 +110,7 @@
.chat-message-user {
text-align: right;
background: #d1e7dd;
color: #0f5132;
color: #003d1a;
border-radius: 1em 1em 0 1em;
margin: 0.5em 0 0.5em auto;
max-width: 75%;
Expand All @@ -104,7 +120,7 @@
.chat-message-assistant {
text-align: left;
background: #d1dce7;
color: #0f3051;
color: #001529;
border-radius: 1em 1em 1em 0;
margin: 0.5em auto 0.5em 0;
max-width: 75%;
Expand Down Expand Up @@ -361,14 +377,18 @@ h6 {
.dropdown .dropbtn {
font-size: 16px;
border: none;
outline: none;
color: white;
padding: 14px 16px;
background-color: inherit;
font-family: inherit; /* Important for vertical align on mobile phones */
margin: 0; /* Important for vertical align on mobile phones */
}

.dropdown .dropbtn:focus-visible {
outline: 3px solid #ffc107;
outline-offset: 2px;
}

#left-navigation {
position: fixed;
left: 0px;
Expand Down Expand Up @@ -1027,3 +1047,149 @@ h6 {
color: white;
}

/* ==========================================================================
WCAG Accessibility implementation
btn-outline-primary color overrides per theme
========================================================================== */

[data-bs-theme="light"] .btn-outline-primary {
--bs-btn-color: #0060F0;
--bs-btn-border-color: #0060F0;
--bs-btn-hover-bg: #0060F0;
--bs-btn-hover-border-color: #0060F0;
--bs-btn-active-bg: #0060F0;
--bs-btn-active-border-color: #0060F0;
}

[data-bs-theme="light"] .btn-link {
--bs-btn-color: #0060F0;
--bs-btn-hover-color: #0056B3;
--bs-btn-active-color: #0056B3;
}

[data-bs-theme="dark"] .btn-outline-primary {
--bs-btn-color: #85B6FF;
--bs-btn-border-color: #85B6FF;
--bs-btn-hover-bg: #85B6FF;
--bs-btn-hover-border-color: #85B6FF;
--bs-btn-active-bg: #85B6FF;
--bs-btn-active-border-color: #85B6FF;
}

/* btn-outline-secondary:*/
[data-bs-theme="dark"] .btn-outline-secondary {
--bs-btn-color: #AAAAAA;
--bs-btn-border-color: #AAAAAA;
--bs-btn-hover-color: #212529;
--bs-btn-hover-bg: #AAAAAA;
--bs-btn-hover-border-color: #AAAAAA;
--bs-btn-active-color: #212529;
--bs-btn-active-bg: #AAAAAA;
--bs-btn-active-border-color: #AAAAAA;
}

/* Higher contrast for links (Light mode) */
[data-bs-theme="light"] p a {
color: #1A6BCC;
}

[data-bs-theme="light"] p a:hover,
[data-bs-theme="light"] p a:focus {
color: #0056B3;
}

/* back to original color in dark mode*/
[data-bs-theme="dark"] p a {
color: #85B6FF;
}

/* Higher contrast links on .bg-darker-light background*/
[data-bs-theme="dark"] .bg-darker-light a:not(.btn) {
color: #9EC5FE;
}
[data-bs-theme="dark"] .bg-darker-light .btn-link {
--bs-btn-color: #9EC5FE;
--bs-btn-hover-color: #cfe2ff;
--bs-btn-active-color: #cfe2ff;
}

[data-bs-theme="light"] .bg-darker-light a:not(.btn) {
color: #1A6BCC;
}
[data-bs-theme="light"] .bg-darker-light .btn-link {
--bs-btn-color: #1A6BCC;
--bs-btn-hover-color: #0056B3;
--bs-btn-active-color: #0056B3;
}

/* ==========================================================================
Status label colors per theme
========================================================================== */

/* Light mode */
[data-bs-theme="light"] .status-active {
color: #177D4D;
}
[data-bs-theme="light"] .status-archived{
color: #8B6313;
}
[data-bs-theme="light"] .status-historical {
color: #876608;
}
[data-bs-theme="light"] .status-revoked {
color: #dc3545;
}

/* Dark mode */
[data-bs-theme="dark"] .status-active {
color: #57C78B;
}
[data-bs-theme="dark"] .status-archived,
[data-bs-theme="dark"] .status-historical {
color: #ffcd39;
}
[data-bs-theme="dark"] .status-revoked {
color: #ea868f;
}

/* EUCC assurance levels */
[data-bs-theme="light"] .eucc-assurance-high {
color: #177D4D;
}
[data-bs-theme="dark"] .eucc-assurance-high {
color: #57C78B;
}
[data-bs-theme="light"] .eucc-assurance-substantial {
color: #946300;
}
[data-bs-theme="dark"] .eucc-assurance-substantial {
color: #FFCA2C;
}

/* ==========================================================================
Alert link colors per theme
========================================================================== */

[data-bs-theme="light"] .alert-primary a,
[data-bs-theme="light"] .alert-info a,
[data-bs-theme="light"] .bg-darker-light .alert-primary a,
[data-bs-theme="light"] .bg-darker-light .alert-info a {
color: #0158E4;
}

[data-bs-theme="light"] .alert-warning a {
color: #6B4800;
}

[data-bs-theme="dark"] .alert-info a,
[data-bs-theme="dark"] .bg-darker-light .alert-info a {
color: #9EC5FE;
}

/*File metadata collapsible button — visible focus ring*/

.metadata-container > button:focus-visible {
outline: 3px solid var(--bs-focus-ring-color, #86b7fe);
outline-offset: 2px;
border-radius: 0.25rem;
}
3 changes: 2 additions & 1 deletion sec_certs_page/static/network.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@ class CertificateNetwork {
.text("Status");

const statusFilter = statusBox.append("select")
.attr("name", "status");
.attr("name", "status")
.attr("aria-label", "Filter by status");

for (let status in this.statuses) {
statusFilter.append("option")
Expand Down
76 changes: 38 additions & 38 deletions sec_certs_page/templates/cc/entry/index.html.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@
<tr>
<th scope="col">Name</th>
<th scope="col">Certificate ID</th>
<th scope="col"></th>
<th scope="col"><span class="visually-hidden">Actions</span></th>
</tr>
</thead>
{% if previous %}
Expand All @@ -369,19 +369,19 @@
<td>
<a href="{{ url_for("cc.entry", hashid=other['_id']) }}">{{ other["name"] | truncate(120, true) }}</a>
{% if other["name"] == cert["name"] and cert["name"] %}
<span class="badge rounded-pill bg-info text-dark"
title="Certificate name matches exactly."
data-bs-toggle="tooltip"><i
class="fas fa-equals"></i></span>
<span class="badge rounded-pill bg-info text-dark" role="img"
aria-label="Certificate name matches exactly."
data-bs-toggle="tooltip" title="Certificate name matches exactly."><i
class="fas fa-equals" aria-hidden="true"></i></span>
{% endif %}
</td>
<td>
{{ other["heuristics"]["cert_id"] }}
{% if other["heuristics"]["cert_id"] == cert["heuristics"]["cert_id"] and cert["heuristics"]["cert_id"] %}
<span class="badge rounded-pill bg-info text-dark"
title="Certificate ID matches exactly."
data-bs-toggle="tooltip"><i
class="fas fa-equals"></i></span>
<span class="badge rounded-pill bg-info text-dark" role="img"
aria-label="Certificate ID matches exactly."
data-bs-toggle="tooltip" title="Certificate ID matches exactly."><i
class="fas fa-equals" aria-hidden="true"></i></span>
{% endif %}
</td>
<td class="text-end">
Expand All @@ -399,19 +399,19 @@
<td>
<a href="{{ url_for("cc.entry", hashid=other['_id']) }}">{{ other["name"] | truncate(120, true) }}</a>
{% if other["name"] == cert["name"] and cert["name"] %}
<span class="badge rounded-pill bg-info text-dark"
title="Certificate name matches exactly."
data-bs-toggle="tooltip"><i
class="fas fa-equals"></i></span>
<span class="badge rounded-pill bg-info text-dark" role="img"
aria-label="Certificate name matches exactly."
data-bs-toggle="tooltip" title="Certificate name matches exactly."><i
class="fas fa-equals" aria-hidden="true"></i></span>
{% endif %}
</td>
<td>
{{ other["heuristics"]["cert_id"] }}
{% if other["heuristics"]["cert_id"] == cert["heuristics"]["cert_id"] and cert["heuristics"]["cert_id"] %}
<span class="badge rounded-pill bg-info text-dark"
title="Certificate ID matches exactly."
data-bs-toggle="tooltip"><i
class="fas fa-equals"></i></span>
<span class="badge rounded-pill bg-info text-dark" role="img"
aria-label="Certificate ID matches exactly."
data-bs-toggle="tooltip" title="Certificate ID matches exactly."><i
class="fas fa-equals" aria-hidden="true"></i></span>
{% endif %}
</td>
<td class="text-end">
Expand All @@ -436,7 +436,7 @@
<tr>
<th scope="col">Name</th>
<th scope="col">Certificate ID</th>
<th scope="col"></th>
<th scope="col"><span class="visually-hidden">Actions</span></th>
</tr>
</thead>
{% for similar_cert in similar %}
Expand All @@ -446,39 +446,39 @@
<a href="{{ url_for("cc.entry", hashid=similar_cert['_id']) }}"
title="{{ similar_cert["name"] }}">{{ similar_cert["name"] | truncate(120, true) }}</a>
{% if similar_cert["name"] == cert["name"] and cert["name"] %}
<span class="badge rounded-pill bg-info text-dark"
title="Certificate name matches exactly."
data-bs-toggle="tooltip"><i
class="fas fa-equals"></i></span>
<span class="badge rounded-pill bg-info text-dark" role="img"
aria-label="Certificate name matches exactly."
data-bs-toggle="tooltip" title="Certificate name matches exactly."><i
class="fas fa-equals" aria-hidden="true"></i></span>
{% endif %}
{% if "state" in similar_cert %}
{% if "cert" in similar_cert["state"] and similar_cert["state"]["cert"]["source_hash"] == cert["state"]["cert"]["source_hash"] and cert["state"]["cert"]["source_hash"] %}
<span class="badge rounded-pill bg-info text-dark"
title="Certificate PDF file matches exactly."
data-bs-toggle="tooltip"><i
class="fas fa-file-alt"></i></span>
<span class="badge rounded-pill bg-info text-dark" role="img"
aria-label="Certificate PDF file matches exactly."
data-bs-toggle="tooltip" title="Certificate PDF file matches exactly."><i
class="fas fa-file-alt" aria-hidden="true"></i></span>
{% endif %}
{% if "report" in similar_cert["state"] and similar_cert["state"]["report"]["source_hash"] == cert["state"]["report"]["source_hash"] and cert["state"]["report"]["source_hash"] %}
<span class="badge rounded-pill bg-info text-dark"
title="Certification report PDF file matches exactly."
data-bs-toggle="tooltip"><i
class="fas fa-file-alt"></i></span>
<span class="badge rounded-pill bg-info text-dark" role="img"
aria-label="Certification report PDF file matches exactly."
data-bs-toggle="tooltip" title="Certification report PDF file matches exactly."><i
class="fas fa-file-alt" aria-hidden="true"></i></span>
{% endif %}
{% if "st" in similar_cert["state"] and similar_cert["state"]["st"]["source_hash"] == cert["state"]["st"]["source_hash"] and cert["state"]["st"]["source_hash"] %}
<span class="badge rounded-pill bg-info text-dark"
title="Security target PDF file matches exactly."
data-bs-toggle="tooltip"><i
class="fas fa-file-alt"></i></span>
<span class="badge rounded-pill bg-info text-dark" role="img"
aria-label="Security target PDF file matches exactly."
data-bs-toggle="tooltip" title="Security target PDF file matches exactly."><i
class="fas fa-file-alt" aria-hidden="true"></i></span>
{% endif %}
{% endif %}
</td>
<td>
{{ similar_cert["heuristics"]["cert_id"] }}
{% if similar_cert["heuristics"]["cert_id"] == cert["heuristics"]["cert_id"] and cert["heuristics"]["cert_id"] %}
<span class="badge rounded-pill bg-info text-dark"
title="Certificate ID matches exactly."
data-bs-toggle="tooltip"><i
class="fas fa-equals"></i></span>
<span class="badge rounded-pill bg-info text-dark" role="img"
aria-label="Certificate ID matches exactly."
data-bs-toggle="tooltip" title="Certificate ID matches exactly."><i
class="fas fa-equals" aria-hidden="true"></i></span>
{% endif %}
</td>
<td class="text-end">
Expand Down
4 changes: 2 additions & 2 deletions sec_certs_page/templates/cc/include.html.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@

{% macro render_status(status) %}
{% if status == "active" %}
<span class="text-success"><i class="fas fa-check-square"></i> active</span>
<span class="status-active"><i class="fas fa-check-square"></i> active</span>
{% elif status == "archived" %}
<span class="text-warning"><i class="fas fa-times-circle"></i> archived</span>
<span class="status-archived"><i class="fas fa-times-circle"></i> archived</span>
{% else %}
<span>{{ status }}</span>
{% endif %}
Expand Down
Loading