From d12c040927052726a42591f15521849ddd611f35 Mon Sep 17 00:00:00 2001 From: Chris Gilligan <49878588+UTCGilligan@users.noreply.github.com> Date: Mon, 21 Jul 2025 16:37:42 -0400 Subject: [PATCH 01/15] UTCT-112: Uprgrade PHP QRCode package and fix deprecations. Signed-off-by: Chris Gilligan <49878588+UTCGilligan@users.noreply.github.com> --- user/plugins/seans-qrcode/composer.json | 2 +- user/plugins/seans-qrcode/composer.lock | 42 +++++++++++++++++-------- user/plugins/seans-qrcode/plugin.php | 4 +-- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/user/plugins/seans-qrcode/composer.json b/user/plugins/seans-qrcode/composer.json index 50777e1..a675f35 100644 --- a/user/plugins/seans-qrcode/composer.json +++ b/user/plugins/seans-qrcode/composer.json @@ -1,7 +1,7 @@ { "require": { "php": "^8.0", - "chillerlan/php-qrcode": "^4.4.0", + "chillerlan/php-qrcode": "^4.4.0 || ^5.0.3", "ext-mbstring": "*", "ext-gd": "*" } diff --git a/user/plugins/seans-qrcode/composer.lock b/user/plugins/seans-qrcode/composer.lock index a8f411f..86af967 100644 --- a/user/plugins/seans-qrcode/composer.lock +++ b/user/plugins/seans-qrcode/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "409d7829335c97990d5bc31bc1b151c5", + "content-hash": "a5894bd54cb64bf2386db406a79e7bc1", "packages": [ { "name": "chillerlan/php-qrcode", - "version": "4.4.2", + "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/chillerlan/php-qrcode.git", - "reference": "345ed8e4ffb56e6b3fcd9f42e3970b9026fa6ce4" + "reference": "42e215640e9ebdd857570c9e4e52245d1ee51de2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/chillerlan/php-qrcode/zipball/345ed8e4ffb56e6b3fcd9f42e3970b9026fa6ce4", - "reference": "345ed8e4ffb56e6b3fcd9f42e3970b9026fa6ce4", + "url": "https://api.github.com/repos/chillerlan/php-qrcode/zipball/42e215640e9ebdd857570c9e4e52245d1ee51de2", + "reference": "42e215640e9ebdd857570c9e4e52245d1ee51de2", "shasum": "" }, "require": { @@ -26,10 +26,14 @@ "php": "^7.4 || ^8.0" }, "require-dev": { + "chillerlan/php-authenticator": "^4.3.1 || ^5.2.1", + "ext-fileinfo": "*", "phan/phan": "^5.4.5", + "phpcompatibility/php-compatibility": "10.x-dev", "phpmd/phpmd": "^2.15", "phpunit/phpunit": "^9.6", "setasign/fpdf": "^1.8.2", + "slevomat/coding-standard": "^8.15", "squizlabs/php_codesniffer": "^3.11" }, "suggest": { @@ -40,17 +44,26 @@ "type": "library", "autoload": { "psr-4": { - "chillerlan\\QRCode\\": "src/" + "chillerlan\\QRCode\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "MIT", + "Apache-2.0" ], "authors": [ { "name": "Kazuhiko Arase", - "homepage": "https://github.com/kazuhikoarase" + "homepage": "https://github.com/kazuhikoarase/qrcode-generator" + }, + { + "name": "ZXing Authors", + "homepage": "https://github.com/zxing/zxing" + }, + { + "name": "Ashot Khanamiryan", + "homepage": "https://github.com/khanamiryan/php-qrcode-detector-decoder" }, { "name": "Smiley", @@ -62,26 +75,29 @@ "homepage": "https://github.com/chillerlan/php-qrcode/graphs/contributors" } ], - "description": "A QR code generator with a user friendly API. PHP 7.4+", + "description": "A QR Code generator and reader with a user-friendly API. PHP 7.4+", "homepage": "https://github.com/chillerlan/php-qrcode", "keywords": [ "phpqrcode", "qr", "qr code", + "qr-reader", "qrcode", - "qrcode-generator" + "qrcode-generator", + "qrcode-reader" ], "support": { + "docs": "https://php-qrcode.readthedocs.io", "issues": "https://github.com/chillerlan/php-qrcode/issues", - "source": "https://github.com/chillerlan/php-qrcode/tree/4.4.2" + "source": "https://github.com/chillerlan/php-qrcode" }, "funding": [ { "url": "https://ko-fi.com/codemasher", - "type": "ko_fi" + "type": "Ko-Fi" } ], - "time": "2024-11-15T15:36:24+00:00" + "time": "2024-11-21T16:12:34+00:00" }, { "name": "chillerlan/php-settings-container", diff --git a/user/plugins/seans-qrcode/plugin.php b/user/plugins/seans-qrcode/plugin.php index 3860e39..6a94ed9 100644 --- a/user/plugins/seans-qrcode/plugin.php +++ b/user/plugins/seans-qrcode/plugin.php @@ -37,8 +37,8 @@ class LogoOptions extends QROptions{ // size in QR modules, multiply with QROptions::$scale for pixel size - protected int $logoSpaceWidth; - protected int $logoSpaceHeight; + protected ?int $logoSpaceWidth; + protected ?int $logoSpaceHeight; } // Kick in if the loader does not recognize a valid pattern From 69cecb4fcbe1de89e237224db9254e45211a1d7c Mon Sep 17 00:00:00 2001 From: Chris Gilligan <49878588+UTCGilligan@users.noreply.github.com> Date: Sat, 20 Dec 2025 13:12:33 -0500 Subject: [PATCH 02/15] UTCT-228: Accessible frontend form enhancements and styles. Signed-off-by: Chris Gilligan <49878588+UTCGilligan@users.noreply.github.com> --- frontend/assets/sass/styles.scss | 24 ++++++ frontend/dist/styles.css | 133 +++++++++++++++++++------------ index.php | 58 +++++++++++++- 3 files changed, 161 insertions(+), 54 deletions(-) diff --git a/frontend/assets/sass/styles.scss b/frontend/assets/sass/styles.scss index 7cb7c98..a9efa8a 100644 --- a/frontend/assets/sass/styles.scss +++ b/frontend/assets/sass/styles.scss @@ -81,3 +81,27 @@ $border-radius: 6px; } } } + +/* Extra styling for the skip link when it becomes visible */ +.skip-link { + background-color: #0d6efd; /* Bootstrap primary */ + color: #fff; + padding: 0.5rem 1rem; + text-decoration: none; + position: absolute; + top: 0.5rem; + left: 0.5rem; + z-index: 1050; +} + +.skip-link:focus { + outline: 3px solid #ffc107; +} + +/* Highlight the "Customize Link" toggle when it has keyboard focus */ +.btn.btn-link:focus, +.btn.btn-link:focus-visible { + outline: 3px solid #ffc107 !important; // strong yellow outline + outline-offset: 2px; + box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, .5) !important; +} diff --git a/frontend/dist/styles.css b/frontend/dist/styles.css index 1cc6000..f961e31 100644 --- a/frontend/dist/styles.css +++ b/frontend/dist/styles.css @@ -513,8 +513,8 @@ legend { width: 100%; padding: 0; margin-bottom: 0.5rem; - font-size: calc(1.275rem + 0.3vw); line-height: inherit; + font-size: calc(1.275rem + 0.3vw); } @media (min-width: 1200px) { legend { @@ -543,6 +543,10 @@ legend + * { -webkit-appearance: textfield; outline-offset: -2px; } +[type=search]::-webkit-search-cancel-button { + cursor: pointer; + filter: grayscale(1); +} /* rtl:raw: [type="tel"], @@ -592,9 +596,9 @@ progress { } .display-1 { - font-size: calc(1.625rem + 4.5vw); font-weight: 300; line-height: 1.2; + font-size: calc(1.625rem + 4.5vw); } @media (min-width: 1200px) { .display-1 { @@ -603,9 +607,9 @@ progress { } .display-2 { - font-size: calc(1.575rem + 3.9vw); font-weight: 300; line-height: 1.2; + font-size: calc(1.575rem + 3.9vw); } @media (min-width: 1200px) { .display-2 { @@ -614,9 +618,9 @@ progress { } .display-3 { - font-size: calc(1.525rem + 3.3vw); font-weight: 300; line-height: 1.2; + font-size: calc(1.525rem + 3.3vw); } @media (min-width: 1200px) { .display-3 { @@ -625,9 +629,9 @@ progress { } .display-4 { - font-size: calc(1.475rem + 2.7vw); font-weight: 300; line-height: 1.2; + font-size: calc(1.475rem + 2.7vw); } @media (min-width: 1200px) { .display-4 { @@ -636,9 +640,9 @@ progress { } .display-5 { - font-size: calc(1.425rem + 2.1vw); font-weight: 300; line-height: 1.2; + font-size: calc(1.425rem + 2.1vw); } @media (min-width: 1200px) { .display-5 { @@ -647,9 +651,9 @@ progress { } .display-6 { - font-size: calc(1.375rem + 1.5vw); font-weight: 300; line-height: 1.2; + font-size: calc(1.375rem + 1.5vw); } @media (min-width: 1200px) { .display-6 { @@ -766,7 +770,7 @@ progress { } .col { - flex: 1 0 0%; + flex: 1 0 0; } .row-cols-auto > * { @@ -975,7 +979,7 @@ progress { @media (min-width: 576px) { .col-sm { - flex: 1 0 0%; + flex: 1 0 0; } .row-cols-sm-auto > * { flex: 0 0 auto; @@ -1144,7 +1148,7 @@ progress { } @media (min-width: 768px) { .col-md { - flex: 1 0 0%; + flex: 1 0 0; } .row-cols-md-auto > * { flex: 0 0 auto; @@ -1313,7 +1317,7 @@ progress { } @media (min-width: 992px) { .col-lg { - flex: 1 0 0%; + flex: 1 0 0; } .row-cols-lg-auto > * { flex: 0 0 auto; @@ -1482,7 +1486,7 @@ progress { } @media (min-width: 1200px) { .col-xl { - flex: 1 0 0%; + flex: 1 0 0; } .row-cols-xl-auto > * { flex: 0 0 auto; @@ -1651,7 +1655,7 @@ progress { } @media (min-width: 1400px) { .col-xxl { - flex: 1 0 0%; + flex: 1 0 0; } .row-cols-xxl-auto > * { flex: 0 0 auto; @@ -2287,9 +2291,11 @@ textarea.form-control-lg { top: 0; left: 0; z-index: 2; + max-width: 100%; height: 100%; padding: 1rem 0.75rem; overflow: hidden; + color: rgba(var(--bs-body-color-rgb), 0.65); text-align: start; text-overflow: ellipsis; white-space: nowrap; @@ -2325,18 +2331,19 @@ textarea.form-control-lg { .form-floating > .form-select { padding-top: 1.625rem; padding-bottom: 0.625rem; + padding-left: 0.75rem; } .form-floating > .form-control:focus ~ label, .form-floating > .form-control:not(:placeholder-shown) ~ label, .form-floating > .form-control-plaintext ~ label, .form-floating > .form-select ~ label { - color: rgba(var(--bs-body-color-rgb), 0.65); transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem); } -.form-floating > .form-control:focus ~ label::after, -.form-floating > .form-control:not(:placeholder-shown) ~ label::after, -.form-floating > .form-control-plaintext ~ label::after, -.form-floating > .form-select ~ label::after { +.form-floating > .form-control:-webkit-autofill ~ label { + transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem); +} +.form-floating > textarea:focus ~ label::after, +.form-floating > textarea:not(:placeholder-shown) ~ label::after { position: absolute; inset: 1rem 0.375rem; z-index: -1; @@ -2345,9 +2352,8 @@ textarea.form-control-lg { background-color: #ebebeb; border-radius: var(--bs-border-radius); } -.form-floating > .form-control:-webkit-autofill ~ label { - color: rgba(var(--bs-body-color-rgb), 0.65); - transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem); +.form-floating > textarea:disabled ~ label::after { + background-color: var(--bs-secondary-bg); } .form-floating > .form-control-plaintext ~ label { border-width: 0 0; @@ -2356,10 +2362,6 @@ textarea.form-control-lg { .form-floating > .form-control:disabled ~ label { color: #6c757d; } -.form-floating > :disabled ~ label::after, -.form-floating > .form-control:disabled ~ label::after { - background-color: var(--bs-secondary-bg); -} .input-group { position: relative; @@ -2442,7 +2444,7 @@ textarea.form-control-lg { border-bottom-right-radius: 0; } .input-group > :not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback) { - margin-left: calc(0 * -1); + margin-left: calc(-1 * 0); border-top-left-radius: 0; border-bottom-left-radius: 0; } @@ -2484,7 +2486,7 @@ textarea.form-control-lg { .was-validated .form-control:valid, .form-control.is-valid { border-color: var(--bs-form-valid-border-color); padding-right: calc(1.5em + 0.75rem); - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1'/%3e%3c/svg%3e"); background-repeat: no-repeat; background-position: right calc(0.375em + 0.1875rem) center; background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); @@ -2503,7 +2505,7 @@ textarea.form-control-lg { border-color: var(--bs-form-valid-border-color); } .was-validated .form-select:valid:not([multiple]):not([size]), .was-validated .form-select:valid:not([multiple])[size="1"], .form-select.is-valid:not([multiple]):not([size]), .form-select.is-valid:not([multiple])[size="1"] { - --bs-form-select-bg-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); + --bs-form-select-bg-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1'/%3e%3c/svg%3e"); padding-right: 4.125rem; background-position: right 0.75rem center, center right 2.25rem; background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); @@ -3210,7 +3212,7 @@ textarea.form-control-lg { flex-flow: row wrap; } .card-group > .card { - flex: 1 0 0%; + flex: 1 0 0; margin-bottom: 0; } .card-group > .card + .card { @@ -3221,24 +3223,24 @@ textarea.form-control-lg { border-top-right-radius: 0; border-bottom-right-radius: 0; } - .card-group > .card:not(:last-child) .card-img-top, - .card-group > .card:not(:last-child) .card-header { + .card-group > .card:not(:last-child) > .card-img-top, + .card-group > .card:not(:last-child) > .card-header { border-top-right-radius: 0; } - .card-group > .card:not(:last-child) .card-img-bottom, - .card-group > .card:not(:last-child) .card-footer { + .card-group > .card:not(:last-child) > .card-img-bottom, + .card-group > .card:not(:last-child) > .card-footer { border-bottom-right-radius: 0; } .card-group > .card:not(:first-child) { border-top-left-radius: 0; border-bottom-left-radius: 0; } - .card-group > .card:not(:first-child) .card-img-top, - .card-group > .card:not(:first-child) .card-header { + .card-group > .card:not(:first-child) > .card-img-top, + .card-group > .card:not(:first-child) > .card-header { border-top-left-radius: 0; } - .card-group > .card:not(:first-child) .card-img-bottom, - .card-group > .card:not(:first-child) .card-footer { + .card-group > .card:not(:first-child) > .card-img-bottom, + .card-group > .card:not(:first-child) > .card-footer { border-bottom-left-radius: 0; } } @@ -3255,11 +3257,11 @@ textarea.form-control-lg { --bs-accordion-btn-padding-y: 1rem; --bs-accordion-btn-color: var(--bs-body-color); --bs-accordion-btn-bg: var(--bs-accordion-bg); - --bs-accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23212529' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='M2 5L8 11L14 5'/%3e%3c/svg%3e"); + --bs-accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23212529' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='m2 5 6 6 6-6'/%3e%3c/svg%3e"); --bs-accordion-btn-icon-width: 1.25rem; --bs-accordion-btn-icon-transform: rotate(-180deg); --bs-accordion-btn-icon-transition: transform 0.2s ease-in-out; - --bs-accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='rgb%285.2, 44, 101.2%29' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='M2 5L8 11L14 5'/%3e%3c/svg%3e"); + --bs-accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='rgb%285.2, 44, 101.2%29' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='m2 5 6 6 6-6'/%3e%3c/svg%3e"); --bs-accordion-btn-focus-box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); --bs-accordion-body-padding-x: 1.25rem; --bs-accordion-body-padding-y: 1rem; @@ -3369,16 +3371,15 @@ textarea.form-control-lg { .accordion-flush > .accordion-item:last-child { border-bottom: 0; } -.accordion-flush > .accordion-item > .accordion-header .accordion-button, .accordion-flush > .accordion-item > .accordion-header .accordion-button.collapsed { - border-radius: 0; -} -.accordion-flush > .accordion-item > .accordion-collapse { +.accordion-flush > .accordion-item > .accordion-collapse, +.accordion-flush > .accordion-item > .accordion-header .accordion-button, +.accordion-flush > .accordion-item > .accordion-header .accordion-button.collapsed { border-radius: 0; } [data-bs-theme=dark] .accordion-button::after { - --bs-accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='rgb%28109.8, 168, 253.8%29'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); - --bs-accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='rgb%28109.8, 168, 253.8%29'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); + --bs-accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='rgb%28109.8, 168, 253.8%29'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708'/%3e%3c/svg%3e"); + --bs-accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='rgb%28109.8, 168, 253.8%29'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708'/%3e%3c/svg%3e"); } .alert { @@ -3478,19 +3479,19 @@ textarea.form-control-lg { .btn-close { --bs-btn-close-color: #000; - --bs-btn-close-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e"); + --bs-btn-close-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414'/%3e%3c/svg%3e"); --bs-btn-close-opacity: 0.5; --bs-btn-close-hover-opacity: 0.75; --bs-btn-close-focus-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); --bs-btn-close-focus-opacity: 1; --bs-btn-close-disabled-opacity: 0.25; - --bs-btn-close-white-filter: invert(1) grayscale(100%) brightness(200%); box-sizing: content-box; width: 1em; height: 1em; padding: 0.25em 0.25em; color: var(--bs-btn-close-color); background: transparent var(--bs-btn-close-bg) center/1em auto no-repeat; + filter: var(--bs-btn-close-filter); border: 0; border-radius: 6px; opacity: var(--bs-btn-close-opacity); @@ -3512,11 +3513,16 @@ textarea.form-control-lg { } .btn-close-white { - filter: var(--bs-btn-close-white-filter); + --bs-btn-close-filter: invert(1) grayscale(100%) brightness(200%); +} + +:root, +[data-bs-theme=light] { + --bs-btn-close-filter: ; } -[data-bs-theme=dark] .btn-close { - filter: var(--bs-btn-close-white-filter); +[data-bs-theme=dark] { + --bs-btn-close-filter: invert(1) grayscale(100%) brightness(200%); } .clearfix::after { @@ -3826,6 +3832,10 @@ textarea.form-control-lg { .visually-hidden-focusable:not(:focus):not(:focus-within):not(caption) { position: absolute !important; } +.visually-hidden *, +.visually-hidden-focusable:not(:focus):not(:focus-within) * { + overflow: hidden !important; +} .stretched-link::after { position: absolute; @@ -9359,4 +9369,27 @@ textarea.form-control-lg { width: 100%; border-radius: 6px !important; } +} +/* Extra styling for the skip link when it becomes visible */ +.skip-link { + background-color: #0d6efd; /* Bootstrap primary */ + color: #fff; + padding: 0.5rem 1rem; + text-decoration: none; + position: absolute; + top: 0.5rem; + left: 0.5rem; + z-index: 1050; +} + +.skip-link:focus { + outline: 3px solid #ffc107; +} + +/* Highlight the "Customize Link" toggle when it has keyboard focus */ +.btn.btn-customize-link:focus, +.btn.btn-customize-link:focus-visible { + outline: 3px solid #ffc107 !important; + outline-offset: 2px; + box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.5) !important; } \ No newline at end of file diff --git a/index.php b/index.php index 51f7c1f..eed8e3e 100644 --- a/index.php +++ b/index.php @@ -84,6 +84,22 @@ function shorten() + +
@@ -126,18 +142,52 @@ function shorten() -
From 137f2ccc35f89d8c92209fac925059e7f6b448d0 Mon Sep 17 00:00:00 2001 From: Chris Gilligan <49878588+UTCGilligan@users.noreply.github.com> Date: Tue, 6 Jan 2026 10:59:15 -0500 Subject: [PATCH 15/15] UTCT-241: Remove PHP 8 deprecated code from QRImageWithLogo. Signed-off-by: Chris Gilligan <49878588+UTCGilligan@users.noreply.github.com> --- user/plugins/seans-qrcode/QRImageWithLogo.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/user/plugins/seans-qrcode/QRImageWithLogo.php b/user/plugins/seans-qrcode/QRImageWithLogo.php index 967041e..41cd2bd 100644 --- a/user/plugins/seans-qrcode/QRImageWithLogo.php +++ b/user/plugins/seans-qrcode/QRImageWithLogo.php @@ -12,12 +12,8 @@ * @noinspection PhpComposerExtensionStubsInspection */ -// namespace chillerlan\QRCode; - use chillerlan\QRCode\Output\{QRCodeOutputException, QRImage}; -use function imagecopyresampled, imagecreatefrompng, imagesx, imagesy, is_file, is_readable; - /** * @property \chillerlan\QRCodeExamples\LogoOptions $options */