/**
 * Clay 3.165.0
 *
 * SPDX-FileCopyrightText: © 2020 Liferay, Inc. <https://liferay.com>
 * SPDX-FileCopyrightText: © 2020 Contributors to the project Clay <https://github.com/liferay/clay/graphs/contributors>
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
/**
 * Bootstrap v4.4.1
 *
 * SPDX-FileCopyrightText: © 2019 Twitter, Inc. <https://twitter.com>
 * SPDX-FileCopyrightText: © 2019 The Bootstrap Authors <https://getbootstrap.com/>
 *
 * SPDX-License-Identifier: LicenseRef-MIT-Bootstrap
 */
/**
 * Clay 3.165.0
 *
 * SPDX-FileCopyrightText: © 2020 Liferay, Inc. <https://liferay.com>
 * SPDX-FileCopyrightText: © 2020 Contributors to the project Clay <https://github.com/liferay/clay/graphs/contributors>
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
/**
 * Bootstrap v4.4.1
 *
 * SPDX-FileCopyrightText: © 2019 Twitter, Inc. <https://twitter.com>
 * SPDX-FileCopyrightText: © 2019 The Bootstrap Authors <https://getbootstrap.com/>
 *
 * SPDX-License-Identifier: LicenseRef-MIT-Bootstrap
 */
.quick-access-nav {
  position: fixed;
  z-index: 999;
}

.sr-only {
  border: 0;
  clip: rect(0, 0, 0, 0);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

.sr-only-focusable:active, .sr-only-focusable:focus {
  clip: auto;
  height: auto;
  overflow: visible;
  position: static;
  white-space: normal;
  width: auto;
}

.lfr-asset-column-details .lfr-asset-categories {
  color: #7d7d7d;
}
.lfr-asset-column-details .lfr-asset-categories .lfr-asset-category {
  color: #555;
}
.lfr-asset-column-details .lfr-asset-description {
  color: #444;
  font-style: italic;
  margin: 0.5em auto 2em;
  -ms-hyphens: none;
  -webkit-hyphens: none;
  hyphens: none;
}
.lfr-asset-column-details .lfr-asset-icon {
  border-right: 1px solid transparent;
  color: #999;
  float: left;
  line-height: 1em;
  margin-right: 10px;
  padding-right: 10px;
}
.lfr-asset-column-details .lfr-asset-icon.last {
  border-width: 0;
}
.lfr-asset-column-details .lfr-asset-tags {
  color: #7d7d7d;
}
.lfr-asset-column-details .lfr-asset-tags .tag {
  color: #555;
}
.lfr-asset-column-details .lfr-asset-metadata {
  clear: both;
  margin-bottom: 1.5em;
  padding-bottom: 1.5em;
}
.lfr-asset-column-details .lfr-panel {
  clear: both;
  margin-bottom: 0.2em;
}
.lfr-asset-column-details .lfr-panel.lfr-extended {
  border: 1px solid #ccc;
  margin-bottom: 0;
}
.lfr-asset-column-details .taglib-custom-attributes-list label,
.lfr-asset-column-details .lfr-asset-field label {
  display: block;
}
.lfr-asset-column-details .taglib-custom-attributes-list {
  margin-bottom: 1em;
}

.overlay {
  position: absolute;
}

.overlay-hidden,
.overlaymask-hidden {
  display: none;
}

.lfr-form-row {
  border-bottom: 1px solid #ccc;
  margin-bottom: 10px;
  margin-top: 10px;
  padding: 1px 5px 25px;
  position: relative;
}
.lfr-form-row:after {
  clear: both;
  content: "";
  display: block;
  height: 0;
}
.lfr-form-row:hover {
  border: solid #ccc;
  border-width: 1px 0;
  padding-top: 0;
}
.lfr-form-row.lfr-form-row-inline .form-group {
  margin-right: 5px;
}
.lfr-form-row legend .field-label {
  float: left;
  margin-right: 10px;
}
.lfr-form-row .handle-sort-vertical {
  background: url(../images/application/handle_sort_vertical.png) no-repeat 0 50%;
  cursor: move;
  padding-left: 20px;
}
.lfr-form-row fieldset {
  border-width: 0;
  margin: 0;
  padding: 0;
}

.lfr-autorow-controls {
  bottom: 5px;
  position: absolute;
  right: 5px;
}

.datepicker-popover-content .popover-content {
  padding: 0.75rem 1rem;
}

.dropdown.open > .dropdown-menu, .overlay-content .open > .dropdown-menu {
  display: block;
}

.user-avatar-link {
  display: block;
  position: relative;
}
.panel-notifications-count, html:not(#__):not(#___) .cadmin .panel-notifications-count {
  border-radius: 50rem;
  display: flex;
  margin: 0;
  max-width: none;
  position: absolute;
  right: calc(100% - 0.7rem);
  top: -0.4rem;
}

.badge, html:not(#__):not(#___) .cadmin .badge {
  margin: 0.25rem;
}

.user-avatar-link .text-default {
  align-items: center;
  display: flex;
}
.user-avatar-link .text-default .user-full-name {
  margin-left: 0.5rem;
}
@media (max-width: 575.98px) {
  .user-avatar-link .text-default .user-full-name {
    display: none;
  }
}

.user-personal-bar .fieldset {
  position: relative;
}
.user-personal-bar .user-avatar-link .panel-notifications-count {
  right: calc(100% - 1rem);
  top: -0.6rem;
}

.form-control-inline {
  background-color: transparent;
  font-size: 1.125rem;
  font-weight: 700;
}
.form-control-inline:not(:hover) {
  border-color: transparent;
}
.form-control-inline::placeholder {
  color: #a9afb5;
  font-style: italic;
}

.form-search .input-group {
  position: relative;
}
.form-search .input-group.advanced-search .search-query {
  padding-left: 40px;
  z-index: 0;
}
.form-search .input-group.advanced-search .toggle-advanced {
  cursor: pointer;
  left: 0;
  line-height: 1;
  padding: 8px 10px;
  position: absolute;
  top: 0;
}
.form-search .input-group.advanced-search .toggle-advanced .caret {
  margin-top: 7px;
}
.form-search .input-group.advanced-search .toggle-advanced .icon-search {
  font-size: 14px;
}
@media (max-width: 991.98px) {
  .form-search .input-group {
    width: 100%;
  }
  .form-search .input-group .btn {
    clip: rect(0, 0, 0, 0);
    left: -9999px;
    position: absolute;
  }
  .form-search .input-group input.search-query {
    width: 100%;
  }
}

.lfr-table {
  border-collapse: collapse;
  clear: both;
}
.lfr-table > tbody > tr > td,
.lfr-table > tbody > tr > th,
.lfr-table > thead > tr > td,
.lfr-table > thead > tr > th,
.lfr-table > tfoot > tr > td,
.lfr-table > tfoot > tr > th {
  padding: 0 5px;
  overflow-wrap: break-all;
  word-wrap: break-all;
}
.lfr-table > tbody > tr > td:first-child, .lfr-table > tbody > tr > td.first-child,
.lfr-table > tbody > tr > th:first-child,
.lfr-table > tbody > tr > th.first-child,
.lfr-table > thead > tr > td:first-child,
.lfr-table > thead > tr > td.first-child,
.lfr-table > thead > tr > th:first-child,
.lfr-table > thead > tr > th.first-child,
.lfr-table > tfoot > tr > td:first-child,
.lfr-table > tfoot > tr > td.first-child,
.lfr-table > tfoot > tr > th:first-child,
.lfr-table > tfoot > tr > th.first-child {
  padding-left: 0;
}
.lfr-table > tbody > tr > td:last-child, .lfr-table > tbody > tr > td.last-child,
.lfr-table > tbody > tr > th:last-child,
.lfr-table > tbody > tr > th.last-child,
.lfr-table > thead > tr > td:last-child,
.lfr-table > thead > tr > td.last-child,
.lfr-table > thead > tr > th:last-child,
.lfr-table > thead > tr > th.last-child,
.lfr-table > tfoot > tr > td:last-child,
.lfr-table > tfoot > tr > td.last-child,
.lfr-table > tfoot > tr > th:last-child,
.lfr-table > tfoot > tr > th.last-child {
  padding-right: 0;
}
.lfr-table > tbody > tr > th,
.lfr-table > thead > tr > th,
.lfr-table > tfoot > tr > th {
  font-weight: bold;
}

.lfr-pagination:after {
  clear: both;
  content: "";
  display: block;
  height: 0;
  visibility: hidden;
}
.lfr-pagination .dropdown-menu {
  display: none;
}
.lfr-pagination .dropdown-toggle .icon-caret-down {
  margin-left: 5px;
}
.lfr-pagination .lfr-pagination-controls {
  float: left;
}
.lfr-pagination .lfr-pagination-controls .search-results {
  display: inline-block;
  margin-left: 10px;
  margin-top: 5px;
  top: 10px;
}
.lfr-pagination .lfr-pagination-controls li .lfr-pagination-link {
  border-width: 0;
  clear: both;
  color: #333;
  display: block;
  font-weight: normal;
  line-height: 20px;
  padding: 3px 20px;
  text-align: left;
  white-space: nowrap;
  width: 100%;
}
.lfr-pagination .lfr-pagination-delta-selector {
  float: left;
}
@media (max-width: 991.98px) {
  .lfr-pagination .lfr-pagination-delta-selector .lfr-icon-menu-text {
    display: none;
  }
}
.lfr-pagination .pagination-content {
  float: right;
}

.lfr-panel.lfr-extended {
  border: 1px solid transparent;
  border-color: #dedede #bfbfbf #bfbfbf #dedede;
}
.lfr-panel.lfr-extended.lfr-collapsible .lfr-panel-button {
  display: block;
}
.lfr-panel.lfr-extended.lfr-collapsed .lfr-panel-titlebar {
  border-bottom-width: 0;
}
.lfr-panel.panel-default .panel-heading {
  border-bottom-width: 0;
}
.lfr-panel .toggler-header {
  cursor: pointer;
}

.sidebar-sm .sheet-subtitle {
  font-size: 0.75rem;
  margin-bottom: 1rem;
}
.sidebar-sm .form-control[type=file] {
  padding: 0;
}
.sidebar-sm .article-content-description .input-localized.input-localized-editor .input-group-item .wrapper .form-control {
  min-height: auto;
  padding: 0.285rem 0.75rem;
}
.sidebar-sm .list-group-item-flex {
  padding: 0.5rem 0.25rem;
}
.sidebar-sm .list-group-item-flex .autofit-col {
  padding-left: 0.25rem;
  padding-right: 0.25rem;
}

.lfr-translation-manager {
  border-radius: 4px;
  display: inline-block;
  margin-top: 0.5em;
  min-height: 1.8em;
}
.lfr-translation-manager .lfr-translation-manager-content .lfr-translation-manager-default-locale {
  display: inline-block;
  width: auto;
}
.lfr-translation-manager .lfr-translation-manager-content .lfr-translation-manager-icon-menu {
  float: none;
  padding: 0.4em 0;
}
.lfr-translation-manager .lfr-translation-manager-content .lfr-translation-manager-icon-menu li,
.lfr-translation-manager .lfr-translation-manager-content .lfr-translation-manager-icon-menu li strong {
  display: inline;
}
.lfr-translation-manager .lfr-translation-manager-content .lfr-translation-manager-translations-message {
  margin: 10px 0;
}
.lfr-translation-manager .lfr-translation-manager-available-translations {
  white-space: normal;
}
.lfr-translation-manager .lfr-translation-manager-available-translations .lfr-translation-manager-available-translations-links {
  line-height: 1;
}
.lfr-translation-manager .lfr-translation-manager-translation {
  border: 1px solid transparent;
  border-radius: 4px;
  cursor: pointer;
  display: inline-block;
  margin: 0.2em;
  padding: 0.4em 0.3em 0.4em 0.5em;
  text-decoration: none;
}
.lfr-translation-manager .lfr-translation-manager-translation * {
  vertical-align: middle;
}
.lfr-translation-manager .lfr-translation-manager-translation img {
  margin-right: 0.3em;
}
.lfr-translation-manager .lfr-translation-manager-translation:hover {
  background-color: #d1e5ef;
}
.lfr-translation-manager .lfr-translation-manager-translation.lfr-translation-manager-translation-editing {
  background-color: #598bec;
  border-color: #224fa8;
  color: #fff;
}
.lfr-translation-manager .lfr-translation-manager-change-default-locale {
  margin: 0 0.4em;
}
.lfr-translation-manager .lfr-translation-manager-delete-translation {
  display: inline-block;
  padding: 0 2px;
}
.lfr-translation-manager .lfr-translation-manager-delete-translation svg {
  pointer-events: none;
}

.lfr-tree a {
  text-decoration: none;
}
.lfr-tree li {
  margin-bottom: 2px;
  padding-left: 0;
}
.lfr-tree li ul li, .lfr-tree li.tree-item {
  padding-left: 0;
}
.lfr-tree li.tree-item {
  padding-left: 5px;
}
.lfr-tree li.tree-item li {
  padding-left: 20px;
}
.lfr-tree li.tree-item ul {
  margin-left: 0;
  margin-top: 5px;
}

.lfr-upload-container {
  margin-bottom: 1rem;
}
.lfr-upload-container .upload-target {
  border: 3px dashed #e5e7e9;
  margin-bottom: 1rem;
  min-height: 2rem;
  padding: 2rem 0;
  position: relative;
  text-align: center;
}
.upload-drop-intent .lfr-upload-container .upload-target {
  z-index: 100;
}
.upload-drop-active .lfr-upload-container .upload-target {
  background-color: #92e5a5;
  border-color: #69db83;
}
.lfr-upload-container .upload-target .drop-file-text {
  font-weight: normal;
}
.mobile .lfr-upload-container .upload-target .drop-file-text {
  display: none;
}
.lfr-upload-container .upload-target .small {
  display: block;
  margin: 5px 0;
  text-transform: lowercase;
}
.lfr-upload-container .manage-upload-target {
  padding-top: 5px;
  position: relative;
}
.lfr-upload-container .manage-upload-target .select-files {
  float: left;
  line-height: 0;
  margin: 0 1.125rem 1.125rem;
  padding: 0 0 0 5px;
}
.lfr-upload-container .cancel-uploads,
.lfr-upload-container .clear-uploads {
  background-repeat: no-repeat;
  float: right;
}
.lfr-upload-container .cancel-uploads {
  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAnFBMVEX////4YWP/dXjyS07/dXj9bXD6a234YWP4XWD2WVv2VFfsOTzoLzHmKSvkISP2VFf0TE/vREftPT/iHB72WVvvREf0TE//hon/gYX/fYD/e33/dXj/cXP9bXD/a236a23/Zmb4YWP4XWD/Wl32WVv/VVj2VFf3VFb0TE/yS072SUvvREfuQELtPT/sOTzrMzXoLzHnLC/mKSvkISPh2jkWAAAAF3RSTlMAESIiMzMzMzMzMzMzMzNERERERHd3qtw8lzkAAACOSURBVHjaZcjZDsIgEIXhcd+tu5YBKUixttS6vP+7OQKJTfxvTr4D7Tpxu/2w410SjDjwVvLQ805TPiRryfQeKM6OTI68K/BJPHGlJZJjSqSMofEOGXbJecsTgzkds58V5+J8refBU7Jx9yIrmkW0sA6gqbLyuaRjZZWtgXq58rEFan0jf3uTfRuIkf/7AO8DDcVPSSG3AAAAAElFTkSuQmCC);
  margin-right: 0;
}
.lfr-upload-container .clear-uploads {
  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAdVBMVEX///+6QwTEVx65RQPEVx3EWB64RQPDVxq5RAO5RAO5RQPATQ65RQO5RQO5RQPRczjJZCW9TQTLay28QgTdZAHhaAPmdyHqeQXrikDudgDvfxj0nWP1qHL2tY33tY34dgD+za7+1rj/dxH/fxj/hiH/kk3///9TM3sUAAAAFHRSTlMAbXd4eHh6gN3e3+Hi4+T5+/z8/mIsq5IAAABHSURBVBjTY2CgGWDlFuZhRuIz8cspyggxIgQ4ZFWVVCQ4EQLCCmpqalLCCAFeaWV5SVE+hAC7gJi4iCAbkqksXMK8bNRzNADCOQN++eLhCQAAAABJRU5ErkJggg==);
  padding-left: 16px;
}
.lfr-upload-container .upload-file.upload-complete.file-saved {
  padding-left: 25px;
}
.lfr-upload-container .upload-file .file-title {
  display: inline-block;
  max-width: 95%;
  overflow: hidden;
  padding-right: 16px;
  text-overflow: ellipsis;
  vertical-align: middle;
  white-space: nowrap;
}
.lfr-upload-container .upload-file .icon-file {
  font-size: 40px;
}
.lfr-upload-container .upload-list-info {
  margin: 1em 0 0.5em;
}
.lfr-upload-container .upload-list-info .h4,
.lfr-upload-container .upload-list-info h4 {
  font-size: 1.3em;
}
.lfr-upload-container .cancel-button {
  color: #6c757d;
  margin-top: 1px;
  position: absolute;
  right: 5px;
  top: 50%;
  white-space: nowrap;
}
.lfr-upload-container .cancel-button .cancel-button-text {
  display: none;
  margin-left: 5px;
}
.lfr-upload-container .cancel-button:hover .cancel-button-text {
  display: inline;
}
.lfr-upload-container .cancel-button .lexicon-icon {
  height: 12px;
}
.lfr-upload-container .delete-button {
  color: #6c757d;
}
.lfr-upload-container .delete-button-col {
  padding-right: 10px;
}
.lfr-upload-container .file-added .success-message {
  float: right;
  font-weight: normal;
}
.lfr-upload-container .upload-error {
  opacity: 1;
  padding-left: 25px;
}
.lfr-upload-container .upload-complete .cancel-button,
.lfr-upload-container .delete-button,
.lfr-upload-container .upload-complete.file-saved .delete-button,
.lfr-upload-container .upload-complete.upload-error .delete-button {
  display: none;
}
.lfr-upload-container .multiple-files .upload-error {
  background: #f5c4c9 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJPSURBVDjLpZPLS5RhFMYfv9QJlelTQZwRb2OKlKuINuHGLlBEBEOLxAu46oL0F0QQFdWizUCrWnjBaDHgThCMoiKkhUONTqmjmDp2GZ0UnWbmfc/ztrC+GbM2dXbv4ZzfeQ7vefKMMfifyP89IbevNNCYdkN2kawkCZKfSPZTOGTf6Y/m1uflKlC3LvsNTWArr9BT2LAf+W73dn5jHclIBFZyfYWU3or7T4K7AJmbl/yG7EtX1BQXNTVCYgtgbAEAYHlqYHlrsTEVQWr63RZFuqsfDAcdQPrGRR/JF5nKGm9xUxMyr0YBAEXXHgIANq/3ADQobD2J9fAkNiMTMSFb9z8ambMAQER3JC1XttkYGGZXoyZEGyTHRuBuPgBTUu7VSnUAgAUAWutOV2MjZGkehgYUA6O5A0AlkAyRnotiX3MLlFKduYCqAtuGXpyH0XQmOj+TIURt51OzURTYZdBKV2UBSsOIcRp/TVTT4ewK6idECAihtUKOArWcjq/B8tQ6UkUR31+OYXP4sTOdisivrkMyHodWejlXwcC38Fvs8dY5xaIId89VlJy7ACpCNCFCuOp8+BJ6A631gANQSg1mVmOxxGQYRW2nHMha4B5WA3chsv22T5/B13AIicWZmNZ6cMchTXUe81Okzz54pLi0uQWp+TmkZqMwxsBV74Or3od4OISPr0e3SHa3PX0f3HXKofNH/UIG9pZ5PeUth+CyS2EMkEqs4fPEOBJLsyske48/+xD8oxcAYPzs4QaS7RR2kbLTTOTQieczfzfTv8QPldGvTGoF6/8AAAAASUVORK5CYII=) no-repeat 5px 5px;
  border-color: #bd2130;
  color: #bd2130;
  font-weight: normal;
  margin-bottom: 16px;
  padding: 8px 8px 8px 24px;
}
.lfr-upload-container .multiple-files .upload-error .error-message {
  display: block;
}
.lfr-upload-container .multiple-files .upload-complete.file-saved .form-check-middle-left .card-body,
.lfr-upload-container .multiple-files .upload-complete.upload-error .form-check-middle-left .card-body {
  padding-left: 1rem;
}
.lfr-upload-container .multiple-files .upload-complete.file-saved .form-check-middle-left .custom-control-label,
.lfr-upload-container .multiple-files .upload-complete.upload-error .form-check-middle-left .custom-control-label {
  display: none;
}
.lfr-upload-container .single-file .upload-error {
  list-style: none;
  margin-top: 1em;
}
.lfr-upload-container .single-file .upload-error .upload-error-message {
  margin-bottom: 0.5em;
}
.lfr-upload-container .upload-complete {
  padding-left: 5px;
}
.lfr-upload-container .upload-complete .error-message,
.lfr-upload-container .upload-complete .success-message {
  font-weight: bold;
  margin-left: 1em;
}
.lfr-upload-container .upload-complete .delete-button {
  display: inline-block;
}
.lfr-upload-container .upload-complete .select-file:disabled + .custom-control-label {
  display: none;
}
.lfr-upload-container .progress {
  display: none;
  margin-top: 0.5rem;
}
.lfr-upload-container .file-uploading .progress {
  display: flex;
}

.lfr-alert-container {
  left: 0;
  position: absolute;
  right: auto;
  top: auto;
  width: 100%;
  z-index: 430;
}
.lfr-alert-container.inline-alert-container {
  position: relative;
}
.lfr-alert-container.inline-alert-container .lfr-alert-wrapper {
  padding: 0;
}
.lfr-alert-container .lfr-alert-wrapper {
  margin-bottom: 5px;
  overflow: hidden;
}

.lfr-search-container td .overlay.entry-action {
  position: static;
}
.lfr-search-container td .overlay.entry-action .btn a {
  display: block;
  padding: 4px 12px;
}

.contextual-sidebar {
  height: calc(
		100vh - var(--control-menu-container-height) - 49px
	);
  pointer-events: none;
  position: fixed;
  right: 0;
  top: calc(var(--control-menu-container-height) + 49px);
  transform: translateX(100%);
  transition: transform ease 0.5s;
  visibility: hidden;
  width: 320px;
  will-change: transform;
}
.contextual-sidebar.contextual-sidebar-visible {
  pointer-events: auto;
  transform: translateX(0);
  visibility: visible;
}

@media (min-width: 768px) {
  .contextual-sidebar {
    height: calc(
			100vh - var(--control-menu-container-height) - 64px
		);
    top: calc(
			var(--control-menu-container-height) + 64px
		);
  }
  .contextual-sidebar-content {
    transition: padding ease 0.5s;
    will-change: padding;
  }
  .contextual-sidebar-visible .contextual-sidebar-content,
  .contextual-sidebar-visible + .contextual-sidebar-content {
    padding-right: 320px;
  }
}
.taglib-discussion {
  font-size: 0.875rem;
  margin-top: 1rem;
}
.taglib-discussion .actions-menu .component-action {
  display: inline-flex;
}
.taglib-discussion .button-holder {
  margin: 1rem 0;
}
.taglib-discussion .comment-container {
  margin-bottom: 1.5rem;
}
.taglib-discussion .lfr-discussion .lfr-discussion-form-edit .alloy-editor-placeholder {
  border-left-color: #dbdde1;
}
.taglib-discussion .lfr-discussion-body {
  font-size: 1rem;
}
@media (min-width: 576px) {
  .taglib-discussion .lfr-discussion-body {
    padding-left: 3.5rem;
  }
}
@media (min-width: 576px) {
  .taglib-discussion .lfr-discussion-details .taglib-user-display {
    word-wrap: break-word;
  }
}
.taglib-discussion .lfr-discussion-details .taglib-user-display .user-details .user-name {
  font-weight: bold;
  text-decoration: none;
}
.taglib-discussion .lfr-discussion-details .taglib-user-display .user-details .user-name:hover {
  text-decoration: underline;
}
.taglib-discussion .lfr-discussion-details .taglib-user-display .user-profile-image .avatar {
  background-size: 50px;
}
.taglib-discussion .lfr-discussion-container {
  border-bottom: 1px solid #e7e7ed;
  margin-bottom: 1.5rem;
}
.taglib-discussion .lfr-discussion-container:first-of-type {
  border-top: 1px solid #e7e7ed;
  padding-top: 1.5rem;
}
.taglib-discussion .lfr-discussion-container:last-of-type {
  border-bottom: 0;
}
.taglib-discussion .lfr-discussion-container .lfr-discussion {
  padding-left: 1rem;
}
.taglib-discussion .lfr-discussion-container .lfr-discussion .lfr-discussion .lfr-discussion .lfr-discussion {
  padding-left: 0;
}
@media (min-width: 576px) {
  .taglib-discussion .lfr-discussion-container .lfr-discussion {
    padding-left: 3.5rem;
  }
}
.taglib-discussion .lfr-discussion-parent-link {
  color: #67678c;
  font-weight: 600;
  margin-left: 1em;
}
@media (max-width: 767.98px) {
  .taglib-discussion .lfr-discussion-parent-link {
    display: block;
    margin-left: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}
.taglib-discussion .lfr-discussion-controls .autofit-col:first-of-type > .btn-outline-borderless {
  margin-left: -0.75rem;
}
.taglib-discussion .lfr-discussion-more-comments {
  border-top: 1px solid #e7e7ed;
  margin-top: 1.5rem;
  padding-top: 1.5rem;
  text-align: center;
}
.taglib-discussion .username {
  color: #272833;
  font-weight: 600;
}
.taglib-discussion .taglib-workflow-status {
  margin-left: 0.5rem;
}
.taglib-discussion .workflow-value {
  text-transform: uppercase;
}
@media (min-width: 576px) {
  .taglib-discussion .actions-menu {
    display: none;
  }
  .taglib-discussion .comment-container:hover .actions-menu,
  .taglib-discussion .actions-menu:focus,
  .taglib-discussion .actions-menu.open {
    display: inline-block;
  }
}

.drop-zone {
  min-height: 80px;
  padding: 20px;
  text-align: center;
}
.drop-zone.drop-enabled {
  outline: 2px dashed transparent;
}
.drop-zone.drop-enabled:not(.no-border) {
  outline-color: rgba(176, 180, 187, 0.5);
}
.drop-zone p {
  margin: 10px auto 0;
  max-width: 75%;
}

.drop-here-info {
  font-size: 25px;
  height: 100%;
  left: 0;
  min-height: 100px;
  opacity: 0;
  position: absolute;
  text-align: center;
  top: 0;
  visibility: hidden;
  width: 100%;
  transition: all 0.2s ease-in-out;
}
@media (prefers-reduced-motion: reduce) {
  .drop-here-info {
    transition: none;
  }
}
.drop-here-info {
  transition: none;
}

.drop-here-info .drop-here-indicator {
  height: 115px;
  left: 0;
  margin: auto;
  position: absolute;
  right: 0;
  top: 50%;
  transform: translate(0, -50%);
}
.drop-here-info .drop-icons {
  display: inline-block;
  position: relative;
  width: 160px;
  transition: all 0.2s ease-in-out;
}
@media (prefers-reduced-motion: reduce) {
  .drop-here-info .drop-icons {
    transition: none;
  }
}
.drop-here-info .drop-icons {
  transition: none;
}

.drop-here-info .drop-icons span {
  border-radius: 3px;
  position: absolute;
  text-align: center;
  transition: all 0.3s ease-in-out;
}
@media (prefers-reduced-motion: reduce) {
  .drop-here-info .drop-icons span {
    transition: none;
  }
}
.drop-here-info .drop-icons span {
  transition: none;
}

.drop-here-info .drop-icons span:nth-of-type(1) {
  box-shadow: 5px 4px 0 0 rgba(0, 0, 0, 0.08);
  height: 60px;
  left: 0;
  line-height: 60px;
  opacity: 0;
  top: 10px;
  transform: rotate(25deg);
  width: 60px;
}
.drop-here-info .drop-icons span:nth-of-type(2) {
  background: #00c2ff;
  color: #fff;
  height: 80px;
  left: 40px;
  line-height: 80px;
  width: 80px;
  z-index: 2;
}
.drop-here-info .drop-icons span:nth-of-type(3) {
  box-shadow: -5px 4px 0 0 rgba(0, 0, 0, 0.08);
  display: block;
  font-size: 45px;
  height: 70px;
  left: 90px;
  line-height: 70px;
  opacity: 0;
  position: relative;
  top: 8px;
  transform: rotate(-25deg);
  width: 70px;
  z-index: 1;
}
.drop-here-info .drop-icons span:nth-of-type(1), .drop-here-info .drop-icons span:nth-of-type(3) {
  background: #e8e6e8;
  color: #a5a6ac;
}
.drop-here-info .drop-text {
  color: #fff;
  display: block;
  font-size: 20px;
  margin-left: 0;
  margin-top: 20px;
}
.drop-active .drop-here-info {
  background-color: rgba(0, 0, 0, 0.6);
  opacity: 1;
  visibility: visible;
  z-index: 100;
}
.drop-active .drop-here-info .drop-icons span:nth-of-type(1), .drop-active .drop-here-info .drop-icons span:nth-of-type(3) {
  opacity: 1;
}
.drop-active .drop-here-info span:nth-of-type(1) {
  transform: rotate(-20deg);
}
.drop-active .drop-here-info span:nth-of-type(2) {
  transform: scale(1);
}
.drop-active .drop-here-info span:nth-of-type(3) {
  transform: rotate(15deg);
}

.taglib-empty-result-message.sheet {
  margin-bottom: 24px;
}
.taglib-empty-result-message .taglib-empty-result-message-description {
  color: #6c757d;
  margin-top: 8px;
}
.taglib-empty-result-message .taglib-empty-result-message-header,
.taglib-empty-result-message .taglib-empty-result-message-header-has-plus-btn,
.taglib-empty-result-message .taglib-empty-search-result-message-header {
  background-position: center;
  background-repeat: no-repeat;
  background-size: 100%;
  margin-left: auto;
  margin-right: auto;
}
.taglib-empty-result-message .taglib-empty-result-message-header,
.taglib-empty-result-message .taglib-empty-result-message-header-has-plus-btn {
  max-width: 200px;
  padding-top: 250px;
}
.taglib-empty-result-message .taglib-empty-result-message-header,
.taglib-empty-result-message .taglib-empty-result-message-header-has-plus-btn {
  background-image: url(../images/states/empty_state.svg);
}
@media (prefers-reduced-motion: reduce) {
  .taglib-empty-result-message .taglib-empty-result-message-header,
  .taglib-empty-result-message .taglib-empty-result-message-header-has-plus-btn {
    background-image: url(../images/states/empty_state_reduced_motion.svg);
  }
}
.c-prefers-reduced-motion .taglib-empty-result-message .taglib-empty-result-message-header,
.c-prefers-reduced-motion .taglib-empty-result-message .taglib-empty-result-message-header-has-plus-btn {
  background-image: url(../images/states/empty_state_reduced_motion.svg);
}
.taglib-empty-result-message .taglib-empty-search-result-message-header {
  background-image: url(../images/states/search_state.svg);
  max-width: 210px;
  padding-top: 232px;
}
@media (prefers-reduced-motion: reduce) {
  .taglib-empty-result-message .taglib-empty-search-result-message-header {
    background-image: url(../images/states/search_state_reduced_motion.svg);
  }
}
.c-prefers-reduced-motion .taglib-empty-result-message .taglib-empty-search-result-message-header {
  background-image: url(../images/states/search_state_reduced_motion.svg);
}
.taglib-empty-result-message .taglib-empty-state {
  background-image: url(../images/states/empty_state.svg);
  margin: auto;
  max-width: 250px;
  padding-top: 250px;
}
@media (prefers-reduced-motion: reduce) {
  .taglib-empty-result-message .taglib-empty-state {
    background-image: url(../images/states/empty_state_reduced_motion.svg);
  }
}
.c-prefers-reduced-motion .taglib-empty-result-message .taglib-empty-state {
  background-image: url(../images/states/empty_state_reduced_motion.svg);
}
.taglib-empty-result-message .taglib-success-state {
  background-image: url(../images/states/success_state.svg);
  margin: auto;
  max-width: 250px;
  padding-top: 250px;
}
@media (prefers-reduced-motion: reduce) {
  .taglib-empty-result-message .taglib-success-state {
    background-image: url(../images/states/success_state_reduced_motion.svg);
  }
}
.c-prefers-reduced-motion .taglib-empty-result-message .taglib-success-state {
  background-image: url(../images/states/success_state_reduced_motion.svg);
}
.taglib-empty-result-message .taglib-search-state {
  background-image: url(../images/states/search_state.svg);
  margin: auto;
  max-width: 250px;
  padding-top: 250px;
}
@media (prefers-reduced-motion: reduce) {
  .taglib-empty-result-message .taglib-search-state {
    background-image: url(../images/states/search_state_reduced_motion.svg);
  }
}
.c-prefers-reduced-motion .taglib-empty-result-message .taglib-search-state {
  background-image: url(../images/states/search_state_reduced_motion.svg);
}
.taglib-empty-result-message .taglib-empty-result-message-title {
  font-size: 1rem;
  margin-top: 48px;
}
.taglib-empty-result-message .taglib-empty-result-message-description {
  font-size: 0.875rem;
}
.taglib-empty-result-message .taglib-empty-result-message-header + .taglib-empty-result-message-title,
.taglib-empty-result-message .taglib-empty-search-result-message-header + .taglib-empty-result-message-title,
.taglib-empty-result-message .taglib-empty-state + .taglib-empty-result-message-title,
.taglib-empty-result-message .taglib-success-state + .taglib-empty-result-message-title,
.taglib-empty-result-message .taglib-search-state + .taglib-empty-result-message-title {
  font-size: 1.25rem;
  font-weight: bold;
  text-align: center;
}
.taglib-empty-result-message .taglib-empty-result-message-header ~ .taglib-empty-result-message-description, .taglib-empty-result-message .taglib-empty-result-message-header ~ .taglib-empty-result-message-actions,
.taglib-empty-result-message .taglib-empty-search-result-message-header ~ .taglib-empty-result-message-description,
.taglib-empty-result-message .taglib-empty-search-result-message-header ~ .taglib-empty-result-message-actions,
.taglib-empty-result-message .taglib-empty-state ~ .taglib-empty-result-message-description,
.taglib-empty-result-message .taglib-empty-state ~ .taglib-empty-result-message-actions,
.taglib-empty-result-message .taglib-success-state ~ .taglib-empty-result-message-description,
.taglib-empty-result-message .taglib-success-state ~ .taglib-empty-result-message-actions,
.taglib-empty-result-message .taglib-search-state ~ .taglib-empty-result-message-description,
.taglib-empty-result-message .taglib-search-state ~ .taglib-empty-result-message-actions {
  font-size: 1rem;
  text-align: center;
}

.field-wrapper.form-inline .control-label {
  display: inline-block;
}

.field-wrapper-html .input-localized .input-group-item {
  flex-wrap: nowrap;
}

.taglib-header {
  border-bottom: 1px solid #c8c9ca;
  color: #555;
  margin-bottom: 1em;
  padding-bottom: 10px;
}
.taglib-header .header-title {
  display: inline-block;
  margin: 0.1em;
  max-width: 100%;
  text-overflow: ellipsis;
  vertical-align: middle;
  white-space: nowrap;
  word-wrap: normal;
}
.taglib-header .header-back-to {
  display: inline-block;
  vertical-align: middle;
}
.taglib-header .header-back-to a {
  display: block;
  font-weight: bold;
  padding: 0 0.3em 0 0;
  text-decoration: none;
}

.taglib-icon {
  text-decoration: none;
}
.taglib-icon:not(.btn):hover .taglib-text, .taglib-icon:not(.btn):focus .taglib-text {
  text-decoration: underline;
}
.taglib-icon[lang] > img {
  vertical-align: baseline;
  width: 16px;
}

.taglib-icon-help {
  color: #6c757d !important;
}
.taglib-icon-help:hover, .taglib-icon-help:active {
  color: #343a40 !important;
}

.icon-monospaced {
  color: inherit;
  display: inline-block;
  height: 2rem;
  line-height: 34px;
  text-align: center;
  width: 2rem;
}
.icon-monospaced.lexicon-icon {
  padding: 8px;
}

.taglib-icon-list li {
  float: left;
  margin-right: 1em;
}
.taglib-icon-list:after {
  clear: both;
  content: "";
  display: block;
  height: 0;
  visibility: hidden;
}

.lfr-icon-menu .lfr-icon-menu-icon {
  max-width: none;
}
@media (max-width: 767.98px) {
  .table-cell.last .lfr-icon-menu .dropdown-toggle {
    text-align: center;
  }
  .table-cell.last .lfr-icon-menu .dropdown-toggle > img,
  .table-cell.last .lfr-icon-menu .dropdown-toggle .lfr-icon-menu-text {
    display: none;
  }
}

.lfr-menu-list {
  float: none;
  overflow-y: auto;
  position: relative;
}
.lfr-menu-list.direction-right {
  margin: 0 2px;
}
.lfr-menu-list.dropdown-menu {
  float: none;
  position: relative;
}
@media (max-width: 991.98px) {
  .lfr-menu-list.dropdown-menu > li > a {
    font-size: 22px;
    line-height: 40px;
    white-space: normal;
  }
  .lfr-menu-list.dropdown-menu > li > a img {
    margin-bottom: 3px;
  }
}
.lfr-menu-list.dropdown-menu .search-panel {
  margin-bottom: 0;
}
.lfr-menu-list.dropdown-menu .search-panel .form-group {
  margin: 0 16px;
}
.lfr-menu-list.dropdown-menu .search-panel .menu-item-filter {
  width: auto;
}
body > .lfr-menu-list ul {
  border-radius: 4px;
}

.lfr-icon-menu-open:after {
  clear: both;
  content: "";
  display: table;
}
.lfr-icon-menu-open .dropdown-menu {
  position: static;
}

.input-localized.input-localized-editor .form-control {
  border-width: 0;
  height: 100%;
  padding: 0;
}
.input-localized .input-group-item {
  flex-direction: column;
}
.input-localized .input-localized-content {
  margin-left: 6px;
}
.input-group .input-localized .input-localized-content {
  margin-top: 3px;
}
.input-localized .lfr-input-localized .lfr-input-localized-state {
  background-color: #ddd;
}
.input-localized .lfr-input-localized .lfr-input-localized-state.lfr-input-localized-state-error {
  background-color: #ff0047;
}
.input-localized .lfr-input-localized-default a {
  margin-right: 14px;
}
.input-localized .lfr-input-localized-state {
  height: 4px;
  margin: 3px 5px;
  width: 4px;
}
.input-localized .palette-item-inner .lfr-input-localized-flag {
  font-size: 16px;
  opacity: 0.5;
}
.input-localized .palette-item,
.input-localized .palette-item-hover,
.input-localized .palette-item-hover .palette-item-inner {
  border-color: transparent;
}
.input-localized .palette-item-inner {
  border-color: #666;
  display: block;
  height: 16px;
  width: 16px;
}
.input-localized .palette-item-selected .lfr-input-localized-state {
  background: #27c1f2;
}

.input-localized-palette-container .palette-items-container {
  font-size: 0;
  margin: 0;
  white-space: normal;
}
.input-localized-palette-container .palette-item {
  border-width: 0;
  padding: 0.5rem 1.25rem;
}
.input-localized-palette-container .palette-item-inner {
  border: 1px solid;
  margin-right: 4px;
  width: 16px;
}
.input-localized-palette-container .palette-item-inner img {
  display: block;
}

.taglib-move-boxes {
  margin-bottom: 1em;
}
.taglib-move-boxes label {
  border-bottom: 1px solid transparent;
  display: block;
  margin-bottom: 5px;
  padding: 5px;
}
.taglib-move-boxes .toolbar {
  text-align: center;
}
.taglib-move-boxes .arrow-button img {
  border-width: 0;
  height: 16px;
  width: 16px;
}
.taglib-move-boxes .choice-selector {
  width: 100%;
}
.taglib-move-boxes .choice-selector label {
  background: #ebf1f9;
  border-bottom-color: #8db2f3;
}
.taglib-move-boxes .field-content {
  margin-bottom: 0;
}
.taglib-move-boxes .move-arrow-buttons {
  margin-top: 5em;
}
.taglib-move-boxes .move-arrow-buttons .arrow-button {
  display: block;
}
.taglib-move-boxes .sortable-container {
  margin-top: 10px;
}
.taglib-move-boxes .sortable-container .btn.edit-selection {
  margin-bottom: 10px;
}
.taglib-move-boxes .sortable-container .move-option {
  background-color: transparent;
  border-top: 1px solid #ddd;
  display: none;
  margin: 2px 0;
  padding: 2px;
  position: relative;
}
.taglib-move-boxes .sortable-container .move-option.selected {
  display: block;
}
.taglib-move-boxes .sortable-container .move-option.move-option-dragging {
  background-color: #fafafa;
}
.taglib-move-boxes .sortable-container .move-option .checkbox,
.taglib-move-boxes .sortable-container .move-option .handle {
  position: absolute;
}
.taglib-move-boxes .sortable-container .move-option .checkbox {
  display: none;
  margin: 7px 0 0 5px;
}
.taglib-move-boxes .sortable-container .move-option .handle {
  color: #999;
  cursor: pointer;
  font-size: 1.5em;
  padding: 6px;
}
.taglib-move-boxes .sortable-container .move-option .title {
  font-size: 1.2em;
  margin: 1px 0 1px 30px;
}
.taglib-move-boxes .sortable-container.edit-list-active .move-option {
  display: block;
}
.taglib-move-boxes .sortable-container.edit-list-active .move-option .checkbox {
  display: inline-block;
}
.taglib-move-boxes .sortable-container.edit-list-active .move-option .handle {
  display: none;
}
.mobile .taglib-move-boxes .selector-container {
  display: none;
}

.item-selector .card-row > .autofit-col-expand {
  padding-top: 4px;
}
.item-selector .drop-zone {
  background-color: #f1f2f5;
  margin-top: 1rem;
}
.item-selector .input-file {
  height: 0.1px;
  opacity: 0;
  overflow: hidden;
  position: absolute;
  width: 0.1px;
  z-index: -1;
}
.item-selector .input-file + label {
  position: relative;
}
.item-selector .input-file + label::before {
  border-radius: 4px;
  bottom: -2px;
  content: "";
  display: block;
  left: -2px;
  position: absolute;
  right: -2px;
  top: -2px;
  transition: box-shadow 0.15s ease-in-out;
}
.item-selector .input-file:focus + label::before {
  box-shadow: 0 0 0 2px #fff, 0 0 0 4px #75b8ff;
}
.item-selector .item-selector-list-row:hover {
  background-color: #e5f2ff;
  cursor: pointer;
}

.lfr-map {
  border: 1px solid #ccc;
  min-height: 400px;
  width: 100%;
}
.lfr-map .home-button {
  margin: 5px;
}
@media (max-width: 575.98px) {
  .lfr-map .home-button {
    height: 35px;
    width: 45px;
  }
}
.lfr-map .search-controls {
  font-size: 15px;
  margin-top: 5px;
  width: 100%;
}
@media (min-width: 576px) {
  .lfr-map .search-controls {
    width: 50%;
  }
}
.lfr-map .search-controls .search-input {
  width: 100%;
}

.navbar .navbar-collapse {
  max-height: none;
}
.navbar .navbar-collapse:after, .navbar .navbar-collapse:before {
  display: inline;
}
@media (max-width: 767.98px) {
  .navbar .navbar-search {
    background-color: #f3f3f3;
    border-top-width: 0;
    width: 100%;
  }
}
.navbar .navbar-search .form-search {
  margin: 8px 0;
}
@media (min-width: 768px) {
  .navbar .navbar-search .form-search {
    float: right;
    max-width: 275px;
  }
}
@media (max-width: 767.98px) {
  .navbar .navbar-search .form-search .input-group {
    width: 100%;
  }
}
@media (max-width: 991.98px) {
  .navbar .container .navbar-btn,
  .navbar .container-fluid .navbar-btn {
    margin-bottom: 5px;
    width: 45px;
  }
  .navbar .container .navbar-collapse.open,
  .navbar .container-fluid .navbar-collapse.open {
    border-width: 0;
    display: block;
    height: auto;
    overflow: visible;
  }
}

.taglib-portlet-preview.show-borders {
  border: 1px solid #828f95;
  margin-bottom: 1em;
  padding: 3px 3px 1em;
}
.taglib-portlet-preview.show-borders .title {
  background-color: #d3dadd;
  font-size: 1.4em;
  font-weight: bold;
  padding: 0.5em;
}
.taglib-portlet-preview .preview {
  margin: 1em;
  min-height: 90px;
}

.lfr-search-container .entry-action {
  width: 1px;
}
.lfr-search-container .entry-action .taglib-icon {
  white-space: nowrap;
}

.lfr-search-container-wrapper.lfr-search-container-fixed-first-column {
  position: relative;
}
@media (min-width: 576px) {
  .lfr-search-container-wrapper.lfr-search-container-fixed-first-column .table-responsive {
    margin-left: 375px;
    width: auto;
  }
}
.lfr-search-container-wrapper.lfr-search-container-fixed-first-column .table-responsive .table {
  position: static;
}
.lfr-search-container-wrapper.lfr-search-container-fixed-first-column .table-responsive .table .lfr-search-iterator-fixed-header {
  left: 12px;
  position: fixed;
  right: 12px;
  top: -1px;
  z-index: 989;
}
.lfr-search-container-wrapper.lfr-search-container-fixed-first-column .table-responsive .table .lfr-search-iterator-fixed-header > th {
  display: block;
  padding: 0;
}
.lfr-search-container-wrapper.lfr-search-container-fixed-first-column .table-responsive .table .lfr-search-iterator-fixed-header > th .lfr-search-iterator-fixed-header-inner-wrapper {
  overflow-x: hidden;
}
@media (min-width: 576px) {
  .lfr-search-container-wrapper.lfr-search-container-fixed-first-column .table-responsive .table .lfr-search-iterator-fixed-header > th .lfr-search-iterator-fixed-header-inner-wrapper {
    margin-left: 375px;
  }
}
.lfr-search-container-wrapper.lfr-search-container-fixed-first-column .table-responsive .table .lfr-search-iterator-fixed-header > th .lfr-search-iterator-fixed-header-inner-wrapper table {
  border-collapse: collapse;
  width: 100%;
}
.lfr-search-container-wrapper.lfr-search-container-fixed-first-column .table-responsive .table .lfr-search-iterator-fixed-header > th .lfr-search-iterator-fixed-header-inner-wrapper table th {
  border-radius: 0;
}
.lfr-search-container-wrapper.lfr-search-container-fixed-first-column .table-responsive .table td,
.lfr-search-container-wrapper.lfr-search-container-fixed-first-column .table-responsive .table th {
  width: auto;
}
@media (min-width: 576px) {
  .lfr-search-container-wrapper.lfr-search-container-fixed-first-column .table-responsive .table td:first-child,
  .lfr-search-container-wrapper.lfr-search-container-fixed-first-column .table-responsive .table th:first-child {
    background-color: #fff;
    left: 0;
    position: absolute;
    right: 15px;
  }
}
.lfr-search-container-wrapper.lfr-search-container-fixed-first-column .table-responsive .table th {
  height: auto;
}
.lfr-search-container-wrapper a:not(.btn):not(.component-action):not(.page-link) {
  color: #495057;
  font-weight: 500;
  text-decoration: underline;
}
.lfr-search-container-wrapper a:not(.btn):not(.component-action):not(.page-link):focus, .lfr-search-container-wrapper a:not(.btn):not(.component-action):not(.page-link):hover {
  color: #000;
}
.lfr-search-container-wrapper .dropdown-action .dropdown-toggle {
  color: #6c757d;
}
.lfr-search-container-wrapper .dropdown-action .dropdown-toggle:hover {
  color: #343a40;
}
.lfr-search-container-wrapper .lfr-icon-menu > .dropdown-toggle {
  color: #6c757d;
}
.lfr-search-container-wrapper .lfr-icon-menu > .dropdown-toggle:active, .lfr-search-container-wrapper .lfr-icon-menu > .dropdown-toggle:focus, .lfr-search-container-wrapper .lfr-icon-menu > .dropdown-toggle:hover {
  background-color: #f7f8f9;
  border-radius: 4px;
  color: #343a40;
}
.lfr-search-container-wrapper .lfr-search-container-list .list-group:first-child dt:not(.list-group-header) + .list-group-item {
  border-top-left-radius: 0.25rem;
  border-top-right-radius: 0.25rem;
}
.lfr-search-container-wrapper .lfr-search-container-list .list-group:last-child .list-group-item:nth-last-child(2) {
  border-bottom-left-radius: 0.25rem;
  border-bottom-right-radius: 0.25rem;
}
.lfr-search-container-wrapper .lfr-search-container-list + .taglib-search-iterator-page-iterator-bottom {
  margin-top: 20px;
}
.lfr-search-container-wrapper .list-group {
  margin-bottom: 0;
}
.lfr-search-container-wrapper .list-group + .list-group .list-group-header:first-child,
.lfr-search-container-wrapper .list-group + .list-group .list-group-item:first-child {
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}
.lfr-search-container-wrapper .list-group .list-group-item .h4,
.lfr-search-container-wrapper .list-group .list-group-item h4 {
  font-size: 0.875rem;
  line-height: 1.5;
  margin-bottom: 0;
}
.lfr-search-container-wrapper .list-group .list-group-item .h5,
.lfr-search-container-wrapper .list-group .list-group-item .h6,
.lfr-search-container-wrapper .list-group .list-group-item h5,
.lfr-search-container-wrapper .list-group .list-group-item h6 {
  font-size: 0.875rem;
  font-weight: 400;
  line-height: 1.5;
  margin-bottom: 0;
}
.lfr-search-container-wrapper .list-group .list-group-item span + h2.h5 {
  font-weight: 600;
}
.lfr-search-container-wrapper .list-group .list-group-item .h6 + .h5,
.lfr-search-container-wrapper .list-group .list-group-item h6 + h5 {
  font-weight: 600;
}
.lfr-search-container-wrapper .table-list tbody tr:nth-last-child(2) td:first-child,
.lfr-search-container-wrapper .table-list tbody tr:nth-last-child(2) th:first-child {
  border-bottom-left-radius: 0.25rem;
}
.lfr-search-container-wrapper .table-list tbody tr:nth-last-child(2) td:last-child,
.lfr-search-container-wrapper .table-list tbody tr:nth-last-child(2) th:last-child {
  border-bottom-right-radius: 0.25rem;
}

.user-info {
  display: flex;
}
.user-info .sticker {
  align-self: center;
}
.user-info .user-details {
  margin-left: 1rem;
}
.user-info .user-name {
  color: #343a40;
  font-weight: 600;
}
.user-info .date-info {
  color: #6c757d;
}

.user-status-tooltip .user-status-avatar {
  float: left;
  margin-right: 5px;
}
.user-status-tooltip .user-status-avatar .user-status-avatar-image {
  width: 27px;
}
.user-status-tooltip .user-status-info {
  display: inline-block;
  overflow: hidden;
}
.user-status-tooltip .user-status-info .user-status-date {
  font-size: 11px;
}

.lfr-search-container {
  margin-top: 1.5em;
  overflow: auto;
}
@media (max-width: 767.98px) {
  .lfr-search-container .selector-button {
    width: auto;
  }
}
.touch .lfr-search-container {
  -webkit-overflow-scrolling: touch;
}
.touch .lfr-search-container .searchcontainer-content .table {
  max-width: none;
}

.taglib-page-iterator {
  clear: both;
  height: auto;
  width: auto;
}
.taglib-page-iterator .lfr-pagination-buttons {
  float: right;
  margin: 0;
}
@media (max-width: 991.98px) {
  .taglib-page-iterator .lfr-pagination-buttons {
    width: 100%;
  }
}
@media (max-width: 991.98px) and (max-width: 767.98px) {
  .taglib-page-iterator .lfr-pagination-buttons {
    float: none;
    margin-top: 20px;
  }
}
@media (max-width: 991.98px) {
  .taglib-page-iterator .lfr-pagination-buttons > li {
    display: inline-block;
    width: 50%;
  }
  .taglib-page-iterator .lfr-pagination-buttons > li.first, .taglib-page-iterator .lfr-pagination-buttons > li.last {
    display: none;
  }
  .taglib-page-iterator .lfr-pagination-buttons > li > a {
    line-height: 20px;
    padding: 11px 19px;
  }
}
.taglib-page-iterator .lfr-pagination-config {
  float: left;
  line-height: 46px;
}
@media (max-width: 767.98px) {
  .taglib-page-iterator .lfr-pagination-config {
    float: none;
  }
  .taglib-page-iterator .lfr-pagination-config .current-page-menu {
    display: block;
  }
  .taglib-page-iterator .lfr-pagination-config .current-page-menu .btn {
    display: block;
  }
}
.taglib-page-iterator .lfr-pagination-config .lfr-pagination-delta-selector,
.taglib-page-iterator .lfr-pagination-config .lfr-pagination-page-selector {
  display: inline;
}
.taglib-page-iterator .lfr-pagination-config .lfr-pagination-delta-selector {
  float: none;
}
@media (max-width: 991.98px) {
  .taglib-page-iterator .lfr-pagination-config .lfr-pagination-delta-selector {
    display: none;
  }
}
.taglib-page-iterator .search-results {
  float: left;
  line-height: 46px;
  margin-left: 10px;
}
@media (max-width: 991.98px) {
  .taglib-page-iterator .search-results {
    display: none;
  }
}

@media (max-width: 991.98px) {
  ul.pagination ul.inline-scroller {
    max-height: inherit;
  }
}
.taglib-search-toggle .form-search {
  position: relative;
}
.taglib-search-toggle .form-search .input-group-btn {
  position: absolute;
}
@media (min-width: 992px) {
  .taglib-search-toggle .form-search .input-group-btn {
    position: static;
  }
}
.taglib-search-toggle .toggle-advanced {
  color: inherit;
  margin-left: 10px;
  position: absolute;
  top: 8px;
}
.taglib-search-toggle .toggle-advanced, .taglib-search-toggle .toggle-advanced:hover, .taglib-search-toggle .toggle-advanced:focus {
  text-decoration: none;
}

.taglib-search-toggle-advanced-wrapper .taglib-search-toggle-advanced {
  background-color: #fcfcfc;
  border: solid #ddd;
  border-width: 0 1px 1px;
  margin-top: 0;
  padding: 15px 15px 0;
}
.navbar-search .taglib-search-toggle-advanced-wrapper .taglib-search-toggle-advanced {
  border-width: 1px 0 0;
}
.taglib-search-toggle-advanced-wrapper .taglib-search-toggle-advanced .taglib-search-toggle-advanced-content {
  position: relative;
}
.taglib-search-toggle-advanced-wrapper .taglib-search-toggle-advanced .taglib-search-toggle-advanced-content .match-fields {
  margin-bottom: 0;
}
.taglib-search-toggle-advanced-wrapper .taglib-search-toggle-advanced .taglib-search-toggle-advanced-content .match-fields-legend {
  color: #999;
  font-size: 13px;
}
.taglib-search-toggle-advanced-wrapper .btn.close {
  margin-right: 5px;
  position: relative;
  z-index: 1;
}

.taglib-user-display {
  padding: 0.5em;
}
.taglib-user-display .avatar {
  background: no-repeat center;
  background-size: 60px;
  display: block;
  height: 60px;
  margin: 0 auto;
  width: 60px;
}
.taglib-user-display .avatar.author:after {
  background: rgba(50, 168, 230, 0.5);
  border-radius: 50%;
  content: "";
  display: block;
  height: 100%;
  width: 100%;
}
.taglib-user-display .user-details {
  margin-top: 1em;
}
.taglib-user-display .user-name {
  font-size: 1.1em;
  font-weight: bold;
}
.taglib-user-display a .user-name {
  text-decoration: underline;
}
.taglib-user-display.display-style-1 .user-profile-image {
  float: left;
  margin-right: 24px;
}
.taglib-user-display.display-style-1 .user-name {
  display: inline-block;
  margin-top: 10px;
}
.taglib-user-display.display-style-1 .user-details {
  margin-top: 0;
}
.taglib-user-display.display-style-2 .user-profile-image,
.taglib-user-display.display-style-2 .user-name {
  clear: both;
  display: block;
  min-height: 20px;
  text-align: center;
}
.taglib-user-display.display-style-3 {
  padding: 0;
}
.taglib-user-display.display-style-3 .user-profile-image {
  display: inline-block;
  vertical-align: middle;
}

.taglib-workflow-status .workflow-id,
.taglib-workflow-status .workflow-version,
.taglib-workflow-status .workflow-status {
  color: #999;
}
.table-cell .taglib-workflow-status {
  margin: 0;
}
.table-cell .taglib-workflow-status .workflow-status {
  padding-left: 0;
}

.lfr-autocomplete-input-list .yui3-aclist-list {
  margin: 0;
}

.portal-popup .sheet > .lfr-nav {
  margin-top: -24px;
}
.portal-popup .contacts-portlet .portlet-configuration-container .form {
  position: static;
}
.portal-popup .lfr-form-content {
  padding: 24px 12px;
}
.portal-popup .portlet-body,
.portal-popup .portlet-boundary,
.portal-popup .portlet-column,
.portal-popup .portlet-layout {
  height: 100%;
}
.portal-popup .portlet-column {
  position: static;
}
.portal-popup .dialog-body > .container-fluid-max-xl,
.portal-popup .dialog-body .container-view,
.portal-popup .export-dialog-tree > .container-fluid-max-xl,
.portal-popup .export-dialog-tree .container-view,
.portal-popup .lfr-dynamic-uploader > .container-fluid-max-xl,
.portal-popup .lfr-dynamic-uploader .container-view,
.portal-popup .lfr-form-content > .container-fluid-max-xl,
.portal-popup .lfr-form-content .container-view,
.portal-popup .portlet-configuration-body-content > .container-fluid-max-xl,
.portal-popup .portlet-configuration-body-content .container-view,
.portal-popup .process-list > .container-fluid-max-xl,
.portal-popup .process-list .container-view,
.portal-popup .roles-selector-body > .container-fluid-max-xl,
.portal-popup .roles-selector-body .container-view {
  padding-top: 20px;
}
.portal-popup .dialog-body > .container-fluid-max-xl .nav-tabs-underline,
.portal-popup .dialog-body .container-view .nav-tabs-underline,
.portal-popup .export-dialog-tree > .container-fluid-max-xl .nav-tabs-underline,
.portal-popup .export-dialog-tree .container-view .nav-tabs-underline,
.portal-popup .lfr-dynamic-uploader > .container-fluid-max-xl .nav-tabs-underline,
.portal-popup .lfr-dynamic-uploader .container-view .nav-tabs-underline,
.portal-popup .lfr-form-content > .container-fluid-max-xl .nav-tabs-underline,
.portal-popup .lfr-form-content .container-view .nav-tabs-underline,
.portal-popup .portlet-configuration-body-content > .container-fluid-max-xl .nav-tabs-underline,
.portal-popup .portlet-configuration-body-content .container-view .nav-tabs-underline,
.portal-popup .process-list > .container-fluid-max-xl .nav-tabs-underline,
.portal-popup .process-list .container-view .nav-tabs-underline,
.portal-popup .roles-selector-body > .container-fluid-max-xl .nav-tabs-underline,
.portal-popup .roles-selector-body .container-view .nav-tabs-underline {
  margin-left: -15px;
  margin-right: -15px;
  margin-top: -20px;
}
.portal-popup .dialog-body > .lfr-nav + .container-fluid-max-xl,
.portal-popup .export-dialog-tree > .lfr-nav + .container-fluid-max-xl,
.portal-popup .lfr-dynamic-uploader > .lfr-nav + .container-fluid-max-xl,
.portal-popup .lfr-form-content > .lfr-nav + .container-fluid-max-xl,
.portal-popup .portlet-configuration-body-content > .lfr-nav + .container-fluid-max-xl,
.portal-popup .process-list > .lfr-nav + .container-fluid-max-xl,
.portal-popup .roles-selector-body > .lfr-nav + .container-fluid-max-xl {
  padding-top: 0;
}
.portal-popup .login-container {
  padding: 1rem;
}
.portal-popup .navbar ~ .portlet-configuration-setup,
.portal-popup .portlet-export-import-container {
  height: calc(100% - 48px);
  position: relative;
}
@media (min-width: 576px) {
  .portal-popup .navbar ~ .portlet-configuration-setup,
  .portal-popup .portlet-export-import-container {
    height: calc(100% - 48px);
  }
}
.portal-popup .panel-group .panel {
  border-left-width: 0;
  border-radius: 0;
  border-right-width: 0;
}
.portal-popup .panel-group .panel + .panel {
  border-top-width: 0;
  margin-top: 0;
}
.portal-popup .panel-heading {
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}
.portal-popup .portlet-configuration-setup .lfr-nav {
  margin-left: auto;
  margin-right: auto;
  max-width: 1280px;
  padding-left: 3px;
  padding-right: 3px;
}
@media (min-width: 576px) {
  .portal-popup .portlet-configuration-setup .lfr-nav {
    padding-left: 8px;
    padding-right: 8px;
  }
}
.portal-popup .lfr-dynamic-uploader,
.portal-popup .process-list {
  bottom: 0;
  display: block;
  left: 0;
  overflow: auto;
  position: absolute;
  right: 0;
  top: 48px;
  -webkit-overflow-scrolling: touch;
}
@media (min-width: 576px) {
  .portal-popup .lfr-dynamic-uploader,
  .portal-popup .process-list {
    top: 48px;
  }
}
.portal-popup .portlet-export-import-publish-processes {
  top: 0;
}
.portal-popup .dialog-footer {
  background-color: #fff;
  border-top: 1px solid #dee2e6;
  bottom: 0;
  display: flex;
  flex-direction: row-reverse;
  left: 0;
  margin: 0;
  padding: 10px 24px;
  width: 100%;
  z-index: 989;
}
@media (min-width: 768px) {
  .portal-popup .dialog-footer {
    position: fixed;
  }
}
.portal-popup .dialog-footer .btn {
  margin-left: 1rem;
  margin-right: 0;
}
.portal-popup .dialog-footer.dialog-footer-not-reverse {
  flex-direction: initial;
  justify-content: flex-end;
}
@media (min-width: 768px) {
  .portal-popup .dialog-body:not(:last-child),
  .portal-popup .lfr-dynamic-uploader:not(:last-child),
  .portal-popup .lfr-form-content:not(:last-child),
  .portal-popup .portlet-configuration-body-content:not(:last-child),
  .portal-popup .roles-selector-body:not(:last-child) {
    padding-bottom: 60px;
  }
}
.portal-popup .lfr-dynamic-uploader {
  display: table;
  table-layout: fixed;
  width: 100%;
}
.portal-popup .lfr-dynamic-uploader.hide-dialog-footer {
  bottom: 0;
}
.portal-popup .lfr-dynamic-uploader.hide-dialog-footer + .dialog-footer {
  display: none;
}
.portal-popup .portlet-configuration-edit-permissions .portlet-configuration-body-content {
  display: flex;
  flex-direction: column;
  overflow: visible;
}
.portal-popup .portlet-configuration-edit-permissions .portlet-configuration-body-content > form {
  flex-grow: 1;
  max-width: none;
  overflow: auto;
}
.portal-popup .portlet-configuration-edit-templates .portlet-configuration-body-content {
  bottom: 0;
}
.portal-popup:not(.article-preview) #main-content,
.portal-popup:not(.article-preview) #wrapper {
  bottom: 0;
  left: 0;
  overflow: auto;
  padding: 0;
  position: absolute;
  right: 0;
  top: 0;
  -webkit-overflow-scrolling: touch;
}
@media print {
  .portal-popup:not(.article-preview) #main-content,
  .portal-popup:not(.article-preview) #wrapper {
    position: initial;
  }
}
.portal-popup .columns-max > .portlet-layout.row {
  margin-left: 0;
  margin-right: 0;
}
.portal-popup .columns-max > .portlet-layout.row > .portlet-column {
  padding-left: 0;
  padding-right: 0;
}

html:not(#__):not(#___) .portlet-layout.dragging {
  border-collapse: separate;
}
html:not(#__):not(#___) .drop-area {
  background-color: #d3dadd;
}
html:not(#__):not(#___) .active-area {
  background: #ffc;
}
html:not(#__):not(#___) .portlet-boundary.yui3-dd-dragging {
  opacity: 0.6;
}
html:not(#__):not(#___) .portlet-boundary.yui3-dd-dragging .portlet {
  border: 2px dashed #ccc;
}
html:not(#__):not(#___) .sortable-layout-proxy {
  opacity: 1;
}
html:not(#__):not(#___) .sortable-layout-proxy .portlet-topper {
  background-image: none;
}
html:not(#__):not(#___) .proxy {
  cursor: move;
  opacity: 0.65;
  position: absolute;
}
html:not(#__):not(#___) .proxy.generic-portlet {
  height: 200px;
  width: 300px;
}
html:not(#__):not(#___) .proxy.generic-portlet .portlet-title {
  padding: 10px;
}
html:not(#__):not(#___) .proxy.not-intersecting .forbidden-action {
  background: url(../images/application/forbidden_action.png) no-repeat;
  display: block;
  height: 32px;
  position: absolute;
  right: -15px;
  top: -15px;
  width: 32px;
}
html:not(#__):not(#___) .resizable-proxy {
  border: 1px dashed #828f95;
  position: absolute;
  visibility: hidden;
}
html:not(#__):not(#___) .sortable-proxy {
  background: #727c81;
  margin-top: 1px;
}
html:not(#__):not(#___) .sortable-layout-drag-target-indicator {
  margin: 2px 0;
}
html:not(#__):not(#___) .yui3-dd-proxy {
  z-index: 1110 !important;
}

.portlet-layout.dragging {
  border-collapse: separate;
}

.drop-area {
  background-color: #d3dadd;
}

.active-area {
  background: #ffc;
}

.portlet-boundary.yui3-dd-dragging {
  opacity: 0.6;
  transform: scale(0.8);
  transition: transform 0.3s ease;
}
@media (prefers-reduced-motion: reduce) {
  .portlet-boundary.yui3-dd-dragging {
    transition: none;
  }
}
.c-prefers-reduced-motion .portlet-boundary.yui3-dd-dragging {
  transition: none;
}
.portlet-boundary.yui3-dd-dragging .portlet {
  border: 2px dashed #ccc;
}

.sortable-layout-proxy {
  opacity: 1;
}
.sortable-layout-proxy .portlet-topper {
  background-image: none;
}

.proxy {
  cursor: move;
  opacity: 0.65;
  position: absolute;
}
.proxy.generic-portlet {
  height: 200px;
  width: 300px;
}
.proxy.generic-portlet .portlet-title {
  padding: 10px;
}
.proxy.not-intersecting .forbidden-action {
  background: url(../images/application/forbidden_action.png) no-repeat;
  display: block;
  height: 32px;
  position: absolute;
  right: -15px;
  top: -15px;
  width: 32px;
}

.resizable-proxy {
  border: 1px dashed #828f95;
  position: absolute;
  visibility: hidden;
}

.sortable-proxy {
  background: #727c81;
  margin-top: 1px;
}

.sortable-layout-drag-target-indicator {
  margin: 2px 0;
}

.yui3-dd-proxy {
  z-index: 1110 !important;
}

.portlet-column-content.empty {
  padding: 50px;
}

.lfr-portlet-title-editable {
  margin-top: 0;
  z-index: 9999;
}
.lfr-portlet-title-editable .lfr-portlet-title-editable-content {
  padding: 0;
}
.lfr-portlet-title-editable .lfr-portlet-title-editable-content .field-input {
  margin-bottom: 0;
}
.lfr-portlet-title-editable .lfr-portlet-title-editable-content .textfield-label {
  display: none;
}
.lfr-portlet-title-editable .lfr-portlet-title-editable-content .btn-toolbar-content {
  display: inline-block;
  vertical-align: bottom;
}
.lfr-portlet-title-editable .lfr-portlet-title-editable-content .btn-group {
  margin-top: 0;
}
.lfr-portlet-title-editable .lfr-portlet-title-editable-content .btn {
  display: inline-block;
  float: none;
  margin-top: 0;
  width: auto;
}

.lfr-source-editor {
  border: solid 0 #ccc;
  border-bottom-width: 2px;
  position: relative;
}
.lfr-source-editor .ace_editor {
  height: 100%;
}
.lfr-source-editor .lfr-source-editor-toolbar li > .btn {
  background-color: #fff;
  border: transparent;
  color: #717383;
  outline: 0;
}
.lfr-source-editor .lfr-source-editor-code {
  background-color: #fff;
  color: #2b4259;
}
.lfr-source-editor .lfr-source-editor-code .ace_gutter {
  background-color: #ededef;
  color: #868896;
  overflow: hidden;
}
.lfr-source-editor .lfr-source-editor-code .ace_gutter .ace_fold-widget {
  font-family: fontawesome-alloy;
  text-align: center;
  vertical-align: middle;
}
.lfr-source-editor .lfr-source-editor-code .ace_gutter .ace_fold-widget.ace_open, .lfr-source-editor .lfr-source-editor-code .ace_gutter .ace_fold-widget.ace_closed {
  background-image: none;
}
.lfr-source-editor .lfr-source-editor-code .ace_gutter .ace_fold-widget.ace_open:before {
  content: "▾";
}
.lfr-source-editor .lfr-source-editor-code .ace_gutter .ace_fold-widget.ace_closed:before {
  content: "▸";
}
.lfr-source-editor .lfr-source-editor-code .ace_gutter .ace_gutter-active-cell {
  color: #fff;
}
.lfr-source-editor .lfr-source-editor-code .ace_gutter .ace_gutter-active-line {
  background-color: #717383;
}
.lfr-source-editor .lfr-source-editor-code .ace_gutter .ace_gutter-layer {
  border-right: solid 1px #ccc;
}
.lfr-source-editor .lfr-source-editor-code .ace_gutter .ace_info {
  background-image: none;
}
.lfr-source-editor .lfr-source-editor-code .ace_content .ace_active-line {
  background-color: #ededef;
}
.lfr-source-editor .lfr-source-editor-code .ace_content .ace_constant {
  color: #34adab;
}
.lfr-source-editor .lfr-source-editor-code .ace_content .ace_tag {
  color: #1d5ec7;
}
.lfr-source-editor .lfr-source-editor-code .ace_content .ace_string {
  color: #ff6c58;
}
.lfr-source-editor .lfr-source-editor-code .ace_content .ace_string.ace_regex {
  color: #f00;
}
.lfr-source-editor.ace_dark .lfr-source-editor-code {
  background-color: #47474f;
  color: #fff;
}
.lfr-source-editor.ace_dark .lfr-source-editor-code .ace_gutter {
  background: #54555e;
  color: #fff;
}
.lfr-source-editor.ace_dark .lfr-source-editor-code .ace_gutter .ace_gutter-active-line {
  background-color: #009aed;
}
.lfr-source-editor.ace_dark .lfr-source-editor-code .ace_content .ace_active-line {
  background-color: #11394e;
}
.lfr-source-editor.ace_dark .lfr-source-editor-code .ace_content .ace_cursor {
  color: #fff;
}
.lfr-source-editor.ace_dark .lfr-source-editor-code .ace_content .ace_tag {
  color: #4d91ff;
}

.lfr-fullscreen-source-editor {
  height: 100%;
  overflow: hidden;
}
.lfr-fullscreen-source-editor .lfr-fullscreen-source-editor-header {
  height: 40px;
  margin-right: 4px;
  margin-top: 4px;
  min-height: 40px;
}
.lfr-fullscreen-source-editor .lfr-fullscreen-source-editor-content {
  height: 95%;
  position: relative;
}
.lfr-fullscreen-source-editor .lfr-fullscreen-source-editor-content .panel-splitter {
  border: 1px solid #ccc;
  position: absolute;
}
.lfr-fullscreen-source-editor .lfr-fullscreen-source-editor-content .preview-panel {
  display: inline-block;
  overflow-y: auto;
  padding-left: 20px;
}
.lfr-fullscreen-source-editor .lfr-fullscreen-source-editor-content .source-panel {
  display: inline-block;
}
.lfr-fullscreen-source-editor .lfr-fullscreen-source-editor-content.vertical .source-panel,
.lfr-fullscreen-source-editor .lfr-fullscreen-source-editor-content.vertical .preview-panel {
  height: 100%;
  width: 50%;
}
.lfr-fullscreen-source-editor .lfr-fullscreen-source-editor-content.vertical .panel-splitter {
  height: 100%;
  left: 50%;
  top: 0;
}
.lfr-fullscreen-source-editor .lfr-fullscreen-source-editor-content.horizontal .source-panel,
.lfr-fullscreen-source-editor .lfr-fullscreen-source-editor-content.horizontal .preview-panel {
  height: 50%;
  width: 100%;
}
.lfr-fullscreen-source-editor .lfr-fullscreen-source-editor-content.horizontal .panel-splitter {
  top: 50%;
  width: 100%;
}
.lfr-fullscreen-source-editor .lfr-fullscreen-source-editor-content.simple .panel-splitter,
.lfr-fullscreen-source-editor .lfr-fullscreen-source-editor-content.simple .preview-panel {
  display: none;
}
.lfr-fullscreen-source-editor .lfr-fullscreen-source-editor-content.simple .source-panel {
  height: 100%;
  width: 100%;
}

.lfr-fulscreen-source-editor-dialog .modal-footer {
  text-align: left;
}

.file-icon-color-0 {
  background-color: #fff;
  color: #6c757d;
}

.file-icon-color-1 {
  background-color: #fff;
  color: #6c757d;
}

.file-icon-color-2 {
  background-color: #fff;
  color: #24a892;
}

.file-icon-color-3 {
  background-color: #fff;
  color: #ff4d4d;
}

.file-icon-color-4 {
  background-color: #fff;
  color: #ff6200;
}

.file-icon-color-5 {
  background-color: #fff;
  color: #bf66ff;
}

.file-icon-color-6 {
  background-color: #fff;
  color: #0099e6;
}

.file-icon-color-7 {
  background-color: #fff;
  color: #ff4db2;
}

.lfr-item-viewer.uploading > div:not(.progress-container) {
  opacity: 0.3;
}
.lfr-item-viewer.uploading > .progress-container {
  visibility: visible;
}
.lfr-item-viewer .aspect-ratio a.item-preview {
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
  height: 100%;
  position: absolute;
  width: 100%;
}
.lfr-item-viewer .image-viewer-base-image-list {
  padding-top: 35px;
}
.lfr-item-viewer .item-preview:hover {
  cursor: pointer;
}
.lfr-item-viewer .progress-container {
  background-color: #fff;
  left: 0;
  margin: 0 auto;
  padding: 20px 30px;
  position: absolute;
  right: 0;
  text-align: center;
  top: 50%;
  transform: translateY(-50%);
  visibility: hidden;
  width: 80%;
  z-index: 1000;
}
.lfr-item-viewer .progress-container a {
  position: absolute;
  right: 30px;
}
.lfr-item-viewer .progress-container .progress {
  margin-top: 10px;
}
.lfr-item-viewer .search-info {
  background-color: #d3e8f1;
}
.lfr-item-viewer .search-info .keywords {
  font-size: 1.4em;
  font-weight: bold;
}
.lfr-item-viewer .search-info .change-search-folder {
  font-size: 0.8em;
  font-weight: normal;
}
.lfr-item-viewer .upload-view {
  display: table;
  height: 400px;
  margin-top: 20px;
  width: 100%;
}
.lfr-item-viewer .upload-view > div {
  display: table-cell;
  vertical-align: middle;
}
.lfr-item-viewer .yui3-widget-bd {
  position: relative;
}

.lfr-menu-expanded li a:focus {
  background-color: #5b677d;
  color: #fff;
  text-shadow: -1px -1px #2c2f34;
}

.lfr-url-error {
  display: inline-block;
  white-space: normal;
  overflow-wrap: break-all;
  word-wrap: break-all;
}

.lfr-page-layouts {
  padding: 0;
}
.lfr-page-layouts input[type=radio] {
  opacity: 0;
  position: absolute;
}
.lfr-page-layouts input[type=radio]:checked + .card-horizontal {
  cursor: default;
}
.lfr-page-layouts input[type=radio]:checked + .card-horizontal::after {
  bottom: calc(0.0625rem * -1);
  content: "";
  left: calc(0.0625rem * -1);
  position: absolute;
  right: calc(0.0625rem * -1);
  transition: height 0.15s ease-out;
}
@media (prefers-reduced-motion: reduce) {
  .lfr-page-layouts input[type=radio]:checked + .card-horizontal::after {
    transition: none;
  }
}
.lfr-page-layouts input[type=radio]:checked + .card-horizontal::after {
  transition: none;
}

.lfr-page-layouts .card-horizontal {
  cursor: pointer;
  outline: 0;
  transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}
@media (prefers-reduced-motion: reduce) {
  .lfr-page-layouts .card-horizontal {
    transition: none;
  }
}
.lfr-page-layouts .card-horizontal {
  transition: none;
}

.lfr-page-layouts .card-horizontal::after {
  border-radius: 0rem 0rem 0.25rem 0.25rem;
  bottom: calc(0.0625rem * -1);
  content: "";
  height: 0rem;
  left: calc(0.0625rem * -1);
  position: absolute;
  right: calc(0.0625rem * -1);
  transition: height 0.15s ease-out;
}
@media (prefers-reduced-motion: reduce) {
  .lfr-page-layouts .card-horizontal::after {
    transition: none;
  }
}
.lfr-page-layouts .card-horizontal::after {
  transition: none;
}

.modal-body.dialog-iframe-bd {
  overflow: hidden;
  padding: 0;
}

.modal-dialog:not(.dialog-iframe-modal):not(.modal-full-screen) {
  position: relative;
}
.modal-dialog.dialog-iframe-modal {
  max-width: none;
}
.modal-dialog.modal-dialog-sm {
  max-width: 500px;
}
.modal-dialog .yui3-resize-handles-wrapper {
  pointer-events: all;
}
.modal-dialog .yui3-resize-handles-wrapper .yui3-resize-handle-inner-br {
  bottom: 0;
  right: 0;
}

.modal-open .modal {
  display: block;
}

.sheet > .panel-group .sheet-footer {
  margin-bottom: 0;
}

.sheet-footer .btn {
  margin-right: calc(1rem * 0.5);
}
.sheet-footer .btn:last-child {
  margin-right: 0;
}

.tag-items {
  list-style: none;
  margin: 0 1em 0 0;
  padding: 0 1em 0.5em;
  white-space: normal;
}
.tag-items li {
  display: inline-block;
  margin: 0 1em 0 0;
  max-width: 100%;
}

.tag-selected {
  color: #000;
  font-weight: bold;
  text-decoration: none;
}

.tag-cloud .tag-popularity-1 {
  font-size: 1em;
}
.tag-cloud .tag-popularity-2 {
  font-size: 1.3em;
}
.tag-cloud .tag-popularity-3 {
  font-size: 1.6em;
}
.tag-cloud .tag-popularity-4 {
  font-size: 1.9em;
}
.tag-cloud .tag-popularity-5 {
  font-size: 2.2em;
}
.tag-cloud .tag-popularity-6 {
  font-size: 2.5em;
}

.lfr-portal-tooltip {
  display: inline-flex;
}
.lfr-portal-tooltip,
.lfr-portal-tooltip a {
  -webkit-touch-callout: none;
  -moz-user-select: none;
  -ms-user-select: none;
  -webkit-user-select: none;
  user-select: none;
}

.tree-node .icon-check {
  padding-right: 2px;
}
.tree-node .tree-node-checked .icon-check {
  padding-right: 0;
}
.tree-node [class^=icon-] {
  margin-right: 5px;
}
.tree-node .tree-node-checkbox-container {
  margin-right: 0;
}
.tree-node .tree-node-selected .tree-label {
  background: none;
}

.tree-node-content .tree-hitarea {
  color: #999;
  font-size: 10px;
  padding-right: 6px;
}
.tree-node-content .tree-label {
  margin-left: 3px;
}
.tree-node-content .tree-node-hidden-hitarea {
  visibility: hidden;
}

.tree-node-selected .tree-label {
  background-color: transparent;
}

.tree-view li.tree-node .tree-node-content svg.lexicon-icon {
  pointer-events: none;
}

.user-icon-color-0 {
  background-color: #fff;
  box-shadow: 0 0 0 1px #dee2e6;
  color: #6c757d;
}

.user-icon-color-1 {
  background-color: #fff;
  box-shadow: 0 0 0 1px #dee2e6;
  color: #66abff;
}

.user-icon-color-2 {
  background-color: #fff;
  box-shadow: 0 0 0 1px #dee2e6;
  color: #ff6200;
}

.user-icon-color-3 {
  background-color: #fff;
  box-shadow: 0 0 0 1px #dee2e6;
  color: #ff4d4d;
}

.user-icon-color-4 {
  background-color: #fff;
  box-shadow: 0 0 0 1px #dee2e6;
  color: #24a892;
}

.user-icon-color-5 {
  background-color: #fff;
  box-shadow: 0 0 0 1px #dee2e6;
  color: #ff4db2;
}

.user-icon-color-6 {
  background-color: #fff;
  box-shadow: 0 0 0 1px #dee2e6;
  color: #53a117;
}

.user-icon-color-7 {
  background-color: #fff;
  box-shadow: 0 0 0 1px #dee2e6;
  color: #bf66ff;
}

.user-icon-color-8 {
  background-color: #fff;
  box-shadow: 0 0 0 1px #dee2e6;
  color: #b38900;
}

.user-icon-color-9 {
  background-color: #fff;
  box-shadow: 0 0 0 1px #dee2e6;
  color: #0099e6;
}

.collapse.open {
  display: block;
}

.navbar-toggler-icon {
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20viewBox='0%200%2016%2016'%20xmlns='http://www.w3.org/2000/svg'%3E%3Cpath%20class='lexicon-icon-outline'%20d='M15%203H1a1%201%200%200%201%200-2h14a1%201%200%200%201%200%202Zm0%206H1a1%201%200%200%201%200-2h14a1%201%200%200%201%200%202ZM1%2015h14a1%201%200%200%200%200-2H1a1%201%200%200%200%200%202Z'%20fill='%23212529'/%3E%3C/svg%3E");
  height: 1em;
  width: 1em;
}

.navbar-nav .nav-item.hover:after {
  bottom: -0.125rem;
  content: "";
  height: 0.125rem;
  left: 0;
  position: absolute;
  width: 100%;
}

.navbar .navbar-toggler .c-inner {
  max-width: none;
}

html:not(#__):not(#___) .cadmin.portlet-topper {
  position: relative;
}
html:not(#__):not(#___) .cadmin.portlet-topper .portlet-topper-toolbar .portlet-icon-back {
  background: url(../images/arrows/12_left.png) no-repeat 0 50%;
  padding: 5px 5px 5px 18px;
}
html:not(#__):not(#___) .cadmin.portlet-topper .portlet-topper-toolbar .portlet-options .lfr-icon-menu-text {
  display: none;
}
html:not(#__):not(#___) .cadmin .component-action.portlet-options {
  color: white;
}

body.portlet {
  border-width: 0;
}

.portlet-icon-back {
  margin-top: -2px;
}
.portlet-topper .portlet-topper-toolbar .portlet-icon-back {
  background: url(../images/arrows/12_left.png) no-repeat 0 50%;
  padding: 5px 5px 5px 18px;
}

.portlet-options-dropdown {
  z-index: 1035;
}

.portlet-topper {
  position: relative;
}
.portlet-topper .portlet-topper-toolbar .portlet-options .lfr-icon-menu-text {
  display: none;
}
.portlet-draggable .portlet-topper {
  cursor: move;
}

.portlet-title-editable {
  cursor: pointer;
}

.portlet-title-text {
  display: inline-block;
  margin-top: 0;
  max-width: 95%;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: top;
  white-space: nowrap;
}
.panel-page-body .portlet-title-text, .panel-page-content .portlet-title-text {
  cursor: auto;
}

.portlet-minimized .portlet-content {
  padding: 0;
}

.portlet-nested-portlets .portlet-boundary {
  left: 0 !important;
  position: relative !important;
  top: 0 !important;
}

.portlet-layout .portlet-header {
  margin-bottom: calc(1rem);
}

@media (min-width: 576px) {
  .portlet .visible-interaction {
    display: none;
  }
}
@media (max-width: 767.98px) {
  .controls-hidden .portlet .visible-interaction {
    display: none;
  }
}
.portlet:hover .visible-interaction, .portlet.open .visible-interaction, .portlet.focus .visible-interaction {
  display: block;
}

.controls-hidden .lfr-meta-actions,
.controls-hidden .lfr-configurator-visibility {
  display: none;
}
.controls-hidden .portlet-title-editable {
  pointer-events: none;
}
.controls-hidden .portlet-topper {
  display: none !important;
}
.controls-hidden .portlet-topper-toolbar {
  display: none !important;
}

html:not(#__):not(#___) .cadmin.portlet-topper {
  background-color: #f7f7f7;
  border-color: transparent;
  border-radius: 0 0;
  border-style: solid;
  border-width: 1px 1px 1px 1px;
  color: rgba(0, 0, 0, 0.5);
  display: box;
  display: flex;
  height: 28px;
  padding: 3px 12px 3px 24px;
  position: relative;
}
html:not(#__):not(#___) .cadmin.portlet-topper .lexicon-icon {
  height: 12px;
  width: 12px;
}
html:not(#__):not(#___) .cadmin.portlet-topper .lexicon-icon.lexicon-icon-drag {
  height: 16px;
  width: 16px;
}
html:not(#__):not(#___) .portlet > .cadmin.portlet-topper {
  display: none;
}
@media (min-width: 768px) {
  html:not(#__):not(#___) .portlet > .cadmin.portlet-topper {
    display: flex;
    left: 0;
    opacity: 0;
    position: absolute;
    right: 0;
    transform: translateY(-97%);
    transition: opacity 0.15s;
    top: 0;
  }
}
@media (min-width: 768px) and (prefers-reduced-motion: reduce) {
  html:not(#__):not(#___) .portlet > .cadmin.portlet-topper {
    transition: none;
  }
}
@media (min-width: 768px) {
  html:not(#__):not(#___) .portlet > .c-prefers-reduced-motion .cadmin.portlet-topper {
    transition: none;
  }
}
html:not(#__):not(#___) .cadmin .portlet-actions {
  float: right;
}
html:not(#__):not(#___) .cadmin .portlet-options {
  display: inline-block;
}
html:not(#__):not(#___) .cadmin .portlet-title-menu {
  flex: 0 1 auto;
}
html:not(#__):not(#___) .cadmin .portlet-title-menu > span > a {
  display: inline-block;
  text-decoration: none;
}
html:not(#__):not(#___) .cadmin .portlet-topper-toolbar {
  margin: 0;
  padding-left: 0;
}
html:not(#__):not(#___) .cadmin .portlet-topper-toolbar > a,
html:not(#__):not(#___) .cadmin .portlet-topper-toolbar > span > a,
html:not(#__):not(#___) .cadmin .portlet-topper-toolbar .lfr-icon-menu > a {
  color: rgba(0, 0, 0, 0.5);
}
html:not(#__):not(#___) .cadmin .portlet-topper-toolbar > a:focus, html:not(#__):not(#___) .cadmin .portlet-topper-toolbar > a:hover {
  text-decoration: none;
}
html:not(#__):not(#___) .cadmin .portlet-name-text {
  font-size: 12px;
  font-weight: 600;
  margin-left: 4px;
}
html:not(#__):not(#___) .cadmin .portlet-title-default {
  flex: 1 1 auto;
  line-height: 2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
@media (min-width: 576px) {
  html:not(#__):not(#___) .lfr-configurator-visibility .portlet:hover .portlet-topper, html:not(#__):not(#___) .lfr-configurator-visibility .portlet.focus .portlet-topper, html:not(#__):not(#___) .lfr-configurator-visibility .portlet.open .portlet-topper {
    opacity: 0.5;
  }
}
@media (min-width: 768px) {
  html:not(#__):not(#___) .controls-visible .portlet:hover > .portlet-content-editable, html:not(#__):not(#___) .controls-visible .portlet.open > .portlet-content-editable, html:not(#__):not(#___) .controls-visible .portlet.focus > .portlet-content-editable {
    border-color: transparent;
    border-top-left-radius: 0;
    border-top-right-radius: 0;
  }
}
@media (min-width: 768px) {
  html:not(#__):not(#___) .controls-visible .portlet:hover > .cadmin.portlet-topper, html:not(#__):not(#___) .controls-visible .portlet.open > .cadmin.portlet-topper, html:not(#__):not(#___) .controls-visible .portlet.focus > .cadmin.portlet-topper {
    opacity: 1;
  }
}
@media (min-width: 768px) {
  html:not(#__):not(#___) .controls-visible .portlet.open > .cadmin.portlet-topper {
    transition-duration: 0ms;
  }
}
@media (max-width: 767.98px) {
  html:not(#__):not(#___) .controls-visible .cadmin.portlet-topper {
    align-items: center;
    display: box;
    display: flex;
  }
}
html:not(#__):not(#___) .controls-visible .cadmin .portlet-topper-toolbar {
  display: block;
}

.portlet {
  margin-bottom: 10px;
  position: relative;
}
@media (min-width: 768px) {
  .controls-visible .portlet:hover > .portlet-content-editable, .controls-visible .portlet.open > .portlet-content-editable, .controls-visible .portlet.focus > .portlet-content-editable {
    border-color: transparent;
    border-top-left-radius: 0;
    border-top-right-radius: 0;
  }
}
@media (min-width: 768px) {
  .controls-visible .portlet:hover > .portlet-topper, .controls-visible .portlet.open > .portlet-topper, .controls-visible .portlet.focus > .portlet-topper {
    opacity: 1;
  }
}
@media (min-width: 576px) {
  .lfr-configurator-visibility .portlet:hover .portlet-topper, .lfr-configurator-visibility .portlet.focus .portlet-topper, .lfr-configurator-visibility .portlet.open .portlet-topper {
    opacity: 0.5;
  }
}

.portlet-content-editable {
  border-color: transparent;
  border-radius: 0 0;
  border-style: solid;
  border-width: 2px 2px 2px 2px;
  transition: border-color 0.15s ease;
}
.portlet > .portlet-content-editable {
  border-color: transparent;
}
@media (max-width: 767.98px) {
  .controls-visible .portlet-content-editable {
    border-color: transparent;
    border-top-left-radius: 0;
    border-top-right-radius: 0;
  }
}

.portlet-options {
  display: inline-block;
}

.portlet-title-default {
  flex: 1 1 auto;
  line-height: 2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.portlet-title-menu {
  flex: 0 1 auto;
}
.portlet-title-menu > span > a {
  display: inline-block;
  text-decoration: none;
}

.portlet-topper {
  background-color: #f7f7f7;
  border-color: transparent;
  border-radius: 0 0;
  border-style: solid;
  border-width: 1px 1px 1px 1px;
  color: rgba(0, 0, 0, 0.5);
  display: box;
  display: flex;
  padding: 3px 12px 3px 24px;
  position: relative;
}
.portlet > .portlet-topper {
  display: none;
}
@media (min-width: 768px) {
  .portlet > .portlet-topper {
    display: flex;
    left: 0;
    opacity: 0;
    position: absolute;
    right: 0;
    transition: opacity 0.15s;
    top: 0;
  }
}
@media (min-width: 768px) and (prefers-reduced-motion: reduce) {
  .portlet > .portlet-topper {
    transition: none;
  }
}
@media (min-width: 768px) {
  .portlet > .portlet-topper {
    transition: none;
  }
}
@media (max-width: 767.98px) {
  .controls-visible .portlet-topper {
    display: box;
    display: flex;
  }
}

.portlet-topper-toolbar {
  margin: 0;
  padding-left: 0;
}
.portlet-topper-toolbar > a,
.portlet-topper-toolbar > span > a,
.portlet-topper-toolbar .lfr-icon-menu > a {
  color: rgba(0, 0, 0, 0.5);
}
.portlet-topper-toolbar > a:focus, .portlet-topper-toolbar > a:hover {
  text-decoration: none;
}
.controls-visible .portlet-topper-toolbar {
  display: block;
}

.lfr-panel-page .portlet-title {
  font-size: 13px;
}

.portlet-borderless .portlet-content {
  padding: calc(1rem);
}
.portlet-decorate .portlet-content {
  background: #fff;
  border-color: transparent;
  border-style: solid;
  border-width: 2px 2px 2px 2px;
  padding: calc(1rem);
  word-wrap: break-word;
}
.portlet-barebone .portlet-content {
  padding: 0;
}

.portlet-dynamic-data-lists-display .lfr-ddm-field-group,
.portlet-dynamic-data-lists .lfr-ddm-field-group {
  margin-bottom: 10px;
  margin-top: 10px;
  padding: 28px 24px;
}

.breadcrumb.breadcrumb-vertical {
  display: inline-block;
  text-align: center;
}
.breadcrumb.breadcrumb-vertical li {
  display: block;
}
.breadcrumb.breadcrumb-vertical li.last, .breadcrumb.breadcrumb-vertical li.only {
  background: none;
}
.breadcrumb.breadcrumb-vertical .divider {
  background: url(../images/arrows/07_down.png) no-repeat 50% 100%;
  display: block;
  height: 10px;
  overflow: hidden;
  text-indent: 101%;
  white-space: nowrap;
}

.navbar form {
  margin: 0;
}

:not(.inline-item) > .loading-animation {
  margin-bottom: 20px;
  margin-top: 20px;
}
.product-menu .loading-animation {
  margin-top: 160px;
}

@keyframes lfr-drop-active {
  0% {
    background-color: #ebebeb;
    border-color: #ddd;
  }
  50% {
    background-color: #ddedde;
    border-color: #7d7;
    transform: scale(1.1);
  }
  75% {
    background-color: #ddedde;
    border-color: #7d7;
  }
  100% {
    background-color: #ebebeb;
    border-color: #ddd;
  }
}
.lfr-upload-container .progress-bar,
.lfr-upload-container .progress {
  border-radius: 10px;
}
.lfr-upload-container .upload-file,
.lfr-upload-container .upload-target {
  border-radius: 5px;
}
.upload-drop-active .lfr-upload-container .upload-target {
  animation: none;
}
.upload-drop-intent .lfr-upload-container .upload-target {
  animation: lfr-drop-active 1s ease 0.2s infinite;
}

.select-files {
  border-radius: 5px;
}

.taglib-form-navigator > .form-steps > ul.form-navigator.list-group {
  box-shadow: none;
}
.taglib-form-navigator > .form-steps > ul.form-navigator.list-group .tab .tab-label:hover .number, .taglib-form-navigator > .form-steps > ul.form-navigator.list-group .tab .tab-label:focus .number {
  box-shadow: 0 0 5px 0 #333;
  transition-duration: 0.25s;
  transition-property: box-shadow;
  transition-timing-function: ease-out;
}
.taglib-form-navigator > .form-steps > ul.form-navigator.list-group .tab .tab-label .number {
  border-radius: 50%;
}

@keyframes progress-bar-stripes {
  from {
    background-position: 40px 0;
  }
  to {
    background-position: 0 0;
  }
}
.lfr-progress-active .progress-bar-status,
.lfr-upload-container .file-uploading .progress-bar .progress {
  animation: progress-bar-stripes 0.5s linear infinite;
  background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.3) 25%, rgba(255, 255, 255, 0) 25%, rgba(255, 255, 255, 0) 50%, rgba(255, 255, 255, 0.3) 50%, rgba(255, 255, 255, 0.3) 75%, rgba(255, 255, 255, 0) 75%, rgba(255, 255, 255, 0));
  background-size: 40px 40px;
  transition: width, 0.5s, ease-out;
}
@media (prefers-reduced-motion: reduce) {
  .lfr-progress-active .progress-bar-status,
  .lfr-upload-container .file-uploading .progress-bar .progress {
    transition: none;
  }
}
.c-prefers-reduced-motion .lfr-progress-active .progress-bar-status,
.c-prefers-reduced-motion .lfr-upload-container .file-uploading .progress-bar .progress {
  transition: none;
}

@keyframes highlight-animation {
  from {
    background-color: #ffc;
  }
  to {
    background-color: transparent;
  }
}
.highlight-animation {
  animation: highlight-animation 0.7s;
}

.portlet-options.btn-group .dropdown-toggle, .portlet-options.btn-group.open .dropdown-toggle {
  box-shadow: none;
}

.form-group.form-inline.input-boolean-wrapper label, .form-group.form-inline.input-checkbox-wrapper label {
  gap: 0.3125rem;
}

/* ─────────────────────────────────────────────────────────────────────────────
   Harf theme — custom CSS.

   This file carries ONLY what must load once per page and cannot live in a
   fragment or the Stylebook:

     1. @font-face for the self-hosted DGA font families   (step 2)
     2. the DGA Platform Code component classes, delayered (step 3)

   It deliberately does NOT carry design tokens. The 204 --ddga-* custom properties
   belong to the Stylebook, which is the single source of truth for design
   (README §17 directive 1 / directive 11).

   ⚠ LOAD ORDER IS LOAD-BEARING. This file compiles into css/main.css AFTER Clay,
   so the unlayered DGA rules below win ties against Clay on source order. Liferay's
   Clay and classic-theme CSS carry no @layer at all, and unlayered CSS beats layered
   CSS regardless of specificity — which is why nothing here may be wrapped in
   @layer. Enforced by scripts/check-theme-css-order.sh.
   ──────────────────────────────────────────────────────────────────────────── */
/* ═══════════════════════════════════════════════════════════════════════════
   1. FONTS — self-hosted, subsetted, upright only
   ═══════════════════════════════════════════════════════════════════════════

   Why self-hosted: loading from Google's CDN is not acceptable for a Saudi
   government network posture. These files are served from this theme.

   Why subsetted: the full families are ~1.4 MB of TTF. Subsetting to the Arabic
   + Latin ranges and encoding as woff2 brings all six faces to 288 KB total.
   Arabic shaping is preserved — init/medi/fina/rlig/liga/calt all survive
   (verified: subsetting dropped zero features from IBM Plex Sans Arabic).

   Why upright only: neither family ships an italic Arabic face, so every
   `font-style: italic` would be synthetic oblique. On connected Arabic script
   that looks wrong, so the italic declarations are being removed at source
   rather than faked here.

   Weights map to the DGA tokens actually used across the app:
     400 --ddga-font-weight-regular    500 --ddga-font-weight-medium
     600 --ddga-font-weight-semibold   700 --ddga-font-weight-bold

   IBM Plex Mono is deliberately NOT here: --ddga-font-mono is never referenced,
   and the single monospace declaration in the app uses the system stack. */
@font-face {
  font-family: "IBM Plex Sans Arabic";
  src: url("../fonts/IBMPlexSansArabic-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Sans Arabic";
  src: url("../fonts/IBMPlexSansArabic-Medium.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Sans Arabic";
  src: url("../fonts/IBMPlexSansArabic-SemiBold.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Sans Arabic";
  src: url("../fonts/IBMPlexSansArabic-Bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
/* Fallback family in the --ddga-font-ar stack, for glyphs IBM Plex lacks. Only
   400 and 700 are shipped: as a fallback it is rarely reached, and 500/600
   synthesise acceptably from 400 in that narrow case. */
@font-face {
  font-family: "Noto Sans Arabic";
  src: url("../fonts/NotoSansArabic-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Noto Sans Arabic";
  src: url("../fonts/NotoSansArabic-Bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
/* ═══════════════════════════════════════════════════════════════════════════
   2. DGA COMPONENT CLASSES
   ═══════════════════════════════════════════════════════════════════════════

   Generated by tools/dga-port/port-components.mjs from @dev-dga/css, with the
   `@layer ddga-components` wrapper stripped.

   ⚠ READ THIS BEFORE THE PER-IMPORT NOTES BELOW — GENERATORS REMOVED 2026-07-28.
   tools/dga-port/ was removed together with frontend-source/ (README §15). Every
   "re-run that script", "do not hand-edit", and "delete this line once <component>
   joins the COMPONENTS list" instruction in this section is therefore VOID as an
   instruction, and is kept only because it still explains WHY each partial looks the
   way it does. Concretely:
     · There is no script to re-run after an @dev-dga/css bump. Re-derive by hand from
       node_modules/@dev-dga/css/dist/ (root package.json pins 0.12.0; npm install).
     · The COMPONENTS allow-list no longer exists, so dga-date-controls and
       dga-admin-components will NEVER be folded into dga-components. Both imports
       below are PERMANENT — do not delete them waiting for a merge that cannot happen.
     · "Do not hand-edit the generated partial" now inverts: hand-editing is the ONLY
       way to change these files. Keep the @layer wrapper stripped when you do —
       scripts/check-theme-css-order.sh is the sole remaining backstop. */
/* ─────────────────────────────────────────────────────────────────────────────
   DGA semantic layer — GENERATED, DO NOT EDIT BY HAND.

   Source:    @dev-dga/css v0.12.0 (variables.css aliases + themes.css)
   Generator: tools/dga-port/port-tokens.mjs  ← REMOVED, see below

   ⚠ GENERATOR REMOVED 2026-07-28 — THIS FILE IS NOW HAND-MAINTAINED.
   tools/dga-port/ went with frontend-source/ (README §15), taking port-tokens.mjs
   and its token-coverage.json with it. "GENERATED, DO NOT EDIT BY HAND" above
   records how this file was ORIGINALLY produced — there is nothing left to re-run.
   This matters more here than elsewhere: the per-declaration trailing comments —
   the "light var(--ddga-brand-600) = #1b8354 → dark var(--ddga-brand-400) = #54c08a"
   notes beside each dark re-point — were emitted by a resolver that followed var()
   chains down to the literal they end at.
   Hand-edit a value and NOTHING will re-resolve or re-check that comment, so a stale
   comment can outlive the value it describes. Change a value and its comment together,
   reading both from node_modules/@dev-dga/css (variables.css for light, dark.css for
   dark). Per README §17.3 the dark primary is #54c08a, NOT the #1b8354 Figma shows.

   These 43 tokens are ALIASES — their value is var(--ddga-…), not a literal.
   A Style Book token holds a value that an editor widget edits; a ColorPicker cannot
   hold a reference. So the semantic layer lives here as CSS and resolves against the
   161 literal tokens the Style Book provides.

   ⚠ CONSEQUENCE: changing a semantic colour (e.g. which brand step --ddga-color-primary
   points at) requires a developer and a theme redeploy — it is NOT a Style Book edit.
   Only the 161 literal values below it are author-editable.

   Declared at :root to match the scope Liferay emits Style Book tokens into.
   Unlayered on purpose — see docs/reference/THEME-BUILD.md.
   ──────────────────────────────────────────────────────────────────────────── */
:root {
  --ddga-color-primary: var(--ddga-brand-600);
  --ddga-color-primary-hover: var(--ddga-brand-700);
  --ddga-color-primary-active: var(--ddga-brand-900);
  --ddga-color-secondary: var(--ddga-gray-100);
  --ddga-color-secondary-hover: var(--ddga-gray-200);
  --ddga-color-secondary-foreground: var(--ddga-gray-950);
  --ddga-color-foreground: var(--ddga-gray-950);
  --ddga-color-muted: var(--ddga-gray-100);
  --ddga-color-muted-foreground: var(--ddga-gray-500);
  --ddga-color-border: var(--ddga-gray-200);
  --ddga-color-input: var(--ddga-gray-300);
  /* Modal scrim — LIGHT. Added 2026-07-24 for the shared confirm dialog
   * (harf-overlays, spec 021). This is the FIRST modal in the platform, so no
   * scrim token existed; check-color-literals correctly rejected the rgb()
   * literal that was written into the fragment first. The token belongs here,
   * not in fragment CSS — directive 11: the Stylebook is the single source of
   * design truth. Figma does not define a scrim for the admin dialogs, so per
   * README §17.3 rule 2 (Figma silent → DGA authoritative) it is derived from
   * the DGA neutral ramp rather than invented. */
  --ddga-scrim: rgb(13 18 28 / 45%); /* var(--ddga-gray-950) at 45% */
  --ddga-color-card-foreground: var(--ddga-gray-950);
  --ddga-color-destructive: var(--ddga-error-600);
  --ddga-color-destructive-hover: var(--ddga-error-700);
  --ddga-color-error: var(--ddga-error-600);
  --ddga-color-error-hover: var(--ddga-error-700);
  --ddga-color-success: var(--ddga-success-600);
  --ddga-color-success-hover: var(--ddga-success-700);
  --ddga-color-warning: var(--ddga-warning-600);
  --ddga-color-warning-hover: var(--ddga-warning-700);
  --ddga-color-info: var(--ddga-info-600);
  --ddga-color-info-hover: var(--ddga-info-700);
  --ddga-color-ring: var(--ddga-brand-600);
  --ddga-color-focus-ring: var(--ddga-text-primary);
  --ddga-text-secondary: var(--ddga-gray-700);
  --ddga-text-tertiary: var(--ddga-gray-600);
  --ddga-text-placeholder: var(--ddga-gray-400);
  --ddga-brand-25: var(--ddga-sa-25);
  --ddga-brand-50: var(--ddga-sa-50);
  --ddga-brand-100: var(--ddga-sa-100);
  --ddga-brand-200: var(--ddga-sa-200);
  --ddga-brand-300: var(--ddga-sa-300);
  --ddga-brand-400: var(--ddga-sa-400);
  --ddga-brand-500: var(--ddga-sa-500);
  --ddga-brand-600: var(--ddga-sa-600);
  --ddga-brand-700: var(--ddga-sa-700);
  --ddga-brand-800: var(--ddga-sa-800);
  --ddga-brand-900: var(--ddga-sa-900);
  --ddga-brand-950: var(--ddga-sa-950);
  --ddga-color-primary: var(--ddga-brand-600);
  --ddga-color-primary-hover: var(--ddga-brand-700);
  --ddga-color-primary-active: var(--ddga-brand-900);
  --ddga-color-ring: var(--ddga-brand-600);
}

/* Brand-alias sets from themes.css — class-scoped (8 of them), so they are
   not :root token values and cannot be Style Book tokens either. Applying one of these
   classes re-points the --ddga-brand-* ramp at a different palette. */
.ddga-theme-sa-green {
  --ddga-brand-25: var(--ddga-sa-25);
  --ddga-brand-50: var(--ddga-sa-50);
  --ddga-brand-100: var(--ddga-sa-100);
  --ddga-brand-200: var(--ddga-sa-200);
  --ddga-brand-300: var(--ddga-sa-300);
  --ddga-brand-400: var(--ddga-sa-400);
  --ddga-brand-500: var(--ddga-sa-500);
  --ddga-brand-600: var(--ddga-sa-600);
  --ddga-brand-700: var(--ddga-sa-700);
  --ddga-brand-800: var(--ddga-sa-800);
  --ddga-brand-900: var(--ddga-sa-900);
  --ddga-brand-950: var(--ddga-sa-950);
  --ddga-color-primary-foreground: #fff;
}

.ddga-theme-gray {
  --ddga-brand-25: var(--ddga-gray-25);
  --ddga-brand-50: var(--ddga-gray-50);
  --ddga-brand-100: var(--ddga-gray-100);
  --ddga-brand-200: var(--ddga-gray-200);
  --ddga-brand-300: var(--ddga-gray-300);
  --ddga-brand-400: var(--ddga-gray-400);
  --ddga-brand-500: var(--ddga-gray-500);
  --ddga-brand-600: var(--ddga-gray-600);
  --ddga-brand-700: var(--ddga-gray-700);
  --ddga-brand-800: var(--ddga-gray-800);
  --ddga-brand-900: var(--ddga-gray-900);
  --ddga-brand-950: var(--ddga-gray-950);
  --ddga-color-primary-foreground: #fff;
}

.ddga-theme-error {
  --ddga-brand-25: var(--ddga-error-25);
  --ddga-brand-50: var(--ddga-error-50);
  --ddga-brand-100: var(--ddga-error-100);
  --ddga-brand-200: var(--ddga-error-200);
  --ddga-brand-300: var(--ddga-error-300);
  --ddga-brand-400: var(--ddga-error-400);
  --ddga-brand-500: var(--ddga-error-500);
  --ddga-brand-600: var(--ddga-error-600);
  --ddga-brand-700: var(--ddga-error-700);
  --ddga-brand-800: var(--ddga-error-800);
  --ddga-brand-900: var(--ddga-error-900);
  --ddga-brand-950: var(--ddga-error-950);
  --ddga-color-primary-foreground: #fff;
}

.ddga-theme-warning {
  --ddga-brand-25: var(--ddga-warning-25);
  --ddga-brand-50: var(--ddga-warning-50);
  --ddga-brand-100: var(--ddga-warning-100);
  --ddga-brand-200: var(--ddga-warning-200);
  --ddga-brand-300: var(--ddga-warning-300);
  --ddga-brand-400: var(--ddga-warning-400);
  --ddga-brand-500: var(--ddga-warning-500);
  --ddga-brand-600: var(--ddga-warning-600);
  --ddga-brand-700: var(--ddga-warning-700);
  --ddga-brand-800: var(--ddga-warning-800);
  --ddga-brand-900: var(--ddga-warning-900);
  --ddga-brand-950: var(--ddga-warning-950);
  --ddga-color-primary-foreground: #fff;
}

.ddga-theme-success {
  --ddga-brand-25: var(--ddga-success-25);
  --ddga-brand-50: var(--ddga-success-50);
  --ddga-brand-100: var(--ddga-success-100);
  --ddga-brand-200: var(--ddga-success-200);
  --ddga-brand-300: var(--ddga-success-300);
  --ddga-brand-400: var(--ddga-success-400);
  --ddga-brand-500: var(--ddga-success-500);
  --ddga-brand-600: var(--ddga-success-600);
  --ddga-brand-700: var(--ddga-success-700);
  --ddga-brand-800: var(--ddga-success-800);
  --ddga-brand-900: var(--ddga-success-900);
  --ddga-brand-950: var(--ddga-success-950);
  --ddga-color-primary-foreground: #fff;
}

.ddga-theme-info {
  --ddga-brand-25: var(--ddga-info-25);
  --ddga-brand-50: var(--ddga-info-50);
  --ddga-brand-100: var(--ddga-info-100);
  --ddga-brand-200: var(--ddga-info-200);
  --ddga-brand-300: var(--ddga-info-300);
  --ddga-brand-400: var(--ddga-info-400);
  --ddga-brand-500: var(--ddga-info-500);
  --ddga-brand-600: var(--ddga-info-600);
  --ddga-brand-700: var(--ddga-info-700);
  --ddga-brand-800: var(--ddga-info-800);
  --ddga-brand-900: var(--ddga-info-900);
  --ddga-brand-950: var(--ddga-info-950);
  --ddga-color-primary-foreground: #fff;
}

.ddga-theme-gold {
  --ddga-brand-25: var(--ddga-gold-25);
  --ddga-brand-50: var(--ddga-gold-50);
  --ddga-brand-100: var(--ddga-gold-100);
  --ddga-brand-200: var(--ddga-gold-200);
  --ddga-brand-300: var(--ddga-gold-300);
  --ddga-brand-400: var(--ddga-gold-400);
  --ddga-brand-500: var(--ddga-gold-500);
  --ddga-brand-600: var(--ddga-gold-600);
  --ddga-brand-700: var(--ddga-gold-700);
  --ddga-brand-800: var(--ddga-gold-800);
  --ddga-brand-900: var(--ddga-gold-900);
  --ddga-brand-950: var(--ddga-gold-950);
  --ddga-color-primary-foreground: #0d121c;
}

.ddga-theme-lavender {
  --ddga-brand-25: var(--ddga-lavender-25);
  --ddga-brand-50: var(--ddga-lavender-50);
  --ddga-brand-100: var(--ddga-lavender-100);
  --ddga-brand-200: var(--ddga-lavender-200);
  --ddga-brand-300: var(--ddga-lavender-300);
  --ddga-brand-400: var(--ddga-lavender-400);
  --ddga-brand-500: var(--ddga-lavender-500);
  --ddga-brand-600: var(--ddga-lavender-600);
  --ddga-brand-700: var(--ddga-lavender-700);
  --ddga-brand-800: var(--ddga-lavender-800);
  --ddga-brand-900: var(--ddga-lavender-900);
  --ddga-brand-950: var(--ddga-lavender-950);
  --ddga-color-primary-foreground: #fff;
}

/* ── dark mode — GENERATED from @dev-dga/css v0.12.0 dark.css ─────────────────
   42 semantic re-points onto the same primitive ramp the light theme uses.
   Cross-checked against the Figma "Themes" collection (Dark mode): every Figma dark
   value lands on an existing --ddga-* primitive step, so there is no second literal
   set and no hand-written colour here.

   Three selectors, deliberately:
     [data-theme=dark]         @dev-dga's own contract; _dga-components.scss already
                               ships button/carousel/accordion rules keyed on it.
     [data-color-scheme=dark]  what portal_normal.ftl emits. An ADDITIONAL trigger only
                               — never the light opt-out, because it comes from an admin
                               side-navigation session click that is always "light" for
                               an anonymous visitor.
     prefers-color-scheme      what actually serves an anonymous visitor. No session, no
                               JS, no template change. data-theme="light" opts back out.

   Colour only — no directional or box properties, so RTL is unaffected.

   SPECIFICITY, measured not assumed: Liferay emits the Style Book literal tokens from
   an INLINE <style> at :root, and that inline sheet comes AFTER the theme's main.css in
   document order. A bare [data-theme=dark] ties it at (0,1,0) and therefore LOSES on
   source order — measured on the rendered page, the alias tokens flipped to dark while
   the literals (--ddga-color-background, --ddga-text-primary) stayed light.
   :root[data-theme=dark] is (0,2,0) and wins regardless of order.

   ── THE PALETTE, LIGHT vs DARK ────────────────────────────────────────────────
   Both columns are RESOLVED by the generator through the same primitive ramp:
   the light side from variables.css :root (+ .ddga-theme-sa-green in themes.css
   for tokens defined only there), the dark side from dark.css. No value here was
   typed by hand. All 42 land on a different value in dark (42 verified changed,
   0 unchanged) — so every one of them is load-bearing.

   The row to know, because it is the one the client ruled on: --ddga-color-primary
   is #1b8354 in light and #54c08a in dark. Figma holds Link/link-primary and
   Button/button-background-primary-default at #1b8354 in BOTH modes; the DGA
   library re-points, and the DGA library is the authority here (README §17.3).

   TOKEN                                LIGHT — variables.css    resolves to  DARK — dark.css             resolves to
   -----------------------------------  -----------------------  -----------  --------------------------  -----------
   --ddga-color-background              #fff                     #fff         var(--ddga-gray-900)        #111927
   --ddga-color-foreground              var(--ddga-gray-950)     #0d121c      var(--ddga-gray-100)        #f3f4f6
   --ddga-color-muted                   var(--ddga-gray-100)     #f3f4f6      var(--ddga-gray-800)        #1f2a37
   --ddga-color-muted-foreground        var(--ddga-gray-500)     #6c737f      var(--ddga-gray-400)        #9da4ae
   --ddga-color-border                  var(--ddga-gray-200)     #e5e7eb      var(--ddga-gray-700)        #384250
   --ddga-color-card                    #fff                     #fff         var(--ddga-gray-800)        #1f2a37
   --ddga-color-card-foreground         var(--ddga-gray-950)     #0d121c      var(--ddga-gray-100)        #f3f4f6
   --ddga-color-input                   var(--ddga-gray-300)     #d2d6db      var(--ddga-gray-700)        #384250
   --ddga-color-primary                 var(--ddga-brand-600)    #1b8354      var(--ddga-brand-400)       #54c08a
   --ddga-color-primary-hover           var(--ddga-brand-700)    #166a45      var(--ddga-brand-300)       #88d8ad
   --ddga-color-primary-active          var(--ddga-brand-900)    #104631      var(--ddga-brand-500)       #25935f
   --ddga-color-primary-foreground      #fff                     #fff         var(--ddga-gray-950)        #0d121c
   --ddga-color-secondary               var(--ddga-gray-100)     #f3f4f6      var(--ddga-gray-800)        #1f2a37
   --ddga-color-secondary-hover         var(--ddga-gray-200)     #e5e7eb      var(--ddga-gray-700)        #384250
   --ddga-color-secondary-foreground    var(--ddga-gray-950)     #0d121c      var(--ddga-gray-100)        #f3f4f6
   --ddga-color-destructive             var(--ddga-error-600)    #d92d20      var(--ddga-error-400)       #f97066
   --ddga-color-destructive-hover       var(--ddga-error-700)    #b42318      var(--ddga-error-500)       #f04438
   --ddga-color-destructive-foreground  #fff                     #fff         var(--ddga-gray-950)        #0d121c
   --ddga-color-error                   var(--ddga-error-600)    #d92d20      var(--ddga-error-400)       #f97066
   --ddga-color-error-hover             var(--ddga-error-700)    #b42318      var(--ddga-error-500)       #f04438
   --ddga-color-error-foreground        #fff                     #fff         var(--ddga-gray-950)        #0d121c
   --ddga-color-success                 var(--ddga-success-600)  #079455      var(--ddga-success-400)     #47cd89
   --ddga-color-success-hover           var(--ddga-success-700)  #067647      var(--ddga-success-500)     #17b26a
   --ddga-color-success-foreground      #fff                     #fff         var(--ddga-gray-950)        #0d121c
   --ddga-color-warning                 var(--ddga-warning-600)  #dc6803      var(--ddga-warning-400)     #fdb022
   --ddga-color-warning-hover           var(--ddga-warning-700)  #b54708      var(--ddga-warning-500)     #f79009
   --ddga-color-warning-foreground      #fff                     #fff         var(--ddga-gray-950)        #0d121c
   --ddga-color-info                    var(--ddga-info-600)     #1570ef      var(--ddga-info-400)        #53b1fd
   --ddga-color-info-hover              var(--ddga-info-700)     #175cd3      var(--ddga-info-500)        #2e90fa
   --ddga-color-info-foreground         #fff                     #fff         var(--ddga-gray-950)        #0d121c
   --ddga-color-ring                    var(--ddga-brand-600)    #1b8354      var(--ddga-brand-400)       #54c08a
   --ddga-text-primary                  #161616                  #161616      #fff                        #fff
   --ddga-text-secondary                var(--ddga-gray-700)     #384250      var(--ddga-alpha-white-70)  #ffffffb3
   --ddga-text-tertiary                 var(--ddga-gray-600)     #4d5761      var(--ddga-alpha-white-60)  #fff9
   --ddga-text-placeholder              var(--ddga-gray-400)     #9da4ae      var(--ddga-gray-500)        #6c737f

   Shadows — literal in both files, so there is no alias to resolve:

   TOKEN              LIGHT — variables.css                                 DARK — dark.css
   -----------------  ----------------------------------------------------  ----------------------------------------------------
   --ddga-shadow-xs   0 1px 2px 0 #1018280d                                 0 1px 2px 0 #0000004d
   --ddga-shadow-sm   0 1px 3px 0 #1018281a, 0 1px 2px 0 #1018280f          0 1px 3px 0 #0006, 0 1px 2px 0 #0000004d
   --ddga-shadow-md   0 2px 4px -2px #1018280f, 0 4px 8px -2px #1018281a    0 2px 4px -2px #0000004d, 0 4px 8px -2px #00000073
   --ddga-shadow-lg   0 4px 6px -2px #10182808, 0 12px 16px -4px #10182814  0 4px 6px -2px #0000004d, 0 12px 16px -4px #00000080
   --ddga-shadow-xl   0 8px 8px -4px #10182808, 0 20px 24px -4px #10182814  0 8px 8px -4px #0000004d, 0 20px 24px -4px #00000080
   --ddga-shadow-2xl  0 24px 48px -12px #1018282e                           0 24px 48px -12px #0009
   --ddga-shadow-3xl  0 32px 64px -12px #10182824                           0 32px 64px -12px #0000008c
   ────────────────────────────────────────────────────────────────────────────── */
:root[data-theme=dark],
:root[data-color-scheme=dark] {
  color-scheme: dark;
  --ddga-color-background: var(--ddga-gray-900); /* light #fff  →  dark var(--ddga-gray-900) = #111927 */
  --ddga-color-foreground: var(--ddga-gray-100); /* light var(--ddga-gray-950) = #0d121c  →  dark var(--ddga-gray-100) = #f3f4f6 */
  --ddga-color-muted: var(--ddga-gray-800); /* light var(--ddga-gray-100) = #f3f4f6  →  dark var(--ddga-gray-800) = #1f2a37 */
  --ddga-color-muted-foreground: var(--ddga-gray-400); /* light var(--ddga-gray-500) = #6c737f  →  dark var(--ddga-gray-400) = #9da4ae */
  --ddga-color-border: var(--ddga-gray-700); /* light var(--ddga-gray-200) = #e5e7eb  →  dark var(--ddga-gray-700) = #384250 */
  --ddga-color-card: var(--ddga-gray-800); /* light #fff  →  dark var(--ddga-gray-800) = #1f2a37 */
  --ddga-color-card-foreground: var(--ddga-gray-100); /* light var(--ddga-gray-950) = #0d121c  →  dark var(--ddga-gray-100) = #f3f4f6 */
  --ddga-color-input: var(--ddga-gray-700); /* light var(--ddga-gray-300) = #d2d6db  →  dark var(--ddga-gray-700) = #384250 */
  --ddga-scrim: rgb(0 0 0 / 60%); /* light rgb(13 18 28 / 45%)  →  dark deeper, because the dialog surface is already dark and a 45% scrim would not separate it from the page */
  --ddga-color-primary: var(--ddga-brand-400); /* light var(--ddga-brand-600) = #1b8354  →  dark var(--ddga-brand-400) = #54c08a */
  --ddga-color-primary-hover: var(--ddga-brand-300); /* light var(--ddga-brand-700) = #166a45  →  dark var(--ddga-brand-300) = #88d8ad */
  --ddga-color-primary-active: var(--ddga-brand-500); /* light var(--ddga-brand-900) = #104631  →  dark var(--ddga-brand-500) = #25935f */
  --ddga-color-primary-foreground: var(--ddga-gray-950); /* light #fff  →  dark var(--ddga-gray-950) = #0d121c */
  --ddga-color-secondary: var(--ddga-gray-800); /* light var(--ddga-gray-100) = #f3f4f6  →  dark var(--ddga-gray-800) = #1f2a37 */
  --ddga-color-secondary-hover: var(--ddga-gray-700); /* light var(--ddga-gray-200) = #e5e7eb  →  dark var(--ddga-gray-700) = #384250 */
  --ddga-color-secondary-foreground: var(--ddga-gray-100); /* light var(--ddga-gray-950) = #0d121c  →  dark var(--ddga-gray-100) = #f3f4f6 */
  --ddga-color-destructive: var(--ddga-error-400); /* light var(--ddga-error-600) = #d92d20  →  dark var(--ddga-error-400) = #f97066 */
  --ddga-color-destructive-hover: var(--ddga-error-500); /* light var(--ddga-error-700) = #b42318  →  dark var(--ddga-error-500) = #f04438 */
  --ddga-color-destructive-foreground: var(--ddga-gray-950); /* light #fff  →  dark var(--ddga-gray-950) = #0d121c */
  --ddga-color-error: var(--ddga-error-400); /* light var(--ddga-error-600) = #d92d20  →  dark var(--ddga-error-400) = #f97066 */
  --ddga-color-error-hover: var(--ddga-error-500); /* light var(--ddga-error-700) = #b42318  →  dark var(--ddga-error-500) = #f04438 */
  --ddga-color-error-foreground: var(--ddga-gray-950); /* light #fff  →  dark var(--ddga-gray-950) = #0d121c */
  --ddga-color-success: var(--ddga-success-400); /* light var(--ddga-success-600) = #079455  →  dark var(--ddga-success-400) = #47cd89 */
  --ddga-color-success-hover: var(--ddga-success-500); /* light var(--ddga-success-700) = #067647  →  dark var(--ddga-success-500) = #17b26a */
  --ddga-color-success-foreground: var(--ddga-gray-950); /* light #fff  →  dark var(--ddga-gray-950) = #0d121c */
  --ddga-color-warning: var(--ddga-warning-400); /* light var(--ddga-warning-600) = #dc6803  →  dark var(--ddga-warning-400) = #fdb022 */
  --ddga-color-warning-hover: var(--ddga-warning-500); /* light var(--ddga-warning-700) = #b54708  →  dark var(--ddga-warning-500) = #f79009 */
  --ddga-color-warning-foreground: var(--ddga-gray-950); /* light #fff  →  dark var(--ddga-gray-950) = #0d121c */
  --ddga-color-info: var(--ddga-info-400); /* light var(--ddga-info-600) = #1570ef  →  dark var(--ddga-info-400) = #53b1fd */
  --ddga-color-info-hover: var(--ddga-info-500); /* light var(--ddga-info-700) = #175cd3  →  dark var(--ddga-info-500) = #2e90fa */
  --ddga-color-info-foreground: var(--ddga-gray-950); /* light #fff  →  dark var(--ddga-gray-950) = #0d121c */
  --ddga-color-ring: var(--ddga-brand-400); /* light var(--ddga-brand-600) = #1b8354  →  dark var(--ddga-brand-400) = #54c08a */
  --ddga-text-primary: #fff; /* light #161616  →  dark #fff */
  --ddga-text-secondary: var(--ddga-alpha-white-70); /* light var(--ddga-gray-700) = #384250  →  dark var(--ddga-alpha-white-70) = #ffffffb3 */
  --ddga-text-tertiary: var(--ddga-alpha-white-60); /* light var(--ddga-gray-600) = #4d5761  →  dark var(--ddga-alpha-white-60) = #fff9 */
  --ddga-text-placeholder: var(--ddga-gray-500); /* light var(--ddga-gray-400) = #9da4ae  →  dark var(--ddga-gray-500) = #6c737f */
  --ddga-shadow-xs: 0 1px 2px 0 #0000004d; /* light 0 1px 2px 0 #1018280d  →  dark 0 1px 2px 0 #0000004d */
  --ddga-shadow-sm: 0 1px 3px 0 #0006, 0 1px 2px 0 #0000004d; /* light 0 1px 3px 0 #1018281a, 0 1px 2px 0 #1018280f  →  dark 0 1px 3px 0 #0006, 0 1px 2px 0 #0000004d */
  --ddga-shadow-md: 0 2px 4px -2px #0000004d, 0 4px 8px -2px #00000073; /* light 0 2px 4px -2px #1018280f, 0 4px 8px -2px #1018281a  →  dark 0 2px 4px -2px #0000004d, 0 4px 8px -2px #00000073 */
  --ddga-shadow-lg: 0 4px 6px -2px #0000004d, 0 12px 16px -4px #00000080; /* light 0 4px 6px -2px #10182808, 0 12px 16px -4px #10182814  →  dark 0 4px 6px -2px #0000004d, 0 12px 16px -4px #00000080 */
  --ddga-shadow-xl: 0 8px 8px -4px #0000004d, 0 20px 24px -4px #00000080; /* light 0 8px 8px -4px #10182808, 0 20px 24px -4px #10182814  →  dark 0 8px 8px -4px #0000004d, 0 20px 24px -4px #00000080 */
  --ddga-shadow-2xl: 0 24px 48px -12px #0009; /* light 0 24px 48px -12px #1018282e  →  dark 0 24px 48px -12px #0009 */
  --ddga-shadow-3xl: 0 32px 64px -12px #0000008c; /* light 0 32px 64px -12px #10182824  →  dark 0 32px 64px -12px #0000008c */
}

/* Identical re-points for the anonymous visitor, who has no session and no toggle
   state. Same list, same order, same source — see the table above. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme=light]) {
    color-scheme: dark;
    --ddga-color-background: var(--ddga-gray-900); /* light #fff  →  dark var(--ddga-gray-900) = #111927 */
    --ddga-color-foreground: var(--ddga-gray-100); /* light var(--ddga-gray-950) = #0d121c  →  dark var(--ddga-gray-100) = #f3f4f6 */
    --ddga-color-muted: var(--ddga-gray-800); /* light var(--ddga-gray-100) = #f3f4f6  →  dark var(--ddga-gray-800) = #1f2a37 */
    --ddga-color-muted-foreground: var(--ddga-gray-400); /* light var(--ddga-gray-500) = #6c737f  →  dark var(--ddga-gray-400) = #9da4ae */
    --ddga-color-border: var(--ddga-gray-700); /* light var(--ddga-gray-200) = #e5e7eb  →  dark var(--ddga-gray-700) = #384250 */
    --ddga-color-card: var(--ddga-gray-800); /* light #fff  →  dark var(--ddga-gray-800) = #1f2a37 */
    --ddga-color-card-foreground: var(--ddga-gray-100); /* light var(--ddga-gray-950) = #0d121c  →  dark var(--ddga-gray-100) = #f3f4f6 */
    --ddga-color-input: var(--ddga-gray-700); /* light var(--ddga-gray-300) = #d2d6db  →  dark var(--ddga-gray-700) = #384250 */
    --ddga-scrim: rgb(0 0 0 / 60%); /* light rgb(13 18 28 / 45%)  →  dark deeper, per the same reasoning as the explicit dark block above */
    --ddga-color-primary: var(--ddga-brand-400); /* light var(--ddga-brand-600) = #1b8354  →  dark var(--ddga-brand-400) = #54c08a */
    --ddga-color-primary-hover: var(--ddga-brand-300); /* light var(--ddga-brand-700) = #166a45  →  dark var(--ddga-brand-300) = #88d8ad */
    --ddga-color-primary-active: var(--ddga-brand-500); /* light var(--ddga-brand-900) = #104631  →  dark var(--ddga-brand-500) = #25935f */
    --ddga-color-primary-foreground: var(--ddga-gray-950); /* light #fff  →  dark var(--ddga-gray-950) = #0d121c */
    --ddga-color-secondary: var(--ddga-gray-800); /* light var(--ddga-gray-100) = #f3f4f6  →  dark var(--ddga-gray-800) = #1f2a37 */
    --ddga-color-secondary-hover: var(--ddga-gray-700); /* light var(--ddga-gray-200) = #e5e7eb  →  dark var(--ddga-gray-700) = #384250 */
    --ddga-color-secondary-foreground: var(--ddga-gray-100); /* light var(--ddga-gray-950) = #0d121c  →  dark var(--ddga-gray-100) = #f3f4f6 */
    --ddga-color-destructive: var(--ddga-error-400); /* light var(--ddga-error-600) = #d92d20  →  dark var(--ddga-error-400) = #f97066 */
    --ddga-color-destructive-hover: var(--ddga-error-500); /* light var(--ddga-error-700) = #b42318  →  dark var(--ddga-error-500) = #f04438 */
    --ddga-color-destructive-foreground: var(--ddga-gray-950); /* light #fff  →  dark var(--ddga-gray-950) = #0d121c */
    --ddga-color-error: var(--ddga-error-400); /* light var(--ddga-error-600) = #d92d20  →  dark var(--ddga-error-400) = #f97066 */
    --ddga-color-error-hover: var(--ddga-error-500); /* light var(--ddga-error-700) = #b42318  →  dark var(--ddga-error-500) = #f04438 */
    --ddga-color-error-foreground: var(--ddga-gray-950); /* light #fff  →  dark var(--ddga-gray-950) = #0d121c */
    --ddga-color-success: var(--ddga-success-400); /* light var(--ddga-success-600) = #079455  →  dark var(--ddga-success-400) = #47cd89 */
    --ddga-color-success-hover: var(--ddga-success-500); /* light var(--ddga-success-700) = #067647  →  dark var(--ddga-success-500) = #17b26a */
    --ddga-color-success-foreground: var(--ddga-gray-950); /* light #fff  →  dark var(--ddga-gray-950) = #0d121c */
    --ddga-color-warning: var(--ddga-warning-400); /* light var(--ddga-warning-600) = #dc6803  →  dark var(--ddga-warning-400) = #fdb022 */
    --ddga-color-warning-hover: var(--ddga-warning-500); /* light var(--ddga-warning-700) = #b54708  →  dark var(--ddga-warning-500) = #f79009 */
    --ddga-color-warning-foreground: var(--ddga-gray-950); /* light #fff  →  dark var(--ddga-gray-950) = #0d121c */
    --ddga-color-info: var(--ddga-info-400); /* light var(--ddga-info-600) = #1570ef  →  dark var(--ddga-info-400) = #53b1fd */
    --ddga-color-info-hover: var(--ddga-info-500); /* light var(--ddga-info-700) = #175cd3  →  dark var(--ddga-info-500) = #2e90fa */
    --ddga-color-info-foreground: var(--ddga-gray-950); /* light #fff  →  dark var(--ddga-gray-950) = #0d121c */
    --ddga-color-ring: var(--ddga-brand-400); /* light var(--ddga-brand-600) = #1b8354  →  dark var(--ddga-brand-400) = #54c08a */
    --ddga-text-primary: #fff; /* light #161616  →  dark #fff */
    --ddga-text-secondary: var(--ddga-alpha-white-70); /* light var(--ddga-gray-700) = #384250  →  dark var(--ddga-alpha-white-70) = #ffffffb3 */
    --ddga-text-tertiary: var(--ddga-alpha-white-60); /* light var(--ddga-gray-600) = #4d5761  →  dark var(--ddga-alpha-white-60) = #fff9 */
    --ddga-text-placeholder: var(--ddga-gray-500); /* light var(--ddga-gray-400) = #9da4ae  →  dark var(--ddga-gray-500) = #6c737f */
    --ddga-shadow-xs: 0 1px 2px 0 #0000004d; /* light 0 1px 2px 0 #1018280d  →  dark 0 1px 2px 0 #0000004d */
    --ddga-shadow-sm: 0 1px 3px 0 #0006, 0 1px 2px 0 #0000004d; /* light 0 1px 3px 0 #1018281a, 0 1px 2px 0 #1018280f  →  dark 0 1px 3px 0 #0006, 0 1px 2px 0 #0000004d */
    --ddga-shadow-md: 0 2px 4px -2px #0000004d, 0 4px 8px -2px #00000073; /* light 0 2px 4px -2px #1018280f, 0 4px 8px -2px #1018281a  →  dark 0 2px 4px -2px #0000004d, 0 4px 8px -2px #00000073 */
    --ddga-shadow-lg: 0 4px 6px -2px #0000004d, 0 12px 16px -4px #00000080; /* light 0 4px 6px -2px #10182808, 0 12px 16px -4px #10182814  →  dark 0 4px 6px -2px #0000004d, 0 12px 16px -4px #00000080 */
    --ddga-shadow-xl: 0 8px 8px -4px #0000004d, 0 20px 24px -4px #00000080; /* light 0 8px 8px -4px #10182808, 0 20px 24px -4px #10182814  →  dark 0 8px 8px -4px #0000004d, 0 20px 24px -4px #00000080 */
    --ddga-shadow-2xl: 0 24px 48px -12px #0009; /* light 0 24px 48px -12px #1018282e  →  dark 0 24px 48px -12px #0009 */
    --ddga-shadow-3xl: 0 32px 64px -12px #0000008c; /* light 0 32px 64px -12px #10182824  →  dark 0 32px 64px -12px #0000008c */
  }
}
/* ─────────────────────────────────────────────────────────────────────────────
   DGA reset — DELIBERATELY ALMOST EMPTY.

   Decision: **omit @dev-dga/css reset.css.** Not "port it scoped", not "port it
   whole" — omit. Reasoning, rule by rule:

     *,:before,:after { box-sizing:border-box; margin:0; padding:0 }
         Clay already sets box-sizing: border-box globally (Bootstrap reboot).
         The margin/padding half is the problem: unlayered, a universal selector
         would strip spacing from the ENTIRE portal — control menu, admin UI,
         every Liferay widget — not just Harf pages. Enormous blast radius, and
         the DGA components do not depend on it (they set their own spacing).

     body { font-family; color; background-color; font-smoothing; line-height }
         Liferay's theme owns <body>, so colour, background, smoothing and
         line-height stay omitted. ONE declaration had to come back — see below.

     svg { vertical-align: middle; display: block }
         Global svg rules would break Clay's inline icons across the portal.
         Where it actually matters the component CSS already covers it — the
         ported button carries its own `.ddga-button svg` rule.

     .ddga-sr-only  /  [dir=rtl] .ddga-icon-flip
         Self-scoped utility classes, harmless — but verified UNUSED by every
         fragment currently in fragments/harf-fragments. Shipping unused CSS to
         every page is not free.

   TRADE-OFF ACCEPTED: if a future fragment uses .ddga-sr-only or .ddga-icon-flip
   it will be unstyled until someone adds it here, scoped. That is a visible,
   cheap, five-minute failure. The alternative — a universal reset loose in an
   unlayered portal — is an invisible, expensive failure spread across the whole
   admin UI. scripts/check-theme-css-order.sh fails the build if a fragment starts
   using either class while this file stays empty, so the cheap failure is caught
   at build time rather than in review.
   ──────────────────────────────────────────────────────────────────────────── */
/* ═══════════════════════════════════════════════════════════════════════════
   The one rule that had to come back: body font-family
   ═══════════════════════════════════════════════════════════════════════════

   The claim above used to read "the font-family arrives instead through the
   --ddga-font-ar token from the Stylebook, applied where it belongs". Measured,
   that was only half true. The token IS on :root —
   `getComputedStyle(document.documentElement).getPropertyValue('--ddga-font-ar')`
   returns `"IBM Plex Sans Arabic", "Noto Sans Arabic", sans-serif` — but nothing
   applied it to <body>, so it reached an element only where a fragment happened to
   declare `font-family: var(--ddga-font-ar)` itself. Every CONTENT fragment does;
   the two CHROME fragments (site-header, site-footer) did not, and site-header's
   `.nav-link` says `font-family: inherit`. Computed, before this rule:

       body                             system stack
       .harf-site-header                system stack
       .harf-site-header .nav-link      system stack
       .harf-site-footer                system stack
       [class*="about"] p               "IBM Plex Sans Arabic", "Noto Sans Arabic", sans-serif

   Fixing that per element would mean pasting the same declaration into every
   fragment — the lookalike pattern directive 1 forbids, and a new fragment would
   silently ship unstyled. So the single declaration from the DGA reset is restored
   here, VERBATIM from @dev-dga/css/dist/reset.css:

       body{font-family:var(--ddga-font-ar); …}

   Blast radius is this theme only: main.css is served under /o/harf-theme, so it
   loads on Harf pages and nowhere else. The administrator control panel renders
   with admin-theme and is untouched (verified after deploying: still
   `<html class="ltr" dir="ltr" lang="en-US">` with the system stack).

   The other four declarations from that DGA rule stay omitted, for the reasons
   above. */
body {
  font-family: var(--ddga-font-ar);
}

/* ═══════════════════════════════════════════════════════════════════════════
   Two more that had to come back: body colour and background-color
   ═══════════════════════════════════════════════════════════════════════════

   The omission reasoning above — "Liferay's theme owns <body>, so colour and
   background stay omitted" — was written when this theme was light-only. It does
   not survive dark mode.

   MEASURED on the rendered homepage with the dark palette active
   (:root resolving --ddga-color-background to #111927):

       body  background-color   rgb(255, 255, 255)   <- did not follow the theme
       body  color              rgb(33, 37, 41)      <- Bootstrap $body-color

   Neither value is a DGA token at all. The white came from Clay's reboot and the
   #212529 is Bootstrap's default body colour, so in dark mode the page's base
   surface stayed white and any text not explicitly coloured by a fragment stayed
   near-black. Every content fragment paints its own background, which is why this
   was invisible until a fragment did not cover the full viewport.

   Restored VERBATIM from @dev-dga/css/dist/reset.css, which declares:

       body{font-family:var(--ddga-font-ar);color:var(--ddga-color-foreground);
            background-color:var(--ddga-color-background); …}

   These two are surface-relative by definition — <body> IS the page surface — so
   they must re-point with the theme. The remaining two declarations from that rule
   (-webkit-font-smoothing, line-height) stay omitted for the reasons above.

   Blast radius is unchanged: main.css is served under /o/harf-theme only. */
body {
  background-color: var(--ddga-color-background);
  color: var(--ddga-color-foreground);
}

/* ─────────────────────────────────────────────────────────────────────────────
   DGA Platform Code component classes — GENERATED, DO NOT EDIT BY HAND.

   Source:    @dev-dga/css v0.12.0 (dist/components/*.css)
   Generator: tools/dga-port/port-components.mjs  ← REMOVED, see below
   Components: button, carousel, accordion, tag, pagination

   ⚠ GENERATOR REMOVED 2026-07-28 — THIS FILE IS NOW HAND-MAINTAINED.
   tools/dga-port/ went with frontend-source/ (README §15). The "GENERATED, DO NOT
   EDIT BY HAND" line above records how this file was ORIGINALLY produced; it is no
   longer an instruction you can follow, because there is nothing left to re-run.
   To refresh against a newer @dev-dga/css you must now re-derive by hand from
   node_modules/@dev-dga/css/dist/components/*.css (root package.json pins 0.12.0;
   npm install) — and you MUST strip the @layer wrapper yourself, for the reason
   immediately below. check-theme-css-order.sh is the only thing that will catch you.

   ⚠ DELAYERED ON PURPOSE. Upstream ships these inside "@layer ddga-components".
   Liferay's Clay and theme CSS are unlayered, and unlayered CSS beats layered CSS
   regardless of specificity — so layered rules here would never win. The layer
   wrapper is stripped and the rules emitted plain. scripts/check-theme-css-order.sh
   fails the build if an @layer reappears.

   Design tokens are NOT here — they come from the Stylebook (directive 1). These
   rules consume them through var(--ddga-*).
   ──────────────────────────────────────────────────────────────────────────── */
/* ── button — 67 rules, 1 @layer wrapper(s) removed ── */
.ddga-button {
  justify-content: center;
  align-items: center;
  gap: var(--ddga-space-1);
  border-radius: var(--ddga-radius-sm);
  font-weight: var(--ddga-font-weight-medium);
  cursor: pointer;
  border: 1px solid rgba(0, 0, 0, 0);
  font-family: inherit;
  line-height: 1.6;
  text-decoration: none;
  transition: background-color 0.15s, border-color 0.15s, color 0.15s, opacity 0.15s;
  display: inline-flex;
}

.ddga-button--primary {
  background-color: var(--ddga-color-primary);
  color: var(--ddga-color-primary-foreground);
}

.ddga-button--primary:hover:not(:disabled):not([aria-disabled=true]) {
  background-color: var(--ddga-color-primary-hover);
}

.ddga-button--secondary {
  background-color: var(--ddga-color-secondary);
  color: var(--ddga-color-secondary-foreground);
}

.ddga-button--secondary:hover:not(:disabled):not([aria-disabled=true]) {
  background-color: var(--ddga-color-secondary-hover);
}

.ddga-button--black {
  background-color: var(--ddga-gray-950);
  color: #fff;
}

.ddga-button--black:hover:not(:disabled):not([aria-disabled=true]) {
  background-color: var(--ddga-gray-800);
}

.ddga-button--outline {
  color: var(--ddga-color-foreground);
  border-color: var(--ddga-color-input);
  background-color: rgba(0, 0, 0, 0);
}

.ddga-button--outline:hover:not(:disabled):not([aria-disabled=true]) {
  background-color: var(--ddga-color-muted);
}

.ddga-button--ghost {
  color: var(--ddga-color-foreground);
  background-color: rgba(0, 0, 0, 0);
}

.ddga-button--ghost:hover:not(:disabled):not([aria-disabled=true]) {
  background-color: var(--ddga-color-muted);
}

.ddga-button--destructive {
  background-color: var(--ddga-color-destructive);
  color: var(--ddga-color-destructive-foreground);
}

.ddga-button--destructive:hover:not(:disabled):not([aria-disabled=true]) {
  background-color: var(--ddga-color-destructive-hover);
}

.ddga-button--destructive-outline {
  color: var(--ddga-color-destructive);
  border-color: var(--ddga-error-200);
  background-color: rgba(0, 0, 0, 0);
}

.ddga-button--destructive-outline:hover:not(:disabled):not([aria-disabled=true]) {
  background-color: var(--ddga-error-50);
}

.ddga-button--destructive-subtle {
  background-color: var(--ddga-error-50);
  color: var(--ddga-color-destructive);
}

.ddga-button--destructive-subtle:hover:not(:disabled):not([aria-disabled=true]) {
  background-color: var(--ddga-error-100);
}

.ddga-button--destructive-ghost {
  color: var(--ddga-color-destructive);
  background-color: rgba(0, 0, 0, 0);
}

.ddga-button--destructive-ghost:hover:not(:disabled):not([aria-disabled=true]) {
  background-color: var(--ddga-error-50);
}

.ddga-button--primary[aria-pressed=true] {
  background-color: var(--ddga-sa-800);
}

.ddga-button--secondary[aria-pressed=true] {
  background-color: var(--ddga-gray-200);
}

.ddga-button--black[aria-pressed=true] {
  background-color: var(--ddga-gray-700);
}

.ddga-button--destructive[aria-pressed=true] {
  background-color: var(--ddga-error-800);
}

.ddga-button--primary:active:not(:disabled):not([aria-disabled=true]) {
  background-color: var(--ddga-color-primary-active);
}

.ddga-button--secondary:active:not(:disabled):not([aria-disabled=true]) {
  background-color: var(--ddga-color-secondary-hover);
}

.ddga-button--black:active:not(:disabled):not([aria-disabled=true]) {
  background-color: var(--ddga-gray-600);
}

.ddga-button--destructive:active:not(:disabled):not([aria-disabled=true]) {
  background-color: var(--ddga-error-900);
}

.ddga-button--destructive-subtle:active:not(:disabled):not([aria-disabled=true]) {
  background-color: var(--ddga-error-200);
}

.ddga-button--outline:active:not(:disabled):not([aria-disabled=true]), .ddga-button--ghost:active:not(:disabled):not([aria-disabled=true]) {
  background-color: var(--ddga-color-secondary-hover);
}

.ddga-button--destructive-outline:active:not(:disabled):not([aria-disabled=true]), .ddga-button--destructive-ghost:active:not(:disabled):not([aria-disabled=true]) {
  background-color: var(--ddga-error-100);
}

.ddga-button--sm {
  height: 24px;
  padding-inline: var(--ddga-space-2);
  font-size: var(--ddga-font-size-xs);
  line-height: 1.125rem;
}

.ddga-button--md {
  height: 32px;
  padding-inline: var(--ddga-space-3);
  font-size: var(--ddga-font-size-sm);
  line-height: 1.25rem;
}

.ddga-button--lg {
  height: 40px;
  padding-inline: var(--ddga-space-4);
  font-size: var(--ddga-font-size-base);
  line-height: 1.5rem;
}

.ddga-button--icon {
  width: 40px;
  height: 40px;
  font-size: var(--ddga-font-size-base);
  padding: 0;
}

.ddga-button--icon-md {
  width: 32px;
  height: 32px;
  font-size: var(--ddga-font-size-sm);
  padding: 0;
}

.ddga-button--icon-sm {
  width: 28px;
  height: 28px;
  font-size: var(--ddga-font-size-sm);
  padding: 0;
}

.ddga-button--icon-xs {
  width: 24px;
  height: 24px;
  font-size: var(--ddga-font-size-xs);
  padding: 0;
}

.ddga-button--full-width {
  flex: 1 0 100%;
  inline-size: 100%;
}

.ddga-button--on-color.ddga-button--black, .ddga-button--on-color.ddga-button--primary {
  color: var(--ddga-color-foreground);
  background-color: #fff;
  border-color: rgba(0, 0, 0, 0);
}

.ddga-button--on-color.ddga-button--black:hover:not(:disabled):not([aria-disabled=true]), .ddga-button--on-color.ddga-button--primary:hover:not(:disabled):not([aria-disabled=true]) {
  background-color: var(--ddga-alpha-white-80);
}

.ddga-button--on-color.ddga-button--black:active:not(:disabled):not([aria-disabled=true]), .ddga-button--on-color.ddga-button--primary:active:not(:disabled):not([aria-disabled=true]) {
  background-color: var(--ddga-alpha-white-60);
}

.ddga-button--on-color.ddga-button--black[aria-pressed=true], .ddga-button--on-color.ddga-button--primary[aria-pressed=true] {
  background-color: var(--ddga-alpha-white-70);
}

.ddga-button--on-color.ddga-button--secondary, .ddga-button--on-color.ddga-button--ghost {
  color: #fff;
  background-color: rgba(0, 0, 0, 0);
  border-color: rgba(0, 0, 0, 0);
}

.ddga-button--on-color.ddga-button--outline {
  color: #fff;
  border-color: var(--ddga-alpha-white-40);
  background-color: rgba(0, 0, 0, 0);
}

.ddga-button--on-color.ddga-button--secondary:hover:not(:disabled):not([aria-disabled=true]), .ddga-button--on-color.ddga-button--ghost:hover:not(:disabled):not([aria-disabled=true]), .ddga-button--on-color.ddga-button--outline:hover:not(:disabled):not([aria-disabled=true]) {
  background-color: var(--ddga-alpha-white-20);
}

.ddga-button--on-color.ddga-button--secondary:active:not(:disabled):not([aria-disabled=true]), .ddga-button--on-color.ddga-button--ghost:active:not(:disabled):not([aria-disabled=true]), .ddga-button--on-color.ddga-button--outline:active:not(:disabled):not([aria-disabled=true]) {
  background-color: var(--ddga-alpha-white-40);
}

.ddga-button--on-color.ddga-button--secondary[aria-pressed=true], .ddga-button--on-color.ddga-button--ghost[aria-pressed=true], .ddga-button--on-color.ddga-button--outline[aria-pressed=true] {
  background-color: var(--ddga-alpha-white-30);
}

.ddga-button--on-color.ddga-button--destructive-outline, .ddga-button--on-color.ddga-button--destructive-ghost {
  color: var(--ddga-error-200);
}

.ddga-button--on-color.ddga-button--destructive-outline {
  border-color: var(--ddga-error-200);
}

.ddga-button--loading {
  cursor: wait;
  position: relative;
}

.ddga-button__text {
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}

.ddga-button__icon {
  flex-shrink: 0;
  justify-content: center;
  align-items: center;
  display: inline-flex;
}

.ddga-button svg {
  flex-shrink: 0;
  align-self: center;
}

@media (prefers-reduced-motion: reduce) {
  .ddga-button {
    transition: none;
  }
}
.ddga-button:disabled, .ddga-button[aria-disabled=true] {
  cursor: not-allowed;
  background-color: var(--ddga-gray-200);
  color: var(--ddga-gray-400);
  border-color: rgba(0, 0, 0, 0);
}

.ddga-button--outline:disabled, .ddga-button--outline[aria-disabled=true], .ddga-button--destructive-outline:disabled, .ddga-button--destructive-outline[aria-disabled=true] {
  border-color: var(--ddga-color-border);
  background-color: rgba(0, 0, 0, 0);
}

.ddga-button--ghost:disabled, .ddga-button--ghost[aria-disabled=true], .ddga-button--destructive-ghost:disabled, .ddga-button--destructive-ghost[aria-disabled=true] {
  background-color: rgba(0, 0, 0, 0);
}

.ddga-button--on-color:disabled, .ddga-button--on-color[aria-disabled=true] {
  background-color: var(--ddga-alpha-white-20);
  color: var(--ddga-alpha-white-40);
  border-color: var(--ddga-alpha-white-20);
}

[data-theme=dark] .ddga-button:disabled, [data-theme=dark] .ddga-button[aria-disabled=true] {
  background-color: var(--ddga-gray-800);
  color: var(--ddga-gray-500);
}

.ddga-button:focus-visible {
  box-shadow: inset 0 0 0 2px var(--ddga-color-background), inset 0 0 0 4px var(--ddga-color-focus-ring);
  outline: none;
}

.ddga-button--on-color:focus-visible {
  box-shadow: inset 0 0 0 2px var(--ddga-color-foreground), inset 0 0 0 4px #fff;
}

[data-theme=dark] .ddga-button--destructive-subtle {
  background-color: rgba(217, 45, 32, 0.1803921569);
}

[data-theme=dark] .ddga-button--destructive-subtle:hover:not(:disabled):not([aria-disabled=true]) {
  background-color: rgba(217, 45, 32, 0.2784313725);
}

[data-theme=dark] .ddga-button--destructive-outline:hover:not(:disabled):not([aria-disabled=true]), [data-theme=dark] .ddga-button--destructive-ghost:hover:not(:disabled):not([aria-disabled=true]) {
  background-color: rgba(217, 45, 32, 0.1803921569);
}

@media (forced-colors: active) {
  .ddga-button {
    border: 1px solid buttontext;
  }
  .ddga-button:focus-visible {
    outline: 2px solid highlight;
  }
  .ddga-button:disabled, .ddga-button[aria-disabled=true] {
    color: graytext;
    border-color: graytext;
  }
}
/*# sourceMappingURL=button.css.map */
/* ── carousel — 43 rules, 1 @layer wrapper(s) removed ── */
.ddga-carousel {
  box-sizing: border-box;
  padding-inline: var(--ddga-space-6);
  padding-block: var(--ddga-space-8);
  display: grid;
}

.ddga-carousel--dots {
  row-gap: var(--ddga-space-6);
  grid-template-areas: "viewport" "dots";
  justify-items: center;
}

.ddga-carousel--arrows {
  grid-template-columns: auto 1fr auto;
  grid-template-areas: "prev viewport next";
  align-items: center;
  column-gap: 2.75rem;
}

.ddga-carousel--both {
  align-items: center;
  column-gap: 2.75rem;
  row-gap: var(--ddga-space-6);
  grid-template-columns: auto 1fr auto;
  grid-template-areas: "prev viewport next" "dots dots dots";
  justify-items: center;
}

.ddga-carousel [data-slot=carousel-previous] {
  grid-area: prev;
}

.ddga-carousel [data-slot=carousel-next] {
  grid-area: next;
}

.ddga-carousel [data-slot=carousel-viewport] {
  grid-area: viewport;
  justify-self: stretch;
}

.ddga-carousel [data-slot=carousel-dots] {
  grid-area: dots;
}

.ddga-carousel__viewport {
  touch-action: pan-y;
  inline-size: 100%;
  min-inline-size: 0;
  overflow: hidden;
}

.ddga-carousel__track {
  inline-size: 100%;
  transform: translateX(calc(var(--ddga-carousel-index, 0) * -100%));
  will-change: transform;
  transition: transform 0.3s;
  display: flex;
}

[dir=rtl] .ddga-carousel__track {
  transform: translateX(calc(var(--ddga-carousel-index, 0) * 100%));
}

.ddga-carousel__slide {
  box-sizing: border-box;
  flex: 0 0 100%;
  min-inline-size: 0;
}

.ddga-carousel__dots {
  justify-content: center;
  align-items: center;
  gap: var(--ddga-space-2);
  padding: var(--ddga-space-3);
  border-radius: var(--ddga-radius-full);
  display: inline-flex;
}

.ddga-carousel__dots--bare {
  padding: 0;
}

.ddga-carousel__dot {
  border-radius: var(--ddga-radius-full);
  background-color: var(--ddga-color-border);
  cursor: pointer;
  border: none;
  flex-shrink: 0;
  padding: 0;
  transition: background-color 0.15s;
}

.ddga-carousel__dot[data-active] {
  background-color: var(--ddga-color-primary);
}

.ddga-carousel__dot:focus-visible {
  outline: 2px solid var(--ddga-text-primary);
  outline-offset: 2px;
}

.ddga-carousel__dots--sm .ddga-carousel__dot {
  block-size: 8px;
  inline-size: 8px;
}

.ddga-carousel__dots--md .ddga-carousel__dot {
  block-size: 12px;
  inline-size: 12px;
}

.ddga-carousel__dots--lg .ddga-carousel__dot {
  block-size: 16px;
  inline-size: 16px;
}

.ddga-carousel__nav {
  border-radius: var(--ddga-radius-full);
  cursor: pointer;
  border: none;
  flex-shrink: 0;
  justify-content: center;
  align-items: center;
  transition: background-color 0.15s, color 0.15s;
  display: inline-flex;
  position: relative;
}

.ddga-carousel__nav-icon {
  block-size: 24px;
  inline-size: 24px;
}

[dir=rtl] .ddga-carousel__nav-icon {
  transform: scaleX(-1);
}

.ddga-carousel__nav--sm {
  block-size: 32px;
  inline-size: 32px;
}

.ddga-carousel__nav--md {
  block-size: 40px;
  inline-size: 40px;
}

.ddga-carousel__nav--lg {
  block-size: 48px;
  inline-size: 48px;
}

.ddga-carousel__nav--primary {
  background-color: var(--ddga-color-primary);
  color: var(--ddga-color-primary-foreground);
}

.ddga-carousel__nav--primary:hover:not(:disabled):not([aria-disabled=true]) {
  background-color: var(--ddga-color-primary-hover);
}

.ddga-carousel__nav--primary:active:not(:disabled):not([aria-disabled=true]) {
  background-color: var(--ddga-color-primary-active);
}

.ddga-carousel__nav--primary:disabled, .ddga-carousel__nav--primary[aria-disabled=true] {
  background-color: var(--ddga-gray-200);
  color: var(--ddga-gray-400);
  cursor: not-allowed;
}

.ddga-carousel__nav--subtle {
  color: var(--ddga-text-primary);
  background-color: rgba(0, 0, 0, 0);
}

.ddga-carousel__nav--subtle:hover:not(:disabled):not([aria-disabled=true]) {
  background-color: var(--ddga-gray-100);
}

.ddga-carousel__nav--subtle:active:not(:disabled):not([aria-disabled=true]) {
  background-color: var(--ddga-gray-200);
}

.ddga-carousel__nav--subtle:disabled, .ddga-carousel__nav--subtle[aria-disabled=true] {
  color: var(--ddga-gray-400);
  cursor: not-allowed;
}

.ddga-carousel__nav:focus-visible {
  outline: none;
}

.ddga-carousel__nav:focus-visible:after {
  content: "";
  border: 3px solid var(--ddga-text-primary);
  border-radius: var(--ddga-radius-full);
  pointer-events: none;
  position: absolute;
  inset: -5px;
}

[data-theme=dark] .ddga-carousel__nav--subtle:hover:not(:disabled):not([aria-disabled=true]) {
  background-color: var(--ddga-color-muted);
}

[data-theme=dark] .ddga-carousel__nav--subtle:active:not(:disabled):not([aria-disabled=true]) {
  background-color: var(--ddga-color-border);
}

[data-theme=dark] .ddga-carousel__nav--primary:disabled, [data-theme=dark] .ddga-carousel__nav--primary[aria-disabled=true] {
  background-color: var(--ddga-color-muted);
}

@media (prefers-reduced-motion: reduce) {
  .ddga-carousel__track, .ddga-carousel__dot, .ddga-carousel__nav {
    transition: none;
  }
}
@media (forced-colors: active) {
  .ddga-carousel__dot[data-active] {
    background-color: highlight;
  }
  .ddga-carousel__dot:focus-visible, .ddga-carousel__nav:focus-visible:after {
    outline-offset: 2px;
    outline: 2px solid highlight;
  }
  .ddga-carousel__nav:disabled, .ddga-carousel__nav[aria-disabled=true] {
    color: graytext;
  }
}
/*# sourceMappingURL=carousel.css.map */
/* ── accordion — 31 rules, 1 @layer wrapper(s) removed ── */
.ddga-accordion {
  inline-size: 100%;
  color: var(--ddga-text-primary);
  border-block-end: 1px solid var(--ddga-color-input);
  flex-direction: column;
  display: flex;
}

.ddga-accordion__item {
  border-block-start: 1px solid var(--ddga-color-input);
}

.ddga-accordion__header {
  margin: 0;
  display: flex;
}

.ddga-accordion__trigger {
  appearance: none;
  justify-content: flex-start;
  align-items: center;
  gap: var(--ddga-space-4);
  inline-size: 100%;
  padding-inline: var(--ddga-space-4);
  padding-block: var(--ddga-space-4);
  color: var(--ddga-text-primary);
  font-family: inherit;
  font-size: var(--ddga-font-size-base);
  font-weight: var(--ddga-font-weight-semibold);
  text-align: start;
  cursor: pointer;
  background: 0 0;
  border: 0;
  margin: 0;
  line-height: 1.5rem;
  transition: background-color 0.15s;
  display: inline-flex;
}

.ddga-accordion__title {
  text-align: start;
  flex: 1 1 0;
  min-inline-size: 0;
}

.ddga-accordion__trigger:hover {
  background-color: var(--ddga-color-secondary);
}

.ddga-accordion__trigger:active {
  background-color: var(--ddga-color-secondary-hover);
}

.ddga-accordion__trigger:focus-visible {
  outline: 2px solid var(--ddga-color-focus-ring);
  outline-offset: -2px;
}

.ddga-accordion__trigger:disabled, .ddga-accordion__trigger[data-disabled] {
  color: var(--ddga-gray-400);
  cursor: not-allowed;
}

.ddga-accordion__trigger:disabled .ddga-accordion__chevron, .ddga-accordion__trigger[data-disabled] .ddga-accordion__chevron {
  color: var(--ddga-gray-400);
}

.ddga-accordion__chevron {
  block-size: 1rem;
  inline-size: 1rem;
  color: var(--ddga-text-primary);
  flex-shrink: 0;
  transition: transform 0.2s;
}

.ddga-accordion__trigger[data-state=open] .ddga-accordion__chevron {
  transform: rotate(180deg);
}

.ddga-accordion--icon-leading .ddga-accordion__chevron {
  order: -1;
}

.ddga-accordion__content {
  color: var(--ddga-gray-700);
  overflow: hidden;
}

.ddga-accordion__content[data-disabled] {
  color: var(--ddga-gray-400);
}

.ddga-accordion__content[data-state=open] {
  animation: 0.2s ease-out ddga-accordion-down;
}

.ddga-accordion__content[data-state=closed] {
  animation: 0.2s ease-out ddga-accordion-up;
}

.ddga-accordion__content-inner {
  padding-block-start: var(--ddga-space-2);
  padding-block-end: var(--ddga-space-6);
  padding-inline-start: var(--ddga-space-4);
  padding-inline-end: var(--ddga-space-12);
  line-height: 1.5rem;
}

@keyframes ddga-accordion-down {
  0% {
    block-size: 0;
  }
  to {
    block-size: var(--radix-accordion-content-height);
  }
}
@keyframes ddga-accordion-up {
  0% {
    block-size: var(--radix-accordion-content-height);
  }
  to {
    block-size: 0;
  }
}
.ddga-accordion--md .ddga-accordion__trigger {
  padding-block: var(--ddga-space-3);
}

.ddga-accordion--sm .ddga-accordion__trigger {
  padding-block: var(--ddga-space-2);
}

.ddga-accordion--flush .ddga-accordion__trigger {
  padding-inline: 0;
}

.ddga-accordion--flush .ddga-accordion__content-inner {
  padding-inline-start: 0;
}

@media (prefers-reduced-motion: reduce) {
  .ddga-accordion__content[data-state=open], .ddga-accordion__content[data-state=closed] {
    animation: none;
  }
  .ddga-accordion__chevron {
    transition: none;
  }
}
[data-theme=dark] .ddga-accordion__content {
  color: var(--ddga-gray-300);
}

@media (forced-colors: active) {
  .ddga-accordion, .ddga-accordion__item {
    border-color: canvastext;
  }
  .ddga-accordion__trigger:focus-visible {
    outline: 2px solid highlight;
  }
}
/*# sourceMappingURL=accordion.css.map */
/* ── tag — 47 rules, 1 @layer wrapper(s) removed ── */
.ddga-tag {
  justify-content: center;
  align-items: center;
  gap: var(--ddga-space-1);
  border-radius: var(--ddga-radius-full);
  font-weight: var(--ddga-font-weight-medium);
  white-space: nowrap;
  -webkit-user-select: none;
  user-select: none;
  border: 1px solid rgba(0, 0, 0, 0);
  font-family: inherit;
  line-height: 1.4;
  display: inline-flex;
}

.ddga-tag--sm {
  height: 20px;
  padding-inline: var(--ddga-space-2);
  font-size: var(--ddga-font-size-2xs);
  font-weight: var(--ddga-font-weight-semibold);
}

.ddga-tag--md {
  height: 24px;
  padding-inline: var(--ddga-space-2);
  font-size: var(--ddga-font-size-xs);
}

.ddga-tag--lg {
  height: 32px;
  padding-inline: var(--ddga-space-3);
  font-size: var(--ddga-font-size-base);
}

.ddga-tag--squared {
  border-radius: var(--ddga-radius-sm);
}

.ddga-tag--icon-only {
  aspect-ratio: 1;
  padding-inline: 0;
}

.ddga-tag--default {
  background-color: var(--ddga-gray-100);
  color: var(--ddga-gray-700);
}

.ddga-tag--primary {
  background-color: var(--ddga-color-primary);
  color: var(--ddga-color-primary-foreground);
}

.ddga-tag--secondary {
  background-color: var(--ddga-color-secondary);
  color: var(--ddga-color-secondary-foreground);
}

.ddga-tag--destructive {
  background-color: var(--ddga-color-destructive);
  color: var(--ddga-color-destructive-foreground);
}

.ddga-tag--success {
  background-color: var(--ddga-color-success);
  color: var(--ddga-color-success-foreground);
}

.ddga-tag--warning {
  background-color: var(--ddga-color-warning);
  color: var(--ddga-color-warning-foreground);
}

.ddga-tag--info {
  background-color: var(--ddga-color-info);
  color: var(--ddga-color-info-foreground);
}

.ddga-tag--primary-subtle {
  background-color: var(--ddga-sa-50);
  color: var(--ddga-sa-800);
  border-color: var(--ddga-sa-200);
}

.ddga-tag--secondary-subtle {
  background-color: var(--ddga-gray-50);
  color: var(--ddga-gray-800);
  border-color: var(--ddga-gray-200);
}

.ddga-tag--destructive-subtle {
  background-color: var(--ddga-error-50);
  color: var(--ddga-error-800);
  border-color: var(--ddga-error-200);
}

.ddga-tag--success-subtle {
  background-color: var(--ddga-success-50);
  color: var(--ddga-success-800);
  border-color: var(--ddga-success-200);
}

.ddga-tag--warning-subtle {
  background-color: var(--ddga-warning-50);
  color: var(--ddga-warning-800);
  border-color: var(--ddga-warning-200);
}

.ddga-tag--info-subtle {
  background-color: var(--ddga-info-50);
  color: var(--ddga-info-800);
  border-color: var(--ddga-info-200);
}

.ddga-tag--outline {
  color: var(--ddga-color-foreground);
  border-color: var(--ddga-color-border);
  background-color: rgba(0, 0, 0, 0);
}

.ddga-tag--on-color {
  background-color: var(--ddga-alpha-white-20);
  color: #fff;
}

.ddga-tag--outlined {
  background-color: rgba(0, 0, 0, 0);
}

.ddga-tag--outlined.ddga-tag--secondary-subtle {
  border-color: var(--ddga-gray-600);
}

.ddga-tag--outlined.ddga-tag--primary-subtle {
  border-color: var(--ddga-sa-700);
}

.ddga-tag--outlined.ddga-tag--success-subtle {
  border-color: var(--ddga-success-700);
}

.ddga-tag--outlined.ddga-tag--destructive-subtle {
  border-color: var(--ddga-error-700);
}

.ddga-tag--outlined.ddga-tag--warning-subtle {
  border-color: var(--ddga-warning-700);
}

.ddga-tag--outlined.ddga-tag--info-subtle {
  border-color: var(--ddga-info-700);
}

.ddga-tag--outlined.ddga-tag--on-color {
  border-color: var(--ddga-alpha-white-60);
}

.ddga-tag__icon {
  flex-shrink: 0;
  justify-content: center;
  align-items: center;
  display: inline-flex;
}

.ddga-tag__icon > svg, .ddga-tag > svg {
  display: block;
}

.ddga-tag--sm > svg, .ddga-tag--sm > .ddga-tag__icon > svg {
  width: 10px;
  height: 10px;
}

.ddga-tag--md > svg, .ddga-tag--md > .ddga-tag__icon > svg {
  width: 14px;
  height: 14px;
}

.ddga-tag--lg > svg, .ddga-tag--lg > .ddga-tag__icon > svg {
  width: 18px;
  height: 18px;
}

.ddga-tag svg {
  flex-shrink: 0;
  align-self: center;
}

.ddga-tag__close {
  border-radius: var(--ddga-radius-full);
  block-size: 1.5em;
  inline-size: 1.5em;
  color: inherit;
  cursor: pointer;
  font: inherit;
  appearance: none;
  background-color: rgba(0, 0, 0, 0);
  border: 0;
  justify-content: center;
  align-items: center;
  margin-inline: 0.125em -0.25em;
  padding: 0;
  display: inline-flex;
}

.ddga-tag__close > svg {
  block-size: 0.75em;
  inline-size: 0.75em;
}

.ddga-tag__close:hover {
  background-color: color-mix(in srgb, currentColor 18%, transparent);
}

.ddga-tag__close:focus-visible {
  outline: 2px solid var(--ddga-color-ring);
  outline-offset: 1px;
}

[data-theme=dark] .ddga-tag--default, [data-theme=dark] .ddga-tag--secondary-subtle {
  background-color: var(--ddga-alpha-white-10);
  color: var(--ddga-gray-200);
}

[data-theme=dark] .ddga-tag--primary-subtle {
  color: var(--ddga-sa-200, #b8eacb);
  background-color: rgba(27, 131, 84, 0.2);
}

[data-theme=dark] .ddga-tag--destructive-subtle {
  color: var(--ddga-error-200, #fecdca);
  background-color: rgba(217, 45, 32, 0.1803921569);
}

[data-theme=dark] .ddga-tag--success-subtle {
  color: var(--ddga-success-200, #abefc6);
  background-color: rgba(7, 148, 85, 0.1803921569);
}

[data-theme=dark] .ddga-tag--warning-subtle {
  color: var(--ddga-warning-200, #fedf89);
  background-color: rgba(220, 104, 3, 0.1803921569);
}

[data-theme=dark] .ddga-tag--info-subtle {
  color: var(--ddga-info-200, #b2ddff);
  background-color: rgba(21, 112, 239, 0.1607843137);
}

[data-theme=dark] .ddga-tag--secondary-subtle:not(.ddga-tag--outlined), [data-theme=dark] .ddga-tag--primary-subtle:not(.ddga-tag--outlined), [data-theme=dark] .ddga-tag--destructive-subtle:not(.ddga-tag--outlined), [data-theme=dark] .ddga-tag--success-subtle:not(.ddga-tag--outlined), [data-theme=dark] .ddga-tag--warning-subtle:not(.ddga-tag--outlined), [data-theme=dark] .ddga-tag--info-subtle:not(.ddga-tag--outlined) {
  border-color: rgba(0, 0, 0, 0);
}

@media (forced-colors: active) {
  .ddga-tag {
    border: 1px solid canvastext;
  }
}
/*# sourceMappingURL=tag.css.map */
/* ── pagination — 34 rules, 1 @layer wrapper(s) removed ── */
.ddga-pagination {
  color: var(--ddga-text-primary);
  font-family: inherit;
  line-height: 1.4;
}

.ddga-pagination__content {
  align-items: center;
  gap: var(--ddga-space-2);
  flex-wrap: wrap;
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
}

.ddga-pagination__item {
  display: inline-flex;
}

.ddga-pagination__link {
  box-sizing: border-box;
  min-inline-size: var(--_ddga-pg-box);
  block-size: var(--_ddga-pg-box);
  padding-inline: var(--_ddga-pg-pad);
  border-radius: var(--ddga-radius-sm);
  color: var(--ddga-text-primary);
  cursor: pointer;
  background-color: rgba(0, 0, 0, 0);
  border: none;
  justify-content: center;
  align-items: center;
  font-family: inherit;
  text-decoration: none;
  transition: background-color 0.15s, border-color 0.15s;
  display: inline-flex;
  position: relative;
}

.ddga-pagination__link:hover {
  background-color: var(--ddga-color-muted);
}

.ddga-pagination__link:focus-visible {
  box-shadow: inset 0 0 0 2px var(--ddga-text-primary);
  outline: none;
}

.ddga-pagination__link[aria-disabled=true] {
  color: var(--ddga-gray-400);
  pointer-events: none;
}

.ddga-pagination__link--active:after {
  content: "";
  inline-size: var(--_ddga-pg-underline-w);
  border-radius: var(--ddga-radius-full);
  background-color: var(--ddga-color-primary);
  block-size: 3px;
  position: absolute;
  inset-block-end: var(--_ddga-pg-underline-bottom);
  inset-inline-start: 50%;
  transform: translate(-50%);
}

[dir=rtl] .ddga-pagination__link--active:after {
  transform: translate(50%);
}

.ddga-pagination__nav {
  padding-inline: 0;
}

.ddga-pagination__nav-icon {
  block-size: 1.25em;
  inline-size: 1.25em;
}

[dir=rtl] .ddga-pagination__nav-icon {
  transform: scaleX(-1);
}

.ddga-pagination__ellipsis, .ddga-pagination__overflow {
  box-sizing: border-box;
  border: 1px solid var(--ddga-text-primary);
  border-radius: var(--ddga-radius-sm);
}

.ddga-pagination__ellipsis {
  min-inline-size: var(--_ddga-pg-box);
  block-size: var(--_ddga-pg-box);
  color: var(--ddga-text-primary);
  justify-content: center;
  align-items: center;
  display: inline-flex;
}

.ddga-pagination__overflow[data-state=open], .ddga-pagination__overflow:focus-visible {
  background-color: var(--ddga-color-muted);
  border-width: 2px;
}

.ddga-pagination__overflow:focus-visible {
  box-shadow: none;
}

.ddga-pagination__ellipsis-icon {
  block-size: 1em;
  inline-size: 1em;
}

.ddga-pagination__menu {
  box-sizing: border-box;
  padding: var(--ddga-space-1);
  background-color: var(--ddga-color-background);
  border: 1px solid var(--ddga-color-input);
  border-radius: var(--ddga-radius-sm);
  box-shadow: var(--ddga-shadow-xl);
  z-index: 50;
  outline: none;
  font-family: inherit;
}

.ddga-pagination__menu-item {
  align-items: center;
  gap: var(--ddga-space-2);
  box-sizing: border-box;
  inline-size: 3.75rem;
  padding: var(--ddga-space-2);
  border-radius: var(--ddga-radius-sm);
  color: var(--ddga-text-primary);
  font-size: var(--ddga-font-size-sm);
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
  outline: none;
  line-height: 1.4;
  display: flex;
}

.ddga-pagination__menu-item[data-highlighted] {
  background-color: var(--ddga-color-muted);
}

.ddga-pagination__menu-label {
  flex: auto;
  min-inline-size: 0;
}

.ddga-pagination__menu-check {
  block-size: 1.25rem;
  inline-size: 1.25rem;
  color: var(--ddga-text-primary);
  flex-shrink: 0;
}

@media (forced-colors: active) {
  .ddga-pagination__menu {
    border: 1px solid canvastext;
  }
  .ddga-pagination__menu-item[data-highlighted] {
    color: highlighttext;
    background-color: highlight;
  }
}
.ddga-pagination--sm {
  --_ddga-pg-box:1.5rem;
  --_ddga-pg-pad:var(--ddga-space-1);
  --_ddga-pg-underline-w:1rem;
  --_ddga-pg-underline-bottom:1px;
}

.ddga-pagination--md {
  --_ddga-pg-box:2rem;
  --_ddga-pg-pad:.375rem;
  --_ddga-pg-underline-w:1.5rem;
  --_ddga-pg-underline-bottom:2px;
}

.ddga-pagination--lg {
  --_ddga-pg-box:2.5rem;
  --_ddga-pg-pad:var(--ddga-space-2);
  --_ddga-pg-underline-w:1.5rem;
  --_ddga-pg-underline-bottom:3px;
}

.ddga-pagination--sm .ddga-pagination__link, .ddga-pagination--sm .ddga-pagination__ellipsis {
  font-size: var(--ddga-font-size-sm);
}

.ddga-pagination--md .ddga-pagination__link, .ddga-pagination--md .ddga-pagination__ellipsis, .ddga-pagination--lg .ddga-pagination__link, .ddga-pagination--lg .ddga-pagination__ellipsis {
  font-size: var(--ddga-font-size-base);
}

@media (prefers-reduced-motion: reduce) {
  .ddga-pagination__link {
    transition: none;
  }
}
@media (forced-colors: active) {
  .ddga-pagination__link {
    color: linktext;
  }
  .ddga-pagination__link:focus-visible {
    outline-offset: 2px;
    outline: 2px solid highlight;
  }
  .ddga-pagination__link--active:after {
    background-color: highlight;
  }
  .ddga-pagination__ellipsis, .ddga-pagination__overflow {
    border-color: canvastext;
  }
}
/*# sourceMappingURL=pagination.css.map */
/* The two DGA components the generator's COMPONENTS list does not carry yet, ported
   the same way and delayered the same way. PRT-AUTH-01's العمر control is the DGA
   date picker; before this import the page carried no .ddga-date-picker-trigger rule
   at all, so the control rendered borderless and 24px tall. Imported HERE, directly
   after the generated partial, so the cascade position is identical — guard rule 2
   in scripts/check-theme-css-order.sh (DGA component rules must compile after Clay).
   Delete this line together with the partial once "date-picker" and "calendar" join
   tools/dga-port/port-components.mjs. */
/* ─────────────────────────────────────────────────────────────────────────────
   DGA date controls — MECHANICALLY PORTED, DO NOT EDIT BY HAND.

   Source:    @dev-dga/css v0.12.0 (dist/components/{date-picker,calendar}.css)
   Delayered the same way tools/dga-port/port-components.mjs delayered the four it
   carried, and for the same reason: upstream ships these inside
   "@layer ddga-components", Liferay's Clay and theme CSS are unlayered, and
   unlayered CSS beats layered CSS regardless of specificity.

   WHY THIS IS A SEPARATE PARTIAL AND NOT PART OF THE GENERATED ONE.
   The generator's COMPONENTS list was a one-line edit in tools/dga-port/, which was
   not mine to change on this project. The proper home for these two was that list.

   ⚠ THAT EXIT CONDITION IS VOID AS OF 2026-07-28. tools/dga-port/ was removed with
   frontend-source/ (README §15). The instruction that used to sit here — "when
   date-picker and calendar are added to the COMPONENTS list, DELETE this file and
   its @import from _custom.scss" — CANNOT BE FOLLOWED: there is no list, and no
   regeneration will ever fold these two in. So DO NOT DELETE THIS FILE waiting for
   that to happen; it is now permanent, and hand-maintained like its siblings. Its
   separation from _dga-admin-components.scss is now merely historical, not pending.

   WHY THEY ARE NEEDED. PRT-AUTH-01's العمر control is the DGA date picker: Figma
   draws a bordered box whose only content is the placeholder «يوم/شهر/سنة» and no
   glyph, which is .ddga-date-picker-trigger in its placeholder state. Measured on
   the deployed page before this file existed: zero stylesheets carried a
   .ddga-date-picker-trigger rule, so the control rendered with no border and a
   24px height. Directive 11 forbids hand-rolling a lookalike in fragment CSS.

   Design tokens are NOT here — they come from the Stylebook (directive 1).
   ──────────────────────────────────────────────────────────────────────────── */
/* ── date-picker — 41 rules, 1 @layer wrapper(s) removed ── */
.ddga-field[data-slot=date-picker-field] {
  gap: var(--ddga-space-2);
}

.ddga-date-picker__label {
  align-items: center;
  gap: var(--ddga-space-1);
  color: var(--ddga-text-primary);
  font-weight: var(--ddga-font-weight-regular);
  font-size: var(--ddga-font-size-sm);
  line-height: 1.4286;
  display: inline-flex;
}

.ddga-date-picker__required {
  color: var(--ddga-error-700);
}

.ddga-date-picker-trigger {
  align-items: center;
  gap: var(--ddga-space-2);
  inline-size: 100%;
  padding-inline: var(--ddga-space-2);
  border: 1px solid var(--ddga-gray-400);
  border-radius: var(--ddga-radius-sm);
  background-color: var(--ddga-color-background);
  color: var(--ddga-gray-700);
  text-align: start;
  transition: border-color 0.15s, box-shadow 0.15s, background-color 0.15s;
  display: flex;
  position: relative;
}

.ddga-date-picker-trigger--md {
  block-size: 32px;
  font-size: var(--ddga-font-size-sm);
}

.ddga-date-picker-trigger--lg {
  block-size: 40px;
  font-size: var(--ddga-font-size-base);
}

.ddga-date-picker-trigger--filled-lighter {
  background-color: var(--ddga-gray-25);
  border-color: rgba(0, 0, 0, 0);
}

.ddga-date-picker-trigger--filled-darker {
  background-color: var(--ddga-gray-100);
  border-color: rgba(0, 0, 0, 0);
}

.ddga-date-picker__input {
  font-variant-numeric: tabular-nums;
  direction: ltr;
  flex: 0 auto;
  align-items: center;
  min-inline-size: 0;
  display: inline-flex;
}

[dir=rtl] .ddga-date-picker__input {
  direction: rtl;
}

.ddga-date-picker__segment {
  border-radius: var(--ddga-radius-sm);
  color: var(--ddga-gray-700);
  font-variant-numeric: tabular-nums;
  -webkit-tap-highlight-color: transparent;
  outline: none;
  padding-block: 1px;
  padding-inline: 1px;
}

.ddga-date-picker__segment[data-placeholder] {
  color: var(--ddga-gray-500);
}

.ddga-date-picker__segment[data-focused] {
  background-color: var(--ddga-color-primary);
  color: var(--ddga-color-primary-foreground);
}

.ddga-date-picker__segment[data-type=literal] {
  color: var(--ddga-gray-700);
  padding-inline: 0;
}

.ddga-date-picker__segment[data-type=literal][data-focused] {
  color: var(--ddga-gray-700);
  background-color: rgba(0, 0, 0, 0);
}

.ddga-date-picker__open {
  min-inline-size: var(--ddga-space-4);
  cursor: pointer;
  background: 0 0;
  border: 0;
  outline: none;
  flex: auto;
  align-self: stretch;
  padding: 0;
}

.ddga-date-picker-trigger[data-disabled] .ddga-date-picker__open {
  cursor: not-allowed;
}

.ddga-date-picker-trigger--default[data-hovered]:not([data-focus-within]) {
  border-color: var(--ddga-gray-700);
}

.ddga-date-picker-trigger[data-focus-within] {
  box-shadow: var(--ddga-shadow-md);
}

.ddga-date-picker-trigger[data-focus-within]:not([data-pressed]):after {
  content: "";
  inset-inline: 0;
  background-color: var(--ddga-gray-950);
  block-size: 2px;
  position: absolute;
  bottom: -1px;
}

.ddga-date-picker-trigger[data-pressed]:not([data-disabled]):not([data-readonly]), .ddga-date-picker-trigger--pressed {
  background-color: var(--ddga-gray-100);
}

.ddga-date-picker-trigger[data-pressed]:not([data-disabled]):not([data-readonly]):after, .ddga-date-picker-trigger--pressed:after {
  content: "";
  inset-inline: 25%;
  background-color: var(--ddga-gray-950);
  block-size: 2px;
  position: absolute;
  bottom: -1px;
}

.ddga-date-picker-trigger--error, .ddga-date-picker-trigger--error[data-hovered], .ddga-date-picker-trigger--error[data-focus-within] {
  border-color: var(--ddga-error-700);
}

.ddga-date-picker-trigger[data-readonly], .ddga-date-picker-trigger[data-disabled] {
  border-color: var(--ddga-gray-300);
  background-color: rgba(0, 0, 0, 0);
}

.ddga-date-picker-trigger[data-disabled] {
  cursor: not-allowed;
}

.ddga-date-picker-trigger[data-disabled] .ddga-date-picker__segment, .ddga-date-picker-trigger[data-disabled] .ddga-date-picker__segment[data-placeholder], :is(.ddga-field:has(.ddga-date-picker-trigger[data-disabled]) .ddga-date-picker__label, .ddga-field:has(.ddga-date-picker-trigger[data-disabled]) .ddga-date-picker__required) {
  color: var(--ddga-gray-400);
}

.ddga-field:has(.ddga-date-picker-trigger) .ddga-field__message {
  padding-block: var(--ddga-space-1);
}

[data-theme=dark] .ddga-date-picker-trigger {
  border-color: var(--ddga-color-input);
  color: var(--ddga-text-primary);
}

[data-theme=dark] .ddga-date-picker__segment {
  color: var(--ddga-text-primary);
}

[data-theme=dark] .ddga-date-picker__segment[data-placeholder] {
  color: var(--ddga-text-placeholder);
}

[data-theme=dark] .ddga-date-picker-trigger--filled-lighter, [data-theme=dark] .ddga-date-picker-trigger--filled-darker {
  background-color: var(--ddga-color-muted);
}

[data-theme=dark] .ddga-date-picker-trigger--default[data-hovered]:not([data-focus-within]) {
  border-color: var(--ddga-gray-500);
}

[data-theme=dark] .ddga-date-picker-trigger[data-focus-within]:after, [data-theme=dark] .ddga-date-picker-trigger[data-pressed]:not([data-disabled]):not([data-readonly]):after, [data-theme=dark] .ddga-date-picker-trigger--pressed:after {
  background-color: var(--ddga-text-primary);
}

[data-theme=dark] .ddga-date-picker-trigger[data-pressed]:not([data-disabled]):not([data-readonly]), [data-theme=dark] .ddga-date-picker-trigger--pressed {
  background-color: var(--ddga-color-muted);
}

[data-theme=dark] .ddga-date-picker-trigger[data-readonly], [data-theme=dark] .ddga-date-picker-trigger[data-disabled] {
  border-color: var(--ddga-color-border);
}

[data-theme=dark] .ddga-date-picker-trigger[data-disabled] .ddga-date-picker__segment, [data-theme=dark] .ddga-date-picker-trigger[data-disabled] .ddga-date-picker__segment[data-placeholder] {
  color: var(--ddga-text-tertiary);
}

@media (prefers-reduced-motion: reduce) {
  .ddga-date-picker-trigger {
    transition: none;
  }
}
@media (forced-colors: active) {
  .ddga-date-picker-trigger {
    border: 1px solid canvastext;
  }
  .ddga-date-picker-trigger[data-focus-within] {
    outline-offset: 1px;
    outline: 2px solid highlight;
  }
  .ddga-date-picker-trigger[data-disabled] {
    border-color: graytext;
  }
  .ddga-date-picker-trigger[data-disabled] .ddga-date-picker__segment {
    color: graytext;
  }
}
/* ONE substitution in the vendored calendar block, recorded here rather than
   left silent. The DGA build emits
       .ddga-calendar-toggle__button[data-active]{box-shadow:0 1px 2px #00000014}
   — a raw literal in its own compiled output, which check-color-literals
   correctly refuses. It is replaced with var(--ddga-shadow-xs), DGA's own token
   for that shadow: identical geometry (0 1px 2px 0) and, unlike the literal,
   it re-points per mode (light rgb(16 24 40 / 0.05), dark rgb(0 0 0 / 0.3))
   instead of staying a fixed 8%-black in dark. The alpha is not byte-identical
   to the literal — that difference is deliberate and is the point of using the
   token. Nothing else in this vendored block is altered. */
/* ── calendar — 48 rules, 1 @layer wrapper(s) removed ── */
.ddga-calendar-popover {
  z-index: 50;
  background-color: var(--ddga-color-background);
  color: var(--ddga-color-foreground);
  border-radius: var(--ddga-radius-md);
  box-shadow: var(--ddga-shadow-2xl);
  display: flex;
  overflow: hidden;
}

.ddga-calendar-popover[data-entering] {
  animation: 0.12s cubic-bezier(0.16, 1, 0.3, 1) ddga-calendar-in;
}

.ddga-calendar-popover[data-exiting] {
  animation: 80ms ease-in ddga-calendar-out;
}

@keyframes ddga-calendar-in {
  0% {
    opacity: 0;
    transform: translateY(-2px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}
@keyframes ddga-calendar-out {
  0% {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}
.ddga-calendar-dialog {
  min-block-size: 0;
  max-block-size: 100%;
  padding: var(--ddga-space-4);
  box-sizing: border-box;
  outline: none;
  flex: auto;
  overflow: auto;
}

.ddga-calendar-toggle {
  inline-size: 100%;
  background-color: var(--ddga-color-muted);
  border-radius: var(--ddga-radius-md);
  margin-block-end: var(--ddga-space-3);
  padding: 2px;
  display: inline-flex;
}

.ddga-calendar-toggle__button {
  padding-block: var(--ddga-space-1);
  padding-inline: var(--ddga-space-2);
  border-radius: calc(var(--ddga-radius-md) - 2px);
  color: var(--ddga-text-secondary);
  font: inherit;
  font-size: var(--ddga-font-size-sm);
  font-weight: var(--ddga-font-weight-medium);
  cursor: pointer;
  background-color: rgba(0, 0, 0, 0);
  border: 0;
  outline: none;
  flex: 1 1 0;
  transition: background-color 0.12s, color 0.12s;
}

.ddga-calendar-toggle__button[data-active] {
  background-color: var(--ddga-color-background);
  color: var(--ddga-color-foreground);
  box-shadow: var(--ddga-shadow-xs);
}

.ddga-calendar-toggle__button:focus-visible {
  box-shadow: 0 0 0 2px var(--ddga-color-ring);
}

.ddga-calendar {
  inline-size: 392px;
  max-inline-size: 100%;
}

.ddga-calendar__header {
  align-items: center;
  gap: var(--ddga-space-2);
  block-size: 40px;
  margin-block-end: var(--ddga-space-2);
  display: flex;
}

.ddga-calendar__nav-group {
  align-items: center;
  margin-inline-start: auto;
  display: inline-flex;
}

.ddga-calendar__nav {
  border-radius: var(--ddga-radius-sm);
  block-size: 40px;
  inline-size: 40px;
  color: var(--ddga-text-primary);
  cursor: pointer;
  background-color: rgba(0, 0, 0, 0);
  border: 0;
  outline: none;
  justify-content: center;
  align-items: center;
  padding: 0;
  display: inline-flex;
}

.ddga-calendar__nav:hover {
  background-color: var(--ddga-color-muted);
  color: var(--ddga-color-foreground);
}

.ddga-calendar__nav[data-focus-visible] {
  box-shadow: 0 0 0 2px var(--ddga-color-ring);
}

.ddga-calendar__nav[data-disabled] {
  color: var(--ddga-text-tertiary);
  cursor: not-allowed;
}

.ddga-calendar__heading {
  font-size: var(--ddga-font-size-sm);
  font-weight: var(--ddga-font-weight-semibold);
  text-align: center;
  color: var(--ddga-color-foreground);
  flex: auto;
  margin: 0;
}

.ddga-calendar__nav-selects {
  align-items: center;
  gap: var(--ddga-space-2);
  min-inline-size: 0;
  display: inline-flex;
}

.ddga-calendar__select {
  appearance: none;
  border-radius: var(--ddga-radius-sm);
  font: inherit;
  font-weight: var(--ddga-font-weight-medium);
  color: var(--ddga-text-primary);
  cursor: pointer;
  font-variant-numeric: tabular-nums;
  background-color: rgba(0, 0, 0, 0);
  border: 1px solid rgba(0, 0, 0, 0);
  outline: none;
  max-inline-size: 100%;
  margin: 0;
}

.ddga-calendar__select:focus-visible {
  box-shadow: 0 0 0 2px var(--ddga-text-primary);
}

.ddga-calendar__select option {
  color: canvastext;
  background-color: canvas;
}

.ddga-calendar__month-select {
  font-size: var(--ddga-font-size-base);
  line-height: var(--ddga-line-height-base, 1.5);
  padding: 0;
}

.ddga-calendar__year-chip {
  border-radius: var(--ddga-radius-sm);
  align-items: center;
  display: inline-flex;
  position: relative;
}

.ddga-calendar__year-chip:hover {
  background-color: var(--ddga-color-muted);
}

.ddga-calendar__year-select {
  block-size: 32px;
  padding-inline: var(--ddga-space-3) calc(var(--ddga-space-3) + 1rem);
  font-size: var(--ddga-font-size-sm);
  min-inline-size: 4.5ch;
}

.ddga-calendar__year-chevron {
  pointer-events: none;
  block-size: 1rem;
  inline-size: 1rem;
  color: var(--ddga-text-primary);
  position: absolute;
  inset-inline-end: var(--ddga-space-2);
}

.ddga-calendar__grid {
  border-collapse: separate;
  inline-size: 100%;
  border-spacing: 0 var(--ddga-space-1);
}

.ddga-calendar__weekday {
  padding-block: var(--ddga-space-1);
  font-size: var(--ddga-font-size-base);
  font-weight: var(--ddga-font-weight-regular);
  color: var(--ddga-text-tertiary);
  text-align: center;
}

.ddga-calendar__cell {
  appearance: none;
  text-align: center;
  block-size: 2.5rem;
  inline-size: 2.5rem;
  font-size: var(--ddga-font-size-base);
  font-variant-numeric: tabular-nums;
  color: var(--ddga-color-foreground);
  border-radius: var(--ddga-radius-full);
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  background-color: rgba(0, 0, 0, 0);
  border: 0;
  outline: none;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  margin-inline: auto;
  padding: 0;
  line-height: 1;
  display: inline-flex;
}

.ddga-calendar__cell[data-today]:not([data-selected]) {
  box-shadow: inset 0 0 0 2px var(--ddga-color-primary);
  color: var(--ddga-color-primary);
  font-weight: var(--ddga-font-weight-medium);
}

.ddga-calendar__cell-primary {
  font-size: inherit;
  line-height: 1;
}

.ddga-calendar__cell-secondary {
  font-size: var(--ddga-font-size-xs);
  color: var(--ddga-text-tertiary);
  margin-block-start: 1px;
  line-height: 1;
}

.ddga-calendar__cell[data-selected] .ddga-calendar__cell-secondary {
  color: inherit;
  opacity: 0.85;
}

.ddga-calendar__cell[data-hovered]:not([data-disabled]):not([data-selected]) {
  background-color: var(--ddga-sa-100);
}

.ddga-calendar__cell[data-pressed]:not([data-disabled]):not([data-selected]) {
  background-color: var(--ddga-sa-200);
}

.ddga-calendar__cell[data-focus-visible] {
  box-shadow: inset 0 0 0 2px var(--ddga-text-primary);
}

.ddga-calendar__cell[data-selected] {
  background-color: var(--ddga-color-primary);
  color: var(--ddga-color-primary-foreground);
}

.ddga-calendar__cell[data-disabled], .ddga-calendar__cell[data-unavailable] {
  color: var(--ddga-text-placeholder);
  cursor: not-allowed;
}

.ddga-calendar__cell[data-outside-month] {
  color: var(--ddga-text-tertiary);
}

@media (prefers-reduced-motion: reduce) {
  .ddga-calendar-toggle__button {
    transition: none;
  }
  .ddga-calendar-popover[data-entering], .ddga-calendar-popover[data-exiting] {
    animation: none;
  }
}
@media (forced-colors: active) {
  .ddga-calendar-popover {
    border: 1px solid canvastext;
  }
  .ddga-calendar__cell[data-selected] {
    color: highlighttext;
    background-color: highlight;
  }
  .ddga-calendar__cell[data-focus-visible] {
    outline-offset: 1px;
    outline: 2px solid highlight;
  }
  .ddga-calendar-toggle__button[data-active] {
    color: highlighttext;
    background-color: highlight;
  }
}
/* Third one, same port and same delayer, added 2026-08-09. الجنسية went from 11
   options to 177 (every non-Arab country), and a 177-option native <select> cannot be
   used without a filter — so the control becomes a combobox whose list is DGA's own
   `command` searchable-list primitive. Hand-rolling that panel in fragment CSS is what
   directive 11 forbids and what produced dga-date-controls above. Imported in the same
   position, directly after the generated partial, so the cascade position is identical
   (guard rule 2 in scripts/check-theme-css-order.sh). PERMANENT, for the reason the
   block above gives: there is no COMPONENTS list left to fold it into. */
/* ─────────────────────────────────────────────────────────────────────────────
   DGA command (searchable list) — MECHANICALLY PORTED, DO NOT EDIT BY HAND.

   Source:    @dev-dga/css v0.12.0 (dist/components/command.css)
   Delayered exactly as _dga-date-controls.scss delayered date-picker/calendar, and
   for the same reason: upstream ships this inside "@layer ddga-components", Liferay's
   Clay and theme CSS are unlayered, and unlayered CSS beats layered CSS regardless of
   specificity. 1 @layer wrapper removed and the sourceMappingURL comment
   dropped; nothing else changed. Brace balance asserted after the delayer, because a
   delayer that eats one brace too many fails silently and only shows up as one
   unstyled rule at the end of the file.

   WHY IT IS NEEDED. الجنسية carries 177 countries as of 2026-08-09, and a 177-option
   native <select> is not usable without a filter. DGA ships `command` as its official
   searchable-list primitive (__input-wrapper / __search-icon / __input / __list /
   __item / __empty), so directive 11 forbids hand-rolling a lookalike in fragment CSS
   — the same ruling that produced _dga-date-controls.scss.

   Design tokens are NOT here — they come from the Stylebook (directive 1).
   ──────────────────────────────────────────────────────────────────────────── */
.ddga-command {
  background-color: var(--ddga-color-card);
  min-block-size: 0;
  inline-size: 100%;
  color: var(--ddga-color-card-foreground);
  border: 1px solid var(--ddga-color-border);
  border-radius: var(--ddga-radius-md);
  flex-direction: column;
  display: flex;
  overflow: hidden;
}

.ddga-command--dialog {
  background-color: rgba(0, 0, 0, 0);
  border: 0;
  border-radius: 0;
}

.ddga-command__input-wrapper {
  align-items: center;
  gap: var(--ddga-space-2);
  padding-inline: var(--ddga-space-3);
  border-block-end: 1px solid var(--ddga-color-border);
  display: flex;
}

.ddga-command__search-icon {
  block-size: 1rem;
  inline-size: 1rem;
  color: var(--ddga-text-secondary);
  flex-shrink: 0;
}

.ddga-command__input {
  min-inline-size: 0;
  padding-block: var(--ddga-space-3);
  color: inherit;
  font: inherit;
  background-color: rgba(0, 0, 0, 0);
  border: 0;
  outline: none;
  flex: auto;
}

.ddga-command__input::placeholder {
  color: var(--ddga-text-placeholder);
}

.ddga-command__list {
  min-block-size: 0;
  max-block-size: min(360px, 60vh);
  padding: var(--ddga-space-1);
  scroll-padding-block: var(--ddga-space-1);
  flex: auto;
  overflow: hidden auto;
}

.ddga-command__empty {
  padding-block: var(--ddga-space-5);
  padding-inline: var(--ddga-space-3);
  font-size: var(--ddga-font-size-sm);
  color: var(--ddga-text-tertiary);
  text-align: center;
}

.ddga-command__group [cmdk-group-heading] {
  padding-block: var(--ddga-space-1);
  padding-inline: var(--ddga-space-2);
  font-size: var(--ddga-font-size-xs);
  font-weight: var(--ddga-font-weight-semibold);
  color: var(--ddga-text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

[dir=rtl] .ddga-command__group [cmdk-group-heading] {
  letter-spacing: normal;
  text-transform: none;
}

.ddga-command__separator {
  block-size: 1px;
  margin-block: var(--ddga-space-1);
  background-color: var(--ddga-color-border);
}

.ddga-command__item {
  align-items: center;
  gap: var(--ddga-space-2);
  padding-block: var(--ddga-space-2);
  padding-inline: var(--ddga-space-2);
  border-radius: var(--ddga-radius-sm);
  font-size: var(--ddga-font-size-sm);
  color: inherit;
  cursor: default;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  outline: none;
  display: flex;
}

.ddga-command__item[data-selected=true] {
  background-color: var(--ddga-color-muted);
}

.ddga-command__item[data-disabled=true] {
  color: var(--ddga-text-tertiary);
  pointer-events: none;
}

.ddga-command__item-icon {
  block-size: 1rem;
  inline-size: 1rem;
  color: var(--ddga-text-secondary);
  flex-shrink: 0;
  justify-content: center;
  align-items: center;
  display: inline-flex;
}

.ddga-command__item-icon > svg {
  block-size: 1rem;
  inline-size: 1rem;
}

.ddga-command__item-label {
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: auto;
  min-inline-size: 0;
  overflow: hidden;
}

.ddga-command__item-shortcut {
  font-size: var(--ddga-font-size-xs);
  letter-spacing: 0.05em;
  color: var(--ddga-text-tertiary);
  flex-shrink: 0;
  margin-inline-start: auto;
}

[dir=rtl] .ddga-command__item-shortcut {
  letter-spacing: normal;
}

.ddga-command__overlay {
  z-index: 60;
  background-color: rgba(0, 0, 0, 0.5019607843);
  animation-duration: 0.15s;
  animation-timing-function: ease;
  position: fixed;
  inset: 0;
}

.ddga-command-dialog {
  inset-block-start: 12vh;
  z-index: 61;
  inline-size: min(var(--ddga-command-dialog-width, 640px), 100vw - 2rem);
  background-color: var(--ddga-color-card);
  max-block-size: min(70vh, 480px);
  color: var(--ddga-color-card-foreground);
  border: 1px solid var(--ddga-color-border);
  border-radius: var(--ddga-radius-lg);
  box-shadow: var(--ddga-shadow-lg);
  flex-direction: column;
  animation-duration: 0.18s;
  animation-timing-function: ease;
  display: flex;
  position: fixed;
  left: 50%;
  overflow: hidden;
  transform: translate(-50%);
}

.ddga-command-dialog .ddga-command {
  min-block-size: 0;
}

.ddga-command-dialog .ddga-command__list {
  max-block-size: none;
}

.ddga-command__overlay[data-state=open] {
  animation-name: ddga-command-overlay-in;
}

.ddga-command__overlay[data-state=closed] {
  animation-name: ddga-command-overlay-out;
}

.ddga-command-dialog[data-state=open] {
  animation-name: ddga-command-dialog-in;
}

.ddga-command-dialog[data-state=closed] {
  animation-name: ddga-command-dialog-out;
}

@keyframes ddga-command-overlay-in {
  0% {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
@keyframes ddga-command-overlay-out {
  0% {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}
@keyframes ddga-command-dialog-in {
  0% {
    opacity: 0;
    transform: translate(-50%) translateY(-8px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translate(-50%) translateY(0) scale(1);
  }
}
@keyframes ddga-command-dialog-out {
  0% {
    opacity: 1;
    transform: translate(-50%) translateY(0) scale(1);
  }
  to {
    opacity: 0;
    transform: translate(-50%) translateY(-8px) scale(0.98);
  }
}
@media (prefers-reduced-motion: reduce) {
  .ddga-command__overlay, .ddga-command-dialog {
    animation-duration: 0s;
  }
}
@media (forced-colors: active) {
  .ddga-command, .ddga-command-dialog {
    border: 1px solid canvastext;
  }
  .ddga-command__item[data-selected=true] {
    color: highlighttext;
    background-color: highlight;
  }
  .ddga-command__separator {
    background-color: canvastext;
  }
}
/* Same story again, for the SUPERVISOR dashboard (/admin/*, register rows ADM-*).
   Those screens are the first surface to need the DGA Table, Checkbox, Search Box
   and form controls (field / text-input / textarea / select / switch); before this
   import the page carried no .ddga-table rule at all. Ported and delayered by the
   same transform, imported HERE for the identical cascade position. Delete this line
   together with the partial once those names join tools/dga-port/port-components.mjs. */
/* ─────────────────────────────────────────────────────────────────────────────
   DGA Platform Code component classes (SUPERVISOR /admin screens) —
   GENERATED, DO NOT EDIT BY HAND.

   Source:    @dev-dga/css v0.12.0 (dist/components/*.css)
   Generator: tools/dga-port/port-components.mjs transform  ← REMOVED, see below
   Components: table, checkbox, search-box, field, text-input, textarea, select, switch, modal, dropdown-menu, metric

   WHY A SECOND PARTIAL. tools/dga-port/port-components.mjs carried the component
   allow-list `COMPONENTS = ["button", "carousel", "accordion", "tag"]` and emitted
   _dga-components.scss. The supervisor dashboard (register rows ADM-*) is the first
   surface to need the DGA Table, Checkbox, Search Box and form controls. The correct
   permanent fix WAS to append these names to that array and re-run it, folding them
   into _dga-components.scss and deleting this file. That script was outside the
   authoring agent's boundary, so the same transform was re-run here instead of
   hand-writing CSS — directive 11 forbids a lookalike, and these rules are
   byte-derived from @dev-dga/css, not reimplemented.

   ⚠ GENERATOR REMOVED 2026-07-28 — THAT MERGE CAN NO LONGER HAPPEN.
   tools/dga-port/ went with frontend-source/ (README §15). There is no COMPONENTS
   array left to append to, so THIS FILE IS NOW PERMANENT rather than transitional,
   and it is hand-maintained. Two consequences worth knowing before you edit it:
     · scripts/check-color-literals.sh still exempts this file as vendor output. Its
       literals ARE still vendor bytes — but a literal added from here on may well be
       hand-written, and the exemption will not tell you apart. That note is in the
       guard too.
     · the delayering below is no longer reproducible by re-running anything; it is
       baked in. check-theme-css-order.sh is the only backstop.

   ⚠ DELAYERED ON PURPOSE. Upstream ships these inside "@layer ddga-components".
   Liferay's Clay and theme CSS are unlayered, and unlayered CSS beats layered CSS
   regardless of specificity — so layered rules here would never win. The layer
   wrapper is stripped and the rules emitted plain. scripts/check-theme-css-order.sh
   fails the build if an @layer reappears.

   Design tokens are NOT here — they come from the Stylebook (directive 1). These
   rules consume them through var(--ddga-*).
   ──────────────────────────────────────────────────────────────────────────── */
/* ── table — 47 rules, 1 @layer wrapper(s) removed ── */
.ddga-table__region {
  inline-size: 100%;
  overflow: auto hidden;
}

.ddga-table__region[role=region]:focus-visible {
  outline: 2px solid var(--ddga-color-ring);
  outline-offset: 2px;
}

.ddga-table__region:has(> .ddga-table--contained) {
  border: 1px solid var(--ddga-color-input);
  border-radius: var(--ddga-radius-sm);
}

.ddga-table {
  --ddga-table-pad-block:var(--ddga-space-2);
  --ddga-table-pad-inline:var(--ddga-space-4);
  --ddga-table-row-h:4rem;
  border-collapse: collapse;
  inline-size: 100%;
  color: var(--ddga-text-primary);
  font-size: var(--ddga-font-size-base);
  background-color: var(--ddga-color-card);
  text-align: start;
}

.ddga-table--sm {
  --ddga-table-row-h:3rem;
}

.ddga-table--md {
  --ddga-table-row-h:4rem;
}

.ddga-table--lg {
  --ddga-table-row-h:4.5rem;
}

.ddga-table__head, .ddga-table__cell {
  padding-block: var(--ddga-table-pad-block);
  padding-inline: var(--ddga-table-pad-inline);
  text-align: start;
  vertical-align: middle;
}

.ddga-table__cell {
  block-size: var(--ddga-table-row-h);
}

.ddga-table__head {
  background-color: var(--ddga-color-muted);
  block-size: 3rem;
  color: var(--ddga-gray-700);
  font-size: var(--ddga-font-size-xs);
  font-weight: var(--ddga-font-weight-medium);
  white-space: nowrap;
  border-block-end: 1px solid var(--ddga-color-input);
}

.ddga-table__header .ddga-table__head:not(:last-child) {
  border-inline-end: 1px solid var(--ddga-color-input);
}

.ddga-table__head--align-start, .ddga-table__cell--align-start {
  text-align: start;
}

.ddga-table__head--align-center, .ddga-table__cell--align-center {
  text-align: center;
}

.ddga-table__head--align-end, .ddga-table__cell--align-end {
  text-align: end;
}

.ddga-table__caption {
  padding-block: var(--ddga-space-2);
  padding-inline: var(--ddga-table-pad-inline);
  color: var(--ddga-text-tertiary);
  font-size: var(--ddga-font-size-sm);
  text-align: start;
  caption-side: bottom;
}

.ddga-table__body .ddga-table__row {
  transition: background-color 0.12s;
}

.ddga-table__body .ddga-table__row:not(:last-child) {
  border-block-end: 1px solid var(--ddga-color-input);
}

.ddga-table--striped .ddga-table__body .ddga-table__row:nth-child(2n):not(:hover):not([data-state=selected]) {
  background-color: var(--ddga-gray-50);
}

.ddga-table__body .ddga-table__row:hover:not([data-state=selected]) {
  background-color: var(--ddga-color-muted);
}

.ddga-table__body .ddga-table__row[data-state=selected] {
  background-color: var(--ddga-sa-50);
  box-shadow: inset 2px 0 0 0 var(--ddga-color-primary);
}

[dir=rtl] .ddga-table__body .ddga-table__row[data-state=selected] {
  box-shadow: inset -2px 0 0 0 var(--ddga-color-primary);
}

.ddga-table__footer {
  color: var(--ddga-text-primary);
  font-weight: var(--ddga-font-weight-medium);
  border-block-start: 1px solid var(--ddga-color-input);
}

.ddga-table--sticky .ddga-table__header .ddga-table__head {
  z-index: 1;
  background-color: var(--ddga-color-muted);
  position: sticky;
  inset-block-start: 0;
}

.ddga-table__sort-button, .ddga-table__filter-button {
  align-items: center;
  gap: var(--ddga-space-2);
  font: inherit;
  color: inherit;
  cursor: pointer;
  background: 0 0;
  border: 0;
  margin: 0;
  padding: 0;
  display: inline-flex;
}

.ddga-table__filter-button {
  justify-content: center;
}

.ddga-table__sort-button:focus-visible, .ddga-table__filter-button:focus-visible {
  outline: none;
}

.ddga-table__sort-button:disabled, .ddga-table__filter-button:disabled {
  cursor: not-allowed;
}

.ddga-table__icon-box {
  border-radius: var(--ddga-radius-sm);
  flex-shrink: 0;
  justify-content: center;
  align-items: center;
  block-size: 1.25rem;
  inline-size: 1.25rem;
  transition: background-color 0.12s, color 0.12s;
  display: inline-flex;
}

.ddga-table__icon-box > svg {
  block-size: 1rem;
  inline-size: 1rem;
}

.ddga-table__icon-box[data-active=false] {
  background-color: var(--ddga-color-muted);
  color: var(--ddga-text-primary);
}

.ddga-table__icon-box[data-active=true] {
  background-color: var(--ddga-gray-950);
  color: #fff;
}

.ddga-table__sort-button:hover:not(:disabled) .ddga-table__icon-box[data-active=false], .ddga-table__filter-button:hover:not(:disabled) .ddga-table__icon-box[data-active=false] {
  background-color: var(--ddga-gray-200);
}

.ddga-table__sort-button:hover:not(:disabled) .ddga-table__icon-box[data-active=true], .ddga-table__filter-button:hover:not(:disabled) .ddga-table__icon-box[data-active=true] {
  background-color: var(--ddga-gray-800);
}

.ddga-table__sort-button:active:not(:disabled) .ddga-table__icon-box[data-active=false], .ddga-table__filter-button:active:not(:disabled) .ddga-table__icon-box[data-active=false] {
  background-color: var(--ddga-gray-200);
}

.ddga-table__sort-button:active:not(:disabled) .ddga-table__icon-box[data-active=true], .ddga-table__filter-button:active:not(:disabled) .ddga-table__icon-box[data-active=true] {
  background-color: var(--ddga-gray-600);
}

.ddga-table__sort-button:focus-visible .ddga-table__icon-box, .ddga-table__filter-button:focus-visible .ddga-table__icon-box {
  outline: 2px solid var(--ddga-text-primary);
  outline-offset: 0;
}

.ddga-table__sort-button:focus-visible .ddga-table__icon-box[data-active=true], .ddga-table__filter-button:focus-visible .ddga-table__icon-box[data-active=true] {
  box-shadow: inset 0 0 0 1px #fff;
}

.ddga-table__sort-button:disabled .ddga-table__icon-box, .ddga-table__filter-button:disabled .ddga-table__icon-box {
  color: var(--ddga-gray-400);
  background-color: rgba(0, 0, 0, 0);
}

[data-theme=dark] .ddga-table__head {
  color: var(--ddga-text-secondary);
}

[data-theme=dark] .ddga-table--striped .ddga-table__body .ddga-table__row:nth-child(2n):not(:hover):not([data-state=selected]) {
  background-color: var(--ddga-color-muted);
}

@media (forced-colors: active) {
  .ddga-table__head {
    border-block-end-color: canvastext;
  }
  .ddga-table__body .ddga-table__row:not(:last-child), .ddga-table__header .ddga-table__head:not(:last-child), .ddga-table__footer {
    border-color: canvastext;
  }
  .ddga-table__region:has(> .ddga-table--contained) {
    border-color: canvastext;
  }
  .ddga-table__body .ddga-table__row[data-state=selected] {
    box-shadow: inset 2px 0 highlight;
  }
  [dir=rtl] .ddga-table__body .ddga-table__row[data-state=selected] {
    box-shadow: inset -2px 0 highlight;
  }
  .ddga-table__icon-box {
    border: 1px solid canvastext;
  }
  .ddga-table__sort-button:focus-visible .ddga-table__icon-box, .ddga-table__filter-button:focus-visible .ddga-table__icon-box, .ddga-table__region[role=region]:focus-visible {
    outline: 2px solid highlight;
  }
}
/*# sourceMappingURL=table.css.map */
/* ── checkbox — 39 rules, 1 @layer wrapper(s) removed ── */
.ddga-checkbox-row {
  align-items: center;
  gap: var(--ddga-space-2);
  display: flex;
}

.ddga-checkbox {
  border: 1px solid var(--ddga-gray-500);
  border-radius: var(--ddga-radius-xs);
  color: var(--ddga-color-primary-foreground);
  cursor: pointer;
  background-color: rgba(0, 0, 0, 0);
  flex-shrink: 0;
  justify-content: center;
  align-items: center;
  padding: 0;
  transition: background-color 0.15s, border-color 0.15s, box-shadow 0.15s;
  display: inline-flex;
  position: relative;
}

.ddga-checkbox--md {
  block-size: 24px;
  inline-size: 24px;
}

.ddga-checkbox--sm {
  block-size: 20px;
  inline-size: 20px;
}

.ddga-checkbox--xs {
  block-size: 16px;
  inline-size: 16px;
}

.ddga-checkbox:before {
  content: "";
  z-index: -1;
  background-color: var(--ddga-gray-100);
  opacity: 0;
  pointer-events: none;
  border-radius: 9999px;
  transition: opacity 0.15s;
  position: absolute;
  inset: -8px;
}

.ddga-checkbox:not(:disabled):not([data-readonly]):hover:before, .ddga-checkbox:not(:disabled):not([data-readonly]):active:before {
  opacity: 1;
}

.ddga-checkbox[data-state=unchecked]:not(:disabled):not([data-readonly]):active {
  background-color: var(--ddga-gray-300);
}

.ddga-checkbox[data-state=checked], .ddga-checkbox[data-state=indeterminate] {
  background-color: var(--ddga-color-primary);
  border-color: var(--ddga-color-primary);
}

.ddga-checkbox[data-state=checked]:not(:disabled):not([data-readonly]):hover, .ddga-checkbox[data-state=indeterminate]:not(:disabled):not([data-readonly]):hover {
  background-color: var(--ddga-color-primary-hover);
  border-color: var(--ddga-color-primary-hover);
}

.ddga-checkbox[data-state=checked]:not(:disabled):not([data-readonly]):active, .ddga-checkbox[data-state=indeterminate]:not(:disabled):not([data-readonly]):active {
  background-color: var(--ddga-color-primary-active);
  border-color: var(--ddga-color-primary-active);
}

.ddga-checkbox--neutral[data-state=checked], .ddga-checkbox--neutral[data-state=indeterminate] {
  background-color: var(--ddga-gray-950);
  border-color: var(--ddga-gray-950);
}

.ddga-checkbox--neutral[data-state=checked]:not(:disabled):not([data-readonly]):hover, .ddga-checkbox--neutral[data-state=indeterminate]:not(:disabled):not([data-readonly]):hover {
  background-color: var(--ddga-gray-600);
  border-color: var(--ddga-gray-600);
}

.ddga-checkbox--neutral[data-state=checked]:not(:disabled):not([data-readonly]):active, .ddga-checkbox--neutral[data-state=indeterminate]:not(:disabled):not([data-readonly]):active {
  background-color: var(--ddga-gray-500);
  border-color: var(--ddga-gray-500);
}

.ddga-checkbox:focus-visible {
  outline: 2px solid var(--ddga-color-focus-ring);
  outline-offset: 2px;
}

.ddga-checkbox[data-readonly] {
  cursor: default;
  border-color: var(--ddga-gray-400);
}

.ddga-checkbox[data-readonly][data-state=checked], .ddga-checkbox[data-readonly][data-state=indeterminate] {
  border-color: var(--ddga-gray-400);
  color: var(--ddga-color-primary);
  background-color: rgba(0, 0, 0, 0);
}

.ddga-checkbox--neutral[data-readonly][data-state=checked], .ddga-checkbox--neutral[data-readonly][data-state=indeterminate] {
  color: var(--ddga-gray-950);
}

.ddga-checkbox--error {
  border-color: var(--ddga-color-error);
}

.ddga-checkbox--error[data-state=checked], .ddga-checkbox--error[data-state=indeterminate] {
  background-color: var(--ddga-color-error);
  border-color: var(--ddga-color-error);
}

.ddga-checkbox--error:focus-visible {
  outline-color: var(--ddga-color-error);
}

.ddga-checkbox:disabled {
  cursor: not-allowed;
  border-color: var(--ddga-gray-400);
}

.ddga-checkbox:disabled[data-state=checked], .ddga-checkbox:disabled[data-state=indeterminate] {
  background-color: var(--ddga-gray-200);
  border-color: var(--ddga-gray-200);
  color: var(--ddga-color-primary-foreground);
}

.ddga-checkbox-row:has(.ddga-checkbox:disabled) .ddga-checkbox__label {
  cursor: not-allowed;
  color: var(--ddga-text-tertiary);
}

.ddga-checkbox__indicator {
  justify-content: center;
  align-items: center;
  block-size: 100%;
  inline-size: 100%;
  display: inline-flex;
}

.ddga-checkbox__check {
  block-size: 75%;
  inline-size: 75%;
}

.ddga-checkbox__minus {
  background-color: currentColor;
  border-radius: 1px;
  block-size: 12.5%;
  min-block-size: 2px;
  inline-size: 50%;
}

.ddga-checkbox[data-state=checked] .ddga-checkbox__minus, .ddga-checkbox[data-state=indeterminate] .ddga-checkbox__check {
  display: none;
}

.ddga-checkbox__label {
  color: var(--ddga-text-primary);
  font-size: var(--ddga-font-size-base);
  cursor: pointer;
  line-height: 1.4;
}

.ddga-checkbox__required {
  color: var(--ddga-color-error);
  margin-inline-start: 0.125rem;
}

[data-theme=dark] .ddga-checkbox:before {
  background-color: var(--ddga-gray-700);
}

[data-theme=dark] .ddga-checkbox--neutral[data-state=checked], [data-theme=dark] .ddga-checkbox--neutral[data-state=indeterminate] {
  background-color: var(--ddga-gray-100);
  border-color: var(--ddga-gray-100);
}

[data-theme=dark] .ddga-checkbox--neutral[data-readonly][data-state=checked], [data-theme=dark] .ddga-checkbox--neutral[data-readonly][data-state=indeterminate] {
  color: var(--ddga-gray-100);
}

@media (prefers-reduced-motion: reduce) {
  .ddga-checkbox, .ddga-checkbox:before {
    transition: none;
  }
}
@media (forced-colors: active) {
  .ddga-checkbox {
    border: 1px solid canvastext;
  }
  .ddga-checkbox[data-state=checked], .ddga-checkbox[data-state=indeterminate] {
    background-color: canvastext;
  }
  .ddga-checkbox__indicator {
    color: canvas;
  }
  .ddga-checkbox:focus-visible {
    outline-offset: 1px;
    outline: 2px solid highlight;
  }
  .ddga-checkbox:disabled {
    color: graytext;
    border-color: graytext;
  }
}
/*# sourceMappingURL=checkbox.css.map */
/* ── search-box — 11 rules, 1 @layer wrapper(s) removed ── */
.ddga-search-box.ddga-text-input--md {
  block-size: 40px;
  font-size: var(--ddga-font-size-base);
}

.ddga-search-box.ddga-text-input--lg {
  block-size: 48px;
}

.ddga-search-box .ddga-text-input__adornment--start {
  color: var(--ddga-gray-700);
}

[data-theme=dark] .ddga-search-box .ddga-text-input__adornment--start {
  color: var(--ddga-text-tertiary);
}

.ddga-search-box .ddga-text-input__adornment--start svg {
  block-size: 20px;
  inline-size: 20px;
  transform: scaleX(-1);
}

[dir=rtl] .ddga-search-box .ddga-text-input__adornment--start svg {
  transform: none;
}

.ddga-search-box .ddga-text-input__adornment--end svg {
  block-size: 20px;
  inline-size: 20px;
}

.ddga-search-box .ddga-text-input__field::-webkit-search-cancel-button {
  appearance: none;
  display: none;
}

.ddga-search-box .ddga-text-input__field::-webkit-search-decoration {
  appearance: none;
  display: none;
}

.ddga-search-box .ddga-text-input__field::-webkit-search-results-button {
  appearance: none;
  display: none;
}

.ddga-search-box .ddga-text-input__field::-webkit-search-results-decoration {
  appearance: none;
  display: none;
}

/*# sourceMappingURL=search-box.css.map */
/* ── field — 6 rules, 1 @layer wrapper(s) removed ── */
.ddga-field {
  gap: var(--ddga-space-1);
  flex-direction: column;
  display: flex;
}

.ddga-field__message {
  font-size: var(--ddga-font-size-sm);
  margin: 0;
  line-height: 1.4;
}

.ddga-field__message--helper {
  color: var(--ddga-text-secondary);
}

.ddga-field__message--error {
  color: var(--ddga-color-error);
}

.ddga-field__message--with-icon {
  align-items: center;
  gap: var(--ddga-space-2);
  display: inline-flex;
}

.ddga-field__message-icon {
  flex-shrink: 0;
  display: inline-flex;
}

/*# sourceMappingURL=field.css.map */
/* ── text-input — 85 rules, 1 @layer wrapper(s) removed ── */
.ddga-field[data-slot=text-input-field] {
  gap: var(--ddga-space-2);
}

.ddga-text-input__label {
  align-items: center;
  gap: var(--ddga-space-1);
  color: var(--ddga-text-primary);
  font-weight: var(--ddga-font-weight-regular);
  font-size: var(--ddga-font-size-sm);
  line-height: 1.4286;
  display: inline-flex;
}

.ddga-text-input__required {
  color: var(--ddga-error-700);
}

.ddga-text-input {
  align-items: center;
  gap: var(--ddga-space-2);
  inline-size: 100%;
  border: 1px solid var(--ddga-gray-400);
  border-radius: var(--ddga-radius-sm);
  background-color: var(--ddga-color-background);
  color: var(--ddga-gray-700);
  padding-inline-start: var(--ddga-space-2);
  padding-inline-end: var(--ddga-space-4);
  transition: border-color 0.15s, box-shadow 0.15s, background-color 0.15s;
  display: flex;
  position: relative;
}

.ddga-text-input--md {
  block-size: 32px;
  font-size: var(--ddga-font-size-sm);
}

.ddga-text-input--lg {
  block-size: 40px;
  font-size: var(--ddga-font-size-base);
}

.ddga-text-input--filled-lighter {
  background-color: var(--ddga-gray-25);
  border-color: rgba(0, 0, 0, 0);
}

.ddga-text-input--filled-darker {
  background-color: var(--ddga-gray-100);
  border-color: rgba(0, 0, 0, 0);
}

.ddga-text-input__field {
  block-size: 100%;
  min-inline-size: 0;
  color: inherit;
  font: inherit;
  caret-color: var(--ddga-gray-950);
  background: 0 0;
  border: 0;
  outline: none;
  flex: auto;
  padding: 0;
}

.ddga-text-input__field::placeholder {
  color: var(--ddga-gray-500);
}

.ddga-text-input__field:-webkit-autofill {
  -webkit-text-fill-color: var(--ddga-gray-700);
  -webkit-box-shadow: 0 0 0 100vmax var(--ddga-color-background) inset;
  box-shadow: 0 0 0 100vmax var(--ddga-color-background) inset;
  caret-color: var(--ddga-gray-950);
}

.ddga-text-input__field:-webkit-autofill:hover {
  -webkit-text-fill-color: var(--ddga-gray-700);
  -webkit-box-shadow: 0 0 0 100vmax var(--ddga-color-background) inset;
  box-shadow: 0 0 0 100vmax var(--ddga-color-background) inset;
  caret-color: var(--ddga-gray-950);
}

.ddga-text-input__field:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--ddga-gray-700);
  -webkit-box-shadow: 0 0 0 100vmax var(--ddga-color-background) inset;
  box-shadow: 0 0 0 100vmax var(--ddga-color-background) inset;
  caret-color: var(--ddga-gray-950);
}

.ddga-text-input__adornment {
  max-block-size: 100%;
  color: var(--ddga-gray-500);
  flex-shrink: 0;
  align-self: center;
  align-items: center;
  display: inline-flex;
}

.ddga-text-input__adornment svg {
  flex-shrink: 0;
  align-self: center;
}

.ddga-text-input:has(.ddga-text-input__adornment--start) {
  padding-inline-start: var(--ddga-space-2);
}

.ddga-text-input:has(.ddga-text-input__adornment--end) {
  padding-inline-end: var(--ddga-space-2);
}

.ddga-text-input__affix {
  padding-inline: var(--ddga-space-4);
  background-color: var(--ddga-gray-100);
  color: var(--ddga-gray-500);
  white-space: nowrap;
  align-self: stretch;
  align-items: center;
  display: inline-flex;
}

.ddga-text-input--md .ddga-text-input__affix {
  padding-inline: var(--ddga-space-3);
}

.ddga-text-input__affix--subtle {
  background-color: rgba(0, 0, 0, 0);
  padding-inline: 0;
}

.ddga-text-input__adornment--start:has(.ddga-text-input__affix) {
  align-self: stretch;
}

.ddga-text-input__adornment--end:has(.ddga-text-input__affix) {
  align-self: stretch;
}

.ddga-text-input__adornment--start .ddga-text-input__affix {
  border-start-start-radius: var(--ddga-radius-sm);
  border-end-start-radius: var(--ddga-radius-sm);
}

.ddga-text-input__adornment--end .ddga-text-input__affix {
  border-start-end-radius: var(--ddga-radius-sm);
  border-end-end-radius: var(--ddga-radius-sm);
}

.ddga-text-input:has(.ddga-text-input__adornment--start .ddga-text-input__affix) {
  padding-inline-start: 0;
}

.ddga-text-input:has(.ddga-text-input__adornment--end .ddga-text-input__affix) {
  padding-inline-end: 0;
}

.ddga-text-input__dropdown {
  gap: var(--ddga-space-1);
  color: var(--ddga-text-primary);
  font: inherit;
  cursor: pointer;
  border: 0;
  padding-block: 0;
  transition: background-color 0.15s;
}

.ddga-text-input__dropdown--subtle {
  background-color: rgba(0, 0, 0, 0);
}

.ddga-text-input__dropdown-icon {
  flex-shrink: 0;
  block-size: 24px;
  inline-size: 24px;
  display: inline-flex;
}

.ddga-text-input__dropdown-icon > svg {
  block-size: 100%;
  inline-size: 100%;
}

.ddga-text-input__dropdown-chevron {
  flex-shrink: 0;
  block-size: 20px;
  inline-size: 20px;
}

.ddga-text-input--md .ddga-text-input__dropdown-icon {
  block-size: 20px;
  inline-size: 20px;
}

.ddga-text-input--md .ddga-text-input__dropdown-chevron {
  block-size: 16px;
  inline-size: 16px;
}

.ddga-text-input__dropdown:hover {
  background-color: var(--ddga-gray-200);
}

.ddga-text-input__dropdown:active {
  background-color: var(--ddga-gray-300);
}

.ddga-text-input__dropdown--subtle:hover {
  background-color: var(--ddga-gray-100);
}

.ddga-text-input__dropdown--subtle:active {
  background-color: var(--ddga-gray-200);
}

.ddga-text-input__dropdown--selected, .ddga-text-input__dropdown--selected:hover, .ddga-text-input__dropdown--selected:active {
  background-color: var(--ddga-gray-700);
  color: #fff;
}

.ddga-text-input__dropdown:focus-visible {
  box-shadow: inset 0 0 0 2px var(--ddga-text-primary);
  outline: none;
}

.ddga-text-input--default:hover:not(:focus-within) {
  border-color: var(--ddga-gray-700);
}

.ddga-text-input:focus-within {
  box-shadow: var(--ddga-shadow-md);
}

.ddga-text-input--default:focus-within {
  border-color: var(--ddga-gray-400);
}

.ddga-text-input:focus-within:after {
  content: "";
  inset-inline: 0;
  background-color: var(--ddga-gray-950);
  block-size: 2px;
  position: absolute;
  bottom: -1px;
}

.ddga-text-input--pressed {
  background-color: var(--ddga-gray-100);
}

.ddga-text-input:active:not(:has(.ddga-text-input__field:disabled)) {
  background-color: var(--ddga-gray-100);
}

.ddga-text-input:active:after, .ddga-text-input--pressed:after {
  content: "";
  inset-inline: 25%;
  background-color: var(--ddga-gray-950);
  block-size: 2px;
  position: absolute;
  bottom: -1px;
}

.ddga-text-input--error, .ddga-text-input--error:hover:not(:focus-within), .ddga-text-input--error:focus-within {
  border-color: var(--ddga-error-700);
}

.ddga-text-input:has(.ddga-text-input__field:read-only:not(:disabled)) {
  border-color: var(--ddga-gray-300);
  background-color: rgba(0, 0, 0, 0);
}

.ddga-text-input:has(.ddga-text-input__field:disabled) {
  border-color: var(--ddga-gray-300);
  cursor: not-allowed;
  background-color: rgba(0, 0, 0, 0);
}

.ddga-text-input:has(.ddga-text-input__field:disabled) .ddga-text-input__field {
  color: var(--ddga-gray-400);
  cursor: not-allowed;
}

.ddga-text-input:has(.ddga-text-input__field:disabled) .ddga-text-input__field::placeholder {
  color: var(--ddga-gray-400);
}

.ddga-text-input:has(.ddga-text-input__field:disabled) .ddga-text-input__adornment {
  color: var(--ddga-gray-400);
}

:is(.ddga-field[data-slot=text-input-field]:has(.ddga-text-input__field:disabled) .ddga-text-input__label, .ddga-field[data-slot=text-input-field]:has(.ddga-text-input__field:disabled) .ddga-text-input__required) {
  color: var(--ddga-gray-400);
}

.ddga-text-input:has(.ddga-text-input__field:disabled) .ddga-text-input__affix {
  background-color: var(--ddga-gray-200);
}

.ddga-field[data-slot=text-input-field] .ddga-field__message {
  padding-block: var(--ddga-space-1);
}

.ddga-field[data-slot=text-input-field] .ddga-field__message--helper {
  color: var(--ddga-gray-700);
}

.ddga-field[data-slot=text-input-field] .ddga-field__message--error {
  color: var(--ddga-error-700);
}

[data-theme=dark] .ddga-text-input {
  border-color: var(--ddga-color-input);
  color: var(--ddga-text-primary);
}

[data-theme=dark] .ddga-text-input__field {
  caret-color: var(--ddga-text-primary);
}

[data-theme=dark] .ddga-text-input__field::placeholder {
  color: var(--ddga-text-placeholder);
}

[data-theme=dark] .ddga-text-input__adornment {
  color: var(--ddga-text-tertiary);
}

[data-theme=dark] .ddga-text-input__affix {
  background-color: var(--ddga-color-muted);
  color: var(--ddga-text-tertiary);
}

[data-theme=dark] .ddga-text-input__dropdown {
  background-color: var(--ddga-color-muted);
  color: var(--ddga-text-primary);
}

[data-theme=dark] .ddga-text-input__dropdown--subtle {
  background-color: rgba(0, 0, 0, 0);
}

[data-theme=dark] .ddga-text-input__dropdown:hover {
  background-color: var(--ddga-color-border);
}

[data-theme=dark] .ddga-text-input__dropdown--subtle:hover {
  background-color: var(--ddga-color-muted);
}

[data-theme=dark] .ddga-text-input__dropdown:active, [data-theme=dark] .ddga-text-input__dropdown--subtle:active {
  background-color: var(--ddga-color-border);
}

[data-theme=dark] .ddga-text-input__dropdown--selected, [data-theme=dark] .ddga-text-input__dropdown--selected:hover {
  background-color: var(--ddga-gray-700);
  color: #fff;
}

[data-theme=dark] .ddga-text-input__dropdown:focus-visible {
  box-shadow: inset 0 0 0 2px var(--ddga-text-primary);
}

[data-theme=dark] .ddga-text-input--filled-lighter, [data-theme=dark] .ddga-text-input--filled-darker {
  background-color: var(--ddga-color-muted);
}

[data-theme=dark] .ddga-text-input--default:hover:not(:focus-within) {
  border-color: var(--ddga-gray-500);
}

[data-theme=dark] .ddga-text-input:focus-within:after, [data-theme=dark] .ddga-text-input:active:after, [data-theme=dark] .ddga-text-input--pressed:after {
  background-color: var(--ddga-text-primary);
}

[data-theme=dark] .ddga-text-input--pressed {
  background-color: var(--ddga-color-muted);
}

[data-theme=dark] .ddga-text-input:active:not(:has(.ddga-text-input__field:disabled)) {
  background-color: var(--ddga-color-muted);
}

:is([data-theme=dark] .ddga-text-input:has(.ddga-text-input__field:read-only:not(:disabled)), [data-theme=dark] .ddga-text-input:has(.ddga-text-input__field:disabled)) {
  border-color: var(--ddga-color-border);
}

[data-theme=dark] .ddga-text-input:has(.ddga-text-input__field:disabled) .ddga-text-input__field {
  color: var(--ddga-text-tertiary);
}

[data-theme=dark] .ddga-text-input:has(.ddga-text-input__field:disabled) .ddga-text-input__field::placeholder {
  color: var(--ddga-text-tertiary);
}

[data-theme=dark] .ddga-text-input:has(.ddga-text-input__field:disabled) .ddga-text-input__adornment {
  color: var(--ddga-text-tertiary);
}

:is([data-theme=dark] .ddga-field[data-slot=text-input-field]:has(.ddga-text-input__field:disabled) .ddga-text-input__label, [data-theme=dark] .ddga-field[data-slot=text-input-field]:has(.ddga-text-input__field:disabled) .ddga-text-input__required) {
  color: var(--ddga-text-tertiary);
}

[data-theme=dark] .ddga-field[data-slot=text-input-field] .ddga-field__message--helper {
  color: var(--ddga-text-secondary);
}

@media (prefers-reduced-motion: reduce) {
  .ddga-text-input {
    transition: none;
  }
}
@media (forced-colors: active) {
  .ddga-text-input {
    border: 1px solid canvastext;
  }
  .ddga-text-input:focus-within {
    outline-offset: 1px;
    outline: 2px solid highlight;
  }
  .ddga-text-input:has(.ddga-text-input__field:disabled) {
    border-color: graytext;
  }
  .ddga-text-input:has(.ddga-text-input__field:disabled) .ddga-text-input__field {
    color: graytext;
  }
}
/*# sourceMappingURL=text-input.css.map */
/* ── textarea — 47 rules, 1 @layer wrapper(s) removed ── */
.ddga-field[data-slot=textarea-field] {
  gap: var(--ddga-space-2);
}

.ddga-textarea__label {
  align-items: center;
  gap: var(--ddga-space-1);
  color: var(--ddga-text-primary);
  font-weight: var(--ddga-font-weight-regular);
  font-size: var(--ddga-font-size-sm);
  line-height: 1.4286;
  display: inline-flex;
}

.ddga-textarea__required {
  color: var(--ddga-error-700);
}

.ddga-textarea {
  border: 1px solid var(--ddga-gray-400);
  border-radius: var(--ddga-radius-sm);
  background-color: var(--ddga-color-background);
  inline-size: 100%;
  transition: border-color 0.15s, box-shadow 0.15s, background-color 0.15s;
  display: block;
  position: relative;
}

.ddga-textarea--filled-lighter {
  background-color: var(--ddga-gray-25);
  border-color: rgba(0, 0, 0, 0);
}

.ddga-textarea--filled-darker {
  background-color: var(--ddga-gray-100);
  border-color: rgba(0, 0, 0, 0);
}

.ddga-textarea__field {
  inline-size: 100%;
  padding-block: var(--ddga-space-3);
  padding-inline: var(--ddga-space-4);
  color: var(--ddga-text-primary);
  font-family: inherit;
  font-size: var(--ddga-font-size-base);
  caret-color: var(--ddga-gray-950);
  background: 0 0;
  border: 0;
  outline: none;
  line-height: 1.5;
  display: block;
}

.ddga-textarea__field::placeholder {
  color: var(--ddga-gray-500);
}

.ddga-textarea__field--resize-vertical {
  resize: vertical;
}

.ddga-textarea__field--resize-none {
  resize: none;
}

.ddga-textarea__field:-webkit-autofill {
  -webkit-text-fill-color: var(--ddga-text-primary);
  -webkit-box-shadow: 0 0 0 100vmax var(--ddga-color-background) inset;
  box-shadow: 0 0 0 100vmax var(--ddga-color-background) inset;
  caret-color: var(--ddga-gray-950);
}

.ddga-textarea__field:-webkit-autofill:hover {
  -webkit-text-fill-color: var(--ddga-text-primary);
  -webkit-box-shadow: 0 0 0 100vmax var(--ddga-color-background) inset;
  box-shadow: 0 0 0 100vmax var(--ddga-color-background) inset;
  caret-color: var(--ddga-gray-950);
}

.ddga-textarea__field:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--ddga-text-primary);
  -webkit-box-shadow: 0 0 0 100vmax var(--ddga-color-background) inset;
  box-shadow: 0 0 0 100vmax var(--ddga-color-background) inset;
  caret-color: var(--ddga-gray-950);
}

.ddga-textarea--default:hover:not(:focus-within) {
  border-color: var(--ddga-gray-700);
}

.ddga-textarea:focus-within {
  box-shadow: var(--ddga-shadow-md);
}

.ddga-textarea--default:focus-within {
  border-color: var(--ddga-gray-400);
}

.ddga-textarea:focus-within:after {
  content: "";
  inset-inline: 0;
  background-color: var(--ddga-gray-950);
  block-size: 2px;
  position: absolute;
  bottom: -1px;
}

.ddga-textarea--pressed {
  background-color: var(--ddga-gray-100);
}

.ddga-textarea:active:not(:has(.ddga-textarea__field:disabled)) {
  background-color: var(--ddga-gray-100);
}

.ddga-textarea:active:after, .ddga-textarea--pressed:after {
  content: "";
  inset-inline: 25%;
  background-color: var(--ddga-gray-950);
  block-size: 2px;
  position: absolute;
  bottom: -1px;
}

.ddga-textarea--error, .ddga-textarea--error:hover:not(:focus-within), .ddga-textarea--error:focus-within {
  border-color: var(--ddga-error-700);
}

.ddga-textarea:has(.ddga-textarea__field:read-only:not(:disabled)) {
  border-color: var(--ddga-gray-300);
  background-color: rgba(0, 0, 0, 0);
}

.ddga-textarea:has(.ddga-textarea__field:disabled) {
  border-color: var(--ddga-gray-300);
  cursor: not-allowed;
  background-color: rgba(0, 0, 0, 0);
}

.ddga-textarea:has(.ddga-textarea__field:disabled) .ddga-textarea__field {
  color: var(--ddga-gray-400);
  cursor: not-allowed;
  resize: none;
}

.ddga-textarea:has(.ddga-textarea__field:disabled) .ddga-textarea__field::placeholder {
  color: var(--ddga-gray-400);
}

:is(.ddga-field[data-slot=textarea-field]:has(.ddga-textarea__field:disabled) .ddga-textarea__label, .ddga-field[data-slot=textarea-field]:has(.ddga-textarea__field:disabled) .ddga-textarea__required) {
  color: var(--ddga-gray-400);
}

.ddga-field[data-slot=textarea-field] .ddga-field__message {
  padding-block: var(--ddga-space-1);
}

.ddga-field[data-slot=textarea-field] .ddga-field__message--helper {
  color: var(--ddga-gray-700);
}

.ddga-field[data-slot=textarea-field] .ddga-field__message--error {
  color: var(--ddga-error-700);
}

[data-theme=dark] .ddga-textarea {
  border-color: var(--ddga-color-input);
}

[data-theme=dark] .ddga-textarea__field {
  color: var(--ddga-text-primary);
  caret-color: var(--ddga-text-primary);
}

[data-theme=dark] .ddga-textarea__field::placeholder {
  color: var(--ddga-text-placeholder);
}

[data-theme=dark] .ddga-textarea--filled-lighter, [data-theme=dark] .ddga-textarea--filled-darker {
  background-color: var(--ddga-color-muted);
}

[data-theme=dark] .ddga-textarea--default:hover:not(:focus-within) {
  border-color: var(--ddga-gray-500);
}

[data-theme=dark] .ddga-textarea:focus-within:after, [data-theme=dark] .ddga-textarea:active:after, [data-theme=dark] .ddga-textarea--pressed:after {
  background-color: var(--ddga-text-primary);
}

[data-theme=dark] .ddga-textarea--pressed {
  background-color: var(--ddga-color-muted);
}

[data-theme=dark] .ddga-textarea:active:not(:has(.ddga-textarea__field:disabled)) {
  background-color: var(--ddga-color-muted);
}

:is([data-theme=dark] .ddga-textarea:has(.ddga-textarea__field:read-only:not(:disabled)), [data-theme=dark] .ddga-textarea:has(.ddga-textarea__field:disabled)) {
  border-color: var(--ddga-color-border);
}

[data-theme=dark] .ddga-textarea:has(.ddga-textarea__field:disabled) .ddga-textarea__field {
  color: var(--ddga-text-tertiary);
}

[data-theme=dark] .ddga-textarea:has(.ddga-textarea__field:disabled) .ddga-textarea__field::placeholder {
  color: var(--ddga-text-tertiary);
}

:is([data-theme=dark] .ddga-field[data-slot=textarea-field]:has(.ddga-textarea__field:disabled) .ddga-textarea__label, [data-theme=dark] .ddga-field[data-slot=textarea-field]:has(.ddga-textarea__field:disabled) .ddga-textarea__required) {
  color: var(--ddga-text-tertiary);
}

[data-theme=dark] .ddga-field[data-slot=textarea-field] .ddga-field__message--helper {
  color: var(--ddga-text-secondary);
}

@media (prefers-reduced-motion: reduce) {
  .ddga-textarea {
    transition: none;
  }
}
@media (forced-colors: active) {
  .ddga-textarea {
    border: 1px solid canvastext;
  }
  .ddga-textarea:focus-within {
    outline-offset: 1px;
    outline: 2px solid highlight;
  }
  .ddga-textarea:has(.ddga-textarea__field:disabled) {
    border-color: graytext;
  }
  .ddga-textarea:has(.ddga-textarea__field:disabled) .ddga-textarea__field {
    color: graytext;
  }
}
/*# sourceMappingURL=textarea.css.map */
/* ── select — 26 rules, 1 @layer wrapper(s) removed ── */
.ddga-select__label {
  color: var(--ddga-text-primary);
  font-weight: var(--ddga-font-weight-medium);
  font-size: var(--ddga-font-size-sm);
  line-height: 1.4;
}

.ddga-select__required {
  color: var(--ddga-color-error);
  margin-inline-start: 0.125rem;
}

.ddga-select-trigger {
  justify-content: space-between;
  align-items: center;
  gap: var(--ddga-space-2);
  border: 1px solid var(--ddga-color-input);
  border-radius: var(--ddga-radius-sm);
  background-color: var(--ddga-color-background);
  inline-size: 100%;
  color: var(--ddga-text-primary);
  text-align: start;
  cursor: pointer;
  transition: border-color 0.15s, box-shadow 0.15s;
  display: inline-flex;
}

.ddga-select-trigger--sm {
  block-size: 32px;
  padding-inline: var(--ddga-space-3);
  font-size: var(--ddga-font-size-sm);
}

.ddga-select-trigger--md {
  block-size: 36px;
  padding-inline: var(--ddga-space-4);
  font-size: var(--ddga-font-size-base);
}

.ddga-select-trigger:focus-visible {
  border-color: var(--ddga-color-ring);
  box-shadow: 0 0 0 1px var(--ddga-color-ring);
  outline: none;
}

.ddga-select-trigger[data-placeholder] {
  color: var(--ddga-text-placeholder);
}

.ddga-select-trigger:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  background-color: var(--ddga-color-muted);
}

.ddga-select-trigger--error {
  border-color: var(--ddga-color-error);
}

.ddga-select-trigger--error:focus-visible {
  border-color: var(--ddga-color-error);
  box-shadow: 0 0 0 1px var(--ddga-color-error);
}

.ddga-select__icon {
  color: var(--ddga-text-tertiary);
  flex-shrink: 0;
  transition: rotate 0.15s;
}

.ddga-select-trigger[data-state=open] .ddga-select__icon {
  rotate: 180deg;
}

.ddga-select-content {
  min-inline-size: var(--radix-select-trigger-width);
  max-block-size: var(--radix-select-content-available-height);
  z-index: 50;
  background-color: var(--ddga-color-background);
  border: 1px solid var(--ddga-color-border);
  border-radius: var(--ddga-radius-md);
  box-shadow: var(--ddga-shadow-md);
  color: var(--ddga-text-primary);
  overflow: hidden;
}

.ddga-select-viewport {
  padding: var(--ddga-space-1);
}

.ddga-select-item {
  block-size: 32px;
  padding-block: var(--ddga-space-2);
  border-radius: var(--ddga-radius-sm);
  font-size: var(--ddga-font-size-base);
  color: var(--ddga-text-primary);
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
  outline: none;
  align-items: center;
  padding-inline-start: var(--ddga-space-3);
  padding-inline-end: var(--ddga-space-8);
  line-height: 1.4;
  display: flex;
  position: relative;
}

.ddga-select-item[data-highlighted] {
  background-color: var(--ddga-color-muted);
}

.ddga-select-item[data-disabled] {
  color: var(--ddga-text-tertiary);
  cursor: not-allowed;
  pointer-events: none;
}

.ddga-select-item__indicator {
  color: var(--ddga-color-primary);
  align-items: center;
  display: inline-flex;
  position: absolute;
  inset-inline-end: var(--ddga-space-2);
}

.ddga-select-item__check {
  block-size: 1em;
  inline-size: 1em;
}

@media (prefers-reduced-motion: reduce) {
  .ddga-select-trigger, .ddga-select__icon {
    transition: none;
  }
}
@media (forced-colors: active) {
  .ddga-select-trigger {
    border: 1px solid canvastext;
  }
  .ddga-select-trigger:focus-visible {
    outline-offset: 1px;
    outline: 2px solid highlight;
  }
  .ddga-select-trigger:disabled {
    color: graytext;
    border-color: graytext;
  }
  .ddga-select-content {
    border: 1px solid canvastext;
  }
  .ddga-select-item[data-highlighted] {
    color: highlighttext;
    background-color: highlight;
  }
  .ddga-select-item__indicator {
    color: highlighttext;
  }
}
/*# sourceMappingURL=select.css.map */
/* ── switch — 34 rules, 1 @layer wrapper(s) removed ── */
.ddga-switch-row {
  align-items: center;
  gap: var(--ddga-space-2);
  display: flex;
}

.ddga-switch {
  --ddga-switch-off:var(--ddga-gray-950);
  --ddga-switch-on:var(--ddga-color-primary);
  --ddga-switch-ring:var(--ddga-color-foreground);
  box-sizing: border-box;
  border-radius: var(--ddga-radius-full);
  cursor: pointer;
  background-color: rgba(0, 0, 0, 0);
  border: none;
  flex-shrink: 0;
  block-size: 24px;
  inline-size: 48px;
  padding: 0;
  transition: background-color 0.15s, box-shadow 0.15s;
  display: inline-block;
  position: relative;
}

.ddga-switch[data-state=unchecked] {
  box-shadow: inset 0 0 0 1px var(--ddga-switch-off);
}

.ddga-switch[data-state=checked] {
  background-color: var(--ddga-switch-on);
}

.ddga-switch:hover:not(:disabled) {
  --ddga-switch-off:var(--ddga-gray-600);
  --ddga-switch-on:var(--ddga-sa-800);
}

.ddga-switch:active:not(:disabled) {
  --ddga-switch-off:var(--ddga-gray-500);
  --ddga-switch-on:var(--ddga-color-primary-active);
}

.ddga-switch[data-state=checked] {
  --ddga-switch-ring:var(--ddga-text-primary);
}

.ddga-switch:before {
  content: "";
  border: 4px solid var(--ddga-color-muted);
  border-radius: var(--ddga-radius-full);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s;
  position: absolute;
  inset: -4px;
}

.ddga-switch:hover:not(:disabled):before, .ddga-switch:active:not(:disabled):before {
  opacity: 1;
}

.ddga-switch:after {
  content: "";
  border: 2px solid var(--ddga-switch-ring);
  border-radius: var(--ddga-radius-xs);
  opacity: 0;
  pointer-events: none;
  position: absolute;
  inset: -4px;
}

.ddga-switch:focus-visible {
  outline: none;
}

.ddga-switch:focus-visible:before {
  opacity: 0;
}

.ddga-switch:focus-visible:after {
  opacity: 1;
}

.ddga-switch__thumb {
  border-radius: var(--ddga-radius-full);
  background-color: var(--ddga-switch-off);
  will-change: translate;
  block-size: 16px;
  inline-size: 16px;
  transition: translate 0.15s, background-color 0.15s;
  position: absolute;
  inset-block-start: 4px;
  inset-inline-start: 4px;
  translate: 0;
}

.ddga-switch[data-state=checked] .ddga-switch__thumb {
  background-color: var(--ddga-color-background);
  box-shadow: var(--ddga-shadow-sm);
  translate: 24px;
}

[dir=rtl] .ddga-switch[data-state=checked] .ddga-switch__thumb {
  translate: -24px;
}

.ddga-switch--error {
  --ddga-switch-off:var(--ddga-color-error);
  --ddga-switch-on:var(--ddga-color-error);
  --ddga-switch-ring:var(--ddga-color-error);
}

.ddga-switch:disabled {
  cursor: not-allowed;
}

.ddga-switch[data-state=unchecked]:disabled {
  box-shadow: inset 0 0 0 1px var(--ddga-gray-400);
}

.ddga-switch[data-state=unchecked]:disabled .ddga-switch__thumb, .ddga-switch[data-state=checked]:disabled {
  background-color: var(--ddga-gray-300);
}

.ddga-switch[data-state=checked]:disabled .ddga-switch__thumb {
  box-shadow: none;
}

.ddga-switch-row:has(.ddga-switch:disabled) .ddga-switch__label {
  cursor: not-allowed;
  color: var(--ddga-text-tertiary);
}

.ddga-switch__label {
  color: var(--ddga-text-primary);
  font-size: var(--ddga-font-size-base);
  cursor: pointer;
  line-height: 1.4;
}

.ddga-switch__required {
  color: var(--ddga-color-error);
  margin-inline-start: 0.125rem;
}

[data-theme=dark] .ddga-switch {
  --ddga-switch-off:var(--ddga-gray-300);
  --ddga-switch-ring:var(--ddga-gray-100);
}

[data-theme=dark] .ddga-switch:hover:not(:disabled) {
  --ddga-switch-off:var(--ddga-gray-200);
}

[data-theme=dark] .ddga-switch:before {
  border-color: var(--ddga-gray-700);
}

@media (prefers-reduced-motion: reduce) {
  .ddga-switch, .ddga-switch:before, .ddga-switch__thumb {
    transition: none;
  }
}
@media (forced-colors: active) {
  .ddga-switch[data-state=unchecked] {
    box-shadow: inset 0 0 0 1px canvastext;
  }
  .ddga-switch[data-state=checked] {
    background-color: highlight;
  }
  .ddga-switch__thumb {
    background-color: canvastext;
  }
  .ddga-switch[data-state=checked] .ddga-switch__thumb {
    background-color: highlighttext;
  }
  .ddga-switch:focus-visible:after {
    border-color: highlight;
  }
  .ddga-switch:disabled[data-state=unchecked] {
    box-shadow: inset 0 0 0 1px graytext;
  }
}
/*# sourceMappingURL=switch.css.map */
/* ── modal — 38 rules, 1 @layer wrapper(s) removed ── */
.ddga-modal__overlay {
  z-index: 60;
  background-color: rgba(0, 0, 0, 0.5019607843);
  animation-duration: 0.15s;
  animation-timing-function: ease;
  position: fixed;
  inset: 0;
}

.ddga-modal {
  z-index: 61;
  gap: var(--ddga-space-2);
  padding: var(--ddga-space-6);
  background-color: var(--ddga-color-card);
  color: var(--ddga-color-card-foreground);
  border-radius: var(--ddga-radius-md);
  box-shadow: var(--ddga-shadow-3xl);
  flex-direction: column;
  max-block-size: calc(100vh - 2rem);
  inline-size: calc(100vw - 2rem);
  animation-duration: 0.18s;
  animation-timing-function: ease;
  display: flex;
  position: fixed;
  top: 50%;
  left: 50%;
  overflow: hidden;
  transform: translate(-50%, -50%);
}

.ddga-modal--default {
  max-inline-size: 600px;
}

.ddga-modal--full {
  block-size: calc(100vh - 2rem);
  max-block-size: calc(100vh - 2rem);
  inline-size: calc(100vw - 2rem);
  max-inline-size: calc(100vw - 2rem);
}

.ddga-modal__header {
  gap: var(--ddga-space-2);
  flex-direction: column;
  padding-inline-end: var(--ddga-space-8);
  display: flex;
}

.ddga-modal__header:has(.ddga-modal__featured-icon) {
  padding-inline-end: 0;
}

.ddga-modal--centered .ddga-modal__header {
  text-align: center;
  align-items: center;
  padding-inline-end: 0;
}

.ddga-modal--centered .ddga-modal__body {
  text-align: center;
}

.ddga-modal--centered .ddga-modal__footer {
  justify-content: center;
}

.ddga-modal__featured-icon {
  border-radius: var(--ddga-radius-full);
  background-color: var(--ddga-gray-50);
  block-size: 2.5rem;
  inline-size: 2.5rem;
  color: var(--ddga-text-primary);
  flex-shrink: 0;
  justify-content: center;
  align-items: center;
  display: inline-flex;
}

.ddga-modal__featured-icon > svg {
  block-size: 1.25rem;
  inline-size: 1.25rem;
}

.ddga-modal__title {
  font-size: var(--ddga-font-size-lg);
  font-weight: var(--ddga-font-weight-semibold);
  color: var(--ddga-gray-800);
  margin: 0;
  line-height: 1.75rem;
}

.ddga-modal__description {
  font-size: var(--ddga-font-size-sm);
  font-weight: var(--ddga-font-weight-regular);
  color: var(--ddga-gray-700);
  margin: 0;
  line-height: 1.25rem;
}

.ddga-modal__body {
  min-block-size: 0;
  font-size: var(--ddga-font-size-sm);
  color: var(--ddga-gray-700);
  flex: auto;
  padding-block-end: var(--ddga-space-4);
  line-height: 1.25rem;
  overflow-y: auto;
}

.ddga-modal__footer {
  justify-content: flex-end;
  align-items: center;
  gap: var(--ddga-space-2);
  display: flex;
}

@media (max-width: 480px) {
  .ddga-modal__footer {
    flex-direction: column-reverse;
    align-items: stretch;
  }
}
.ddga-modal__close {
  block-size: 2rem;
  inline-size: 2rem;
  color: var(--ddga-text-primary);
  cursor: pointer;
  border-radius: var(--ddga-radius-sm);
  background: 0 0;
  border: 0;
  justify-content: center;
  align-items: center;
  padding: 0;
  transition: background-color 0.15s, color 0.15s;
  display: inline-flex;
  position: absolute;
  inset-block-start: 0.875rem;
  inset-inline-end: 0.875rem;
}

.ddga-modal__close > svg {
  block-size: 1.25rem;
  inline-size: 1.25rem;
}

.ddga-modal__close:hover {
  background-color: var(--ddga-color-muted);
}

.ddga-modal__close:focus-visible {
  box-shadow: 0 0 0 2px var(--ddga-color-ring);
  outline: none;
}

.ddga-modal__overlay[data-state=open] {
  animation-name: ddga-modal-overlay-in;
}

.ddga-modal__overlay[data-state=closed] {
  animation-name: ddga-modal-overlay-out;
}

.ddga-modal[data-state=open] {
  animation-name: ddga-modal-in;
}

.ddga-modal[data-state=closed] {
  animation-name: ddga-modal-out;
}

@keyframes ddga-modal-overlay-in {
  0% {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
@keyframes ddga-modal-overlay-out {
  0% {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}
@keyframes ddga-modal-in {
  0% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.96);
  }
  to {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
  }
}
@keyframes ddga-modal-out {
  0% {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
  }
  to {
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.96);
  }
}
[data-theme=dark] .ddga-modal__title {
  color: var(--ddga-text-primary);
}

[data-theme=dark] .ddga-modal__description, [data-theme=dark] .ddga-modal__body {
  color: var(--ddga-text-secondary);
}

[data-theme=dark] .ddga-modal__featured-icon {
  background-color: var(--ddga-alpha-white-10);
}

@media (prefers-reduced-motion: reduce) {
  .ddga-modal, .ddga-modal__overlay {
    animation-duration: 0s;
  }
}
@media (forced-colors: active) {
  .ddga-modal {
    border: 1px solid canvastext;
  }
  .ddga-modal__close:focus-visible {
    box-shadow: none;
    outline: 2px solid highlight;
  }
}
/*# sourceMappingURL=modal.css.map */
/* ── dropdown-menu — 35 rules, 1 @layer wrapper(s) removed ── */
.ddga-dropdown-menu {
  min-inline-size: 192px;
  max-inline-size: 320px;
  padding: var(--ddga-space-2);
  background-color: var(--ddga-color-background);
  color: var(--ddga-text-primary);
  border: 1px solid var(--ddga-color-input);
  border-radius: var(--ddga-radius-md);
  box-shadow: var(--ddga-shadow-2xl);
  z-index: 50;
  outline: none;
  font-family: inherit;
  overflow: clip;
}

.ddga-dropdown-menu[data-state=open] {
  animation: 0.12s cubic-bezier(0.16, 1, 0.3, 1) ddga-dropdown-menu-in;
}

.ddga-dropdown-menu[data-state=closed] {
  animation: 80ms ease-in ddga-dropdown-menu-out;
}

@keyframes ddga-dropdown-menu-in {
  0% {
    opacity: 0;
    transform: translateY(-2px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}
@keyframes ddga-dropdown-menu-out {
  0% {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}
.ddga-dropdown-menu__item {
  align-items: center;
  gap: var(--ddga-space-2);
  inline-size: 100%;
  padding: var(--ddga-space-2);
  border-radius: var(--ddga-radius-sm);
  color: var(--ddga-text-primary);
  cursor: default;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  outline: none;
  display: flex;
}

.ddga-dropdown-menu__item:hover {
  background-color: var(--ddga-gray-100);
}

.ddga-dropdown-menu__item[data-highlighted]:not(:hover):not([data-state=open]) {
  outline: 2px solid var(--ddga-text-primary);
  outline-offset: -2px;
}

.ddga-dropdown-menu__item:active {
  background-color: var(--ddga-gray-200);
}

.ddga-dropdown-menu__item[data-disabled] {
  color: var(--ddga-gray-400);
  pointer-events: none;
}

.ddga-dropdown-menu__item[data-state=checked] {
  background-color: var(--ddga-sa-50);
  color: var(--ddga-color-primary);
}

.ddga-dropdown-menu__item[data-destructive] {
  color: var(--ddga-color-destructive);
}

.ddga-dropdown-menu__item[data-destructive]:hover, .ddga-dropdown-menu__item[data-destructive][data-highlighted] {
  background-color: var(--ddga-error-50);
}

.ddga-dropdown-menu__label {
  min-inline-size: 0;
  font-size: var(--ddga-font-size-base);
  line-height: 1.5;
  font-weight: var(--ddga-font-weight-regular);
  white-space: nowrap;
  text-overflow: ellipsis;
  flex: auto;
  overflow: hidden;
}

.ddga-dropdown-menu__icon {
  block-size: 24px;
  inline-size: 24px;
  color: inherit;
  flex-shrink: 0;
  justify-content: center;
  align-items: center;
  display: inline-flex;
}

.ddga-dropdown-menu__icon > svg {
  block-size: 24px;
  inline-size: 24px;
}

.ddga-dropdown-menu__trailing {
  min-block-size: 24px;
  color: inherit;
  flex-shrink: 0;
  align-items: center;
  margin-inline-start: auto;
  display: inline-flex;
}

.ddga-dropdown-menu__indicator {
  block-size: 24px;
  inline-size: 24px;
  color: inherit;
  flex-shrink: 0;
  justify-content: center;
  align-items: center;
  margin-inline-start: auto;
  display: inline-flex;
}

.ddga-dropdown-menu__indicator-icon {
  block-size: 24px;
  inline-size: 24px;
}

.ddga-dropdown-menu__item--sub[data-state=open] {
  background-color: var(--ddga-gray-100);
}

.ddga-dropdown-menu__sub-chevron {
  block-size: 24px;
  inline-size: 24px;
  color: inherit;
  flex-shrink: 0;
  margin-inline-start: auto;
}

[dir=rtl] .ddga-dropdown-menu__sub-chevron {
  transform: scaleX(-1);
}

.ddga-dropdown-menu__group-label {
  padding-block: var(--ddga-space-2) var(--ddga-space-3);
  padding-inline: var(--ddga-space-2) var(--ddga-space-4);
  font-size: var(--ddga-font-size-xs);
  line-height: 1.5;
  font-weight: var(--ddga-font-weight-bold);
  color: var(--ddga-gray-800);
}

.ddga-dropdown-menu__separator {
  block-size: 1px;
  margin-block: var(--ddga-space-2);
  margin-inline: calc(var(--ddga-space-2) * -1);
  background-color: var(--ddga-color-input);
}

[data-theme=dark] .ddga-dropdown-menu__item:hover, [data-theme=dark] .ddga-dropdown-menu__item--sub[data-state=open] {
  background-color: var(--ddga-color-muted);
}

[data-theme=dark] .ddga-dropdown-menu__item:active {
  background-color: var(--ddga-color-border);
}

[data-theme=dark] .ddga-dropdown-menu__item[data-state=checked] {
  color: var(--ddga-sa-400);
  background-color: rgba(27, 131, 84, 0.1803921569);
}

[data-theme=dark] .ddga-dropdown-menu__item[data-destructive][data-highlighted], [data-theme=dark] .ddga-dropdown-menu__item[data-destructive]:hover {
  color: var(--ddga-error-200, #fecdca);
  background-color: rgba(217, 45, 32, 0.2392156863);
}

@media (forced-colors: active) {
  .ddga-dropdown-menu {
    border: 1px solid canvastext;
  }
  .ddga-dropdown-menu__item:hover, .ddga-dropdown-menu__item[data-highlighted] {
    color: highlighttext;
    background-color: highlight;
  }
  .ddga-dropdown-menu__item:focus-visible {
    outline-color: highlight;
  }
  .ddga-dropdown-menu__separator {
    background-color: canvastext;
  }
}
@media (prefers-reduced-motion: reduce) {
  .ddga-dropdown-menu[data-state=open], .ddga-dropdown-menu[data-state=closed] {
    animation: none;
  }
}
/*# sourceMappingURL=dropdown-menu.css.map */
/* ── metric — 54 rules, 1 @layer wrapper(s) removed ── */
.ddga-metric {
  --ddga-metric-ink:var(--ddga-gray-800);
  gap: var(--ddga-space-6);
  max-inline-size: 22.5rem;
  padding: var(--ddga-space-4);
  background-color: var(--ddga-color-card);
  border-radius: var(--ddga-radius-xl);
  box-shadow: var(--ddga-shadow-md);
  color: var(--ddga-color-card-foreground);
  flex-direction: column;
  display: flex;
}

.ddga-metric__header {
  justify-content: space-between;
  align-items: center;
  gap: var(--ddga-space-2);
  display: flex;
}

.ddga-metric__heading {
  align-items: center;
  gap: var(--ddga-space-2);
  min-inline-size: 0;
  display: flex;
}

.ddga-metric__icon {
  border-radius: var(--ddga-radius-full);
  background-color: var(--ddga-sa-50);
  block-size: 2rem;
  inline-size: 2rem;
  color: var(--ddga-success-700);
  flex: none;
  justify-content: center;
  align-items: center;
  display: inline-flex;
}

.ddga-metric__icon > svg {
  block-size: 1rem;
  inline-size: 1rem;
}

.ddga-metric__action {
  flex: none;
}

.ddga-metric__label {
  color: var(--ddga-metric-ink);
  font-size: var(--ddga-font-size-sm);
  font-weight: var(--ddga-font-weight-medium);
  line-height: 1.4286;
}

.ddga-metric__body {
  gap: var(--ddga-space-6);
  display: flex;
}

.ddga-metric--large .ddga-metric__body {
  flex-direction: column;
}

.ddga-metric--small .ddga-metric__body {
  align-items: flex-end;
  gap: var(--ddga-space-6);
  flex-direction: row;
}

.ddga-metric__figures {
  flex: 1 1 0;
  min-inline-size: 0;
  display: flex;
}

.ddga-metric--large .ddga-metric__figures {
  align-items: center;
  gap: var(--ddga-space-6);
  flex-direction: row;
}

.ddga-metric--small .ddga-metric__figures {
  gap: var(--ddga-space-3);
  flex-direction: column;
}

.ddga-metric__value {
  color: var(--ddga-metric-ink);
  font-size: 2.25rem;
  font-weight: var(--ddga-font-weight-bold);
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  line-height: 2.75rem;
}

[dir=rtl] .ddga-metric__value {
  letter-spacing: normal;
}

.ddga-metric__info {
  align-items: flex-end;
  gap: var(--ddga-space-2);
  display: flex;
}

.ddga-metric--large .ddga-metric__info {
  flex: 1 1 0;
  justify-content: flex-end;
}

[dir=rtl] .ddga-metric--large .ddga-metric__figures {
  flex-direction: row-reverse;
}

[dir=rtl] .ddga-metric--large .ddga-metric__info {
  justify-content: flex-start;
}

.ddga-metric__change {
  --ddga-metric-change-color:var(--ddga-text-secondary);
  color: var(--ddga-metric-change-color);
  font-size: var(--ddga-font-size-sm);
  font-weight: var(--ddga-font-weight-medium);
  font-variant-numeric: tabular-nums;
  align-items: center;
  gap: 0.125rem;
  display: inline-flex;
}

.ddga-metric__change[data-type="02"] {
  gap: var(--ddga-space-1);
}

.ddga-metric__change--up {
  --ddga-metric-change-color:var(--ddga-success-700);
}

.ddga-metric__change--down {
  --ddga-metric-change-color:var(--ddga-error-700);
}

.ddga-metric__change-icon {
  justify-content: center;
  align-items: center;
  display: inline-flex;
}

.ddga-metric__change-icon > svg {
  block-size: 1.25rem;
  inline-size: 1.25rem;
}

.ddga-metric__change-label {
  color: var(--ddga-text-tertiary);
  font-size: var(--ddga-font-size-sm);
}

.ddga-metric__chart {
  --ddga-metric-chart-line:var(--ddga-success-700);
  --ddga-metric-chart-area:var(--ddga-success-600);
  block-size: 4rem;
  position: relative;
}

.ddga-metric__chart[data-trend=down] {
  --ddga-metric-chart-line:var(--ddga-error-700);
  --ddga-metric-chart-area:var(--ddga-error-600);
}

.ddga-metric--large .ddga-metric__chart {
  inline-size: 100%;
}

.ddga-metric--small .ddga-metric__chart {
  flex: none;
  inline-size: 8rem;
}

.ddga-metric__chart-svg {
  block-size: 100%;
  inline-size: 100%;
  display: block;
}

.ddga-metric__chart-line {
  fill: none;
  stroke: var(--ddga-metric-chart-line);
  stroke-width: 2px;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.ddga-metric__chart-marker {
  block-size: 22px;
  inline-size: 22px;
  position: absolute;
  transform: translate(-50%, -50%);
}

.ddga-metric__chart-marker:before {
  content: "";
  border-radius: var(--ddga-radius-full);
  border: 2px solid var(--ddga-metric-chart-line);
  opacity: 0.2;
  position: absolute;
  inset: 0;
}

.ddga-metric__chart-marker:after {
  content: "";
  border-radius: var(--ddga-radius-full);
  background-color: var(--ddga-color-card);
  border: 2px solid var(--ddga-metric-chart-line);
  position: absolute;
  inset: 5px;
}

.ddga-metric__footer {
  gap: var(--ddga-space-4);
  flex-direction: column;
  display: flex;
}

.ddga-metric__divider {
  margin-inline: calc(-1 * var(--ddga-space-4));
  background-color: var(--ddga-color-input);
  block-size: 1px;
}

.ddga-metric__actions {
  justify-content: space-between;
  align-items: center;
  gap: var(--ddga-space-2);
  display: flex;
}

[data-theme=dark] .ddga-metric {
  --ddga-metric-ink:var(--ddga-gray-100);
}

[data-theme=dark] .ddga-metric__icon {
  color: var(--ddga-success-400);
  background-color: rgba(37, 147, 95, 0.1803921569);
}

[data-theme=dark] .ddga-metric__change--up {
  --ddga-metric-change-color:var(--ddga-success-400);
}

[data-theme=dark] .ddga-metric__change--down {
  --ddga-metric-change-color:var(--ddga-error-400);
}

[data-theme=dark] .ddga-metric__chart {
  --ddga-metric-chart-line:var(--ddga-success-400);
}

[data-theme=dark] .ddga-metric__chart[data-trend=down] {
  --ddga-metric-chart-line:var(--ddga-error-400);
}

@media (forced-colors: active) {
  .ddga-metric__icon {
    border: 1px solid canvastext;
  }
  .ddga-metric__divider {
    background-color: canvastext;
  }
}
.ddga-metric-group {
  --ddga-metric-group-gap:var(--ddga-space-4);
}

.ddga-metric-group--gap-sm {
  --ddga-metric-group-gap:var(--ddga-space-3);
}

.ddga-metric-group--gap-md {
  --ddga-metric-group-gap:var(--ddga-space-4);
}

.ddga-metric-group--gap-lg {
  --ddga-metric-group-gap:var(--ddga-space-6);
}

.ddga-metric-group--horizontal {
  gap: var(--ddga-metric-group-gap);
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  display: grid;
}

.ddga-metric-group--horizontal.ddga-metric-group--cols {
  grid-template-columns: repeat(auto-fit, minmax(max(15rem, (100% - (var(--ddga-metric-group-columns) - 1) * var(--ddga-metric-group-gap)) / var(--ddga-metric-group-columns)), 1fr));
}

.ddga-metric-group--vertical {
  gap: var(--ddga-metric-group-gap);
  flex-direction: column;
  display: flex;
}

.ddga-metric-group .ddga-metric {
  max-inline-size: none;
}

/*# sourceMappingURL=metric.css.map */
/* The DGA metric-group `--cols` variant reads `var(--ddga-metric-group-columns)` with
   NO fallback, expecting an author-supplied count set inline per instance. The Harf
   dashboard uses the base `--horizontal` variant (auto-fit), which never reads it — but
   the ported (generated, un-editable) partial still references it, so
   scripts/check-dga-tokens.sh would flag it as an undefined custom property. Defining it
   here satisfies that guard and can never void anything Harf renders, because `--cols`
   is unused. README §17.3 rule 2 (DGA is silent on a default): 3, the dashboard's
   top-row column count. Remove this line if `--cols` is ever adopted with an inline
   value, or once "metric" joins tools/dga-port/port-components.mjs. */
.ddga-metric-group {
  --ddga-metric-group-columns: 3;
}

/* Figma's responsive dimension, which @dev-dga/css does not have. Its spacing ramp
   is flat — 11 steps, one value each — while Figma's Spacing and Typography
   collections carry Desktop/Tablet/Mobile modes and 75 variables genuinely differ
   across them. A Style Book token holds ONE value and cannot express a breakpoint,
   so this is the only home for it. Generated by
   tools/dga-port/port-responsive-space.mjs — do not hand-edit. */
/* ─────────────────────────────────────────────────────────────────────────────
   Figma responsive token layer — GENERATED, DO NOT EDIT BY HAND.

   Source:    Figma "منصة حرف - النسخة الرابعة" variable collections, extracted
              verbatim into tools/dga-port/figma-responsive-tokens.json  ← REMOVED
   Generator: tools/dga-port/port-responsive-space.mjs                   ← REMOVED

   ⚠ GENERATOR AND SOURCE EXTRACT BOTH REMOVED 2026-07-28 — HAND-MAINTAINED NOW.
   tools/dga-port/ went with frontend-source/ (README §15). Unlike the sibling DGA
   partials, this one lost its INPUT as well as its generator: figma-responsive-tokens.json
   was the verbatim extract, and it is gone too.

   ⚠ CORRECTION, MEASURED 2026-07-28 — "just re-pull it from Figma" DOES NOT WORK.
   An earlier version of this note said refreshing meant re-pulling the Spacing/Typography
   collections from Figma and re-extracting by hand. That is FALSE and would waste the
   next person's time, so it is corrected here rather than quietly dropped.

   MEASURED: get_variable_defs returns ONE mode — the collection DEFAULT, which on this
   file is Desktop — for every node, regardless of the frame's width. Probed 6 nodes on
   fileKey n2vs1oaOOfi4Vx2PSeuvFf: 2052:18296, 2588:188186, 240:16406, 2591:215104 and
   the two documented 430-wide MOBILE frames 3486:242820 and 3507:373108. All six
   returned Size/Text/typo-size-text-md = 16 — the DESKTOP value. The mobile base below
   says 12. (A 7th, 2174:24283, is a stale id: "nothing selected".) The light-mode-only
   caveat in docs/reference/FIGMA-VERIFICATION.md is therefore NOT specific to light/dark — it is
   how the server treats EVERY multi-mode collection.

   Cross-checked independently with get_design_context on the 430 Hero 3474:128868: it
   emits typo-size-display-sm 30px / line-heights-display-sm 38px and typo-size-text-md
   16px / 24px — desktop values again, in Figma's own mobile frame. search_design_system
   returns no variables for this file at all.

   CONSEQUENCE — what is and is not verifiable from here:
     · DESKTOP  — verifiable, and VERIFIED. 23 mode-varying tokens were observed across
                  those 6 probes; all 23 match this file's effective desktop value
                  (the ≥1024 block, or the ≥768 value where ≥1024 does not restate it).
                  0 mismatches.
     · TABLET   — NOT reachable through the Figma MCP server. No probe ever returned one.
     · MOBILE   — NOT reachable either, for the same reason.
   The only route to all three modes is Figma's REST endpoint
   GET /v1/files/:key/variables/local, which returns every mode per variable but needs a
   Figma access token this project does not hold. That is an EXPLICIT GAP — do not invent
   a token, a path, or a value to close it (docs/client-inputs/DELIVERY-CLIENT-INPUTS.md).

   ⚠ AND A DESIGN-FILE FACT THAT CONSTRAINS HOW THIS LAYER MAY BE USED.
   Figma's own 430-wide frames render DESKTOP typography (the Hero measurement above).
   So Mobile/Tablet exist as MODES IN THE COLLECTIONS but are not applied to the mobile
   frames. This layer must therefore stay strictly OPT-IN and be consumed ONLY where
   Figma is silent below 1440 — README §17.3 rule 2. Where Figma ships a frame at that
   width, THE FRAME WINS (rule 1); it is the more specific statement of the same
   authority. Every current consumer already obeys this and says so in place — e.g.
   participant-register*, forgot-password-aux and create-account-aux each carry
   "Figma ships no frame below 1440 here → responsive token (rule 2)", and hero-section,
   which DOES have a 430 frame, consumes none of these properties. Do not widen
   consumption to a surface Figma actually draws at mobile width.

   Do NOT interpolate or invent a responsive value (README §17.3, rule 2).

   WHY THIS FILE EXISTS
   @dev-dga/css exposes spacing as a FLAT ramp (--ddga-space-0 … --ddga-space-16,
   11 steps, one value each, no breakpoint dimension). Figma's Spacing and Typography
   collections carry three modes — Desktop / Tablet / Mobile — and 39 of
   104 Spacing and 36 of 46 Typography variables genuinely differ across them.
   Radius carries the same three modes but all 8 of its variables are identical in
   every mode, so it contributes nothing here and is deliberately absent.

   WHY A CUSTOM-PROPERTY LAYER AND NOT A STYLE BOOK TOKEN
   A Liferay Style Book token is { defaultValue, mappings: [cssVariable] } — ONE value,
   no breakpoint dimension anywhere in the shape. It cannot hold a responsive value, for
   the same reason it cannot hold a dark-mode value. And @dev-dga/css offers nothing to
   inherit: its entire dist ships ONE media query, @media (max-width: 480px), and does
   not re-declare any --ddga-* token inside it. Redefining custom properties per media
   query in the theme is therefore the mechanism — no JS, no container queries, and no
   fragment has to restate a breakpoint to get the right number.

   BREAKPOINTS
     base            Figma Mobile mode.
     ≥ 768px         Figma Tablet mode. 768 is Figma's Width/width-xl, the tablet floor.
     ≥ 1024px        Figma Desktop mode. 1024 is Figma's Width/width-2xl.

     The DGA library's only breakpoint, @media (max-width: 480px), is deliberately
     NOT the basis: both of its uses are component-internal (modal footer,
     description list), so it says nothing about page layout.

   Mobile-first, so each query restates only what changes at that step:
   75 at base, 73 at ≥768px, 44 at ≥1024px.

   Consumption is deliberately opt-in: a fragment that needs a responsive value writes
   var(--harf-fig-…) and the breakpoint owns the number. Where Figma states a value
   directly on the frame being built (as the footer frames do for their own type and
   gaps), that frame value wins — it is the more specific statement of the same
   authority. See README §17.3.

   Unlayered on purpose — see docs/reference/THEME-BUILD.md.
   ──────────────────────────────────────────────────────────────────────────── */
:root {
  --harf-fig-card-lg-padding: 16px; /* Figma Card/card-lg-padding — mobile */
  --harf-fig-card-lg-gap: 16px; /* Figma Card/card-lg-gap — mobile */
  --harf-fig-card-md-gap: 12px; /* Figma Card/card-md-gap — mobile */
  --harf-fig-card-md-padding: 16px; /* Figma Card/card-md-padding — mobile */
  --harf-fig-card-sm-padding: 16px; /* Figma Card/card-sm-padding — mobile */
  --harf-fig-card-sm-gap: 12px; /* Figma Card/card-sm-gap — mobile */
  --harf-fig-section-padding: 16px; /* Figma Section/section-padding — mobile */
  --harf-fig-section-gap: 16px; /* Figma Section/section-gap — mobile */
  --harf-fig-text-content-gap: 4px; /* Figma Text/text-content-gap — mobile */
  --harf-fig-icon-text-gap: 4px; /* Figma Icon/icon-text-gap — mobile */
  --harf-fig-buttons-group-gap: 4px; /* Figma Button/buttons-group-gap — mobile */
  --harf-fig-links-group-gap: 8px; /* Figma Link/links-group-gap — mobile */
  --harf-fig-accordion-md-header-gap: 12px; /* Figma Accordion/accordion-md-header-gap — mobile */
  --harf-fig-horizontal-tab-md-button-v-padding: 8px; /* Figma Tab/horizontal-tab-md-button-v-padding — mobile */
  --harf-fig-horizontal-tab-md-button-h-padding: 12px; /* Figma Tab/horizontal-tab-md-button-h-padding — mobile */
  --harf-fig-horizontal-tab-sm-button-v-padding: 4px; /* Figma Tab/horizontal-tab-sm-button-v-padding — mobile */
  --harf-fig-horizontal-tab-sm-button-h-padding: 8px; /* Figma Tab/horizontal-tab-sm-button-h-padding — mobile */
  --harf-fig-vertical-tab-md-button-v-padding: 4px; /* Figma Tab/vertical-tab-md-button-v-padding — mobile */
  --harf-fig-vertical-tab-md-button-h-padding: 8px; /* Figma Tab/vertical-tab-md-button-h-padding — mobile */
  --harf-fig-vertical-tab-sm-button-h-padding: 4px; /* Figma Tab/vertical-tab-sm-button-h-padding — mobile */
  --harf-fig-table-cell-gap: 4px; /* Figma Table/table-cell-gap — mobile */
  --harf-fig-table-cell-v-padding: 4px; /* Figma Table/table-cell-v-padding — mobile */
  --harf-fig-table-cell-h-padding: 12px; /* Figma Table/table-cell-h-padding — mobile */
  --harf-fig-control-title-error-gap: 8px; /* Figma Control/control-title-error-gap — mobile */
  --harf-fig-control-switch-error-icon-gap: 4px; /* Figma Control/control-switch-error-icon-gap — mobile */
  --harf-fig-progress-indicator-gap: 16px; /* Figma Progress Indicator/progress-indicator-gap — mobile */
  --harf-fig-progress-text-content-side-padding: 12px; /* Figma Progress Indicator/progress-text-content-side-padding — mobile */
  --harf-fig-control-radio-error-icon-gap: 48px; /* Figma Control/control-radio-error-icon-gap — mobile */
  --harf-fig-pagination-items-padding: 4px; /* Figma Pagination/pagination-Items-padding — mobile */
  --harf-fig-button-menu-gap: 4px; /* Figma Button/button-menu-gap — mobile */
  --harf-fig-modal-padding: 16px; /* Figma Model/modal-padding — mobile */
  --harf-fig-modal-content-bottom-padding: 8px; /* Figma Model/modal-content-bottom-padding — mobile */
  --harf-fig-link-md-gap: 4px; /* Figma Link/link-md-gap — mobile */
  --harf-fig-notification-gap: 8px; /* Figma Notification/notification-gap — mobile */
  --harf-fig-notification-padding: 12px; /* Figma Notification/notification-padding — mobile */
  --harf-fig-notification-h-padding: 16px; /* Figma Notification/notification-h-padding — mobile */
  --harf-fig-notification-alert-h-padding: 16px; /* Figma Notification/notification-alert-h-padding — mobile */
  --harf-fig-notification-toast-v-padding: 12px; /* Figma Notification/notification-toast-v-padding — mobile */
  --harf-fig-notification-toast-desktop-h-padding: 16px; /* Figma Notification/notification-toast-desktop-h-padding — mobile */
  --harf-fig-typo-size-display-2xl: 48px; /* Figma Size/Display/typo-size-display-2xl — mobile */
  --harf-fig-typo-size-display-xl: 40px; /* Figma Size/Display/typo-size-display-xl — mobile */
  --harf-fig-typo-size-display-ig: 32px; /* Figma Size/Display/typo-size-display-Ig — mobile */
  --harf-fig-typo-size-display-md: 24px; /* Figma Size/Display/typo-size-display-md — mobile */
  --harf-fig-typo-size-display-sm: 20px; /* Figma Size/Display/typo-size-display-sm — mobile */
  --harf-fig-typo-size-display-xs: 18px; /* Figma Size/Display/typo-size-display-xs — mobile */
  --harf-fig-typo-size-text-xl: 16px; /* Figma Size/Text/typo-size-text-xl — mobile */
  --harf-fig-typo-size-text-ig: 14px; /* Figma Size/Text/typo-size-text-Ig — mobile */
  --harf-fig-typo-size-text-md: 12px; /* Figma Size/Text/typo-size-text-md — mobile */
  --harf-fig-typo-size-text-sm: 10px; /* Figma Size/Text/typo-size-text-sm — mobile */
  --harf-fig-typo-size-text-xs: 8px; /* Figma Size/Text/typo-size-text-xs — mobile */
  --harf-fig-typo-size-text-2xs: 8px; /* Figma Size/Text/typo-size-text-2xs — mobile */
  --harf-fig-line-heights-display-2xl: 64px; /* Figma Line Height/Display/line-heights-display-2xl — mobile */
  --harf-fig-line-heights-display-xl: 56px; /* Figma Line Height/Display/line-heights-display-xl — mobile */
  --harf-fig-line-heights-display-ig: 40px; /* Figma Line Height/Display/line-heights-display-Ig — mobile */
  --harf-fig-line-heights-display-md: 32px; /* Figma Line Height/Display/line-heights-display-md — mobile */
  --harf-fig-line-heights-display-sm: 28px; /* Figma Line Height/Display/line-heights-display-sm — mobile */
  --harf-fig-line-heights-display-xs: 24px; /* Figma Line Height/Display/line-heights-display-xs — mobile */
  --harf-fig-line-heights-text-xl: 24px; /* Figma Line Height/Text/line-heights-text-xl — mobile */
  --harf-fig-line-heights-text-ig: 20px; /* Figma Line Height/Text/line-heights-text-Ig — mobile */
  --harf-fig-line-heights-text-md: 18px; /* Figma Line Height/Text/line-heights-text-md — mobile */
  --harf-fig-line-heights-text-sm: 14px; /* Figma Line Height/Text/line-heights-text-sm — mobile */
  --harf-fig-line-heights-text-xs: 12px; /* Figma Line Height/Text/line-heights-text-xs — mobile */
  --harf-fig-line-heights-text-2xs: 10px; /* Figma Line Height/Text/line-heights-text-2xs — mobile */
  --harf-fig-paragraph-spacing-display-2xl: 56px; /* Figma Paragraph Spacing/Display/paragraph-spacing-display-2xl — mobile */
  --harf-fig-paragraph-spacing-display-xl: 48px; /* Figma Paragraph Spacing/Display/paragraph-spacing-display-xl — mobile */
  --harf-fig-paragraph-spacing-display-ig: 36px; /* Figma Paragraph Spacing/Display/paragraph-spacing-display-Ig — mobile */
  --harf-fig-paragraph-spacing-display-md: 30px; /* Figma Paragraph Spacing/Display/paragraph-spacing-display-md — mobile */
  --harf-fig-paragraph-spacing-display-sm: 24px; /* Figma Paragraph Spacing/Display/paragraph-spacing-display-sm — mobile */
  --harf-fig-paragraph-spacing-display-xs: 20px; /* Figma Paragraph Spacing/Display/paragraph-spacing-display-xs — mobile */
  --harf-fig-paragraph-spacing-text-xl: 16px; /* Figma Paragraph Spacing/Text/paragraph-spacing-text-xl — mobile */
  --harf-fig-paragraph-spacing-text-ig: 14px; /* Figma Paragraph Spacing/Text/paragraph-spacing-text-Ig — mobile */
  --harf-fig-paragraph-spacing-text-md: 12px; /* Figma Paragraph Spacing/Text/paragraph-spacing-text-md — mobile */
  --harf-fig-paragraph-spacing-text-sm: 10px; /* Figma Paragraph Spacing/Text/paragraph-spacing-text-sm — mobile */
  --harf-fig-paragraph-spacing-text-xs: 8px; /* Figma Paragraph Spacing/Text/paragraph-spacing-text-xs — mobile */
  --harf-fig-paragraph-spacing-text-2xs: 8px; /* Figma Paragraph Spacing/Text/paragraph-spacing-text-2xs — mobile */
}

@media (min-width: 768px) {
  :root {
    --harf-fig-card-lg-padding: 24px; /* Figma Card/card-lg-padding — tablet */
    --harf-fig-card-lg-gap: 24px; /* Figma Card/card-lg-gap — tablet */
    --harf-fig-card-md-gap: 20px; /* Figma Card/card-md-gap — tablet */
    --harf-fig-card-md-padding: 24px; /* Figma Card/card-md-padding — tablet */
    --harf-fig-card-sm-padding: 24px; /* Figma Card/card-sm-padding — tablet */
    --harf-fig-card-sm-gap: 20px; /* Figma Card/card-sm-gap — tablet */
    --harf-fig-section-padding: 24px; /* Figma Section/section-padding — tablet */
    --harf-fig-section-gap: 24px; /* Figma Section/section-gap — tablet */
    --harf-fig-text-content-gap: 8px; /* Figma Text/text-content-gap — tablet */
    --harf-fig-icon-text-gap: 8px; /* Figma Icon/icon-text-gap — tablet */
    --harf-fig-buttons-group-gap: 8px; /* Figma Button/buttons-group-gap — tablet */
    --harf-fig-links-group-gap: 12px; /* Figma Link/links-group-gap — tablet */
    --harf-fig-horizontal-tab-md-button-v-padding: 12px; /* Figma Tab/horizontal-tab-md-button-v-padding — tablet */
    --harf-fig-horizontal-tab-md-button-h-padding: 16px; /* Figma Tab/horizontal-tab-md-button-h-padding — tablet */
    --harf-fig-horizontal-tab-sm-button-v-padding: 8px; /* Figma Tab/horizontal-tab-sm-button-v-padding — tablet */
    --harf-fig-horizontal-tab-sm-button-h-padding: 12px; /* Figma Tab/horizontal-tab-sm-button-h-padding — tablet */
    --harf-fig-vertical-tab-md-button-v-padding: 6px; /* Figma Tab/vertical-tab-md-button-v-padding — tablet */
    --harf-fig-vertical-tab-md-button-h-padding: 12px; /* Figma Tab/vertical-tab-md-button-h-padding — tablet */
    --harf-fig-vertical-tab-sm-button-h-padding: 6px; /* Figma Tab/vertical-tab-sm-button-h-padding — tablet */
    --harf-fig-table-cell-gap: 8px; /* Figma Table/table-cell-gap — tablet */
    --harf-fig-table-cell-v-padding: 8px; /* Figma Table/table-cell-v-padding — tablet */
    --harf-fig-table-cell-h-padding: 16px; /* Figma Table/table-cell-h-padding — tablet */
    --harf-fig-control-title-error-gap: 12px; /* Figma Control/control-title-error-gap — tablet */
    --harf-fig-control-switch-error-icon-gap: 8px; /* Figma Control/control-switch-error-icon-gap — tablet */
    --harf-fig-progress-indicator-gap: 8px; /* Figma Progress Indicator/progress-indicator-gap — tablet */
    --harf-fig-progress-text-content-side-padding: 16px; /* Figma Progress Indicator/progress-text-content-side-padding — tablet */
    --harf-fig-control-radio-error-icon-gap: 16px; /* Figma Control/control-radio-error-icon-gap — tablet */
    --harf-fig-pagination-items-padding: 8px; /* Figma Pagination/pagination-Items-padding — tablet */
    --harf-fig-button-menu-gap: 8px; /* Figma Button/button-menu-gap — tablet */
    --harf-fig-modal-padding: 24px; /* Figma Model/modal-padding — tablet */
    --harf-fig-modal-content-bottom-padding: 16px; /* Figma Model/modal-content-bottom-padding — tablet */
    --harf-fig-link-md-gap: 8px; /* Figma Link/link-md-gap — tablet */
    --harf-fig-notification-gap: 16px; /* Figma Notification/notification-gap — tablet */
    --harf-fig-notification-padding: 16px; /* Figma Notification/notification-padding — tablet */
    --harf-fig-notification-h-padding: 24px; /* Figma Notification/notification-h-padding — tablet */
    --harf-fig-notification-alert-h-padding: 24px; /* Figma Notification/notification-alert-h-padding — tablet */
    --harf-fig-notification-toast-v-padding: 16px; /* Figma Notification/notification-toast-v-padding — tablet */
    --harf-fig-notification-toast-desktop-h-padding: 24px; /* Figma Notification/notification-toast-desktop-h-padding — tablet */
    --harf-fig-typo-size-display-2xl: 56px; /* Figma Size/Display/typo-size-display-2xl — tablet */
    --harf-fig-typo-size-display-xl: 48px; /* Figma Size/Display/typo-size-display-xl — tablet */
    --harf-fig-typo-size-display-ig: 36px; /* Figma Size/Display/typo-size-display-Ig — tablet */
    --harf-fig-typo-size-display-md: 30px; /* Figma Size/Display/typo-size-display-md — tablet */
    --harf-fig-typo-size-display-sm: 24px; /* Figma Size/Display/typo-size-display-sm — tablet */
    --harf-fig-typo-size-display-xs: 20px; /* Figma Size/Display/typo-size-display-xs — tablet */
    --harf-fig-typo-size-text-xl: 18px; /* Figma Size/Text/typo-size-text-xl — tablet */
    --harf-fig-typo-size-text-ig: 16px; /* Figma Size/Text/typo-size-text-Ig — tablet */
    --harf-fig-typo-size-text-md: 14px; /* Figma Size/Text/typo-size-text-md — tablet */
    --harf-fig-typo-size-text-sm: 12px; /* Figma Size/Text/typo-size-text-sm — tablet */
    --harf-fig-typo-size-text-xs: 10px; /* Figma Size/Text/typo-size-text-xs — tablet */
    --harf-fig-line-heights-display-2xl: 72px; /* Figma Line Height/Display/line-heights-display-2xl — tablet */
    --harf-fig-line-heights-display-xl: 64px; /* Figma Line Height/Display/line-heights-display-xl — tablet */
    --harf-fig-line-heights-display-ig: 48px; /* Figma Line Height/Display/line-heights-display-Ig — tablet */
    --harf-fig-line-heights-display-md: 40px; /* Figma Line Height/Display/line-heights-display-md — tablet */
    --harf-fig-line-heights-display-sm: 32px; /* Figma Line Height/Display/line-heights-display-sm — tablet */
    --harf-fig-line-heights-display-xs: 28px; /* Figma Line Height/Display/line-heights-display-xs — tablet */
    --harf-fig-line-heights-text-xl: 26px; /* Figma Line Height/Text/line-heights-text-xl — tablet */
    --harf-fig-line-heights-text-ig: 24px; /* Figma Line Height/Text/line-heights-text-Ig — tablet */
    --harf-fig-line-heights-text-md: 20px; /* Figma Line Height/Text/line-heights-text-md — tablet */
    --harf-fig-line-heights-text-sm: 16px; /* Figma Line Height/Text/line-heights-text-sm — tablet */
    --harf-fig-line-heights-text-xs: 14px; /* Figma Line Height/Text/line-heights-text-xs — tablet */
    --harf-fig-line-heights-text-2xs: 12px; /* Figma Line Height/Text/line-heights-text-2xs — tablet */
    --harf-fig-paragraph-spacing-display-2xl: 46px; /* Figma Paragraph Spacing/Display/paragraph-spacing-display-2xl — tablet */
    --harf-fig-paragraph-spacing-display-xl: 56px; /* Figma Paragraph Spacing/Display/paragraph-spacing-display-xl — tablet */
    --harf-fig-paragraph-spacing-display-ig: 40px; /* Figma Paragraph Spacing/Display/paragraph-spacing-display-Ig — tablet */
    --harf-fig-paragraph-spacing-display-md: 32px; /* Figma Paragraph Spacing/Display/paragraph-spacing-display-md — tablet */
    --harf-fig-paragraph-spacing-display-sm: 28px; /* Figma Paragraph Spacing/Display/paragraph-spacing-display-sm — tablet */
    --harf-fig-paragraph-spacing-display-xs: 24px; /* Figma Paragraph Spacing/Display/paragraph-spacing-display-xs — tablet */
    --harf-fig-paragraph-spacing-text-xl: 18px; /* Figma Paragraph Spacing/Text/paragraph-spacing-text-xl — tablet */
    --harf-fig-paragraph-spacing-text-ig: 16px; /* Figma Paragraph Spacing/Text/paragraph-spacing-text-Ig — tablet */
    --harf-fig-paragraph-spacing-text-md: 14px; /* Figma Paragraph Spacing/Text/paragraph-spacing-text-md — tablet */
    --harf-fig-paragraph-spacing-text-sm: 12px; /* Figma Paragraph Spacing/Text/paragraph-spacing-text-sm — tablet */
    --harf-fig-paragraph-spacing-text-xs: 10px; /* Figma Paragraph Spacing/Text/paragraph-spacing-text-xs — tablet */
    --harf-fig-paragraph-spacing-text-2xs: 10px; /* Figma Paragraph Spacing/Text/paragraph-spacing-text-2xs — tablet */
  }
}
@media (min-width: 1024px) {
  :root {
    --harf-fig-card-lg-padding: 32px; /* Figma Card/card-lg-padding — desktop */
    --harf-fig-card-md-gap: 24px; /* Figma Card/card-md-gap — desktop */
    --harf-fig-card-md-padding: 32px; /* Figma Card/card-md-padding — desktop */
    --harf-fig-card-sm-padding: 32px; /* Figma Card/card-sm-padding — desktop */
    --harf-fig-card-sm-gap: 24px; /* Figma Card/card-sm-gap — desktop */
    --harf-fig-section-padding: 32px; /* Figma Section/section-padding — desktop */
    --harf-fig-section-gap: 32px; /* Figma Section/section-gap — desktop */
    --harf-fig-accordion-md-header-gap: 48px; /* Figma Accordion/accordion-md-header-gap — desktop */
    --harf-fig-control-title-error-gap: 16px; /* Figma Control/control-title-error-gap — desktop */
    --harf-fig-typo-size-display-2xl: 72px; /* Figma Size/Display/typo-size-display-2xl — desktop */
    --harf-fig-typo-size-display-xl: 60px; /* Figma Size/Display/typo-size-display-xl — desktop */
    --harf-fig-typo-size-display-ig: 48px; /* Figma Size/Display/typo-size-display-Ig — desktop */
    --harf-fig-typo-size-display-md: 36px; /* Figma Size/Display/typo-size-display-md — desktop */
    --harf-fig-typo-size-display-sm: 30px; /* Figma Size/Display/typo-size-display-sm — desktop */
    --harf-fig-typo-size-display-xs: 24px; /* Figma Size/Display/typo-size-display-xs — desktop */
    --harf-fig-typo-size-text-xl: 20px; /* Figma Size/Text/typo-size-text-xl — desktop */
    --harf-fig-typo-size-text-ig: 18px; /* Figma Size/Text/typo-size-text-Ig — desktop */
    --harf-fig-typo-size-text-md: 16px; /* Figma Size/Text/typo-size-text-md — desktop */
    --harf-fig-typo-size-text-sm: 14px; /* Figma Size/Text/typo-size-text-sm — desktop */
    --harf-fig-typo-size-text-xs: 12px; /* Figma Size/Text/typo-size-text-xs — desktop */
    --harf-fig-typo-size-text-2xs: 10px; /* Figma Size/Text/typo-size-text-2xs — desktop */
    --harf-fig-line-heights-display-2xl: 90px; /* Figma Line Height/Display/line-heights-display-2xl — desktop */
    --harf-fig-line-heights-display-xl: 72px; /* Figma Line Height/Display/line-heights-display-xl — desktop */
    --harf-fig-line-heights-display-ig: 60px; /* Figma Line Height/Display/line-heights-display-Ig — desktop */
    --harf-fig-line-heights-display-md: 44px; /* Figma Line Height/Display/line-heights-display-md — desktop */
    --harf-fig-line-heights-display-sm: 38px; /* Figma Line Height/Display/line-heights-display-sm — desktop */
    --harf-fig-line-heights-display-xs: 32px; /* Figma Line Height/Display/line-heights-display-xs — desktop */
    --harf-fig-line-heights-text-xl: 30px; /* Figma Line Height/Text/line-heights-text-xl — desktop */
    --harf-fig-line-heights-text-ig: 28px; /* Figma Line Height/Text/line-heights-text-Ig — desktop */
    --harf-fig-line-heights-text-md: 24px; /* Figma Line Height/Text/line-heights-text-md — desktop */
    --harf-fig-line-heights-text-sm: 20px; /* Figma Line Height/Text/line-heights-text-sm — desktop */
    --harf-fig-line-heights-text-xs: 18px; /* Figma Line Height/Text/line-heights-text-xs — desktop */
    --harf-fig-line-heights-text-2xs: 14px; /* Figma Line Height/Text/line-heights-text-2xs — desktop */
    --harf-fig-paragraph-spacing-display-2xl: 72px; /* Figma Paragraph Spacing/Display/paragraph-spacing-display-2xl — desktop */
    --harf-fig-paragraph-spacing-display-xl: 60px; /* Figma Paragraph Spacing/Display/paragraph-spacing-display-xl — desktop */
    --harf-fig-paragraph-spacing-display-ig: 48px; /* Figma Paragraph Spacing/Display/paragraph-spacing-display-Ig — desktop */
    --harf-fig-paragraph-spacing-display-md: 36px; /* Figma Paragraph Spacing/Display/paragraph-spacing-display-md — desktop */
    --harf-fig-paragraph-spacing-display-sm: 30px; /* Figma Paragraph Spacing/Display/paragraph-spacing-display-sm — desktop */
    --harf-fig-paragraph-spacing-text-xl: 20px; /* Figma Paragraph Spacing/Text/paragraph-spacing-text-xl — desktop */
    --harf-fig-paragraph-spacing-text-ig: 18px; /* Figma Paragraph Spacing/Text/paragraph-spacing-text-Ig — desktop */
    --harf-fig-paragraph-spacing-text-md: 16px; /* Figma Paragraph Spacing/Text/paragraph-spacing-text-md — desktop */
    --harf-fig-paragraph-spacing-text-sm: 14px; /* Figma Paragraph Spacing/Text/paragraph-spacing-text-sm — desktop */
    --harf-fig-paragraph-spacing-text-xs: 12px; /* Figma Paragraph Spacing/Text/paragraph-spacing-text-xs — desktop */
    --harf-fig-paragraph-spacing-text-2xs: 12px; /* Figma Paragraph Spacing/Text/paragraph-spacing-text-2xs — desktop */
  }
}
/* The three OOTB auth surfaces (/login, /forgot-password, /register-participant).
   These style markup emitted by a WIDGET (com.liferay.login.web), not by a
   fragment, so the rules must load whether or not the page's aux fragment is
   present — and the markup is identical on all three pages, so one partial serves
   them all. Scoped entirely to `.portlet-login`, the css-class-wrapper the three
   portlet components declare. See specs/012-login T009. */
/* ─────────────────────────────────────────────────────────────────────────────
   OOTB AUTH SURFACES — styling the login-web portlets, nothing else.
   (specs/012-login T009 "theme login partial"; extended to the two sibling
   surfaces because all three render the SAME markup from the SAME bundle.)

   WHAT THIS STYLES, AND WHY IT IS A THEME PARTIAL AND NOT FRAGMENT CSS
   Three utility pages embed a widget from `com.liferay.login.web`:

     /login                 com_liferay_login_web_portlet_LoginPortlet
     /forgot-password       com_liferay_login_web_portlet_ForgotPasswordPortlet
     /register-participant  com_liferay_login_web_portlet_CreateAccountPortlet

   RULE 5 is absolute: Liferay owns authentication. Not one line here forks a
   portlet, replaces its markup, or touches a credential — this file only paints
   markup Liferay emits. Anything CSS cannot reach is RECORDED, never worked around.

   The markup below was read out of the SHIPPED bundle, not guessed:
     · bundles/osgi/portal/com.liferay.login.web.jar
         META-INF/resources/login.jsp, forgot_password.jsp, create_account.jsp,
         navigation.jspf, css/main.scss
         OSGI-INF/…LoginPortlet.xml, …ForgotPasswordPortlet.xml,
         …CreateAccountPortlet.xml   →  com.liferay.portlet.css-class-wrapper
                                        = "portlet-login" on ALL THREE. That is
                                        the scope every rule below uses.
     · bundles/tomcat/webapps/ROOT/html/taglib/aui/{input,button,fieldset,form}/*.jsp
     · bundles/tomcat/webapps/ROOT/WEB-INF/shielded-container-lib/util-taglib.jar
         com.liferay.taglib.aui.AUIUtil  (javap): FIELD_PREFIX="field",
         BUTTON_PREFIX="btn", buildControlGroupCss → "form-group[ input-<baseType>-wrapper]",
         buildLabel → class="control-label" for="…", buildCss → "btn[ disabled][ …]".
         `.form-control` is appended for baseType email/password/text/textarea.
     · bundles/osgi/portal/com.liferay.captcha.taglib.jar
         META-INF/resources/captcha/simplecaptcha.jsp  →  ".taglib-captcha"

   So the real, verified selectors are: .portlet-login .login-container,
   form.form.sign-in-form, fieldset > div > .panel-body, .form-group,
   label.control-label, input.field.form-control, .button-holder,
   button.btn.btn-primary > span.lfr-btn-label, div.navigation, .alert,
   .taglib-captcha, and (create account only) Clay's .sheet / .sheet-section /
   h3.sheet-subtitle / .row / [class^="col-"].

   IT IS A THEME PARTIAL because the markup it styles belongs to a WIDGET, not to
   a fragment: it must be painted whether or not the page's aux fragment is
   present, and it is identical on all three pages. Per-page geometry (column
   width, page gutter, the sign-up/sign-in feedback bar) stays in each aux
   fragment, which is where directive 12 configurability lives.

   SOURCE OF TRUTH (README §17.3), applied per declaration below:
     rule 1  Figma states it for THIS surface  → Figma wins.
     rule 2  Figma silent                      → @dev-dga/css wins.
     rule 3  both speak and disagree           → @dev-dga/css wins.
   Figma frames read this session over the figma-bridge MCP:
     Log in           240:16406
     Forget Password  2009:12950
     Sign up - 1      2011:16654
   Encouragingly, Figma and @dev-dga/css AGREE on nearly every value here — the
   40px control height, the 4px radius, the #9da4ae field border, the #6c737f
   placeholder, the #e5e7eb/#9da4ae disabled button and the #d2d6db outline
   border are all simultaneously the Figma value and the DGA token value. Each
   such coincidence is noted where it occurs so a future reader does not have to
   re-derive it.

   Unlayered on purpose — see docs/reference/THEME-BUILD.md and scripts/check-theme-css-order.sh.
   ──────────────────────────────────────────────────────────────────────────── */
/* ═══════════════════════════════════════════════════════════════════════════
   1. TOKEN BRIDGE — the values @dev-dga/css re-points with [data-theme=dark]
   ═══════════════════════════════════════════════════════════════════════════

   @dev-dga/css expresses the dark variants of its form controls as
   `[data-theme=dark] .ddga-text-input{…}` rules (dist/components/text-input.css)
   and `[data-theme=dark] .ddga-button:disabled{…}` (dist/components/button.css).
   We cannot reuse those rules — they key on DGA class names that the OOTB portlet
   never emits — and restating every rule body three times (data-theme,
   data-color-scheme, prefers-color-scheme) would triple this file.

   So the theme-varying values are lifted into custom properties and re-pointed
   once, in the same three selectors _dga-semantic.scss uses and for the same
   reasons documented there. Every value on both sides is an existing --ddga-*
   token; nothing is derived and nothing is invented. */
:root {
  --harf-auth-field-border: var(--ddga-gray-400); /* DGA .ddga-text-input border — and Figma's #9da4ae input stroke is the SAME value */
  --harf-auth-field-fg: var(--ddga-gray-700); /* DGA .ddga-text-input color */
  --harf-auth-field-placeholder: var(--ddga-gray-500); /* DGA .ddga-text-input__field::placeholder — and Figma's #6c737f placeholder is the SAME value */
  --harf-auth-field-hover-border: var(--ddga-gray-700); /* DGA .ddga-text-input--default:hover:not(:focus-within) */
  --harf-auth-field-focus-bar: var(--ddga-gray-950); /* DGA .ddga-text-input:focus-within:after */
  --harf-auth-btn-disabled-bg: var(--ddga-gray-200); /* DGA .ddga-button:disabled — and Figma 2009:12389 disabled fill #e5e7eb is the SAME value */
  --harf-auth-btn-disabled-fg: var(--ddga-gray-400); /* DGA .ddga-button:disabled — and Figma 2009:12389 disabled text #9da4ae is the SAME value */
}

/* :root[…] is (0,2,0) so it outranks the Style Book's inline :root sheet
   regardless of source order — measured and explained in _dga-semantic.scss. */
:root[data-theme=dark],
:root[data-color-scheme=dark] {
  --harf-auth-field-border: var(--ddga-color-input); /* DGA [data-theme=dark] .ddga-text-input */
  --harf-auth-field-fg: var(--ddga-text-primary); /* DGA [data-theme=dark] .ddga-text-input */
  --harf-auth-field-placeholder: var(--ddga-text-placeholder); /* DGA [data-theme=dark] .ddga-text-input__field::placeholder */
  --harf-auth-field-hover-border: var(--ddga-gray-500); /* DGA [data-theme=dark] .ddga-text-input--default:hover */
  --harf-auth-field-focus-bar: var(--ddga-text-primary); /* DGA [data-theme=dark] .ddga-text-input:focus-within:after */
  --harf-auth-btn-disabled-bg: var(--ddga-gray-800); /* DGA [data-theme=dark] .ddga-button:disabled */
  --harf-auth-btn-disabled-fg: var(--ddga-gray-500); /* DGA [data-theme=dark] .ddga-button:disabled */
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme=light]) {
    --harf-auth-field-border: var(--ddga-color-input);
    --harf-auth-field-fg: var(--ddga-text-primary);
    --harf-auth-field-placeholder: var(--ddga-text-placeholder);
    --harf-auth-field-hover-border: var(--ddga-gray-500);
    --harf-auth-field-focus-bar: var(--ddga-text-primary);
    --harf-auth-btn-disabled-bg: var(--ddga-gray-800);
    --harf-auth-btn-disabled-fg: var(--ddga-gray-500);
  }
}
/* ═══════════════════════════════════════════════════════════════════════════
   2. THE PORTLET SHELL
   ═══════════════════════════════════════════════════════════════════════════ */
.portlet-login {
  color: var(--ddga-text-primary);
  font-family: var(--ddga-font-ar);
}

/* login.jsp and forgot_password.jsp wrap their form in .login-container; the
   create-account JSP does not. Nothing decorative in Figma sits on it. */
.portlet-login .login-container {
  inline-size: 100%;
}

/* aui:form renders `class="form <cssClass>"` (taglib/aui/form/start.jsp). */
.portlet-login .form {
  margin: 0;
}

/* aui:fieldset with no label renders <fieldset><legend class="sr-only">…</legend>
   <div class="show" role="presentation"><div class="panel-body"> (fieldset/start.jsp).
   The login-web bundle's own css/main.scss already zeroes the fieldset border,
   padding and bottom margin, so only the inner stack needs shaping.

   Figma 240:16406 "Frame 2609383": VERTICAL auto-layout, gap 20 → --ddga-space-5.
   A flex column with gap is used rather than per-child margins so the last child
   contributes no trailing space (rule 1: Figma states the 20). */
.portlet-login .panel-body {
  display: flex;
  flex-direction: column;
  gap: var(--ddga-space-5);
  padding: 0;
}

.portlet-login .panel-body > .form-group {
  margin-block-end: 0;
}

/* Outside a .panel-body (create_account.jsp puts .form-group directly inside a
   clay:sheet-section) the same 20px is a bottom margin. */
.portlet-login .form-group {
  margin-block-end: var(--ddga-space-5);
}

/* ═══════════════════════════════════════════════════════════════════════════
   3. LABELS AND FIELDS
   ═══════════════════════════════════════════════════════════════════════════

   AUIUtil.buildLabel emits `class="control-label" for="<namespace><name>"`, so the
   label/field association is Liferay's and is left completely alone — only painted.
   Never add/remove `for` or `id` here (RULE 5 and WCAG both depend on them). */
.portlet-login label.control-label {
  color: var(--ddga-text-primary); /* Figma 240:16406 label #161616 = --ddga-text-primary (light) and re-points for dark (rule 1) */
  display: block;
  font-size: var(--ddga-font-size-sm); /* Figma 14px = --ddga-font-size-sm; DGA .ddga-text-input__label agrees */
  font-weight: var(--ddga-font-weight-semibold); /* Figma label is SemiBold 600 (rule 1). DGA .ddga-text-input__label is regular — Figma is the more specific statement for this surface. */
  line-height: 1.4286; /* Figma 20px on 14px; identical to DGA .ddga-text-input__label */
  margin-block-end: var(--ddga-space-2); /* Figma "Text Input" auto-layout gap 8 = --ddga-space-2; DGA .ddga-field[data-slot=text-input-field] agrees */
}

/* The required marker. aui:input renders it as
   <span class="reference-mark text-warning">…asterisk…</span> inside the label —
   Clay paints that amber. Figma 2011:16654 draws the required mark RED, so rule 1
   applies. --ddga-color-error is used rather than DGA's own
   .ddga-text-input__required (--ddga-error-700): error-700 is a PRIMITIVE and
   primitives are absent from dark.css's override list, so it could not re-point
   and would fail contrast on the dark surface. Same colour family, one step, and
   it is the only variant that survives dark mode. */
/* ⛔ THE `.text-warning` TWIN WAS MISSING, AND THE RULE ABOVE HAS BEEN LOSING SINCE
   IT WAS WRITTEN — found 2026-07-27 on the client's report that /forgot-password
   "is still using the old form".

   The mark rendered AMBER (measured on the deployed page: the email label's
   `span.reference-mark.text-warning` computed `rgb(255, 193, 7)`, not the
   `--ddga-color-error` this rule asks for). `.text-warning` is a Bootstrap colour
   utility and carries its OWN `!important` — `clay.css` → `.text-warning{color:#ffc107
   !important}` — and an important declaration is beaten only by another one, never by
   specificity. So the declaration above was correct, outranked, and silent.

   `_captcha.scss` had already worked this out for the captcha's own mark and named
   this exact gap in its header: "an amber required mark on the two surfaces that never
   got the `!important` twin". /login never showed it because our login.jsp does not
   mark the e-mail field required, so the orange only ever appeared here — which is why
   it survived the login pass.

   Scoped to `.portlet-login`, so it covers /forgot-password, /forgot-password-admin
   and /register-participant, and nothing outside the auth widget. */
.portlet-login label.control-label .reference-mark,
.portlet-login label.control-label .reference-mark.text-warning {
  color: var(--ddga-color-error) !important;
  /* Matches the text asterisk this now draws — see the block below. */
  font-size: var(--ddga-font-size-sm);
}

/* THE MARK IS A TEXT ASTERISK, NOT CLAY'S ICON — 2026-08-01, on the client's
   instruction: "make astrisk be light not bold".

   ⚠️ `font-weight` ALONE CANNOT DO THIS, which is why the rule looks like this. The
   mark `aui:input` emits is not a character: it is a 12×12 SPRITE,
   `<svg class="lexicon-icon lexicon-icon-asterisk"><use href="…/icons.svg#asterisk">`
   inside the span (read from the deployed DOM on /login, all three marks identical).
   A sprite is a filled shape — it has no weight axis, so no font declaration reaches
   it and the only lever an icon offers is scale. That is what "bold" is: a solid
   glyph, not a heavy font.

   So the icon is hidden and the span draws a real «*». The platform ALREADY has the
   light mark the client is asking for — `.harf-reg__req` on /register-participant is
   a plain text «*» inheriting the label's weight — so this is not a new treatment,
   it is the existing one reaching the surfaces that were still on the icon. Two
   renderings of one meaning was the defect, exactly as two COLOURS of it were the
   defect this file's colour rule above fixes.

   REGULAR (400) IS THE LIGHTEST WEIGHT THERE IS HERE. --ddga-font-weight-light does
   not exist — the scale defines regular/medium/semibold/bold only (read from the
   computed :root on the deployed page). A literal 300 is not written in its place:
   inventing a value to get past an obstacle is forbidden, and the family loaded here
   ("IBM Plex Sans Arabic") is not guaranteed to ship a 300 face, so it would most
   likely synthesise or snap back to 400 anyway.

   ACCESSIBILITY IS UNAFFECTED: the sprite is `aria-hidden="true"` and the label
   carries a real «مطلوب» beside it (measured — the accessible name reads «كلمة
   المرور مطلوب»). The visible mark was decorative before and still is, so moving it
   into generated content removes nothing from the accessible name.

   No `vertical-align`: `.harf-reg__req` sets none and reads correctly, and the two
   marks are meant to look the same. */
/* EVERY ERROR LINE ON THESE FORMS IS ONE SIZE — added 2026-08-01, client report:
   "font size of errors not the same for captcha and inputs! it should be one value
   for all errors!".

   MEASURED on /login and /forgot-password before this, three sizes for one thing:

       .harf-reg__error      12px     --ddga-font-size-xs    (/register-participant)
       .form-feedback-item   12.8px   Bootstrap `80%`        ← these fields
       captcha error         14px     --ddga-font-size-sm

   THE 12.8px WAS NEVER CHOSEN BY ANYONE. It is Bootstrap's `font-size: 80%` on a
   16px base, inherited because nothing here had ever set a size for validation
   feedback — the auth partial styles the label, the control and the required mark,
   and the error line was simply never in the list. That is the honest answer to how
   the sizes diverged: two of the three were set deliberately and this one was left
   at a framework default.

   `--ddga-font-size-xs` is the value because it is a DGA token AND is already what
   the platform's own error text uses on /register-participant. Standardising on the
   12.8px instead would have meant adopting an accident as the design.

   The captcha's two error paths take the same token in `_captcha.scss`. Both places
   move together — that file's `.text-danger` / `.form-feedback-item` rule says the
   same thing in the other direction.

   No `line-height`: Clay's 1.5 on 12px gives 18px, which is what `.harf-reg__error`
   already renders. Scoped to `.portlet-login`, so it reaches /login, /login-admin,
   /login-judge, /forgot-password, /forgot-password-admin and the register surfaces
   without touching validation feedback anywhere else on the platform. */
.portlet-login .form-feedback-item {
  font-size: var(--ddga-font-size-xs);
}

.portlet-login label.control-label .reference-mark .lexicon-icon {
  display: none;
}

.portlet-login label.control-label .reference-mark::after {
  content: "*";
  font-weight: var(--ddga-font-weight-regular);
}

/* input.field.form-control — the actual control.
   Figma 240:16406 "Input Field": h 40, radius 4, fill #ffffff, stroke #9da4ae,
   padding {right:16, left:8} on an RTL frame → inline-start 16 / inline-end 8.
   DGA .ddga-text-input is the MIRROR of that padding (start 8 / end 16) because
   its start slot is reserved for an adornment; the OOTB input has no adornment,
   so Figma's reading is the correct one here (rule 1). Every other value below is
   simultaneously the Figma value and the DGA value. */
.portlet-login .form-control {
  background-color: var(--ddga-color-background);
  block-size: 40px; /* Figma "Input Field" h=40; DGA .ddga-text-input--lg = 40px */
  border: 1px solid var(--harf-auth-field-border);
  border-radius: var(--ddga-radius-sm); /* Figma cornerRadius 4 = --ddga-radius-sm (.25rem) */
  box-shadow: none;
  color: var(--harf-auth-field-fg);
  font-family: inherit;
  font-size: var(--ddga-font-size-base); /* Figma placeholder 16px; DGA .ddga-text-input--lg agrees */
  inline-size: 100%;
  line-height: 1.5; /* Figma 24px on 16px */
  padding-block: 0;
  padding-inline-end: var(--ddga-space-2);
  padding-inline-start: var(--ddga-space-4);
  transition: background-color 0.15s, border-color 0.15s, box-shadow 0.15s;
}

.portlet-login .form-control::placeholder {
  color: var(--harf-auth-field-placeholder);
  opacity: 1;
}

.portlet-login .form-control:hover:not(:focus) {
  border-color: var(--harf-auth-field-hover-border); /* DGA .ddga-text-input--default:hover:not(:focus-within) (rule 2 — Figma has no hover state on these frames) */
}

/* DGA's focused text input keeps its border colour, adds --ddga-shadow-md, and
   draws a 2px bar along the block-end edge (.ddga-text-input:focus-within:after).
   Reproduced with one inset shadow because the OOTB control is a bare <input>
   with no wrapper to hang a pseudo-element on. Visible in both themes — WCAG 2.4.7. */
.portlet-login .form-control:focus,
.portlet-login .form-control:focus-visible {
  border-color: var(--harf-auth-field-border);
  box-shadow: var(--ddga-shadow-md), inset 0 -2px 0 0 var(--harf-auth-field-focus-bar);
  outline: none;
}

.portlet-login .has-error .form-control,
.portlet-login .form-control[aria-invalid=true] {
  border-color: var(--ddga-color-error);
}

.portlet-login .form-control:disabled,
.portlet-login .form-control[readonly] {
  background-color: transparent;
  border-color: var(--ddga-color-border); /* DGA .ddga-text-input:has(:disabled) (rule 2) */
  color: var(--ddga-text-placeholder);
  cursor: not-allowed;
}

/* Liferay's caps-lock hint (login.jsp `#…passwordCapsLockSpan`) and any
   aui:input help text. Figma has no equivalent; DGA's field message is the
   authority (rule 2): .ddga-field__message = font-size sm, helper colour. */
.portlet-login .form-text,
.portlet-login #passwordCapsLockSpan,
.portlet-login [id$=passwordCapsLockSpan] {
  color: var(--ddga-text-secondary);
  font-size: var(--ddga-font-size-sm);
  line-height: 1.4;
}

/* Clay's select controls (create_account.jsp gender, and Liferay's birthday
   selects) so they do not stand out beside the text fields. */
.portlet-login select.form-control,
.portlet-login .form-control.select {
  block-size: 40px;
  padding-inline-end: var(--ddga-space-8);
}

/* aui:input type="checkbox" — login.jsp "remember me" (renders only when
   company.isAutoLogin()) and create_account.jsp terms of use. */
.portlet-login .form-check-label,
.portlet-login .checkbox label {
  color: var(--ddga-text-primary);
  font-size: var(--ddga-font-size-sm);
  font-weight: var(--ddga-font-weight-regular);
}

.portlet-login input[type=checkbox] {
  accent-color: var(--ddga-color-primary);
}

/* ═══════════════════════════════════════════════════════════════════════════
   4. BUTTONS
   ═══════════════════════════════════════════════════════════════════════════

   aui:button renders <button class="btn[ disabled] btn-primary" …>
   <span class="lfr-btn-label">…</span></button> (taglib/aui/button/end.jsp +
   AUIUtil.buildCss; primary defaults to TRUE for type="submit", init-ext.jspf).

   login.jsp additionally ships the button `disabled` and re-enables it from its
   own inline script on readystatechange — which is why Figma 240:16406 shows the
   greyed CTA. Both states are painted here.

   The geometry below is Figma's and DGA's at the same time: h 40 / radius 4 /
   padding-inline 16 / 16px medium text is `.ddga-button.ddga-button--lg`
   verbatim, and Figma's Button instances measure exactly that. */
.portlet-login .btn {
  align-items: center;
  block-size: 40px;
  border: 1px solid transparent;
  border-radius: var(--ddga-radius-sm);
  cursor: pointer;
  display: inline-flex;
  font-family: inherit;
  font-size: var(--ddga-font-size-base);
  font-weight: var(--ddga-font-weight-medium);
  gap: var(--ddga-space-1);
  justify-content: center;
  line-height: 1.5rem; /* DGA .ddga-button--lg; Figma's 16/24 button text is the SAME value */
  padding-block: 0;
  padding-inline: var(--ddga-space-4);
  text-decoration: none;
  transition: background-color 0.15s, border-color 0.15s, color 0.15s;
}

.portlet-login .btn-primary {
  background-color: var(--ddga-color-primary); /* Figma 2011:18827 fill #1b8354 = --ddga-color-primary in LIGHT. In DARK the DGA library re-points it to #54c08a (--ddga-brand-400) and the library wins — README §17.3 / G184. */
  color: var(--ddga-color-primary-foreground);
}

.portlet-login .btn-primary:hover:not(:disabled):not(.disabled) {
  background-color: var(--ddga-color-primary-hover);
}

.portlet-login .btn-primary:active:not(:disabled):not(.disabled) {
  background-color: var(--ddga-color-primary-active);
}

.portlet-login .btn-secondary,
.portlet-login .btn-cancel {
  background-color: transparent;
  border-color: var(--ddga-color-input); /* DGA .ddga-button--outline; Figma's secondary CTA stroke #d2d6db is the SAME value */
  color: var(--ddga-color-foreground);
}

.portlet-login .btn-secondary:hover:not(:disabled):not(.disabled),
.portlet-login .btn-cancel:hover:not(:disabled):not(.disabled) {
  background-color: var(--ddga-color-muted);
}

.portlet-login .btn:disabled,
.portlet-login .btn.disabled {
  background-color: var(--harf-auth-btn-disabled-bg);
  border-color: transparent;
  color: var(--harf-auth-btn-disabled-fg);
  cursor: not-allowed;
}

/* DGA .ddga-button:focus-visible verbatim (rule 2 — Figma shows no focus state). */
.portlet-login .btn:focus-visible {
  box-shadow: inset 0 0 0 2px var(--ddga-color-background), inset 0 0 0 4px var(--ddga-color-focus-ring);
  outline: none;
}

.portlet-login .lfr-btn-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* aui:button-row → <div class="button-holder …"> (ButtonRowTag, inlined).
   login.jsp puts it OUTSIDE the fieldset, so the whole 32px Figma gap between
   the field stack and the CTA is this margin. */
.portlet-login form.form > .button-holder {
  margin-block: var(--ddga-space-8) 0; /* Figma 2009:12371 section gap 32 = --ddga-space-8 */
  text-align: start; /* Figma pins the CTA to the column's inline-start edge (x 1249→1376 of a 976→1376 column) */
}

/* forgot_password.jsp puts the SAME tag INSIDE the fieldset, where the flex gap
   above already contributes 20px — 12 more reaches Figma's 32. This is
   composition of two Figma numbers, not a third invented one.

   `form.form` is carried in the selector purely for specificity: the login-web
   bundle's own stylesheet declares `.portlet-login .form .button-holder
   {margin-bottom:10px}` at (0,3,0), and a bare `.portlet-login .panel-body >
   .button-holder` would TIE with it and be decided by whichever stylesheet the
   portal happens to emit last. (0,4,1) removes the coin-flip. */
.portlet-login form.form .panel-body > .button-holder {
  margin-block: var(--ddga-space-3) 0;
  text-align: start;
}

/* ═══════════════════════════════════════════════════════════════════════════
   5. ALERTS
   ═══════════════════════════════════════════════════════════════════════════

   <liferay-ui:error> renders either an inline
   <div class="alert alert-dismissible alert-danger" role="alert"> or a Liferay
   toast (html/taglib/ui/error/page.jsp branches on `embed`). Only the inline form
   is reachable from CSS; the toast is portal chrome outside .portlet-login and is
   recorded as a residual difference.

   Figma defines no alert on any of the three frames → rule 2, so the treatment is
   @dev-dga/css's inline-alert: a tint background, a tinted border and the accent
   as the text colour. The dark-mode tint uses DGA's own colour-mix recipe
   (dist/components/inline-alert.css, [data-theme=dark] .ddga-inline-alert--color)
   so it adapts without a second literal set. */
.portlet-login .alert {
  --harf-auth-alert-accent: var(--ddga-color-info); /* default; each variant below re-points it */
  background-color: color-mix(in srgb, var(--harf-auth-alert-accent) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--harf-auth-alert-accent) 45%, transparent);
  border-radius: var(--ddga-radius-md); /* DGA .ddga-inline-alert */
  color: var(--harf-auth-alert-accent);
  font-size: var(--ddga-font-size-sm);
  margin-block-end: var(--ddga-space-5);
  padding-block: var(--ddga-space-3);
  padding-inline: var(--ddga-space-4);
}

.portlet-login .alert-danger {
  --harf-auth-alert-accent: var(--ddga-color-error);
}

.portlet-login .alert-success {
  --harf-auth-alert-accent: var(--ddga-color-success);
}

.portlet-login .alert-warning {
  --harf-auth-alert-accent: var(--ddga-color-warning);
}

.portlet-login .alert .close {
  background: none;
  border: 0;
  color: inherit;
  cursor: pointer;
}

/* ═══════════════════════════════════════════════════════════════════════════
   6. LIFERAY CAPTCHA  (directive 6 — Liferay CAPTCHA, never Google reCAPTCHA)
   ═══════════════════════════════════════════════════════════════════════════

   simplecaptcha.jsp: <div class="my-3 taglib-captcha"><img class="captcha …">
   <a class="… refresh">…</a> + an aui:input text field.
   Figma's login frame draws a Google reCAPTCHA widget, which directive 6 forbids
   outright — so there is no Figma reading to honour and rule 2 applies: the
   Liferay widget is painted with DGA tokens. Recorded as a residual difference.

   ⚠️ LAYOUT IS NO LONGER HERE — it moved to _captcha.scss on 2026-07-26.
   This block used to open with `display: flex; flex-direction: column`, which
   MEASURED as the captcha stacked over THREE lines on /forgot-password and
   /forgot-password-admin, start-aligned. The same widget appears in two other
   containers that this `.portlet-login` scope cannot reach, and each had drifted
   to its own geometry. Geometry now lives once, unscoped, in _captcha.scss; what
   stays below is APPEARANCE only — the dark-mode-safe replacements for OOTB
   colour literals, which were never the defect. Do not re-add flex properties
   here: at (0,2,0) they would silently beat the shared rule and only on these two
   pages, which is exactly how the four-way drift happened. */
/* ⛔ `background-color` REMOVED 2026-07-27 — it turned into a dark-mode defect, and
   the sentence above ("dark-mode-safe replacements … which were never the defect")
   no longer holds for this one declaration.

   It WAS safe until that day. The challenge PNG shipped with its own opaque
   background — flat grey, gradient or transparent, drawn at random per render — so a
   plate behind it was only ever visible at the rounded corners. The captcha
   configuration is now pinned to TransparentBackgroundProducer, which makes this
   plate the challenge's actual background, and `--ddga-color-background` re-points
   DARK. Liferay draws the glyphs in a hardcoded Color.BLACK that no configuration
   key changes, so a dark-mode visitor would get black on near-black: an unreadable
   control on a WCAG-bound portal.

   The plate now has ONE owner — _captcha.scss — which pins it to a mode-INVARIANT
   primitive deliberately and ships an explicit [data-theme=dark] pair saying so.
   Do not reintroduce a background here. Border and radius stay: those are this
   surface's own and they sit outside the image. */
/* ⛔ AND NOW THE BORDER AND RADIUS HAVE GONE TOO — 2026-07-27. The sentence
   immediately above was written one day earlier and was already unsafe when it was
   written; recording that is more useful than editing it away.

   `.portlet-login .taglib-captcha .captcha` set
   `border: 1px solid var(--harf-auth-field-border)`, and that token RE-POINTS in
   dark mode (§1 of this file re-points it to --ddga-color-input). At (0,3,0) it
   outranked the very `[data-theme=dark]` pair _captcha.scss ships to keep the
   challenge plate mode-invariant — so on the two auth surfaces, and only there, the
   deliberate decision was being silently reverted by a rule whose own comment said
   the plate had one owner. Border, radius and the width cap are all the theme
   partial's now.

   ⛔ SO HAVE THE REFRESH AND ERROR RULES — same date, same reason, no defect of
   their own. `.portlet-login .taglib-captcha .refresh { color: --ddga-color-primary }`
   was the third of three answers to "what colour is the refresh icon" (the OOTB
   fragment surfaces said --ddga-text-secondary, OOTB itself says `#6b6c7e`). The
   client's report — "it should be shared across the project" — is about exactly that
   kind of three-way split, so the primary-green one WON and moved to _captcha.scss
   unscoped, because it is the one the client has been looking at on /login and did
   not object to. `.text-danger` moved with it for the same reason.

   NOTHING captcha-related is left in this file. Do not add anything back: at (0,2,0)
   or higher a rule here beats the shared one and does so on these two pages ONLY,
   which is precisely how the four-way drift happened the first time. */
/* ═══════════════════════════════════════════════════════════════════════════
   7. THE OOTB NAVIGATION STRIP
   ═══════════════════════════════════════════════════════════════════════════

   navigation.jspf emits <div class="c-mt-3 navigation"> holding the links
   contributed by LOGIN_FORM_NAVIGATION_PRE/POST — on this bundle,
   SignInNavigationPrePageInclude and ForgetPasswordNavigationPostPageInclude.

   The login-web bundle's OWN stylesheet paints it a hard grey card:
       .portlet-login .navigation { background:#eee; border-top:1px solid #bfbfbf;
                                    padding:10px }
   Two hard-coded literals that can never follow the theme — exactly the defect
   class scripts/check-color-literals.sh exists to prevent, shipped inside the
   vendor bundle where we cannot edit it. Figma shows no such strip on any of the
   three frames, so it is neutralised rather than restyled.

   `div.navigation` is (0,2,1) and the bundle rule is (0,2,0): this wins on
   specificity alone, so it does not matter whether the portlet stylesheet loads
   before or after the theme. */
.portlet-login div.navigation {
  background: none;
  border: 0;
  margin-block-start: var(--ddga-space-5);
  padding: 0;
}

.portlet-login div.navigation .icon-list,
.portlet-login div.navigation ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ddga-space-4);
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Clay's base sheet declares `a:hover { color:#0056b3 }` at (0,1,1) — the exact
   Bootstrap-blue regression already documented in _custom.scss §4. (0,3,1) here
   beats it outright instead of relying on source order, so no link on an auth
   page can fall back to browser/Bootstrap blue in either theme. */
.portlet-login div.navigation a,
.portlet-login div.navigation a:hover,
.portlet-login div.navigation a:focus,
.portlet-login div.navigation a:visited {
  color: var(--ddga-color-primary);
  font-size: var(--ddga-font-size-sm);
  text-decoration: none;
}

.portlet-login div.navigation a:hover {
  text-decoration: underline;
}

.portlet-login div.navigation a:focus-visible {
  outline: 2px solid var(--ddga-color-focus-ring);
  outline-offset: 2px;
}

/* Any other link the portlets emit (e.g. the "you are signed in as x" account
   link in login.jsp). Same anti-blue reasoning. */
.portlet-login a,
.portlet-login a:hover,
.portlet-login a:focus,
.portlet-login a:visited {
  color: var(--ddga-color-primary);
}

.portlet-login a:focus-visible {
  outline: 2px solid var(--ddga-color-focus-ring);
  outline-offset: 2px;
}

/* ═══════════════════════════════════════════════════════════════════════════
   8. CREATE ACCOUNT — Clay sheet chrome
   ═══════════════════════════════════════════════════════════════════════════

   create_account.jsp is the only one of the three built on <clay:sheet> /
   <clay:sheet-section> / <clay:row> / <clay:col md="6">, so it arrives inside
   Clay's white card: border, radius, drop shadow and generous padding.

   Figma 2011:16654 has no card at all — the form sits directly on the page — so
   the card chrome is removed and only the grid is kept. Figma's row gap is 24
   ("Content" frames, HORIZONTAL gap 24) which is exactly Clay's default gutter,
   so the columns need no override. */
.portlet-login .sheet {
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  margin: 0;
  max-inline-size: none;
  padding: 0;
}

.portlet-login .sheet-section {
  margin: 0;
  padding: 0;
}

.portlet-login .sheet-section + .sheet-section {
  margin-block-start: var(--ddga-space-8);
}

/* <h3 class="sheet-subtitle"> groups the OOTB field sets ("User Display Data",
   "Personal Information", "Password", "Verification"). Figma's own group headers
   are 16/24 semibold, which is what DGA uses for a field-group title too. */
.portlet-login .sheet-subtitle {
  border: 0;
  color: var(--ddga-text-primary);
  font-size: var(--ddga-font-size-base);
  font-weight: var(--ddga-font-weight-semibold);
  line-height: 1.5;
  margin-block: 0 var(--ddga-space-4);
  padding: 0;
}

/* ═══════════════════════════════════════════════════════════════════════════
   9. WIDGET TITLE
   ═══════════════════════════════════════════════════════════════════════════

   forgot_password.jsp and create_account.jsp call renderResponse.setTitle(...);
   login.jsp does not. Whether Liferay paints that title depends on the widget's
   own "show title" decoration on the content page, which this file cannot decide.
   Styled defensively so that IF it renders it is the Figma page heading
   (30px/38 bold, --ddga-text-primary) rather than Liferay's portlet-topper type.
   Figma frames: 240:16406 / 2009:12950 / 2011:16654 all use 30px Bold #161616. */
.portlet-login .portlet-title-text,
.portlet-login .portlet-title-default {
  color: var(--ddga-text-primary);
  font-family: var(--ddga-font-ar);
  font-size: 1.875rem; /* 30px — Figma-explicit page heading. @dev-dga/css has no 30px step (--ddga-font-size-2xl = 24, -3xl = 32), so the Figma frame value is written directly; README §17.3 rule 1. */
  font-weight: var(--ddga-font-weight-bold);
  line-height: 1.2667; /* Figma 38px on 30px */
  margin-block-end: var(--ddga-space-8);
  text-transform: none;
}

/* ═══════════════════════════════════════════════════════════════════════════
   10. FORCED COLOURS
   ═══════════════════════════════════════════════════════════════════════════
   Mirrors what @dev-dga/css does for the same components. Keeping the focus
   indicator alive under Windows High Contrast is a WCAG requirement, and the
   system-colour keywords are legal only inside this query (guard 3 of
   scripts/check-editable-form.sh). */
@media (forced-colors: active) {
  .portlet-login .form-control {
    border: 1px solid canvastext;
  }
  .portlet-login .form-control:focus {
    outline: 2px solid highlight;
    outline-offset: 1px;
  }
  .portlet-login .btn {
    border: 1px solid buttontext;
  }
  .portlet-login .btn:focus-visible {
    outline: 2px solid highlight;
  }
  .portlet-login .btn:disabled,
  .portlet-login .btn.disabled {
    border-color: graytext;
    color: graytext;
  }
}
@media (prefers-reduced-motion: reduce) {
  .portlet-login .btn,
  .portlet-login .form-control {
    transition: none;
  }
}
/* ═══════════════════════════════════════════════════════════════════════════
   9. /c/portal/update_password — THE PASSWORD-RESET LANDING PAGE
   ═══════════════════════════════════════════════════════════════════════════

   Client, 2026-07-27: "this page still like old way … it has a weird title above
   as well".

   IT ESCAPED THE WHOLE AUTH PASS, because sections 2-8 above scope every rule to
   `portlet-login`. Worth stating plainly: scoping to a portlet class is correct and
   also means a fourth surface can render the same markup unstyled and nothing will
   report it. §14 below is written without that scope for exactly this reason.

   ⚠️ CORRECTED 2026-07-29 — THIS PARAGRAPH NAMED THE WRONG FILE. It used to read
   "a PORTAL SERVLET route that renders ROOT/html/portal/update_password.jsp". It is
   not that file. The page is rendered by com.liferay.login.web's own
   META-INF/resources/update_password.jsp, and two independent readings of the
   served markup establish it: the fields carry this bundle's namespace
   (`_com_liferay_login_web_portlet_ForgotPasswordPortlet_password1`), and the
   response contains `id="main-content"` while containing no `class="mt-4 sheet
   sheet-lg"` — the exact pair of strings that distinguishes the two shipped
   near-twin files. The claim mattered: it is the file a JSP override has to target,
   and overriding the other one would have changed nothing, silently.
   modules/harf-login-navigation now overrides the correct one.

   THE «WEIRD TITLE» is Liferay's own portlet chrome. Measured on the live page: an
   `h2.portlet-title-text` reading «أحصل على كلمة السر - حَرْف» — the `get-password`
   language key plus the site name — laid out at viewport top 0, i.e. ABOVE the site
   header and clipped by it. Nothing in the design has it, and the page already
   carries its own heading (`h2.sheet-title`, «غيّر كلمة السر»), so hiding the chrome
   removes a duplicate rather than the only title. This is the SAME artefact and the
   same fix already applied to the MFA verify screen in _mfa-otp.scss.

   `display: none` rather than the clip pattern used for the captcha label, and the
   difference is deliberate: the captcha label is the field's accessible NAME and had
   to survive, whereas this is decorative chrome duplicating a visible `h2` that stays
   in the document. Nothing is removed from the accessibility tree that is not still
   present.

   SCOPED BY A MARKER CLASS, NOT BY `.portlet`. `section.portlet` and
   `.portlet-header` are generic Liferay chrome on every widget on every page; a bare
   rule would hide portlet titles product-wide.

   ⚠️ WHO SETS THE MARKER CHANGED ON 2026-07-29, and that is the whole of the
   client's "not Liferay design" report. js/main.js used to add
   `harf-update-password` in the BROWSER, after render — so the design existed only
   once a script had finished, and the client caught the page twice in stock Clay
   chrome. It is now a class on the JSP's own root element
   (modules/harf-login-navigation/…/update_password.jsp, HARF BLOCK 3), i.e. present
   in the first byte of the response.

   ⚠️ THE FIRST SELECTOR BELOW NO LONGER MATCHES ANYTHING — the marker used to sit
   on the portlet SECTION, so `.harf-update-password .portlet-header` reached that
   portlet's own header; it now sits inside the portlet's content, and a header is
   its ANCESTOR.

   ⚠️⚠️ AND THE FIRST DRAFT OF THIS NOTE SAID THAT COST NOTHING, "because the header
   it hid measured h=0". THAT WAS WRONG, in the way this project keeps paying for:
   h=0 was measured on a DIFFERENT element. There are two `h2.portlet-title-text` on
   this page — `#portlet_new-password`'s, which the rule further down hides and which
   does measure 0, and the ForgotPasswordPortlet's own, which came back at 981,137
   380x38 the moment the marker moved, sitting right above the page's real heading.
   `document.querySelector('.portlet-title-text')` returns the first, so the probe
   answered about the wrong one — the DOM-measures-the-wrong-element caveat in
   docs/reference/FIGMA-VERIFICATION.md, again.

   FIXED AT SOURCE RATHER THAN BY RESTORING THE HIDE: update_password.jsp now calls
   `renderResponse.setTitle()`, so that chrome title IS the page heading and the JSP
   emits no heading of its own. Nothing is hidden to make the screen look right,
   which is why the dead selector below can stay dead.

   The fields need no rules here: measured on the live page they already compute
   400x40, border #9da4ae, radius 4px — identical to /login — because those come from
   the generic `.form-control` block, which is not portlet-scoped. */
.harf-update-password > .portlet-content > .portlet-header,
.harf-update-password .portlet-header {
  display: none;
}

/* THE STRAY TITLE IS NOT THE FORM PORTLET'S — corrected 2026-07-27 after measuring
   instead of assuming.

   The rule above hides the header of the portlet that CONTAINS the password fields,
   and it does that correctly (that portlet's own title, «نسيت كلمة السر» — the
   layout's name leaking in — measures h=0). But it is not what the client saw.

   This route renders the WHOLE PAGE inside a synthetic portlet the portal creates for
   it: `section#portlet_new-password`, a direct child of `#content`, whose own
   `.portlet-content > .portlet-header` carries `h2.portlet-title-text` reading
   «أحصل على كلمة السر - حَرْف» — the `get-password` key plus the site name. Measured
   at viewport top 0, height 38, i.e. laid out ABOVE the site header, which is itself
   nested inside this same portlet. That is the element in the report.

   ⚠️ THE FIRST PROBE READ THE WRONG NODE and briefly said the fix had failed:
   `document.querySelector('.portlet-header')` returns the FIRST of the FIVE on this
   page, which is this one and not the form's. The rule was working the whole time.
   Same family as the DOM-measures-the-wrong-element caveat in
   docs/reference/FIGMA-VERIFICATION.md — scope the probe to the element under test.

   DIRECT-CHILD PATH, NOT A DESCENDANT SELECTOR. `#portlet_new-password` wraps the
   header, the footer and every nav widget, so `#portlet_new-password .portlet-header`
   would hide portlet chrome for all of them. Only this portlet's own header is
   targeted. The id is read off the live page, not guessed. */
#portlet_new-password > .portlet-content > .portlet-header {
  display: none;
}

/* ═══════════════════════════════════════════════════════════════════════════
   10. ONE FIELD RHYTHM, THE REGISTER FORM'S — 2026-07-27
   ═══════════════════════════════════════════════════════════════════════════

   Client: "make all auth pages like register form, it has harf-reg__form, it's make
   good space between inputs".

   MEASURED FIRST, on the deployed pages, because the two forms turned out to be
   closer than the report suggested and the difference was not where it looked:

     /register-participant   input bottom → next label top = 20px, uniform
     /login                  input bottom → next label top = 40px

   And the 40 is NOT a bigger container gap. `.panel-body` already computes
   `display: flex` with `row-gap: 20px` and every `.form-group` computes
   `margin: 0` — i.e. the auth container ALREADY has the register form's 20px. The
   first field's group is also clean: 223..291, h=68 = label 20 + gap 8 + control 40,
   with the input flush to the group's bottom edge. The extra 20px is dead space at
   the TOP of the following group, above its label, so the rhythm reads as uneven
   rather than as generous.

   These rules make the container's gap the ONLY thing that spaces fields, which is
   exactly the contract `.harf-reg__form` gets from its own `gap` and `.harf-reg__field`
   from theirs. Nothing is added: the 20px stays 20px, it is just no longer doubled on
   some rows and not others.

   THE LABEL→CONTROL GAP IS DELIBERATELY LEFT AT 8px and NOT changed to the register
   form's 12px. §3 above derives the 8 from Figma 240:16406's "Text Input" auto-layout
   for THIS surface, which is rule 1 — Figma explicit wins. The client's report is about
   the space BETWEEN INPUTS, and that is what these rules change; borrowing the register
   page's label gap would overwrite a Figma value with another page's, which §17.3 rule 1
   forbids. Recorded so it is visibly a decision rather than an omission. */
.portlet-login .panel-body > .form-group,
.portlet-login .form-group {
  margin-block: 0;
  padding-block: 0;
}

/* The label is the first thing in a group; nothing may push it down. Its own
   bottom margin (the 8px above) is untouched. */
.portlet-login .form-group > label.control-label:first-child {
  margin-block-start: 0;
}

/* ═══════════════════════════════════════════════════════════════════════════
   11. THE SAME GAP EVERYWHERE — 2026-07-27
   ═══════════════════════════════════════════════════════════════════════════

   Client: "the space between captcha and primary login is so close, please ensure all
   spaces in login and auth pages are good and the same, different in spaces make it
   weird".

   MEASURED on the deployed /login, every block in the form top to bottom:

     e-mail group        → password group        20px   ← the intended rhythm
     password group      → «نسيت كلمة المرور؟»    4px   ← deliberate, see below
     forgot link         → captcha block          0px   ✗
     captcha block       → «تسجيل الدخول»          8px   ✗  the reported one

   So the form had four different gaps. Two causes, both found rather than guessed:

   (a) `.harf-login-aux__forgot-inline` carries `margin-block: -16px -20px`. The -16
       pulls the link up under the password field, which is Figma's placement and is
       KEPT. The **-20 exists only to cancel `.panel-body`'s 20px row-gap** so that
       whatever followed did not move — and what follows is the captcha, which is why
       it ended up flush.
   (b) `.button-holder` is a SIBLING OF THE FIELDSET, not a child of `.panel-body`, so
       the 20px row-gap never applied to it at all. Its distance from the captcha was
       whatever the captcha's own bottom margin happened to be — 8px from a Bootstrap
       `mb-2` on the wrapper.

   FIXED BY GIVING THE OUTER STACK THE SAME CONTRACT THE INNER ONE ALREADY HAS: one
   flex column, one gap, and no ad-hoc margins competing with it.

   WHAT IS DELIBERATELY *NOT* EQUALISED: the 4px under the password field. «نسيت كلمة
   المرور؟» is an annotation ON that field — Figma 240:16406 places it immediately
   below the control, and login-aux relocates Liferay's own anchor there for exactly
   that reason. Making it 20px like everything else would detach it from the field it
   belongs to and read as a fifth form row. "The same" applies to the rhythm BETWEEN
   BLOCKS, not to a label bound to a control. Stated so the exception is visible. */
.portlet-login .input-container {
  display: flex;
  flex-direction: column;
  gap: var(--ddga-space-5); /* 20px — the same value .panel-body already uses */
}

/* The captcha is a block in that rhythm like any other, so its own margins must not
   add to the gap. `my-3` is the taglib's, `mb-2` is on the wrapper; both are replaced
   by the container's gap. Scoped to the auth surfaces so /contact and the two register
   fragments keep the spacing their own columns give them. */
.portlet-login .taglib-captcha,
.portlet-login .harf-login-captcha,
.portlet-login .form-group.mb-2 {
  margin-block: 0;
}

/* `mb-2` NEEDS THE IMPORTANT TWIN, and the rule above could not win without it —
   measured: with `margin-block: 0` in place the captcha wrapper still ended 8px above
   the panel body's edge, which is Bootstrap's `.mb-2 { margin-bottom: 0.5rem !important }`.
   Spacing utilities carry `!important` exactly like the `.text-warning` colour utility
   in §3 did, and for the same reason an important declaration is only ever beaten by
   another one — specificity is irrelevant. This is the third time that has bitten this
   file; if a Bootstrap utility class is on the element, assume `!important`. */
.portlet-login .form-group.mb-2,
.portlet-login .taglib-captcha.my-3 {
  margin-block-end: 0 !important;
  margin-block-start: 0 !important;
}

/* Restores the 20px the -20px was cancelling. The -16px top stays: that is the Figma
   placement, and it is why this rule sets only the end. */
.portlet-login .harf-login-aux__forgot-inline {
  margin-block-end: 0;
}

/* BH-648 — THE ALERT IS A BLOCK IN THIS RHYTHM TOO, and it was the one block §11 never
   collected. §5 gives `.portlet-login .alert` its own `margin-block-end: space-5`, which
   was correct while the alert stood alone; inside the gapped column it ADDS to the gap.

   MEASURED on /login before this rule, wrong credentials submitted, 1440 wide:

     resting   inline-alert-container y=223 h=0 → fieldset y=243        gap 20px
     error     alert y=243 h=50 → fieldset y=333                        gap 40px

   i.e. exactly double, and the only doubled gap on the form — the button row below it
   measured 20px in both states. That is the visible "extra space" in the reported
   screenshot, and it is the same class of defect as the captcha and button-row margins
   collected above: an ad-hoc margin competing with the container's gap.

   Scoped to the container rather than applied to `.portlet-login .alert` outright, so an
   alert rendered anywhere OUTSIDE the flex column (the `.panel-body` success branches in
   login.jsp, which are not flex children of it) keeps the margin it still needs. No
   `!important`: the §5 rule is a plain declaration, and (0,3,0) here beats its (0,2,0). */
.portlet-login .input-container > .alert {
  margin-block-end: 0;
}

/* BH-648, hardening — NOT the reported defect, and stated as such so the next reader
   does not take it for the fix.

   Clay reserves room for the dismiss button with `.alert-dismissible { padding-right:
   2.5rem }` (40px) and positions `.close` absolutely inside it. §5's
   `padding-inline: var(--ddga-space-4)` sets BOTH logical sides to 16px and, at (0,2,0)
   against Clay's (0,1,0), deletes that reservation while the button stays put.

   MEASURED: with the reported message the two do NOT collide — the close box starts at
   x=1380 and the text ends at x=1379, a 0.73px clearance. So this is a latent defect,
   not the observed one: one more character of copy, or a longer translation, and the
   dismiss button lands on the text. The gutter is restored on the inline-END side, which
   is where `.close` sits in BOTH directions (Clay's physical `right` is inline-end in
   LTR, and the RTL build flips it to `left`, which is inline-end in RTL). */
.portlet-login .alert-dismissible {
  padding-inline-end: 2.5rem;
}

/* THE BUTTON ROW SITS IN A DIFFERENT PLACE ON EACH PAGE, so its own margin has to go
   or the gap depends on which JSP rendered it. Measured:

     /login             `.button-holder` is a SIBLING OF THE FIELDSET → spaced by
                        `.input-container`'s 20px gap; its own margin-top is 0.
     /forgot-password   `.button-holder` is a CHILD OF `.panel-body` → gets the 20px
                        row-gap AND its own `margin-top: 12px` on top = 32px.

   Same component, same intent, two different numbers purely because of where the
   markup puts it. Zeroing the margin makes the container's gap the only source of
   spacing on both, which is the whole point of §11.

   ⚠️ AND IT NEEDS `!important` — established by probe, not assumed. Injecting a
   late rule with this exact selector and no `!important` left the computed value at
   12px; the same rule WITH it won. So the 12px is an important declaration and, as in
   §3 and §11 above, only another important one beats it. That is now the fourth
   Bootstrap/Clay utility in this file to behave that way. */
.portlet-login .button-holder {
  margin-block-start: 0 !important;
}

/* ─────────────────────────────────────────────────────────────────────────────
   §13. SHOW/HIDE PASSWORD — the eye on the sign-in field.

   Client instruction 2026-07-29: «please make show password icon that exists in
   register pw, in login as well, and in all forms that have pw».

   WHY THE RULES LIVE HERE AND NOT IN A FRAGMENT. The sign-in form is a JSP served
   by the LoginPortlet (our override in modules/harf-login-navigation), not a
   fragment, so `.portlet-login` in this file is the only place that styles it —
   the same place every other control on this page is styled from. One rule set
   therefore covers /login, /login-admin and /login-judge, because all three render
   the same portlet through the same override.

   THE BOX IS BUILT BY SCRIPT, and this depends on that. <aui:input> emits its own
   label and input inside a .form-group and a taglib cannot be given a child, so
   login.jsp moves the button into a .harf-login__pw-box that wraps the INPUT.

   ⚠️ THE BOX DOES **NOT** WRAP THE INPUT ALONE — corrected 2026-08-01, measured.
   This section used to say Liferay's validation feedback "stays outside the box",
   and centring the eye on the box (`inset-block-start: 50%` + translateY(-50%))
   rested entirely on that. It is false, and the client screenshotted the result:
   submit /login with an empty password and the eye DROPS.

   MEASURED, /login and /login-admin, both identical:

       state           box h   eye centre − input centre
       no error         40px    +0px
       error shown      63px   +11px      ← the defect

   WHY. Liferay's own validator puts the message there. From the shipped
   aui-form-validator.js (fetched from the running 2026.Q1.9 portal at
   /o/frontend-js-aui-web/aui/aui-form-validator/aui-form-validator.js, not from
   documentation):

       target = field;
       ...
       target.placeAfter(stackContainer);     // ← line 1142

   `placeAfter(field)` makes the message the INPUT'S NEXT SIBLING, so it lands in
   whatever element the input's parent happens to be — and since the script
   re-parents the input into this box, that parent is this box. The div
   (.form-feedback-item.form-validator-stack.help-block, 19px + 4px) grows the box
   40 → 63px, and an eye centred at 50% OF THE BOX drops by half of that. Note
   `findFieldContainer`'s `.form-group` default is a red herring: it governs the
   has-error CLASS, not where the message is placed. There is no per-field way to
   redirect `placeAfter`, so the box will keep receiving the node.

   THE FIX — CENTRE THE EYE ON THE INPUT, NOT ON THE BOX. The input and the eye are
   assigned the SAME grid cell (row 1), so the eye is centred on the 40px control
   whatever else the box comes to contain; anything Liferay injects auto-places into
   row 2 and cannot move it. That is also what the registration form gets for free —
   its error <p> is a SIBLING of .harf-reg__password, so the box there really does
   hold the input alone. This makes the two DOMs behave the same way rather than
   only look the same on a clean form.

   NO MAGIC NUMBER, deliberately: the alternative fix — `inset-block-start: 0` plus
   `block-size: 40px` on the button — hardcodes today's control height and would
   silently de-centre if the control ever changed.

   `z-index: 1` because the eye must stay clickable on top of the input it now
   shares a cell with. `justify-self: end` is inline-end, so it resolves to the LEFT
   in RTL and the RIGHT in LTR without a direction-specific rule — the same
   behaviour the old `inset-inline-end` gave.

   Values are the registration form's, unchanged — same 20px glyph, same
   --ddga-space-3 inset (now a margin, since the button is in flow), same
   --ddga-text-tertiary resting colour. This is one control appearing on two
   screens, so it is not re-derived from Figma here; the registration form is where
   it was measured (fragments/harf-fragments/participant-register/index.css).
   --ddga-text-tertiary and --ddga-text-primary are both re-pointed by the DGA
   library in dark, so no dark pair is needed.
   ───────────────────────────────────────────────────────────────────────────── */
.portlet-login .harf-login__pw-box {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  position: relative;
}

/* Keeps typed characters from running under the glyph. The base rule sets
   padding-inline-end: --ddga-space-2; this replaces it with room for the icon,
   matching .harf-reg__password .harf-reg__input exactly. */
.portlet-login .harf-login__pw-box .form-control {
  padding-inline-end: calc(var(--ddga-space-4) + 20px);
}

/* Row 1 holds BOTH — that is the whole fix. Liferay's injected feedback carries no
   placement of its own, so grid auto-placement drops it into row 2. */
.portlet-login .harf-login__pw-box > .form-control,
.portlet-login .harf-login__eye {
  grid-column: 1;
  grid-row: 1;
}

.portlet-login .harf-login__eye {
  align-items: center;
  align-self: center;
  background: none;
  border: 0;
  color: var(--ddga-text-tertiary);
  cursor: pointer;
  display: inline-flex;
  justify-content: center;
  justify-self: end;
  margin-inline-end: var(--ddga-space-3);
  padding: 0;
  position: relative;
  z-index: 1;
}

.portlet-login .harf-login__eye:hover,
.portlet-login .harf-login__eye:focus-visible {
  color: var(--ddga-text-primary);
}

.portlet-login .harf-login__eye-icon {
  block-size: 20px;
  inline-size: 20px;
}

/* One glyph per state, chosen by CSS — nothing is fetched, so the icon cannot
   arrive late or 404. With JS off the button is never un-hidden at all, so the
   field simply stays masked. */
.portlet-login .harf-login__eye[data-shown=false] .harf-login__eye-icon--hide,
.portlet-login .harf-login__eye[data-shown=true] .harf-login__eye-icon--show {
  display: none;
}

/* ─────────────────────────────────────────────────────────────────────────────
   §14. THE AUTH SCREENS' OWN HEAD, LEAD AND RULES — 2026-07-29

   Client, 2026-07-29, on /forgot-password and /c/portal/update_password: "the
   Content like title, description are different, please ensure it match with
   image", and for the reset page "this page should be handled with our fragment
   like design not liferay design".

   THE MARKUP THESE STYLE IS OURS AND IS SERVER-RENDERED. It comes from two JSP
   overrides in modules/harf-login-navigation — forgot_password.jsp and
   update_password.jsp — which replaced, respectively, a description the page did
   not have and Liferay's `sheet-header`/`sheet-text` card. Read those files for
   the copy and for why a JSP override rather than a Fragment.

   ⚠️ WHY THE SPACING IS RESTATED HERE RATHER THAN INHERITED. update_password.jsp
   used to wrap its heading in `div.sheet-header` and its body in `div.sheet-text`,
   and those two Clay classes were carrying the vertical rhythm — measured on the
   deployed page before the change, `margin: 0 0 48px` and `0 0 24px`. Dropping the
   card dropped the margins with it, so `.harf-auth__head` has to own them or the
   heading collides with the first field. That is a real dependency the class names
   hid, and it is written down rather than rediscovered.

   NOT SCOPED TO `.portlet-login`. Every earlier section in this file is, which is
   exactly why /c/portal/update_password escaped the whole auth pass once already
   (see §9). These selectors are our own class names, so they select our markup on
   whichever surface renders it and nothing else anywhere.
   ───────────────────────────────────────────────────────────────────────────── */
/* ⚠️ THERE IS NO `.harf-auth__title` RULE, AND THAT IS THE POINT. The reset page
   drew its own <h1> in the first draft of this work and ended up with TWO page
   headings — Liferay's portlet chrome was already painting the portlet's display
   name above it, and a rule further up this file had been quietly hiding that.
   Both screens now set the heading with `renderResponse.setTitle()`, so §9's
   `.portlet-login .portlet-title-text` is the only page-heading rule in this
   file and there is exactly one heading per screen. Do not add a second here. */
/* The description under the heading — «سيتم إرسال بريد شبكي…» on /forgot-password,
   «أدخل كلمة مرور قوية…» on the reset page, and the confirmation sentence on the
   sent state. Body copy, secondary colour: it explains the screen, it is not part
   of a control. */
.harf-auth__lead {
  color: var(--ddga-text-secondary);
  font-size: var(--ddga-font-size-base);
  font-weight: var(--ddga-font-weight-regular);
  line-height: 1.5;
  margin-block: 0 var(--ddga-space-6);
  max-inline-size: 46ch; /* Keeps the sentence readable on a 1440 page rather than running the full column width. */
}

/* «لم تستلم الرسالة؟ إعادة إرسال» — the confirmation state's only action. */
.harf-auth__resend {
  color: var(--ddga-text-secondary);
  font-size: var(--ddga-font-size-sm);
  margin-block: 0;
}

.harf-auth__resend-link {
  color: var(--ddga-color-primary);
  font-weight: var(--ddga-font-weight-semibold);
  text-decoration: underline;
}

.harf-auth__resend-link:focus-visible {
  outline: 2px solid var(--ddga-color-focus-ring);
  outline-offset: 2px;
}

/* ── The password-requirements checklist ─────────────────────────────────────
   A HINT. The server is still the only thing that decides whether a password is
   accepted, and each row is rendered only when the live password policy actually
   enforces it — see update_password.jsp HARF BLOCK 2.

   `data-harf-met` is written by that file's own inline script as the visitor
   types. The RESTING state is "not met", so with JavaScript off the list renders
   grey and never ticks, which is the honest state for a hint that cannot observe
   anything. */
.harf-auth__rules {
  list-style: none;
  margin-block: var(--ddga-space-5) var(--ddga-space-6);
  padding: 0;
}

.harf-auth__rule {
  align-items: center;
  color: var(--ddga-text-secondary);
  display: flex;
  font-size: var(--ddga-font-size-sm);
  gap: var(--ddga-space-2);
  line-height: 1.5;
  margin-block-end: var(--ddga-space-2);
}

.harf-auth__rule:last-child {
  margin-block-end: 0;
}

.harf-auth__rule-icon {
  block-size: 20px;
  color: var(--ddga-text-tertiary);
  flex: none;
  inline-size: 20px;
}

.harf-auth__rule[data-harf-met=true] {
  color: var(--ddga-text-primary);
}

.harf-auth__rule[data-harf-met=true] .harf-auth__rule-icon {
  color: var(--ddga-color-primary);
}

@media (forced-colors: active) {
  /* `currentColor` on the tick collapses to the same system colour in both
     states under High Contrast, so the met/unmet distinction would vanish.
     Nothing is lost: the list is a hint and the server still reports every real
     rejection in its own alert. Stated so the omission is visibly a decision. */
  .harf-auth__rule[data-harf-met=true] .harf-auth__rule-icon {
    color: highlight;
  }
}
/* The «خطأ:» type prefix that <liferay-ui:error> renders in front of every error
   sentence, removed from sight and kept for screen readers. Deliberately NOT scoped,
   for the reason "captcha" below is not: the same taglib markup appears on the three
   auth pages, the MFA screens, the OOTB Form widget and inside the register
   fragments. Imported after "auth-pages" so that where specificity ties, source
   order agrees with intent. See the partial's own header for the measurement. */
/* ═══════════════════════════════════════════════════════════════════════════
   ALERT TITLES — «خطأ:» leaves the SCREEN and stays for ASSISTIVE TECHNOLOGY
   ═══════════════════════════════════════════════════════════════════════════

   Reported 2026-07-27: every error alert on the platform opened with a prefix
   before the sentence itself. On the register form it read «أقفل خطأ: …» and on
   the OOTB auth pages «خطأ: …». Two different mechanisms produced those two
   strings, and only the second one is CSS's to fix — the first was a fragment
   reading `textContent` off the whole alert and collecting the dismiss button's
   screen-reader label, fixed in participant-register/index.js (`alertMessageOf`).

   MEASURED CAUSE OF THE «خطأ:» HALF, from the shipped bundle rather than inferred.
   bundles/tomcat/webapps/ROOT/html/taglib/ui/error/page.jsp line 34 is:

     <strong class="lead"><%= alertTitle %></strong><%= alertMessage %>

   so the title is real, visible markup — Clay gives `.alert .lead` a
   `margin-right` and nothing else (clay.css, measured), so it renders inline in
   front of the message on every <liferay-ui:error> in the product.

   WHY IT GOES, and on whose authority: Confluence is the copy source for this
   platform's error text (BH-504 page 5093359628 → «Error messages — رسائل الخطأ»
   and the equivalent section on each story page), and not one of those approved
   sentences carries a type prefix. A prefix that the client's own copy register
   does not contain is chrome, so it is treated as chrome.

   ⚠️ HIDDEN, NOT DELETED — and the difference is the whole point. `display: none`
   would take «خطأ:» away from screen readers too, and that is the one audience for
   which the word is load-bearing: the alert's red tint and its ⚠ indicator svg
   (`aria-hidden="true"`, measured on the same JSP line 29) say "error" to sighted
   users and to nobody else. `role="alert"` announces that something happened, not
   what KIND. So the recipe below is Clay's own `.sr-only`, copied verbatim from
   clay.css so the two never drift, and the accessible reading of the alert is
   unchanged: "خطأ: <message>".

   SCOPE — every surface, on purpose. The same taglib renders this markup on
   /login, /forgot-password, /c/portal/update_password, the MFA screens, the OOTB
   Form widget and inside the register fragments, in at least four containers no
   single scope reaches. `_captcha.scss` records what happens when a shared widget
   is styled per-container instead: four surfaces, four different geometries, four
   parity verdicts. One unscoped rule, once.

   The selector list mirrors Clay's own (`.alert .lead, .portlet-msg-alert .lead,
   .portlet-msg-error .lead, …`) so exactly the same set of alerts is covered —
   `.portlet-msg-*` are the legacy aliases the taglib still emits on older JSPs.
   No property Clay sets is overridden, so the (0,2,0) tie with clay.css is not a
   contest; source order (custom after clay) settles it regardless.

   ⛔ NOT COVERED, stated rather than left to be discovered: the TOAST branch of the
   same JSP (lines 40-46) passes the title to `Liferay.Util.openToast` as a JS
   argument, so it never becomes a `.lead` and no stylesheet can reach it.
   `<liferay-ui:error>` takes that branch when `embed` is false. Already recorded as
   a residual difference in _auth-pages.scss §5. */
.alert .lead,
.portlet-msg-alert .lead,
.portlet-msg-error .lead,
.portlet-msg-help .lead,
.portlet-msg-info .lead,
.portlet-msg-progress .lead,
.portlet-msg-success .lead {
  border: 0;
  clip: rect(0, 0, 0, 0);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

/* The Liferay CAPTCHA's LAYOUT, for every surface that renders it — the login and
   forgot-password portlets, the OOTB Form captcha input, and the custom register
   fragments. Deliberately NOT scoped: the same widget markup appears inside three
   different containers, so a scoped rule would have to be written three times and
   would drift three ways (measured: it already had, four surfaces / four
   verdicts). Imported after "auth-pages" so that where specificity ties, source
   order agrees with intent. Appearance stays per-container; only geometry is
   centralised here. See the partial's own header. */
/* ═══════════════════════════════════════════════════════════════════════════
   LIFERAY CAPTCHA — LAYOUT, IN ONE PLACE
   ═══════════════════════════════════════════════════════════════════════════

   WHY THIS FILE EXISTS

   The captcha widget appears on FOUR surfaces in THREE different containers, and
   before this partial each container laid it out differently — none of them on
   one line, none of them centred. MEASURED 2026-07-26 at 1440 with
   scripts/data/captcha-layout-measure.py (own headless-visible Chrome, dpr 1):

     surface                  container                        lines  centred
     /forgot-password-admin   .portlet-login                    3      no
     /forgot-password         .portlet-login                    3      no
     /register-participant    .harf-reg__captcha                1      no
     /contact                 .form-input-captcha               1      no

   Same markup, four verdicts. The markup is Liferay's, from
     bundles/osgi/portal/com.liferay.captcha.taglib.jar
       !/META-INF/resources/captcha/simplecaptcha.jsp
   so the only honest place for its LAYOUT is somewhere every one of those
   containers can see — the theme, which loads on every page. Hence an UNSCOPED
   `.taglib-captcha`, and hence the competing layout declarations were removed
   from _auth-pages.scss and from the four fragments (each now carries a pointer
   comment). Their APPEARANCE rules stay where they are: those are per-container
   dark-mode fixes that replace OOTB colour literals, they were never the defect,
   and they are correct.

   ⛔ THAT LAST SENTENCE NO LONGER HOLDS — amended 2026-07-27, and the amendment is
   the point of the change rather than a side effect of it. The per-container
   appearance rules WERE correct in the narrow sense that each replaced an OOTB
   literal with a token; they were wrong in the aggregate, because four independent
   answers to "what does this field look like" had drifted into four different
   fields — 48px on the register wizards against 40px everywhere else, a borderless
   grey box on the ceremony page, an amber required mark on the two surfaces that
   never got the `!important` twin. The client reported exactly that aggregate
   ("it should be shared across the project"). So APPEARANCE of the widget's own
   controls — field, label, required mark, refresh button, challenge plate — now
   has the same single owner as its layout: this file. What stays per-container is
   only geometry that belongs to the COLUMN rather than to the widget (e.g. the
   ceremony fieldset's 820px cap).

   WHAT THE MARKUP MAKES HARD

   simplecaptcha.jsp emits, in this DOM order:
     <div class="my-3 taglib-captcha">
       <img class="captcha d-inline-block mb-2">          ← Bootstrap mb-2
       <span class="align-top d-inline-block refresh">    ← Bootstrap align-top
       <input type="hidden" name="captchaId">             ← no box, not a flex item
       <div class="form-group input-text-wrapper">        ← a FULL aui:input:
         <label class="control-label">التحقق من النص</label>   a BLOCK label…
         <input class="form-control" name="captchaText">      …ABOVE its field
       </div>
       <p class="text-danger">                            ← only when it errored
   Three of those carry Bootstrap utilities that fight a single line (`my-3`,
   `mb-2`, `align-top`), and the field arrives wrapped in a block `.form-group`
   whose label sits ABOVE it — that block wrapper is what produced the extra
   lines. Both are neutralised below, each with the reason next to it.

   SOURCE OF TRUTH (README §17.3)

   Rule 2 — Figma silent → @dev-dga/css authoritative. Figma draws a **Google
   reCAPTCHA** widget on this surface, which directive 6 forbids outright, so
   there is no Figma reading of the Liferay widget to honour. That is a
   previously recorded finding, not a fresh one: _auth-pages.scss §6 and
   docs/records/DEVIATIONS.md C8.1. I did NOT re-open Figma this round to look for a
   Liferay-captcha frame — the recorded finding is the basis for the absence
   claim, and if a captcha frame is ever added to the file this partial is where
   it lands.

   The ONE-LINE + CENTRED geometry is therefore not from Figma and not invented:
   it is the explicit instruction on the defect list ("It should sit on one line,
   centre-aligned, styled to the design"). Every colour, space and radius below
   is an existing --ddga-* / --harf-* token; scripts/check-color-literals.sh
   fails the build on a literal. */
.taglib-captcha {
  align-items: center;
  display: flex;
  /* wrap so a narrow column degrades to two rows instead of overflowing the
    page — a horizontal scrollbar at 390 is a worse defect than a second row */
  flex-wrap: wrap;
  /* ⚠️ SPLIT INTO TWO AXES 2026-07-27, on report: "the space between label and
    captcha is more than any field, please make it similar".
    This was the shorthand `gap: var(--ddga-space-3)`, which sets BOTH axes — and
    once the label became a full-width first line (see the LABEL rule) the 12px
    row-gap started stacking on top of the label's own 8px bottom margin, giving
    20px where every other field on the form gives 8px. Measured against
    «البريد الشبكي» directly above it on /login.
    Row-gap is now the 8px the rest of the form uses, and the label's own margin
    is 0 so this is the only thing spacing the two lines. Column-gap keeps its
    12px, which is the spacing BETWEEN the three controls and was never wrong.
    Row-gap is deliberately not 0: it is also what separates the controls if they
    wrap at 390. */
  column-gap: var(--ddga-space-3);
  row-gap: var(--ddga-space-2);
  /* ⛔ `margin-block: var(--ddga-space-4)` REMOVED 2026-07-27 on instruction:
    "remove my-3 and margin-block: var(--ddga-space-4); from taglib-captcha".

    It was here to "replace the widget's own Bootstrap `my-3` with a token", and
    that was the wrong shape for the problem: `my-3` is a spacing UTILITY and
    carries `!important`, so this declaration never replaced anything — it was
    ADDED to it, and the captcha ended up with 16px of its own on top of
    Bootstrap's 16px while every neighbouring field spaced itself with a plain
    `.form-group`. That is why the block sat further from its neighbours than they
    sat from each other.

    `my-3` itself is now stripped from the element by js/main.js — removing the
    class is the only way to beat an `!important` utility without answering it
    with another `!important` — and the surrounding wrapper owns the spacing
    instead (`<div class="form-group mb-2 harf-login-captcha">` in
    modules/harf-login-navigation/…/login.jsp). One owner, and it is the same
    mechanism the rest of the form already uses. */
  /* PACKED TO THE INLINE-START (the right, on these RTL surfaces) — corrected
    2026-07-26 on report: "captcha in all pages should be shared component,
    justify right align center, not like that".

    This was `justify-content: center`, which made the captcha the ONLY row on
    any of these forms that was not aligned to the column's inline-start edge:
    every label, field, hint, button row and feedback bar on /register-participant,
    /forgot-password and /contact packs to inline-start, and a centred captcha
    floated out of that column. `align-items: center` above is unchanged — the
    challenge image and the input field still centre against each other
    vertically, which is the "align center" half of the instruction. */
  justify-content: flex-start;
}

/* ⛔ SUPERSEDED 2026-07-27 — kept because the arithmetic in it is still true and
   the next agent will otherwise re-derive it.

   This block used to read: "the aui:input's `.form-group` stays the BLOCK it ships
   as — label above its own field — and that is a decision, not an omission",
   because laying label and field out side by side was MEASURED on 2026-07-26 at
   233px for the group, making the row 152 + 16 + 233 + two 12px gaps = **425px**
   against a **400px** auth column, which wrapped /forgot-password and
   /forgot-password-admin onto two lines.

   The arithmetic was right; the assumption underneath it was that the label had to
   stay VISIBLE. It does not. The label is now visually hidden (see the LABEL rule
   below) and the required mark is moved next to the field, so the group's width is
   the field's alone and the 425px never happens. What survives unchanged from the
   original note, because it was refused then and is still refused now:

     - Shrinking the challenge image is refused. It is already hard to read (≈1 in 3
       illegible before the gimpy-renderer change, see
       configs/common/osgi/configs/README.md) and scaling a captcha down to satisfy
       a layout constraint trades a working capability for a cosmetic one.
     - Widening the auth column is refused. 400px is Figma's, for a surface Figma
       defines.

   The bottom margin still needs killing: it is meant for a top-level field. */
/* ═══════════════════════════════════════════════════════════════════════════
   ONE LINE — the label out of flow, the field where the label used to be
   ═══════════════════════════════════════════════════════════════════════════

   Client instruction, 2026-07-27, verbatim: "liferay captcha is very bad UI, i
   wanna enhance it UI to be one line, align items, input like shared input with
   placeholder, no orange artrisk … it should be shard across the project", with
   two amendments given on the design: the required mark stays but RED and inline
   before the field, and the refresh button centres with the rest of the row.

   WHY THE SELECTORS BELOW ARE DOUBLED — read this once and the rest of the file
   makes sense.

   The captcha renders inside three unrelated containers, and on TWO of them
   (/contact, the ceremony page) it is the OOTB captcha FRAGMENT, which ships a
   stylesheet of its own:
     com.liferay.fragment.collection.contributor.inputs
       → dependencies/captcha/index.css
   That stylesheet is not weak. It carries
     `.form-input-captcha .taglib-captcha .input-text-wrapper`                (0,3,0)
       → `width: calc(100% - 40px)`, which forces the row to wrap, and
     `… .input-text-wrapper label.control-label`                             (0,4,1)
       → `position:absolute; left:0; top:0`, plus `#272833` on the label,
     `… .taglib-captcha .captcha`  (0,3,0) → `flex-grow:1`,
     `… .taglib-captcha .refresh`  (0,3,0) → `#fff` / `#cdced9` / 32px.
   It does NOT load on the login portlet, where the same markup has no such rules.

   Whether it loads before or after the theme is not guaranteed — the repo already
   learned that on this exact markup (ceremony-attendance/index.css: "Order between
   two fragments' stylesheets is not guaranteed on a page, so winning on specificity
   is the only stable way"). So each rule that collides is written twice: a plain
   `.taglib-captcha …` for the login/register surfaces, and a heavier twin that
   outranks the OOTB selector by exactly one step. No `!important` is used for this
   — it is reserved below for the one place where the thing being overridden is
   itself `!important`.

   This is the reason the four per-fragment copies of these rules were deleted
   rather than corrected in place: each was a private answer to the same collision,
   and four private answers is what "shared across the project" was reported
   against. Each fragment now carries a pointer comment where its copy used to be. */
:root {
  /* The ONE value that legitimately differs per surface, so it is a knob rather
    than a fourth copy of the rule. Default is Figma's for the auth surface
    (240:16406 "Input Field" cornerRadius 4 = --ddga-radius-sm, rule 1); the two
    register fragments re-point it to --ddga-radius-md because that is what their
    own .harf-reg__input / .harf-edu__input neighbours use and a captcha field
    with a different radius from the field above it is the defect being fixed.
    Height needs no knob: every surface's own fields measured 40px. */
  --harf-captcha-field-radius: var(--ddga-radius-sm);
  /* THE CHALLENGE IN DARK MODE — see the long note on `.taglib-captcha .captcha`.
    Light: a near-white plate under black ink, and no inversion. */
  --harf-captcha-plate: var(--ddga-gray-25);
  /* The WHOLE filter is the token, not just its argument. `filter: invert($x)`
    makes dart-sass resolve `invert()` as its own COLOUR function and the build
    fails with "$color: var(--harf-captcha-ink-invert) is not a color". Keeping
    the function name inside the custom property means Sass never parses it. */
  --harf-captcha-ink-filter: none;
}

/* Re-pointed in the same three selectors _dga-semantic.scss and _auth-pages.scss
   use, and for the reasons documented there: the site's own toggle writes
   `data-theme`, `data-color-scheme` covers the other convention in this theme, and
   the media query serves a visitor who has never touched the toggle. All three are
   needed or dark mode works only for people who clicked the button. */
:root[data-theme=dark],
:root[data-color-scheme=dark] {
  --harf-captcha-plate: transparent;
  --harf-captcha-ink-filter: invert(1);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme=light]) {
    --harf-captcha-plate: transparent;
    --harf-captcha-ink-filter: invert(1);
  }
}
/* THE FIELD WRAPPER — IT NO LONGER GENERATES A BOX. Changed 2026-08-01, measured.

   ⛔ WHAT THIS REPLACES, and why the replacement is not a tidy-up. The rule used to
   make this wrapper a flex ROW of its own (`display:flex; flex:1 1 0; gap; align-items
   :center`) holding the field alone. Client report 2026-08-01: on a required-field
   error «حقل التحقق من النص مطلوب.» rendered ON THE SAME LINE as the challenge and the
   field — and the field was squeezed to make room for it.

   MEASURED on /login, empty submit:

       .form-group   205px wide, display:flex, flex-wrap:NOWRAP
       children      input 205px               → input  121px   ← squeezed
                     (none)                    → message 79px, 2 lines, beside it

   WHY. Liferay's validator calls `target.placeAfter(stackContainer)` with
   `target = field` (aui-form-validator.js:1142, read from the running 2026.Q1.9
   portal, not from documentation). The message therefore becomes the INPUT'S NEXT
   SIBLING — a child of THIS wrapper — and a non-wrapping flex row has exactly one
   line to put it on. This is the same defect that dropped the sign-in eye on
   2026-08-01 (themes/harf-theme/src/css/_auth-pages.scss §13): a container laid out
   on the assumption that Liferay would not inject into it.

   `display: contents` IS THE LOGICAL END OF WHAT THIS FILE WAS ALREADY DOING. Every
   property this wrapper brings had already been neutralised one at a time — OOTB's
   `width: calc(100% - 40px)` (beaten by a definite `flex-basis` rather than
   outranked), OOTB's `margin`, and the min-content floor. The wrapper exists only
   because <aui:input> emits it; nothing paints it. Removing its BOX makes the field
   and the message direct flex items of `.taglib-captcha`, which is the only way the
   message can take `flex-basis: 100%` and own a line — the identical reason
   js/main.js has to MOVE the label rather than re-order it ("it has to be a real
   child of `.taglib-captcha` to be a flex item of it").

   WHY NOT the one-line alternative, `flex-wrap: wrap` on this wrapper plus a
   full-basis message: the message would wrap under the FIELD and span only the
   wrapper's 205px of a 400px row, so it would sit at the row's inline-END while
   `.text-danger` — the widget's other error line, for a WRONG answer — spans the full
   row from the inline-start. One widget, two error messages, two different places.

   AND IT IS IMMUNE, not tuned: the validator may inject wherever it likes inside this
   wrapper, on every re-validation and after any re-render, and the box tree flattens
   it into the row regardless. Nothing here has to fight `placeAfter`.

   Consequences carried elsewhere, both deliberate:
     · `flex: 1 1 0` moves onto `.taglib-captcha .form-control` — the field is the flex
       item now, and it ships `inline-size: 100%`, which without a definite basis would
       size it at 100% OF THE ROW and wrap the widget.
     · `gap`/`align-items`/`margin-block` are dropped, not relocated. The wrapper held
       one child, so the gap spaced nothing; the row's own `align-items: center` and
       `column-gap` now apply to the field directly. */
.taglib-captcha .form-group,
.form-input-captcha .taglib-captcha .form-group.input-text-wrapper {
  display: contents;
}

/* THE LABEL — «التحقق من النص», ABOVE THE WHOLE ROW.

   ⛔ THIS REVERSES A DECISION MADE EARLIER THE SAME DAY, on the client's
   instruction: "add label to captcha and add asterisk to it instead of this place
   of asterisk". The label had been CLIPPED (accessible name kept, pixels removed)
   with the required mark relocated to sit beside the field. Both are undone.

   Why the reversal is not a return to the reported defect. What was wrong in the
   screenshot was never that a label existed — it was WHERE it sat. OOTB puts the
   label inside the `.form-group`, i.e. INSIDE the row, so it stacked above its own
   field while the challenge image sat beside it, and the widget read as two
   half-aligned columns. It is now a full-width flex item AHEAD of the row, which
   is exactly where every other label on these forms sits relative to its control:

       التحقق من النص *
       [ field ]  [↻]  [ challenge ]      ← still one line

   `flex-basis: 100%` is what buys that: the wrapper already wraps, so a full-basis
   first item takes a line of its own and the three controls flow onto the next
   one. Same mechanism the `.text-danger` rule at the top of this file uses, for the
   same reason.

   THE LABEL IS MOVED BY js/main.js, not by `order`. It has to be a real child of
   `.taglib-captcha` to be a flex item of it, and OOTB nests it one level deeper
   inside `.form-group`. `order` cannot promote a grandchild. The `for`/`id` pair is
   Liferay's and travels with the node untouched — banner rule 5 and WCAG 1.3.1 both
   rest on it, and moving a node changes neither.

   The values are `.portlet-login label.control-label`'s, unchanged, because that is
   the block already derived against Figma 240:16406 for these forms. */
.taglib-captcha label.control-label,
.form-input-captcha .taglib-captcha .form-group.input-text-wrapper label.control-label {
  color: var(--ddga-text-primary);
  display: block;
  flex-basis: 100%;
  font-size: var(--ddga-font-size-sm); /* Figma 14px = --ddga-font-size-sm; DGA .ddga-text-input__label agrees */
  font-weight: var(--ddga-font-weight-semibold); /* Figma label is SemiBold 600 (rule 1) */
  line-height: 1.4286; /* Figma 20px on 14px */
  /* ZERO on both sides, deliberately. The 8px that separates this label from its
    controls — Figma "Text Input" auto-layout gap 8 = --ddga-space-2, which DGA
    .ddga-field[data-slot=text-input-field] agrees with — is supplied ONCE, by the
    wrapper's `row-gap`. It was briefly supplied twice (row-gap 12 + margin 8 =
    20px) and that is the defect the row-gap comment above records. Nothing above:
    the wrapper's own margin-block already spaces the widget from what precedes
    it. */
  margin-block: 0;
  /* OOTB's fragment stylesheet floats this label with `position:absolute; left:0;
    top:0` at (0,4,1). Undone explicitly — the twin selector above is (0,5,1),
    which is the one specificity step needed to reach it. */
  position: static;
  text-align: start;
}

/* THE REQUIRED MARK, and the orange the client reported.

   It is not a text «*». `aui:input required="true"` emits
   `<aui:icon cssClass="reference-mark text-warning" image="asterisk"
   markupView="lexicon">` (read from ROOT/html/taglib/aui/input/page.jsp:44), i.e.
   an `<svg class="lexicon-icon lexicon-icon-asterisk reference-mark text-warning">`
   whose fill is `currentColor`. So `color` paints it — but `.text-warning` is a
   BOOTSTRAP COLOUR UTILITY and carries its own `!important`
   (`/o/harf-theme/css/clay.css` → `.text-warning{color:#ffc107!important}`,
   measured), which no selector can outrank. An important declaration is beaten only
   by another one. That is the whole explanation for the orange in the report: two
   fragments had already worked this out locally and written the `!important` twin,
   and the login and register surfaces — which is where the client saw it — never
   got it. Now nobody has to.

   Red, not amber, because Figma 2011:16654 draws the required mark red and every
   other required mark on every one of these forms is --ddga-color-error / the
   identical --ddga-color-destructive. Two colours for one meaning on one form was
   the defect.

   IT STAYS INSIDE THE LABEL, where the taglib puts it — client instruction,
   2026-07-27: "add asterisk to it instead of this place of asterisk". An earlier
   pass this same day moved it out to sit beside the field; that is reverted, and
   with the label now above the row the mark reads exactly as it does on every
   hand-built field on the platform («…الاسم بالعربية *»). No `flex` sizing here any
   more: it is inline content of the label, not a flex item of the row.

   NO EXTRA MARGIN. A 4px `margin-inline-start` was tried and removed the same day:
   side by side with «البريد الشبكي*» directly above it, the captcha's asterisk sat
   visibly further from its text. Both labels come from the same `aui:input`, so
   whatever whitespace the taglib emits between the text and the icon is already
   identical on both — adding to one of them is what made them differ. */
.taglib-captcha .reference-mark,
.taglib-captcha .reference-mark.text-warning {
  color: var(--ddga-color-error) !important;
  font-size: var(--ddga-font-size-sm);
}

/* LIGHT, NOT BOLD — 2026-08-01, client instruction: "make astrisk be light not bold".

   The twin of the block in _auth-pages.scss, which carries the full reasoning: the
   mark is a 12×12 Clay SPRITE, not a character, so it has no weight axis and no font
   declaration can reach it; the icon is hidden and a real «*» drawn in its place at
   the lightest weight the DGA scale defines (regular/400 — there is no `light` token
   and one is not invented).

   IT IS DUPLICATED RATHER THAN SHARED, deliberately and for the same reason the
   COLOUR rule above is duplicated: the captcha renders on /contact and the ceremony
   page, which are OUTSIDE `.portlet-login`, so the auth selector cannot reach them.
   Change one of these two and change the other. */
.taglib-captcha .reference-mark .lexicon-icon {
  display: none;
}

.taglib-captcha .reference-mark::after {
  content: "*";
  font-weight: var(--ddga-font-weight-regular);
}

/* `mb-2` and `align-top` are on the img and the refresh icon in the JSP itself.
   Both predate the flex container and both break vertical centring. `flex: 0 0 auto`
   answers OOTB's `flex-grow: 1`, which would let the challenge stretch into the
   space the field needs.

   ⚠️ `!important` — ADDED 2026-07-27 AFTER MEASURING, and the measurement is the
   reason it is here. This rule has read `margin-block-end: 0` since 2026-07-26 with
   a comment claiming it neutralised `mb-2`. IT NEVER DID. `.mb-2` is a Bootstrap
   SPACING UTILITY and those carry `!important` exactly like the `.text-warning`
   colour utility documented further down — so a plain declaration at any
   specificity loses. Measured on the deployed page, all five surfaces:
   `getComputedStyle(img).marginBottom` = **8px**, putting the challenge's centre
   4px above the field's and the refresh button's on every single one. That 4px is
   part of what "align items" was reported about, and it was invisible to a reader
   of this file because the rule LOOKED like it had already handled it.

   `margin-block-end` and `margin-bottom` resolve to the same computed property in
   this writing mode, so the logical form competes with Bootstrap's physical one
   directly; the logical spelling is kept for consistency with the rest of the
   file. */
.taglib-captcha .captcha,
.form-input-captcha .taglib-captcha img.captcha {
  flex: 0 0 auto;
  margin-block-end: 0 !important;
}

/* "refresh button should be align center as well" — client, 2026-07-27, on the
   design. `align-items: center` on the row already does the vertical half; these
   two centre the GLYPH inside its own 40px box (the box itself is set further down,
   with the WCAG 2.5.8 reasoning), which is what was visibly off: the icon sat at the
   top of its box because of the JSP's `align-top`.

   `margin-left: 0` is not a typo for the logical property — it CANCELS a physical
   `margin-left: 8px` that OOTB sets, which on an RTL page opens a gap on the wrong
   side. The row's `gap` supplies the spacing instead. */
.taglib-captcha .refresh,
.form-input-captcha .taglib-captcha .refresh.d-inline-block {
  align-self: center;
  flex: 0 0 auto;
  margin-inline: 0;
  margin-left: 0;
  vertical-align: middle;
}

/* The error paragraph is a sibling of the controls, not part of the row. Forcing
   a full-width basis keeps it on its own line whatever else wrapped.

   Colour arrived here on 2026-07-27 from `.portlet-login .taglib-captcha
   .text-danger` in _auth-pages.scss. It was correct there and is unchanged; it is
   here because the other three surfaces had no equivalent and were rendering
   Bootstrap's `.text-danger` literal, which does not re-point for dark mode.

   ⛔ THE SIZE THAT CAME WITH IT WAS `--ddga-font-size-sm`, AND IT IS NOW `-xs` —
   corrected 2026-08-01 on the client's report: "font size of errors not the same for
   captcha and inputs! it should be one value for all errors!". Correct, and measured
   on /login and /forgot-password — there were THREE sizes for one thing:

       .harf-reg__error       12px     --ddga-font-size-xs   ← a token, and the
                                                               platform's own error text
       .form-feedback-item    12.8px   Bootstrap `80%`       ← an artifact, not a
                                                               designed value
       .text-danger (here)    14px     --ddga-font-size-sm

   `-xs` wins because it is the only one of the three that is BOTH a DGA token and
   already in use for this exact purpose on /register-participant. The 12.8px is
   Bootstrap arithmetic that nobody chose, so matching the majority would have meant
   standardising on an accident. `.portlet-login .form-feedback-item` in
   _auth-pages.scss is set to the same token in the same pass — the two must move
   together or this report comes straight back. No `line-height` is set: Clay's 1.5
   on 12px gives the 18px `.harf-reg__error` already renders at.

   ⚠️ TWO ERROR PATHS, ONE LINE — `.form-feedback-item` added 2026-08-01.
   This widget can report two different failures and until now only one of them was
   styled here:
     · `.text-danger`        — SERVER-side, the answer was WRONG. Rendered by
                               simplecaptcha.jsp itself, already a sibling of the
                               controls.
     · `.form-feedback-item` — CLIENT-side, the field was left EMPTY. Injected by
                               Liferay's validator NEXT TO THE FIELD, which is why
                               `.taglib-captcha .form-group` is now `display: contents`
                               — without that this selector cannot reach the row and
                               `flex-basis: 100%` has nothing to be a basis of.
   They say the same kind of thing about the same field, so they get the same line in
   the same place. `.form-validator-stack` and `.help-block` ride on the same node;
   matching the first class is enough and is the one Clay documents. */
.taglib-captcha .text-danger,
.taglib-captcha .form-feedback-item {
  color: var(--ddga-color-error);
  flex-basis: 100%;
  font-size: var(--ddga-font-size-xs);
  margin-block-end: 0;
  /* 4px BELOW THE ROW — the same gap every other field's error uses. Client,
     2026-08-01: "the space between error and line is more than another inputs".

     MEASURED on /login before this, all three messages on one submit:

         البريد الشبكي   gap 4px   (Clay's own margin-top: 4px)
         كلمة المرور         gap 4px   (same)
         التحقق من النص      gap 8px   ← the odd one out

     The 8px was not a spacing decision, it was the ABSENCE of one: this rule zeroed
     the margin, so the wrapper's `row-gap` — 8px, and correct for what it is actually
     for — became the only thing between the row and the message.

     WHY A NEGATIVE PULL RATHER THAN A SMALLER row-gap. That row-gap also spaces the
     LABEL from the controls, where 8px is right and is matched to the fields above.
     Dropping it to 4px and giving the label a 4px margin to make its 8px back would
     supply one gap from two places — which is exactly the mistake recorded in the
     row-gap comment at the top of this file (row-gap 12 + label margin 8 = 20px). The
     row-gap stays the single owner of the label gap; only the error line opts out.

     Written in tokens rather than as -4px so it reads as what it is: "4px, starting
     from the row-gap's 8px". Both are the DGA scale — space-1 = .25rem, space-2 =
     .5rem, read from the computed :root on the deployed page. */
  margin-block-start: calc(var(--ddga-space-1) - var(--ddga-space-2));
  /* Follows the row it belongs to — inline-start, not centre. */
  text-align: start;
}

/* ═══════════════════════════════════════════════════════════════════════════
   APPEARANCE — added 2026-07-27, and only because the CONFIGURATION changed
   ═══════════════════════════════════════════════════════════════════════════

   The header above says appearance rules stay in the per-container partials. That is
   still right for the per-container dark-mode fixes it was written about. These three
   rules are different in kind: they are the CSS half of a change made in
   configs/common/osgi/configs/com.liferay.captcha.configuration.CaptchaConfiguration
   .config, which now pins the background producer to TransparentBackgroundProducer for
   every surface at once. A transparent challenge has no surface of its own, so exactly
   one place has to supply it — and it must be the same place that owns the layout, or
   the widget acquires a plate on three surfaces and not the fourth.

   Client trigger, 2026-07-27: "liferay captcha UI is very bad, i wanna a way to enhance
   the view". What the configuration could and could not reach is set out in that
   README; this file handles what is left.

   SOURCE OF TRUTH: unchanged from the header — Figma draws a Google reCAPTCHA here,
   directive 6 forbids it, so README §17.3 rule 2 applies and @dev-dga/css is
   authoritative. Every value below is an existing token. */
/* WHY A MODE-INVARIANT GREY AND NOT --ddga-color-card. The challenge glyphs are drawn
   by Liferay in hardcoded `Color.BLACK` (read from DefaultWordRenderer's static
   initialiser) and no configuration key changes that. A semantic surface token flips
   dark in dark mode and would put black text on a dark plate — invisible. --ddga-gray-25
   is a PRIMITIVE: it does not flip, which is the property needed here. Deliberate, and
   the one place in this theme where not following the mode is the correct answer.

   WHY PADDING RATHER THAN A BORDER ON THE IMAGE. `getSimpleCaptcha()` calls
   `addBorder()` unconditionally — there is no config key — so an opaque black 1px
   rectangle is baked INTO the PNG (verified: corner pixels read ff000000 even on the
   transparent background). A CSS border would sit directly against it as a double rule,
   and a border-radius would slice the baked rectangle's corners off. Padding insets the
   bitmap inside the plate instead, so the baked frame reads as the challenge's own edge
   and the plate reads as ours. Fighting it was tried on paper and loses: clip-path can
   crop the frame but clips the element's own border and background with it. */
/* ⛔ THE CHALLENGE IS NOW SCALED TO THE FIELD'S HEIGHT — 2026-07-27, on the explicit
   instruction "try to reduce image height to match with input". THIS REVERSES A
   STANDING REFUSAL IN THIS FILE and the refusal is left in place above, verbatim,
   because it is the reason to be careful here rather than a mistake to erase:

     "Shrinking the image is refused — the challenge is already hard to read (≈1 in
      3 illegible before the gimpy-renderer change) and scaling a captcha down to
      satisfy a layout constraint trades a working capability for a cosmetic one."

   The concern was raised and the instruction was given anyway, so it is the
   client's call and this is what it looks like. ⚠️ IF COMPLAINTS ABOUT UNREADABLE
   CAPTCHAS APPEAR, THIS RULE IS THE FIRST THING TO REVERT — deleting the four
   declarations below restores the native 170×50 challenge exactly.

   HOW THE 40px IS SPENT, because the naive version wastes most of it. The box is
   `border-box`, so 4px padding + 1px border on a 40px box would leave the bitmap
   only 30px — a 40% reduction. Padding and border are therefore dropped and the
   whole 40px goes to the bitmap: 170×50 scales to 136×40, a 20% reduction instead.

   Dropping them is safe here for a reason specific to this image. The padding
   existed to inset the challenge away from an opaque black 1px rectangle that
   `getSimpleCaptcha()` bakes INTO the PNG via an unconditional `addBorder()` — with
   the padding gone that baked frame simply becomes the visible edge, which is what
   a CSS border was imitating anyway. The background is still required: the
   challenge is pinned to TransparentBackgroundProducer, so this plate IS the
   backing the hardcoded-black glyphs are read against.

   The corner radius does slice the baked frame's corners, which this file warned
   about when the frame sat inside padding. It is accepted deliberately: matching
   the field's corner is the point of the instruction, and the cost is 4px of a
   black hairline at each corner. */
.taglib-captcha .captcha,
.form-input-captcha .taglib-captcha img.captcha {
  background-color: var(--harf-captcha-plate);
  block-size: var(--ddga-space-10); /* 40px — the shared field height, exactly */
  border: 1px solid var(--harf-auth-field-border);
  border-radius: var(--harf-captcha-field-radius);
  inline-size: auto; /* keep the 17:5 aspect ratio; do not stretch the glyphs */
  /* Never wider than the column it sits in. Arrived 2026-07-27 from
    `.portlet-login .taglib-captcha .captcha`; it also replaces OOTB's
    `max-width: 190px`, which was a no-op at `simpleCaptchaWidth=170` but would
    silently cap a future wider challenge at a value nobody chose. */
  max-inline-size: 100%;
  padding: 0;
  /* `none` in light, `invert(1)` in dark. See the block below. */
  filter: var(--harf-captcha-ink-filter);
  object-fit: none;
}

/* This pair is NOT a copy-paste slip — it restates the light values on purpose, and
   it is here because scripts/check-dark-contrast.sh is right to demand it.

   That guard exists to catch a primitive colour used where a re-pointing semantic
   token was meant, which is the usual mistake. This is the rare case where the
   primitive IS the intent: the plate must stay light in dark mode because the ink on
   it is Liferay's hardcoded Color.BLACK, so a plate that follows the theme would
   render the challenge invisible to a dark-mode visitor. Writing the dark rule out
   makes that a decision recorded in the code rather than a primitive that merely
   looks like an oversight. --ddga-gray-300 keeps enough edge against the dark page
   behind it; the black frame baked into the PNG does the rest. */
/* ═══════════════════════════════════════════════════════════════════════════
   THE CHALLENGE IN DARK MODE — the ink is inverted, not the plate pinned
   ═══════════════════════════════════════════════════════════════════════════

   ⛔ THIS REPLACES A RULE THAT WAS WRONG, and the wrongness is worth recording
   because the reasoning behind it was sound and still produced a bad answer.

   What was here until 2026-07-27:

       [data-theme=dark] .taglib-captcha .captcha {
           background-color: var(--ddga-gray-25);   // deliberately mode-INVARIANT
           border-color:     var(--ddga-gray-300);
       }

   …with a long comment explaining that the plate MUST stay light because Liferay
   draws the glyphs in a hardcoded `Color.BLACK` that no configuration key changes,
   so a plate following the theme would render the challenge invisible. Every one of
   those facts is true. The conclusion did not follow. Reported by the client as
   "dark mode still not fixed" — correctly: a bright white rectangle on a dark page
   was the one thing in the widget that never changed.

   WHAT THE PNG ACTUALLY CONTAINS — measured, not assumed. The rendered bitmap was
   read back through a canvas on /login (same-origin, so untainted) at its natural
   170×50:

       total pixels        8500
       fully transparent   5582   (66%)
       partially opaque     963   (antialiased glyph edges)
       fully opaque        1955
       DISTINCT opaque colours:  exactly ONE — rgb(0,0,0)
       all four corners    [0,0,0,255]   ← the frame addBorder() bakes in
       centre pixel        [0,0,0,202]

   So the image is not "black ink on a background". It is TRANSPARENT except for
   pure-black ink — glyphs, the CurvedLineNoiseProducer line, and the baked border,
   all the same single colour. That is what `TransparentBackgroundProducer` in
   configs/common/osgi/configs/…CaptchaConfiguration.config produces.

   WHY INVERSION IS THE RIGHT ANSWER AND NOT A TRICK. `filter: invert(1)` maps the
   colour channels and LEAVES ALPHA UNTOUCHED, so 66% of the bitmap stays fully
   transparent and the black ink becomes white ink. Pair that with a transparent
   plate and the challenge is white-on-dark-page — real dark mode, at the same
   contrast the light rendering has, with no plate to look out of place. Nothing is
   hidden and nothing is faked: the same pixels are shown, at inverted luminance.

   It also needs no server change, which matters — the alternatives were all worse
   and were checked rather than assumed. `DefaultWordRenderer` takes its colours
   from a static initialiser, and the OSGi configuration accepts only class NAMES,
   so no key can recolour the ink. A custom WordRenderer module could, but the
   server cannot know which theme the visitor is in, so it would have to pick one
   and be wrong half the time. The colour decision belongs on the client, and this
   is the client-side expression of it.

   The plate token goes to `transparent` in dark rather than to a dark colour: with
   the ink inverted there is nothing left for a plate to do, and a solid one would
   only reintroduce a rectangle that does not belong to the page. */
/* The answer is four ASCII digits on an RTL page. Left as-is, the caret starts at the
   right and a typed digit string is composed in the surrounding paragraph direction,
   which is the same class of defect fixed on the OTP boxes in _mfa-otp.scss the same
   day: the field's direction has to match the TOKEN it holds, not the page. Centred
   because a 4-character answer in a field sized for 10 otherwise sits against one edge. */
.taglib-captcha input[name$=captchaText] {
  direction: ltr;
  text-align: center;
}

/* A bare Clay icon is a ~16px hit target. WCAG 2.5.8 asks for 24px minimum and the DGA
   controls around it are 40px, so it was both hard to hit and visibly not part of the
   set. No colour is set: it inherits the link colour the theme already resolves per
   mode.

   The twin outranks OOTB's `.form-input-captcha .taglib-captcha .refresh` (0,3,0),
   which hardcodes 32px and `#fff` / `#cdced9` — a 32px target and two literals that
   cannot re-point for dark mode.

   ⚠️ THE TWIN'S SELECTOR WAS WRONG ON THE FIRST ATTEMPT AND THE MEASUREMENT CAUGHT
   IT. It read `a.refresh`, reasoned from `liferay-ui:icon` being given a `url`
   (`javascript:void(0);`) and therefore rendering an anchor. It does not: with
   `label="false"` and a tooltip it renders a **`<span>`**. Measured on the deployed
   page — `refresh.tag = "span"`, `className = "align-top d-inline-block refresh
   lfr-portal-tooltip"` — so the twin matched nothing and /contact kept OOTB's 32px
   white box while the other four surfaces got the 40px one. A three-way split
   turned into a two-way split; the whole point of this file is that there is no
   split at all.

   `.refresh.d-inline-block` is the corrected step. `d-inline-block` is written into
   simplecaptcha.jsp's own `cssClass` attribute, so it is as stable as the `refresh`
   class beside it and does not depend on which element the icon taglib chooses. */
.taglib-captcha .refresh,
.form-input-captcha .taglib-captcha .refresh.d-inline-block {
  align-items: center;
  background-color: transparent;
  block-size: var(--ddga-space-10);
  border: 0;
  border-radius: var(--ddga-radius-md);
  /* THE THIRD ANSWER WINS, on purpose. This icon had three colours across the
    platform: --ddga-color-primary on the two auth pages, --ddga-text-secondary on
    the two OOTB-fragment pages, and OOTB's own `#6b6c7e` where neither rule
    reached. Primary is the one kept, because it is the one the client has been
    looking at on /login and did not object to, and because it re-points correctly
    for dark mode on its own (dark.css: --ddga-color-primary → --ddga-brand-400 =
    #54c08a, which is G184 / README §17.3). The svg below inherits it. */
  color: var(--ddga-color-primary);
  display: inline-flex;
  inline-size: var(--ddga-space-10);
  justify-content: center;
  padding: 0;
}

.taglib-captcha .refresh:hover,
.form-input-captcha .taglib-captcha .refresh.d-inline-block:hover {
  background-color: var(--ddga-color-muted);
}

/* ⚠️ `.refresh` IS NOT THE BUTTON. Measured on the deployed page — the taglib emits
   a nest, not a leaf:
     <span class="align-top d-inline-block refresh lfr-portal-tooltip" title="…">
       <a href="javascript:void(0);" class="lfr-icon-item taglib-icon" id="<ns>axoo__">
         <span class="c-inner" tabindex="-1"><svg class="lexicon-icon …">
   That matters twice over, and the first attempt at this file missed both:

   1. COLOUR. The rule above paints the outer SPAN, but Clay's base sheet carries
      `a { color: #007bff }` and the anchor sits between the span and the glyph. So
      the anchor re-set the colour and `fill: currentColor` faithfully resolved it to
      BLUE. Measured: on /contact the span computed
      `color: rgb(27,131,84)` (ours) while the svg computed `rgb(0,123,255)`. It
      looked green on /login only because `_auth-pages.scss` happens to paint
      `.portlet-login a`, which is a coincidence of scope, not a working rule.
      `color: inherit` on the anchor makes the span's colour the single source again.

   2. THE HIT TARGET. simplecaptcha.jsp attaches its click listener to
      `<ns><refreshCaptchaId>`, and that id is on the ANCHOR. So the 40px box set
      above was on a span that is not clickable, while the thing a visitor must
      actually hit stayed inline at roughly glyph size. The WCAG 2.5.8 fix was
      cosmetic until the anchor was made to fill its box. */
.taglib-captcha .refresh a,
.form-input-captcha .taglib-captcha .refresh.d-inline-block a {
  align-items: center;
  block-size: 100%;
  color: inherit;
  display: flex;
  inline-size: 100%;
  justify-content: center;
}

/* Replaces OOTB `.refresh svg { fill: #6b6c7e }` — a literal, so it stays near-black
   in dark mode. `currentColor` hands the glyph back to the rule above, which is the
   only way one declaration can serve both modes. */
.taglib-captcha .refresh svg,
.form-input-captcha .taglib-captcha .refresh.d-inline-block svg {
  fill: currentColor;
}

.taglib-captcha .refresh:focus-visible {
  outline: 2px solid var(--ddga-color-focus-ring);
  outline-offset: 1px;
}

/* ───────────────────────────────────────────────────────────────────────────
   THE ANSWER FIELD — "input like shared input with placeholder"
   ───────────────────────────────────────────────────────────────────────────

   One statement of the DGA text input, for every surface the widget renders on.
   Before this it was stated FOUR times — `.portlet-login .form-control` in
   _auth-pages.scss and a private copy in each of harf-reg / harf-edu /
   harf-attend — and the copies had already drifted: 48px against everyone else's
   40px on the two register wizards, and a borderless grey box on the ceremony
   page. That drift is what "it should be shared across the project" was reported
   against, so the copies are deleted rather than nudged into agreement.

   The values are the ones `.portlet-login .form-control` already carried and are
   unchanged, because that block is the one that was derived against Figma
   240:16406 "Input Field" (h 40, radius 4, fill #ffffff, stroke #9da4ae) with DGA
   .ddga-text-input agreeing on every one of them. Only two things differ from it:

     · padding is SYMMETRIC here. Figma's {start 16, end 8} is for a field holding
       left-aligned text; this field's content is centred (see `text-align:center`
       above), so an asymmetric inset would visibly off-centre the answer.
     · the radius is the knob declared at the top of this file, because the
       register wizards' own neighbours use --ddga-radius-md and matching the field
       ABOVE it is the entire point of the instruction.

   No twin is needed on these: the OOTB fragment stylesheet does not style
   `.form-control` at all — checked, not assumed. `.portlet-login .form-control` is
   the same (0,2,0) but _auth-pages.scss is imported BEFORE this partial (see
   _custom.scss), so the tie resolves here, which is where the single owner is. */
.taglib-captcha .form-control {
  background-color: var(--ddga-color-background);
  block-size: var(--ddga-space-10); /* 40px — every surface's own fields measured 40px */
  border: 1px solid var(--harf-auth-field-border);
  border-radius: var(--harf-captcha-field-radius);
  box-shadow: none;
  color: var(--harf-auth-field-fg);
  /* MOVED HERE 2026-08-01 from `.taglib-captcha .form-group`, which no longer
     generates a box (see THE FIELD WRAPPER). The field is the flex item now, and
     `inline-size: 100%` below would otherwise be its flex BASE SIZE — 100% of the
     400px row — which wraps the widget onto two lines. A definite `flex-basis: 0`
     makes the algorithm ignore that width for sizing, which is the same mechanism,
     for the same reason, that the wrapper used to defeat OOTB's
     `width: calc(100% - 40px)`. */
  flex: 1 1 0;
  font-family: inherit;
  font-size: var(--ddga-font-size-base);
  inline-size: 100%;
  line-height: 1.5;
  max-inline-size: none;
  min-inline-size: 0;
  padding-block: 0;
  padding-inline: var(--ddga-space-3);
  transition: background-color 0.15s, border-color 0.15s, box-shadow 0.15s;
}

.taglib-captcha .form-control::placeholder {
  color: var(--harf-auth-field-placeholder);
  opacity: 1; /* Firefox dims placeholders by default; the token already encodes the intended contrast */
}

.taglib-captcha .form-control:hover:not(:focus) {
  border-color: var(--harf-auth-field-hover-border);
}

/* Same focus treatment as every other field on these forms: DGA's focused text
   input keeps its border colour, adds --ddga-shadow-md and draws a 2px bar along
   the block-end edge. Reproduced with one inset shadow because this is a bare
   <input> with no wrapper to hang a pseudo-element on. WCAG 2.4.7. */
.taglib-captcha .form-control:focus,
.taglib-captcha .form-control:focus-visible {
  border-color: var(--harf-auth-field-border);
  box-shadow: var(--ddga-shadow-md), inset 0 -2px 0 0 var(--harf-auth-field-focus-bar);
  outline: none;
}

/* `.has-error` is put on the widget's own wrapper by simplecaptcha.jsp when the
   previous answer was wrong, so the field turns red on exactly the occasion the
   visitor needs to notice it. */
.taglib-captcha.has-error .form-control,
.taglib-captcha .form-control[aria-invalid=true] {
  border-color: var(--ddga-color-error);
}

/* «الرمز المؤقت» — the email-OTP multi-factor screen. Imported after "auth-pages"
   and "captcha" for the same reason they are ordered that way: where specificity
   ties, source order should agree with intent. It renders as a MAXIMIZED portlet,
   so no fragment can reach it and its styling has to live here. See the partial's
   own header for the scoping evidence. */
/* «الرمز المؤقت» — the email-OTP multi-factor screen.
   Added 2026-07-26 on report: "when login, MFA OTP page doesn't match the design".

   WHY THIS IS A THEME PARTIAL AND NOT A FRAGMENT
   The MFA challenge renders with the portlet MAXIMIZED
   (`p_p_id=…MFAVerifyPortlet&p_p_state=maximized`), and a maximized portlet is the
   ONLY thing on the page — measured on the live screen, `.harf-login-aux` is
   absent, so no fragment on /login can reach it. The markup comes from this
   project's existing JSP override
   (modules/harf-mfa-email-otp-autosend/…/verify_browser.jsp) and the styling has
   to come from the theme.

   ⛔ TWO RETRACTIONS, 2026-07-27. Both were recorded here as measured and both were
   false. They are corrected in place rather than quietly overwritten, because each
   made this stylesheet look applied while most of it did nothing.

   RETRACTION 1 — THE SCOPE SELECTOR NEVER MATCHED ANYTHING.
   This file claimed `.portlet-mfa-` was "read off the deployed page's portlet
   boundary, not guessed", with a note that "the trailing hyphen is Liferay's, not a
   typo". MEASURED 2026-07-27 on the live challenge, reading className off the
   boundary element itself:
     portlet-boundary portlet-boundary_com_liferay_…_MFAVerifyPortlet_
       portlet-static portlet-static-end decorate portlet-mfa-verify
   The class is **`portlet-mfa-verify`**. The earlier reading was a TRUNCATION taken
   for a value — the same failure mode as the fragment-host name in
   harf-mfa-email-otp-autosend/bnd.bnd, which sat `Installed` for an hour. Every
   boundary-scoped rule below was therefore inert, which is why Liferay's own portlet
   title and its grey `btn-secondary` resend both survived a pass that claimed to
   have styled them.

   RETRACTION 2 — FIGMA DOES DEFINE THIS SURFACE'S WIDTH, SO RULE 2 DID NOT APPLY.
   This file claimed "Figma ships no separate width for this surface, so rule 2 hands
   the sibling auth column's number over" and pinned 400px from /login's
   `2009:12371`. MEASURED on the OTP frame `2591:215104`: the title node is
   x=64 w=1312 and the box row is x=1048 w=328 — the surface has its own band and its
   own geometry. README §17.3 rule 1 (Figma explicit for THIS surface) outranks rule
   2, so the 400px column was a fallback applied where no fallback was needed. The
   result on screen was a 400px column ending at x=1305 against the frame's 1376.

   GEOMETRY, from `2591:215104` — every number below is one of these:
     band            x=64 .. 1376   (1312 wide, 64px page margins)
     title           w=1312, h=38, right-aligned
     description     y=+54, h=30
     six boxes       48x48, gap 8, total 328, right-aligned to 1376
     «تأكيد»         63x40, right-aligned, 24px under the boxes
     countdown       right-aligned, 24px under the button, clock outermost
     resend line     36px under the countdown

   ORDER: boxes → تأكيد → countdown → resend. See the JSP's third-pass note.

   Tokens only; scripts/check-color-literals.sh fails the build on a literal. */
.portlet-mfa-verify {
  font-family: var(--ddga-font-ar);
}

/* Liferay prints its own portlet title — «التحقق من صحة مصادقة متعددة العوامل» —
   above the JSP's content. The design has exactly one heading, and the override
   emits it, so the platform's is suppressed rather than left to read as a second
   title. Hidden, not deleted: it is still the portlet's accessible name. */
.portlet-mfa-verify .portlet-title-text {
  clip-path: inset(50%);
  position: absolute;
  white-space: nowrap;
}

/* The portlet header row is what carried that title plus a back chevron the frame
   does not draw. With the title visually hidden the row collapses to empty
   padding, so the row itself goes too. */
.portlet-mfa-verify .portlet-header {
  display: none;
}

/* Liferay wraps the challenge in `container-fluid-max-xl`, which caps at 1140 and
   centres — 180..1320 in a 1440 viewport. The frame's band is 1312 (64..1376), so
   the cap is raised for THIS portlet only. Not a global container change. */
.portlet-mfa-verify .sign-in-form {
  max-inline-size: 1312px;
}

.harf-otp {
  /* Full band. The children are right-aligned individually, exactly as the frame
     composes them: the title spans 1312 and its TEXT is inline-start, while the
     boxes and the button are 328/63 wide boxes pinned to the same edge. */
  margin-inline: auto;
  max-inline-size: 1312px;
  padding-block: var(--ddga-space-16) var(--ddga-space-16);
  padding-inline: var(--harf-fig-section-padding);
}

@media (min-width: 1024px) {
  .harf-otp {
    padding-inline: 0;
  }
}
.harf-otp__title {
  color: var(--ddga-text-primary);
  font-size: var(--ddga-font-size-3xl);
  font-weight: 700;
  margin: 0 0 var(--ddga-space-4);
}

.harf-otp__description {
  color: var(--ddga-text-secondary);
  font-size: var(--ddga-font-size-base);
  line-height: 1.5;
  margin: 0 0 var(--ddga-space-8);
}

/* The address is already obfuscated by the platform. `dir="ltr"` on the span keeps
   `Inf******@****.com` from being reordered inside the Arabic sentence. */
.harf-otp__address {
  unicode-bidi: isolate;
}

/* ------------------------------------------------------------------- the boxes */
/* 48x48 with an 8px gap — frame `2591:215104`, box row x=1048 w=328 for six boxes
   (6*48 + 5*8 = 328, so the frame's own total confirms both numbers). `flex-start`
   is inline-start, i.e. the right edge of the band in RTL, which is where the frame
   pins the row. --ddga-space-12 is 3rem = 48px and --ddga-space-2 is .5rem = 8px:
   the scale carries both, so no literal is needed. */
/* ⛔ `direction: ltr` IS A BUG FIX, NOT A STYLE PREFERENCE. Reported by the client
   2026-07-27: "OTP MUST BE LEFT TO RIGHT AND PREVENT ANY ONE START FROM RIGHT FIELD".

   The page is RTL, so with the inherited `direction: rtl` this flex row laid its
   children out right-to-left: `boxes[0]` — the FIRST digit of the code, and the box the
   script focuses on load — rendered at the RIGHTMOST position. The value still
   submitted correctly for a visitor who typed into the focused box and let the script
   advance them. But a visitor who read the six-digit code out of the e-mail
   left-to-right and clicked the LEFTMOST box put digit 1 into `boxes[5]`, so
   `boxes.map(…).join('')` produced the code REVERSED and verification failed. That is
   the "opposite OTP" in the report.

   A one-time code is not Arabic text; it is an ASCII/numeric token with a fixed
   left-to-right reading order, which is why the direction is pinned on the row rather
   than inherited. `justify-content` flips with it: the row's main-start is now the LEFT,
   so keeping the group flush against the column's inline-start edge (the RIGHT, on an
   RTL surface) needs `flex-end`, not the `flex-start` this rule carried before. That
   placement is unchanged and is Figma's — frame 2591:215104 puts the boxes at x=1048
   w=328 inside the 1312 band that ends at x=1376, i.e. flush to the band's right edge.

   The ORDER is the client's instruction, not a Figma reading: an empty six-box frame
   cannot show which box holds the first digit. Sequential unlocking is enforced in
   verify_browser.jsp — see HARF change 5 there. */
.harf-otp__boxes {
  direction: ltr;
  display: flex;
  flex-direction: row;
  gap: var(--ddga-space-2);
  justify-content: flex-end;
  margin-block-end: var(--ddga-space-6); /* 24px to «تأكيد» — frame y 220 → 244 */
}

.harf-otp__digit {
  background-color: var(--ddga-color-background);
  border: 1px solid var(--ddga-color-input);
  border-radius: var(--ddga-radius-md);
  block-size: var(--ddga-space-12);
  color: var(--ddga-text-primary);
  flex: none;
  font-family: var(--ddga-font-ar);
  font-size: var(--ddga-font-size-xl);
  font-weight: 600;
  inline-size: var(--ddga-space-12);
  text-align: center;
}

/* A box that is not yet reachable. The script disables every box after the first and
   opens them one at a time, so this state is the visible half of "each field opens when
   the field before it is done" (client, 2026-07-27). It has to READ as not-yet-active —
   an identical-looking box that silently refuses focus is worse than no gating at all. */
.harf-otp__digit:disabled {
  background-color: var(--ddga-color-muted);
  border-color: var(--ddga-color-border);
  color: var(--ddga-text-tertiary);
  cursor: not-allowed;
}

.harf-otp__digit:focus,
.harf-otp__digit:focus-visible {
  border-color: var(--ddga-color-primary);
  outline: 2px solid var(--ddga-color-focus-ring);
  outline-offset: 1px;
}

/* Liferay's own field. It still submits — it is only taken out of the visual and
   tab order once the boxes exist. NOT `display:none`: a field removed from layout
   is also removed from some browsers' form-restore behaviour, and this one carries
   the value. */
.harf-otp__real,
.harf-otp .harf-otp__field .form-control.harf-otp__real {
  block-size: 1px;
  border: 0;
  clip-path: inset(50%);
  inline-size: 1px;
  padding: 0;
  position: absolute;
}

/* The shipped <aui:input> wrapper contributes a label slot and a bottom margin
   that the design does not have. */
.harf-otp__field .form-group {
  margin-block-end: 0;
}

.harf-otp__field .control-label {
  display: none;
}

/* ------------------------------------------------------- submit, countdown, resend */
/* 24px under the button, matching the frame's y 284 → 308. `aui:button-row` ships
   its own margin, so this sets both edges rather than only the one that differed. */
.harf-otp__actions,
.portlet-mfa-verify .harf-otp__actions.button-holder {
  display: flex;
  justify-content: flex-start; /* inline-start, as every other auth surface */
  margin-block: 0 var(--ddga-space-6);
}

/* Liferay renders this as `btn btn-primary`. The design's button is the DGA
   primary, and rather than restate its paint here the OOTB classes are mapped onto
   the same tokens the .ddga-button--primary rule uses — one place, one look. */
.harf-otp__submit,
.portlet-mfa-verify .harf-otp__submit.btn {
  background-color: var(--ddga-color-primary);
  border: 1px solid var(--ddga-color-primary);
  border-radius: var(--ddga-radius-sm);
  /* --ddga-color-primary-foreground is what .ddga-button--primary itself uses;
     `--ddga-color-primary-contrast` was invented and does not exist, which
     check-dga-tokens.sh caught — an undefined custom property invalidates the
     whole declaration silently, so the label would have had no colour at all. */
  color: var(--ddga-color-primary-foreground);
  font-family: var(--ddga-font-ar);
  font-size: var(--ddga-font-size-base);
  font-weight: 500;
  min-block-size: 40px;
  padding-block: 0;
  padding-inline: var(--ddga-space-4);
}

.portlet-mfa-verify .harf-otp__submit.btn:hover:not(:disabled) {
  background-color: var(--ddga-color-primary-hover);
  border-color: var(--ddga-color-primary-hover);
}

.portlet-mfa-verify .harf-otp__submit.btn:disabled {
  opacity: 0.6;
}

/* The frame stacks these on two lines — countdown, then the resend prompt+link —
   both pinned to the band's inline-start edge, 24px under «تأكيد». It was one
   wrapping flex ROW before, which is why the prompt sat beside the timer. */
.harf-otp__resend-row {
  align-items: flex-start;
  display: flex;
  flex-direction: column;
  gap: var(--ddga-space-3); /* 12px — frame countdown y=308 → resend y=344 */
  margin-block-end: var(--ddga-space-4);
}

.harf-otp__countdown {
  align-items: center;
  color: var(--ddga-text-secondary);
  display: inline-flex;
  gap: var(--ddga-space-2);
  font-size: var(--ddga-font-size-base);
}

/* Prompt and link on one line, in that order — RTL puts the prompt outermost, as
   the frame draws «ألم تتلق أي رمز بعد؟ إعادة الإرسال». */
.harf-otp__resend-line {
  align-items: baseline;
  display: inline-flex;
  gap: var(--ddga-space-2);
}

.harf-otp__countdown[hidden] {
  display: none;
}

.harf-otp__clock {
  block-size: var(--ddga-space-5);
  flex: none;
  inline-size: var(--ddga-space-5);
}

.harf-otp__clock-value {
  unicode-bidi: isolate;
}

.harf-otp__resend-prompt {
  color: var(--ddga-text-tertiary);
  font-size: var(--ddga-font-size-sm);
}

/* «إعادة الإرسال» is the SHIPPED sendEmailButton — the platform's resend rate limit
   and its disabled state still govern it, so it is restyled from a Bootstrap
   button into the design's link and not replaced. */
.harf-otp__resend,
.portlet-mfa-verify .harf-otp__resend.btn {
  background: none;
  border: 0;
  color: var(--ddga-color-primary);
  font-family: var(--ddga-font-ar);
  font-size: var(--ddga-font-size-sm);
  padding: 0;
  text-decoration: underline;
}

.portlet-mfa-verify .harf-otp__resend.btn:disabled {
  color: var(--ddga-text-tertiary);
  cursor: not-allowed;
  text-decoration: none;
}

/* Liferay's own status messages. Kept — they are the only feedback that a code was
   actually sent or failed — but shaped to the surface instead of full-width
   Bootstrap alerts. */
.harf-otp__message {
  margin-block-end: var(--ddga-space-4);
}

.harf-otp__message .alert {
  border-radius: var(--ddga-radius-md);
  display: block;
  font-size: var(--ddga-font-size-sm);
  margin: 0;
  padding: var(--ddga-space-3) var(--ddga-space-4);
}

/* Host placement for the shared table pager (`window.HarfPager`, js/main.js). The
   pager's own appearance is the DGA component imported above — this partial only
   positions the host and undoes two RTL rules that reach through the nav's
   dir="ltr". Those two win on specificity, not on order: adding `.harf-pager-host`
   makes them (0,3,0)/(0,3,1) against upstream's (0,2,0)/(0,2,1). Imported after
   "dga-components" regardless, so the source order agrees with the intent. */
/* ─────────────────────────────────────────────────────────────────────────────
   THE SHARED TABLE PAGER — host placement only.

   The pager itself carries NO rules here. Its appearance is @dev-dga/css
   pagination.css, ported verbatim into _dga-components.scss by
   tools/dga-port/port-components.mjs; the DOM is emitted by `window.HarfPager` in
   the theme's js/main.js against the official component's class contract. Every
   rule below is about where the pager SITS and about RTL — nothing restyles the
   component, which is the point of using it.

   It replaces four hand-written pagers: `.harf-pager` (harf-data-table),
   `.harf-adm-aud__pager`, `.harf-adm-ntf__pager` and `.harf-adm-prt__pager`.
   `.harf-pager` was a lookalike of this exact component, which directive 11
   forbids — see the comment block in js/main.js for the full reasoning.

   In the theme and not in a fragment for the reason main.js gives: a fragment's
   CSS only reaches the pages that fragment is placed on, so the next admin table
   would have shipped a fifth pager. Here it is inherited by every page.
   ──────────────────────────────────────────────────────────────────────────── */
/* Figma places the pager at the block end of the table card, on the reading-end
   side — the position the four pagers already shared. `:empty` matters: the host
   is server-rendered markup and stays empty for a single-page result (and until
   harf-data-table's first fetch resolves), so without this an empty host would
   still reserve its 40px row and leave a gap under the last table row. */
.harf-pager-host {
  display: flex;
  justify-content: flex-end;
  min-block-size: 40px;
}

.harf-pager-host:empty {
  display: none;
}

/* RTL — the same correction, for the same reason, as
   frontend-source/.../ArticlesNews.css.

   Figma draws the pager left-to-right (‹ 1 2 3 … 999 ›) even on these Arabic
   screens, so main.js sets dir="ltr" on the <nav>. That handles the row ORDER but
   not these two rules: pagination.css qualifies them with `[dir=rtl]`, which
   tests <html>, and a descendant combinator does not care that an intermediate
   element re-declares dir="ltr". So upstream's mirror and offset both still
   applied — the arrows pointed the wrong way and the active underline sat half a
   box off centre. Undone within this host only, so a genuinely RTL DGA pager
   elsewhere on the platform keeps upstream's behaviour. */
[dir=rtl] .harf-pager-host .ddga-pagination__nav-icon {
  transform: none;
}

[dir=rtl] .harf-pager-host .ddga-pagination__link--active::after {
  transform: translate(-50%);
}

/* The pager's two companions — the result count and the rows-per-page selector.
   Same argument as above: they are shared table chrome, consumed by both
   harf-data-table and admin-audit-log, so fragment CSS cannot carry them. */
/* ─────────────────────────────────────────────────────────────────────────────
   THE SHARED RESULT COUNT AND ROWS-PER-PAGE CONTROL.

   Companion to _harf-pager.scss, and here for the identical reason: a fragment's
   CSS only reaches the pages that fragment is placed on, so the audit log — the
   one admin table that cannot use harf-data-table, because 2026.Q1.9 ships no
   audit REST route — would otherwise have needed a second copy of both rules.
   Both rules were `harf-data-table/index.css`'s (`.harf-table__count` at 126-129,
   `.harf-table__page-size` at 204-223) and moved here verbatim on 2026-08-01. The
   CLASS NAMES ARE UNCHANGED so nothing else had to be touched.

   Behaviour is `window.HarfTableMeta` in the theme's js/main.js.

   ⚠️ THE SELECTOR IS A NATIVE <select>, NOT THE DGA SELECT COMPONENT, and that is
   a recorded deviation rather than a claim of compliance. `@dev-dga/css` does ship
   one — `.ddga-select-trigger` / `.ddga-select-content` / `.ddga-select-item`, in
   _dga-admin-components.scss — but it is a Radix composite driven by
   `data-state`, `data-highlighted` and `--radix-select-trigger-width`, i.e. a
   button plus a popover listbox, not a form control. Adopting it means writing
   that listbox and its keyboard model. Directive 11 forbids a LOOKALIKE, and a
   native control wearing the design system's own tokens is not one — but it is
   also not the component, so: logged here, not quietly styled over. Replacing it
   is a separate job with its own accessibility testing.
   ──────────────────────────────────────────────────────────────────────────── */
.harf-table__count {
  color: var(--ddga-text-secondary);
  font-size: var(--ddga-font-size-sm);
}

/* Rows-per-page selector. The toolbar's own 40px control band, with the same
 * border and radius its buttons carry, so the row keeps reading as one band.
 * Only tokens the toolbar already consumes — nothing here is a new design value.
 *
 * ⚠️ IT RENDERED SHORTER THAN THE BUTTONS BESIDE IT — reported 2026-08-01 with a
 * screenshot of the deployed toolbar, where «10» sits visibly lower and smaller
 * than «تحديث القائمة» and «تصدير التقارير», which are both 40px
 * (.harf-table__toolbar-action). `block-size: 40px` was already declared and was
 * not winning. Nothing in this theme competes for it: grepped _dga-reset.scss,
 * _dga-components.scss and _dga-admin-components.scss for a bare `select` rule
 * and there is none, so the override is coming from outside the theme or the
 * declaration is not binding on a replaced element.
 *
 * Three additions, each defensive rather than a guess at the cause:
 *
 *   · `box-sizing: border-box` — a <select> is a replaced element and does not
 *     inherit a global border-box the way a <div> does, so a content-box 40px
 *     plus border is not the 40px the buttons are.
 *   · `min-block-size` — a UA may treat `block-size` on a replaced element as
 *     advisory against its intrinsic size; a minimum is not advisory.
 *   · `line-height: 24px` — the exact value .harf-table__toolbar-action uses, so
 *     the text sits on the same baseline as the buttons rather than merely
 *     inside a box of the same height.
 *
 * The native chevron is deliberately NOT replaced with `appearance: none` plus a
 * drawn arrow: that is how this control would become the lookalike directive 11
 * forbids, and the frame shows a native affordance. MEASURE the computed height
 * on the deployed page before changing any of this again — the first attempt was
 * a declaration that looked correct and did not take. */
.harf-table__page-size {
  background: var(--ddga-color-card);
  block-size: 40px;
  border: 1px solid var(--harf-color-border-neutral);
  border-radius: var(--ddga-radius-sm);
  box-sizing: border-box;
  color: var(--ddga-text-primary);
  cursor: pointer;
  font-family: inherit;
  font-size: var(--ddga-font-size-base);
  line-height: 24px;
  min-block-size: 40px;
  padding-inline: var(--ddga-space-3);
}

.harf-table__page-size:focus-visible {
  outline: 2px solid var(--ddga-color-primary);
  outline-offset: 2px;
}

/* ═════════════════════════════════════════════════════════════════════════════
   THE TABLE SHELL — toolbar, card, scroll box and table, MOVED HERE 2026-08-02.

   ⛔ WHY THIS MOVE HAD TO HAPPEN, measured rather than reasoned.

   /admin/audit was restructured to carry harf-data-table's own class names, so
   its toolbar and card would compute the same as /admin/participations. It
   changed nothing. The DOM diff afterwards read:

       .harf-table__toolbar   display  flex vs BLOCK
                              justify  space-between vs normal
                              gap      12px vs normal
       .harf-table__card      display  flex vs BLOCK
                              padding  15px vs 0px

   The element carried the class and the class did nothing — because these rules
   lived in `fragments/harf-fragments/harf-data-table/index.css`, and FRAGMENT CSS
   ONLY SHIPS ON PAGES THAT MOUNT THAT FRAGMENT. /admin/audit mounts
   admin-audit-log, so the rules were simply not on the page. Renaming an element
   to match a stylesheet it cannot see is a no-op.

   This is the same lesson the pager and the count already learned, in the same
   file, twice. Anything two table screens must share belongs in the theme; the
   twelve harf-data-table pages load the theme too, so they are unaffected.

   Nothing below was edited in the move — the rules and their comments are the
   originals, in their original order (both `.harf-table__scroll` blocks included,
   because the second one's `overflow` deliberately wins over the first).
   ════════════════════════════════════════════════════════════════════════════ */
.harf-table__toolbar {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: var(--ddga-space-3);
  justify-content: space-between;
  min-block-size: 40px;
}

.harf-table__toolbar-start,
.harf-table__toolbar-end {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: var(--ddga-space-4);
}

.harf-table__card {
  background: var(--ddga-color-card);
  border: 1px solid var(--harf-color-border-neutral);
  border-radius: var(--ddga-radius-md);
  display: flex;
  flex-direction: column;
  gap: var(--ddga-space-4);
  min-block-size: 578px;
  /* 16px MINUS the border, not 16px. A Figma stroke is drawn inside the
   * frame and does not displace children, so the frame's 16px inset is
   * measured from the card's outer edge: card 40, table 56. CSS border-box
   * puts the border outside the padding, so a flat 16 lands the table at 57
   * and leaves it 1068 wide instead of 1072.
   *
   * That 4px is not cosmetic. With table-layout: fixed the seven data
   * columns divide the remainder, and 1068 gives 143.43px each — fractional,
   * so every column border falls between device pixels and renders as two
   * blended greys instead of one crisp #d2d6db line. Measured: three of the
   * separators went missing from a colour scan of the render entirely.
   * 1072 divides to exactly 144 and the borders land on whole pixels. */
  padding: calc(var(--ddga-space-4) - 1px);
}

.harf-table__table {
  /* border-collapse and inline-size now come from `.ddga-table`, the
     OFFICIAL DGA table component, which this fragment's markup carries as
     of 2026-07-25. `separate` + the per-cell grid below were a LOOKALIKE:
     measured that day, /admin/audit and /admin/participations already used
     `ddga-table ddga-table--md` (48px header, 90px rows, one 1px rule per
     row) while all EIGHT harf-data-table screens rendered a bespoke
     `harf-table__table` grid with 0px row separators — two different
     tables in one admin. Directive 11: official DGA components, no
     lookalikes. */
  /* A FLOOR, so the table SCROLLS instead of being crushed. MEASURED at 430px:
   * `inline-size: 100%` + `table-layout: fixed` squeezed ten columns into a
   * 318px table and the headers overlapped into an unreadable run —
   * «اسم البريد المجال المرحلة عدد حالة» printed on top of itself. The page
   * did NOT overflow and every computed width was "correct"; it is only
   * visible in the picture.
   *
   * 40rem (640px) is chosen so ONLY the broken case changes: measured, the
   * table is 1072px at desktop and 641px at tablet — both at or above the
   * floor, so neither gains a scrollbar — while 318px at mobile falls below
   * it and scrolls inside `.harf-table__scroll`, which already carries
   * `overflow-x: auto`. The page body still never scrolls horizontally.
   *
   * The admin design provides NO mobile frame for this screen (checked: the
   * only sub-900px node naming «إدارة المحكمين» is the 256px nav drawer), so
   * per README §17.3 rule 2 nothing is interpolated from a frame — this is the
   * documented fallback of keeping the desktop layout and letting it scroll. */
  min-inline-size: 40rem;
  table-layout: fixed;
}

.harf-table__scroll {
  inline-size: 100%;
  /* MEASURED 2026-07-25 at 390px: scrollWidth 670 vs clientWidth 390 — the page
   * itself scrolled sideways even though this container already had
   * `overflow-x: auto`. Cause: `.harf-table` is a flex column, and a flex item's
   * `min-width` resolves to `auto`, which is the CONTENT width. So this box
   * refused to shrink below the table's min-width and pushed the document
   * instead of scrolling inside itself. `min-inline-size: 0` lets it shrink; the
   * overflow rule then does what it always looked like it was doing.
   *
   * This is why the earlier note above ("the page body never scrolls
   * horizontally") was true of the RULE and false of the RESULT — verify the
   * presence of the result, not the absence of an error. Fixes every admin
   * table on mobile, not just the ceremony list. */
  min-inline-size: 0;
  overflow-x: auto;
}

.harf-table__scroll {
  border-radius: var(--ddga-radius-md);
  /* ⛔ THE SCROLL BOX MUST BE A CONTAINING BLOCK, OR ITS OWN `overflow` DOES NOT
   * BIND ITS ABSOLUTELY-POSITIONED DESCENDANTS. This one line is the whole of
   * the "admin tables are not responsive on mobile" defect reported 2026-08-05.
   *
   * MEASURED at a true 430px layout viewport (`mobile: false`), signed in, on
   * EIGHT admin list pages: `documentElement.scrollWidth` **665** against a
   * **415** client width — the page itself slid sideways and carried the
   * heading and the toolbar off screen, which is what the report's second
   * screenshot shows. The table was NOT the escapee: this box measured
   * client 303 / scroll 640 with `overflow-x: auto`, i.e. it was scrolling its
   * table internally exactly as intended.
   *
   * The escapee was a ONE-PIXEL screen-reader span. `.harf-table__sr` (the
   * accessible name of the actions column, harf-data-table/index.css) is
   * `position: absolute` with no inset, so it sits at its static position
   * inside the LAST `<th>` — which in RTL is hard against the page's left edge
   * and, once the table is wider than this box, lies OUTSIDE it. An
   * absolutely-positioned box is clipped only by an ancestor that is on its
   * containing-block chain; this box was `position: static`, so the span's
   * containing block resolved past it all the way to `#wrapper`. Measured
   * exactly there: `left: -250`, `offsetParent: wrapper`, and 665 - 415 = 250.
   *
   * TWO ARTEFACTS PIN IT, not one:
   *   · positive — forcing `.harf-table__table { min-inline-size: 0 }` at
   *     runtime pulled the span back inside the viewport and `scrollWidth`
   *     fell 665 → 415 on the spot;
   *   · control — /admin/audit does NOT mount harf-data-table and so emits no
   *     `.harf-table__sr`. It measured **415** with a 900px table in a 351px
   *     box, i.e. the identical shell, wider content, no page scroll. The
   *     clip was never broken; only that one span was exempt from it.
   *
   * `position: relative` is the fix rather than a patch on the span, because
   * the span is not special — ANY future absolutely-positioned descendant of a
   * table cell would escape the same way. The two menus that must escape
   * (`.harf-table__menu`, `.harf-table__export-menu`'s panel) are
   * `position: fixed` and are unaffected: a relatively-positioned ancestor
   * does not capture a fixed box.
   *
   * VERIFIED AFTER DEPLOY, on the running instance, signed in: all NINE admin
   * table pages measure `scrollWidth == clientWidth` at 430, 768 and 1440 —
   * /admin/audit included, so nothing it needed to escape was caught. The
   * trap is written up in docs/records/TRAPS-AUDIT.md. */
  position: relative;
  /* Square cell corners would otherwise poke through the rounded corners —
   * that is why this clips. But `overflow: hidden` sets BOTH axes, and this
   * is the SAME selector as the `overflow-x: auto` rule ~500 lines above, at
   * the SAME specificity, so this one won and silently disabled horizontal
   * scrolling on every admin table.
   *
   * MEASURED at a true 430px viewport (`mobile=False` — with `mobile=True`
   * Chrome substitutes its own layout viewport and reports 664, which hid
   * this entirely): the table sat at 640px with `right:359`, i.e. extending
   * **281px past the left edge** in RTL, `documentElement.scrollWidth` 664
   * against a 430 viewport — the page scrolled sideways AND the clipped
   * columns were unreachable, because `hidden` clips without scrolling.
   *
   * Splitting the axes keeps the corner clip on the block axis and gives back
   * the scroll on the inline axis, which is what the rule above always
   * intended. */
  overflow-x: auto;
  overflow-y: hidden;
}

/* Popover placement for the shared DGA date picker (`window.HarfDatePicker`,
   js/main.js). Same argument again: the control is consumed by participant-register,
   admin-audit-log and admin-competition-form, so the panel's `position: fixed` — the
   one thing DGA leaves open, and the whole viewport requirement — cannot live in one
   fragment's CSS. Imported after "dga-date-controls" so it layers on the port
   without editing it. */
/* ─────────────────────────────────────────────────────────────────────────────
   THE SHARED DGA DATE PICKER — popover placement only.

   The calendar itself carries NO rules here. Its appearance is @dev-dga/css
   calendar.css + date-picker.css, ported verbatim into _dga-date-controls.scss;
   the DOM is emitted by `window.HarfDatePicker` in the theme's js/main.js against
   the official component's class contract. Every rule below is about where the
   panel SITS — nothing restyles the component, which is the point of using it.

   WHY THESE FIVE RULES ARE NOT OPTIONAL. They were written for the participant
   register on 2026-07-23 and scoped to `.harf-reg__calendar`, which was correct
   while that fragment was the only consumer. It is not any more: the admin audit
   filter and the competition form now use the same component, and without these
   the panel renders STATIC (so `place()`'s left/top do nothing), stays visible
   when `hidden`, and drops its year caret ~6px below the year.

   So the component always adds `.harf-date-picker__popover` and the rules live
   here. `.harf-reg__calendar` keeps its identical copies in that fragment's CSS
   deliberately — they are the same declarations, they cannot conflict, and the
   register is a critical path that must not depend on a theme WAR landing.

   NOT folded into _dga-date-controls.scss, which is a byte-faithful port of
   @dev-dga/css (39/39 selectors). A local edit there would silently desynchronise
   it from upstream. Same argument the register's own comment already made.
   ──────────────────────────────────────────────────────────────────────────── */
/* POSITION IS THE ONLY THING DGA LEAVES OPEN, and it is the whole viewport
   requirement. `fixed` is deliberate: an absolutely-positioned panel is clipped by
   any scrolling ancestor, and every consumer sits inside portlet chrome. main.js
   writes left / top from getBoundingClientRect(), clamped to the viewport on both
   axes, and re-runs on scroll and resize. */
.harf-date-picker__popover {
  max-inline-size: calc(100vw - 2 * var(--ddga-space-4));
  position: fixed;
}

.harf-date-picker__popover[hidden] {
  display: none;
}

.harf-date-picker__popover .ddga-calendar__grid td {
  padding: 0;
}

/* The year caret rendered ~6px BELOW the year it belongs to, which read as a third
   element on its own line rather than part of the control.

   MEASURED, picker open, 1440 RTL:
     year chip / year text centre  558.5
     nav arrow path centre         558.5   <- correct
     year caret path centre        564.4   <- 5.9px low

   Cause is the markup, NOT the DGA port. DGA styles `.ddga-calendar__year-chevron`
   as a 16x16 absolutely-positioned span and gives it no `display`, so it stays an
   INLINE box — and an inline <svg> inside it aligns to the TEXT BASELINE, dropping
   5.4px. The two nav chevrons escape this only because `.ddga-calendar__nav` is
   `inline-flex` with `align-items: center`, so their svg is a flex item and gets
   centred. No token, colour or size is invented. */
.harf-date-picker__popover .ddga-calendar__year-chevron svg {
  display: block;
}

/* The height chain that puts the site footer at the BOTTOM of a short page.
   Structural page chrome, not a design value: it belongs here rather than in a
   fragment because site-footer renders in all three masters, while fragment CSS
   ships only on pages that render that fragment. See the partial's own header for
   the two measured DOM chains. */
/* ═══════════════════════════════════════════════════════════════════════════
   PAGE CHROME — THE FOOTER SITS AT THE BOTTOM OF A SHORT PAGE
   ═══════════════════════════════════════════════════════════════════════════

   Client, 2026-07-30: "prevent the empty space in the bottom of the footer,
   should be always bottom." Reported against the participant-registration
   choice screen, which is short enough that the footer ended mid-viewport with
   a white band below it.

   ROOT CAUSE — MEASURED, not inferred. portal_normal.ftl opens:

     <div class="d-flex flex-column min-vh-100">              ← ≥100vh: spare height EXISTS
       <div id="wrapper" class="d-flex flex-column flex-fill">  ← claims all of it
         <div id="content">                                    ← plain block: height = content

   so the height chain from `min-vh-100` STOPS at #wrapper. #content and
   everything below it are ordinary blocks, so nothing between #wrapper and the
   footer grows, and the spare viewport height is left as dead space BELOW the
   footer *inside* #wrapper — which paints white. The band in the report is that
   leftover, not a margin on the footer.

   THE TWO CHROME CHAINS, read off the served HTML of the running instance
   (guest, HTTP 200, div/section nesting counted — not assumed):

     /register  /login  /forgot-password  /register-participant
       #content > #master-layout-wrapper
                > [site-header item, #main-content, site-footer item]

     /c/portal/update_password — has NO #master-layout-wrapper. The whole page
     renders inside the synthetic full-page portlet that _auth-pages.scss §9
     already documents, and #content has exactly ONE child:
       #content > section.portlet#portlet_new-password > .portlet-content
                > [site-header item, #main-content, site-footer item]

   In both chains the footer is a SIBLING of #main-content, so one fix serves
   both: carry the growth down to #main-content and let it absorb the leftover.

   WHAT THIS DELIBERATELY IS NOT. No `margin-block-start: auto` on the footer —
   that still needs a growing flex column above it, so it would be the same fix
   with the cause hidden one level further away. No viewport height on the footer
   or on #main-content either: that breaks the moment a page is TALLER than the
   viewport, which is most of them.

   `flex: 1 1 auto`, NOT `flex: 1`. `flex: 1` sets flex-basis to 0, which makes a
   container ignore its own content height; with basis `auto` the item starts at
   its content size and growth only ever consumes space that is genuinely spare.
   min-height on a flex item defaults to `auto`, so a long page cannot be
   squashed by the flex-shrink either.

   :has(#main-content) ON THE PORTLET BRANCH IS A GUARD, NOT DECORATION. It holds
   the rule to the one portlet that wraps a whole page. If some other route puts
   an ordinary portlet as a direct child of #content, that portlet is left alone —
   so a wrong guess about that route is a NO-OP rather than a page splitting its
   height between two portlets. Same technique and same reasoning as
   :not(:has(.harf-pt-tabbar)) in participant-nav-drawer/index.css.

   WHY THE THEME AND NOT A FRAGMENT. participant-nav-drawer/index.css already
   carries the #content / #master-layout-wrapper half of this, for the same
   reason (its own comment: "the grey stops where the content stops and a white
   band shows below it on a short page"). But fragment CSS ships ONLY on pages
   that render that fragment — measured, in that file's own "WHY IT LIVES IN THE
   DRAWER'S STYLESHEET" note — so it fixes six participant screens and nothing
   else. site-footer renders in all three masters (harf-master,
   harf-participant-master, harf-admin-master), so its host chain is chrome for
   every page on the platform and belongs where chrome CSS loads unconditionally.
   The participant copy is left in place rather than deleted: the declarations are
   identical, so neither copy can win a conflict against the other.

   Checked against the two fragments that also style these containers:
   admin-nav-drawer sets `#content { padding-inline-start: 256px }` (padding only,
   and its drawer is position:fixed at that breakpoint), and
   participant-nav-drawer sets the same three declarations as below. Neither
   conflicts.

   NOT WRAPPED IN @layer — see _custom.scss's header for why nothing in this
   theme may be; enforced by scripts/check-theme-css-order.sh. */
#content,
#master-layout-wrapper,
#content > .portlet:has(#main-content),
#content > .portlet > .portlet-content:has(#main-content) {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
}

#main-content {
  flex: 1 1 auto;
}

/* ═══════════════════════════════════════════════════════════════════════════
   3. NDS INLINE-ICON PRIMITIVE
   ═══════════════════════════════════════════════════════════════════════════

   Ported verbatim from the app's own base stylesheet,
   frontend-source/src/index.css:85-96 (".nds-icon" / ".nds-icon svg"). NOT a new
   value — @dev-dga ships no icon component at all (verified: zero occurrences of
   "nds-icon" or "gds-icon" in @dev-dga/css/dist/index.css), so this primitive had
   no definition anywhere in the theme and every icon collapsed.

   MEASURED before this was added, on the rendered homepage: the social buttons in
   .contact__socials computed `width: 0px; height: 0px` on the <svg> and `0px` wide
   on the .nds-icon span — the "empty 32x32 boxes". Six fragments emit .nds-icon
   markup and four of their stylesheets already carry comments overriding
   "the base .nds-icon 1.25em", i.e. they were authored against this rule
   existing. It belongs here, not in a fragment, because it is shared by all of
   them and must load once per page.

   Sizing is deliberately relative (1.25em) so DGA button/menu font-size drives the
   glyph, which is what the per-fragment overrides assume. */
.nds-icon {
  display: inline-flex;
  flex-shrink: 0;
  line-height: 0;
  inline-size: 1.25em;
  block-size: 1.25em;
}

.nds-icon svg {
  display: block;
  inline-size: 100%;
  block-size: 100%;
}

/* ═══════════════════════════════════════════════════════════════════════════
   3. FIXED-SURFACE FOREGROUND — the token @dev-dga/css does not name
   ═══════════════════════════════════════════════════════════════════════════

   There are two DIFFERENT kinds of colour in a themed UI, and conflating them is
   what makes dark mode fail:

     (a) SURFACE-RELATIVE — sits on the page surface and MUST re-point between
         light and dark. --ddga-color-foreground, --ddga-text-primary, and the
         paired *-foreground tokens are all of this kind.

     (b) FIXED-SURFACE — sits on something whose colour does NOT change with the
         theme: a photographic background, a brand-coloured scrim, the dark green
         footer, a filled white on-colour button. These must NOT re-point, or the
         foreground inverts while its surface stays put and the content vanishes.

   @dev-dga/css v0.12.0 DOES express (b) — but only inside components, never as a
   named token. Verified in dist/components/:

       .ddga-button--on-color.ddga-button--outline  { color:#fff }
       .ddga-link--on-color { --ddga-link-color:#fff;
                              --ddga-link-color-hover:var(--ddga-alpha-white-80);
                              --ddga-link-color-pressed:var(--ddga-alpha-white-60);
                              --ddga-link-color-visited:var(--ddga-alpha-white-90) }

   So the VALUE for this category is #fff and the muted steps are the
   --ddga-alpha-white-* family. There is no --ddga-on-color-foreground to point at:
   grep of variables.css returns nothing in that shape, and the only white-ish
   named tokens are the eight alpha steps, none of which is opaque white.

   This token therefore invents no value — #fff is lifted verbatim from DGA's own
   on-colour rules. It names a category the library leaves anonymous, so that the
   distinction is greppable and the build guard has exactly one legal home for an
   opaque-white literal. Reported to the client as a DGA token-set gap.

   WHAT WENT WRONG WITHOUT IT: six rules reached for
   --ddga-color-primary-foreground to mean "white". That token means "the correct
   foreground for whatever --ddga-color-primary currently is" — and dark.css
   re-points it from #fff to var(--ddga-gray-950). MEASURED in dark mode, the hero
   title and subtitle computed rgb(13, 18, 28) on the sa-950 scrim. */
:root {
  --harf-on-fixed-surface: #fff;
}

/* ── (c) SURFACES FIGMA NAMES BUT @dev-dga/css HAS NO SEMANTIC FOR ────────────
   A third category, found by a real rendering defect rather than by reading:
   a surface whose LIGHT value Figma states explicitly, and for which the DGA
   library ships only a PRIMITIVE — and a primitive cannot re-point, because
   dark.css overrides semantics only and never touches the --ddga-gray-* ramp.

   MEASURED on the deployed homepage in dark mode: `.partners` computed
   background rgb(249, 250, 251) — still #f9fafb — while `.partners__title`
   computed rgb(255, 255, 255), because --ddga-text-primary DOES re-point. White
   title on a near-white band: the section title was invisible. Same shape of bug
   as the one --harf-on-fixed-surface was created for, but the opposite way round
   — there the foreground moved and the surface could not; here the surface could
   not move and the foreground did.

   Both values below are DGA primitives, and both pairs come from the Figma
   "Themes" collection, whose Light and Dark values were already cross-checked
   against the DGA ramp in GAPS-CHECKLIST G177:

       Figma token                     Light            Dark
       Background/background-neutral-50  #f9fafb = gray-50   #111927 = gray-900
       Border/border-neutral-primary     #d2d6db = gray-300  #6c737f = gray-500

   So nothing here is derived or invented: each side is an existing --ddga-*
   step, and the pairing is Figma's own. They live in the theme rather than in a
   fragment because a re-pointable token has to be declared in every mode block,
   and those blocks are here. */
:root {
  --harf-color-surface-sunken: var(--ddga-gray-50); /* Figma Background/background-neutral-50 — Light */
  --harf-color-border-neutral: var(--ddga-gray-300); /* Figma Border/border-neutral-primary — Light */
  --harf-color-text-brand-strong: var(--ddga-sa-800); /* Figma text/text-primary-sa-flag — Light */
  /* Ring drawn ON the filled primary card (Figma 2150:25312 «أهداف المسابقة»
     goal 1: a 2px #54c08a circle on the #1b8354 fill).

     MEASURED after the numerals were restored: in DARK the card fill re-points
     to --ddga-brand-400 (#54c08a, G184) while the ring was pinned to that same
     #54c08a, so ring-vs-fill computed 1.00:1 — the circle vanished completely
     while the numeral inside it stayed at 8.29:1. The old "mode-blind-ok"
     note on that rule measured the NUMERAL and mistook it for the ring.

     The pairing is Figma's, mirrored: light puts the lighter green (sa-400) on
     the darker fill; dark puts the darker green (sa-800) on the lighter fill.
     Both sides are existing --ddga-* steps and the ratio is the design's own
     ~2:1 decorative contrast either way — the numeral carries the legibility. */
  --harf-ring-on-primary: var(--ddga-sa-400); /* #54c08a on the #1b8354 fill — Light */
}

/* The same three selectors the generated dark block uses, and for the same
   reasons — see _dga-semantic.scss. :root[…] is (0,2,0) so it outranks the
   Style Book's inline :root sheet regardless of source order. */
:root[data-theme=dark],
:root[data-color-scheme=dark] {
  --harf-color-surface-sunken: var(--ddga-gray-900); /* Figma Background/background-neutral-50 — Dark */
  --harf-color-border-neutral: var(--ddga-gray-500); /* Figma Border/border-neutral-primary — Dark */
  --harf-color-text-brand-strong: var(--ddga-brand-400); /* G184 dark brand — Dark */
  --harf-ring-on-primary: var(--ddga-sa-800); /* #1b8354 on the #54c08a fill — Dark */
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme=light]) {
    --harf-color-surface-sunken: var(--ddga-gray-900); /* Figma Background/background-neutral-50 — Dark */
    --harf-color-border-neutral: var(--ddga-gray-500); /* Figma Border/border-neutral-primary — Dark */
    --harf-color-text-brand-strong: var(--ddga-brand-400); /* G184 dark brand — Dark */
    --harf-ring-on-primary: var(--ddga-sa-800); /* #1b8354 on the #54c08a fill — Dark */
  }
}
/* ═══════════════════════════════════════════════════════════════════════════
   4. DGA COMPONENTS RENDERED AS <a> — restoring the component's own colour
   ═══════════════════════════════════════════════════════════════════════════

   MEASURED with a real mouse hover on the deployed homepage at 1440px:

       .harf-navbar__actions a.ddga-button--primary   color rgb(0, 86, 179)
                                                      on background rgb(22, 106, 69)
       .harf-navbar__actions a.ddga-button--outline   color rgb(0, 86, 179)

   Cause, proven from the CSSOM rather than inferred: Clay's base sheet declares
   `a:hover, a.hover { color: rgb(0, 86, 179) }`. That selector is specificity
   (0,1,1). DGA's own `.ddga-button--primary { color: … }` is (0,1,0). They tie on
   class count and Clay wins on the element component, so every DGA button rendered
   as an <a> reverted to Bootstrap blue on hover. Buttons rendered as <button> were
   never affected, and `.ddga-button--on-color.ddga-button--primary` (0,2,0) already
   outranked it — which is exactly why the hero CTA looked fine and the header CTAs
   did not.

   The fix restates only the MAPPING, never a value: each rule below points at the
   same var() the ported DGA rule uses. Specificity is (0,2,1), which beats Clay's
   (0,1,1) outright rather than relying on source order.

   Scoped to a.ddga-button so nothing else on the page is touched. */
a.ddga-button.ddga-button--primary {
  color: var(--ddga-color-primary-foreground);
}

a.ddga-button.ddga-button--secondary {
  color: var(--ddga-color-secondary-foreground);
}

a.ddga-button.ddga-button--outline,
a.ddga-button.ddga-button--ghost {
  color: var(--ddga-color-foreground);
}

a.ddga-button.ddga-button--black {
  color: var(--harf-on-fixed-surface);
}

/* On-colour variants sit on a fixed surface by definition — see section 3. */
a.ddga-button.ddga-button--on-color.ddga-button--outline,
a.ddga-button.ddga-button--on-color.ddga-button--ghost,
a.ddga-button.ddga-button--on-color.ddga-button--secondary {
  color: var(--harf-on-fixed-surface);
}

/* ═══════════════════════════════════════════════════════════════════════════
   4b. THE SAME REGRESSION, EVERYWHERE ELSE — the general rule
   ═══════════════════════════════════════════════════════════════════════════

   Section 4 above fixed ONE anchor family (a.ddga-button) and only its `color`.
   The defect is not confined to buttons and is not confined to colour. MEASURED
   in the shipped bundle (bundles/.../cms-theme/css/clay.css), Clay declares,
   unlayered:

       a         { color:#0b5fff; text-decoration:none }              (0,0,1)
       a:hover,
       a.hover   { color:#004ad7; text-decoration:underline }         (0,1,1)

   #004ad7 is what clay.css DECLARES; the colour that actually lands is
   rgb(0,86,179) — Bootstrap's #0056b3, from a later copy of the same selector.
   Both are in the sheet, so do not "correct" one to the other: the selector is
   the thing that matters here, and its specificity is identical either way.

   Every anchor styled by a single class is (0,1,0), so on hover it loses BOTH
   its colour AND its text-decoration to Clay. Counted across fragments/: 118
   anchors, 53 distinct component classes, 38 of which declare their own colour.
   The visible symptom is Bootstrap blue plus an underline on things that are not
   links — the report that produced this section was a green primary toolbar
   button whose label went blue and underlined on hover
   (a.harf-table__toolbar-action--primary, which section 4 never matched).

   ⚠ THE CONSTRAINT THAT SHAPES THIS SECTION — read before "simplifying" it.
   Any selector that beats Clay's (0,1,1) ALSO beats every single-class component
   rule, because (0,1,0) is strictly lower. So a global anti-blue rule cannot
   "let the component's own colour through": CSS gives it no way to name a value
   it did not itself set, so it must supply one. Both obvious shortcuts are wrong:
     · `color: inherit`      — a green button would take the page's text colour;
     · `color: currentColor` — used ON the `color` property this resolves to the
                               INHERITED colour, i.e. the same bug respelled.
   Layering is not available either: unlayered CSS beats layered regardless of
   specificity and Clay cannot be retroactively layered (THEME-BUILD.md).

   So the mechanism is a custom property with a default:

       --harf-a-color        the colour this anchor already owns
       --harf-a-decoration   whether it underlines on hover

   An anchor that sets neither is a genuine link and gets DGA's link colours. An
   anchor that owns its appearance sets --harf-a-color ONCE, restating the SAME
   var its own rule already declares — the mapping, never a value. Every entry in
   the opt-out block below was read out of that component's own CSS, with
   @media (forced-colors) excluded (it declares system keywords like `graytext`,
   which are NOT the component's colour and must never be copied here). */
:root {
  /* DGA link.css: --ddga-link-color: var(--ddga-color-primary);
                   --ddga-link-color-hover: var(--ddga-sa-400).
     Figma defines no hover state for bare links, so README §17.3 rule 2
     applies — where Figma is silent the DGA library is authoritative. */
  --harf-link-color: var(--ddga-color-primary);
  --harf-link-hover-color: var(--ddga-sa-400);
}

/* Same three selectors the rest of this file uses for dark — see section 3.
   DGA link.css: [data-theme=dark] .ddga-link--primary
                     { --ddga-link-color-hover: var(--ddga-sa-300) } */
:root[data-theme=dark],
:root[data-color-scheme=dark] {
  --harf-link-hover-color: var(--ddga-sa-300);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme=light]) {
    --harf-link-hover-color: var(--ddga-sa-300);
  }
}
/* Rest state. (0,0,1) ties Clay's `a` and wins on source order — this file
   compiles after Clay (see the file header). Any component class is (0,1,0) and
   still outranks it, so this only reaches anchors nothing else styles. */
a {
  color: var(--harf-a-color, var(--harf-link-color));
}

/* Hover.

   ⚠ THE SPECIFICITY HERE IS EXACT — (0,1,2) — AND IT IS NOT ARBITRARY. It has
   to sit in the ONE gap between two other rules:

       Clay          a:hover                      (0,1,1)   must LOSE to us
       this rule     html a:hover                 (0,1,2)
       a component's own  .x:hover { color }       (0,2,0)   must BEAT us

   MEASURED: 8 of the 32 anchor families already declare their own `:hover`
   colour — .harf-adm-det__view, .harf-adm-det__crumb, .harf-adm-asg__crumb,
   .harf-navbar__brand, .harf-adm-topbar__user, .harf-pt-tabbar__user,
   .harf-pt-drawer__item, .harf-logout-item. At (0,2,0) those ALREADY outranked
   Clay's (0,1,1), so they never had the blue bug at all. An earlier draft of
   this rule used `a[href]:hover` — (0,2,1) — which beat them too and silently
   flattened eight deliberate hover states into no-ops. `html a` buys the extra
   ELEMENT that clears Clay without touching them.

   Decoration defaults to `none` so no component gains an underline it never had
   — bare links opt back in immediately below. */
html a:hover,
html a.hover {
  color: var(--harf-a-color, var(--harf-link-hover-color));
  text-decoration: var(--harf-a-decoration, none);
}

/* A genuine link — one no component class touches — keeps the underline
   affordance. DGA link.css: .ddga-link--standalone:hover { text-decoration:
   underline }. (0,2,1), placed after the block above to win the tie. */
a:not([class]):hover,
a:not([class]).hover {
  text-decoration: underline;
}

/* ── Opt-outs: anchors that own their colour ───────────────────────────────
   Grouped by the value each component's own rule declares. Modifier groups
   follow their base group so the modifier wins the (0,1,0) tie on source order,
   exactly as it does in the component's own stylesheet. */
/* color: var(--ddga-text-primary) */
.ddga-dropdown-menu__item,
.harf-adm-dash__edition,
.harf-adm-drawer__brand-link,
.harf-adm-drawer__link,
.harf-cmpform__cancel,
.harf-contact-sent__btn--secondary,
.harf-logout-item,
.harf-panel__file,
.harf-pt-drawer__brand-link,
.harf-pt-drawer__item,
.harf-pt-tabbar__bell,
.harf-table__toolbar-action {
  --harf-a-color: var(--ddga-text-primary);
}

/* color: var(--ddga-text-secondary) */
.harf-cmpdet__crumb-link,
.harf-cmpform__crumb-link {
  --harf-a-color: var(--ddga-text-secondary);
}

/* color: var(--ddga-text-tertiary) */
.harf-adm-det__view {
  --harf-a-color: var(--ddga-text-tertiary);
}

/* color: var(--ddga-color-success) */
.harf-adm-det__download,
.harf-adm-det__retry,
.harf-adm-det__sum-link {
  --harf-a-color: var(--ddga-color-success);
}

/* color: var(--ddga-color-background) */
.harf-submit__btn--dark,
.harf-submit__template-btn {
  --harf-a-color: var(--ddga-color-background);
}

/* color: var(--ddga-color-card-foreground) */
.harf-choice__card {
  --harf-a-color: var(--ddga-color-card-foreground);
}

/* color: var(--harf-link) — the card link's own token. */
.harf-card__link {
  --harf-a-color: var(--harf-link);
}

/* color: inherit — these deliberately take their parent's colour.

   ⚠ NOT DONE THROUGH --harf-a-color, and this is not a style choice. On a CUSTOM
   property `inherit` is the CSS-wide keyword: it makes --harf-a-color inherit its
   own parent's value (unset here) rather than carrying the token `inherit`
   through to `color`. var() then falls back and the element hovers to the LINK
   colour. MEASURED before this correction: .harf-adm-det__crumb went
   rgb(27,131,84) -> rgb(84,192,138) on hover instead of staying with its parent.
   So these four state `color: inherit` directly, anchor-qualified to (0,2,1) and
   placed after the generic hover rule to win the tie. */
a.harf-adm-asg__crumb:hover,
a.harf-adm-asg__crumb.hover,
a.harf-adm-det__crumb:hover,
a.harf-adm-det__crumb.hover,
a.harf-adm-topbar__user:hover,
a.harf-adm-topbar__user.hover,
a.harf-pt-tabbar__user:hover,
a.harf-pt-tabbar__user.hover {
  color: inherit;
}

/* color: transparent — the visible mark is the icon; the label is for
   assistive tech only (site-footer/index.css). Restated, not "corrected". */
.harf-footer__social-link {
  --harf-a-color: transparent;
}

/* color: var(--ddga-color-primary). AFTER the text-primary group: the two
   --active modifiers must beat their own base class on source order. */
.harf-adm-drawer__link--active,
.harf-error-state__secondary,
.harf-panel__back,
.harf-pt-drawer__item--active,
.harf-table__link {
  --harf-a-color: var(--ddga-color-primary);
}

/* color: var(--ddga-color-primary-foreground). AFTER the groups above, for the
   same reason — .harf-table__toolbar-action--primary modifies a base listed in
   the text-primary group. This is the button in the original report. */
.harf-cmpdet__edit,
.harf-table__toolbar-action--primary {
  --harf-a-color: var(--ddga-color-primary-foreground);
}

/* ── .ddga-button ──────────────────────────────────────────────────────────
   The base class kills the underline for every variant at once: .ddga-button
   itself declares `text-decoration:none`, which is exactly what Clay was
   overriding.

   ⚠ THE COLOUR STILL HAS TO BE RESTATED HERE, even though section 4 already
   restates it. Section 4's `a.ddga-button.ddga-button--primary` is (0,2,1) and
   so is the hover rule above — a TIE, resolved on source order, and this section
   comes later. MEASURED: with only the decoration set here, a hovered
   a.ddga-button--primary went white -> #54c08a, because --harf-a-color was unset
   and fell through to --harf-link-hover-color. Each mapping below is the same
   var the variant's own rule in _dga-components.scss declares; the two on-color
   pairs follow section 5's deliberate dark-mode divergence, not the vendor. */
.ddga-button {
  --harf-a-decoration: none;
}

.ddga-button--primary {
  --harf-a-color: var(--ddga-color-primary-foreground);
}

.ddga-button--secondary {
  --harf-a-color: var(--ddga-color-secondary-foreground);
}

.ddga-button--outline,
.ddga-button--ghost {
  --harf-a-color: var(--ddga-color-foreground);
}

.ddga-button--black {
  --harf-a-color: var(--harf-on-fixed-surface);
}

.ddga-button--destructive {
  --harf-a-color: var(--ddga-color-destructive-foreground);
}

.ddga-button--destructive-outline,
.ddga-button--destructive-subtle,
.ddga-button--destructive-ghost {
  --harf-a-color: var(--ddga-color-destructive);
}

/* On-colour variants sit on a fixed surface by definition — section 3. These
   are (0,2,0) and so already outrank the single-class variants above. */
.ddga-button--on-color.ddga-button--outline,
.ddga-button--on-color.ddga-button--ghost,
.ddga-button--on-color.ddga-button--secondary {
  --harf-a-color: var(--harf-on-fixed-surface);
}

/* Section 5's correction, not the vendor's #f3f4f6-on-#fff. */
.ddga-button--on-color.ddga-button--primary,
.ddga-button--on-color.ddga-button--black {
  --harf-a-color: var(--ddga-gray-950);
}

.ddga-button--on-color.ddga-button--destructive-outline,
.ddga-button--on-color.ddga-button--destructive-ghost {
  --harf-a-color: var(--ddga-error-200);
}

/* Disabled wins over every variant in _dga-components.scss; mirror that here so
   a disabled anchor-button does not brighten on hover. */
.ddga-button[aria-disabled=true] {
  --harf-a-color: var(--ddga-gray-400);
}

/* Genuine links inside content that SHOULD keep the hover underline. They carry
   a class, so the `none` default would otherwise remove an affordance they had.
   DGA link.css: .ddga-link--inline { text-decoration: underline }.

   The four .harf-adm-det__* / .harf-cmpdet__* entries are here for a different
   reason than the first three: MEASURED, they declare NO :hover rule anywhere,
   so the only hover feedback they ever had was Clay's underline arriving with
   the blue. Removing the blue without this would leave them with none at all.
   They are text links, not buttons, so they take DGA's standalone-link
   affordance (.ddga-link--standalone:hover { text-decoration: underline })
   rather than a button's background shift — and their colour, which is
   deliberate (success green on the download/retry actions), does not move. */
.ddga-link,
.harf-card__link,
.harf-table__link,
.harf-adm-det__download,
.harf-adm-det__retry,
.harf-adm-det__sum-link,
.harf-cmpdet__crumb-link {
  --harf-a-decoration: underline;
}

/* ═══════════════════════════════════════════════════════════════════════════
   5. CORRECTING A DARK-MODE DEFECT IN @dev-dga/css v0.12.0 ITSELF
   ═══════════════════════════════════════════════════════════════════════════

   This is the one place the theme deliberately DIVERGES from the vendor. The
   shipped rule (dist/components/button.css, ported verbatim into
   _dga-components.scss) is:

       .ddga-button--on-color.ddga-button--black,
       .ddga-button--on-color.ddga-button--primary
           { color:var(--ddga-color-foreground); background-color:#fff; … }

   Both facts are read straight from the shipped CSS, not inferred:
     · the background is a LITERAL #fff, so it is fixed-surface and cannot change;
     · --ddga-color-foreground IS in dark.css's override list, re-pointing from
       var(--ddga-gray-950) to var(--ddga-gray-100).

   So in dark mode the vendor pairs #f3f4f6 text with a #fff background — a
   contrast ratio of about 1.06:1. It is category (b) conflated with category (a)
   inside the library itself.

   The correction pins the foreground to the same primitive the light theme already
   resolves to. --ddga-gray-950 is a PRIMITIVE, absent from dark.css's 42 overrides,
   so it is fixed by construction. Light mode is therefore byte-identical to before
   (--ddga-color-foreground already resolved to var(--ddga-gray-950)); only dark
   mode changes, and only to stop the text disappearing.

   Not fixed in tools/dga-port/port-components.mjs on purpose: that generator's job
   is to reproduce the vendor faithfully, and a silent divergence buried in
   generated output is exactly the kind of drift this project guards against. It
   belongs here, in the theme's own layer, where it is visible and attributable.
   Re-check this on the next @dev-dga/css upgrade. */
a.ddga-button.ddga-button--on-color.ddga-button--primary,
a.ddga-button.ddga-button--on-color.ddga-button--black,
button.ddga-button.ddga-button--on-color.ddga-button--primary,
button.ddga-button.ddga-button--on-color.ddga-button--black {
  color: var(--ddga-gray-950);
}

/* ═══════════════════════════════════════════════════════════════════════════
   6. THE OOTB DATE PICKER POPOVER — constraining what Liferay emits
   ═══════════════════════════════════════════════════════════════════════════

   The birthday field on /register-participant is OOTB CreateAccountPortlet
   output (<liferay-ui:input-date> -> .lfr-input-date). The INPUT is fine; the
   problem is the calendar, which YUI builds LAZILY ON FOCUS and appends to
   <body> — 187 nodes appear the moment the field is focused, which is why a
   probe that only clicked without focusing saw nothing at all.

   MEASURED, same-origin iframe, Arabic RTL, before this rule:

       viewport 1440 (client 1425)   popover 1815px   overflows right by 405px
       viewport 1024 (client 1009)   popover  983px   97% of the viewport
       viewport  834 (client  819)   popover  734px   90% of the viewport

   At 1440 it ran edge to edge and clipped the weekday header row — سبت was cut
   off entirely and a day number sliced at the right edge.

   CAUSE: .datepicker-popover has `width: auto` with no maximum, and the calendar
   inside is `table.yui3-calendar-grid { width: 100% }` with `table-layout: auto`,
   so the table's INTRINSIC width (seven Arabic weekday names that will not wrap)
   sizes the popover instead of the popover sizing the table.

   FIX, per rule 5: style what Liferay emits — no forked JSP, no replacement
   control. Give the popover a real width and switch the grid to a fixed layout
   so the seven columns divide that width evenly and every header fits.
   `min()` against 100vw keeps it inside the viewport at any width, including
   the narrow ones where the popover is anchored near an edge. */
.datepicker-popover {
  box-sizing: border-box;
  inline-size: min(20rem, 100vw - 2 * var(--ddga-space-4));
  max-inline-size: calc(100vw - 2 * var(--ddga-space-4));
}

.datepicker-popover .datepicker-popover-content {
  box-sizing: border-box;
  max-inline-size: 100%;
  overflow-x: hidden;
}

.datepicker-popover .yui3-calendar-grid {
  inline-size: 100%;
  table-layout: fixed; /* seven equal columns — no header can be clipped */
}

.datepicker-popover .yui3-calendar-grid th,
.datepicker-popover .yui3-calendar-grid td {
  padding-block: var(--ddga-space-1);
  padding-inline: 0;
  text-align: center;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── PAGINATION ARROWS POINT THE WRONG WAY IN RTL (reported 2026-07-23) ──────
   Reported as a GENERAL issue, not a /news issue, so the correction lives here
   in the theme rather than in news-card/index.css — every paginated list on the
   site (Collection Displays, search results, admin tables) emits the same
   markup and had the same defect.

   WHAT IS AND IS NOT BROKEN. Measured on /news, dir="rtl":

       item          glyph         viewport x    verdict
       prevArrow     angle-left    401 (right)   ORDER right, GLYPH wrong
       "1" (active)  —             368
       "2"           —             335
       nextArrow     angle-right   296 (left)    ORDER right, GLYPH wrong

   Liferay already lays the controls out correctly for RTL — previous sits on
   the right, next on the left, and the page numbers run 1, 2 right-to-left. It
   is only the two chevron GLYPHS that are still the LTR pair: "previous" drew
   `<` while sitting at the right-hand end, and "next" drew `>` at the left-hand
   end, so both pointed away from the page they lead to. That is why it reads as
   reversed even though nothing is actually out of order.

   Liferay's RTL pipeline cannot fix this on its own: it flips CSS properties
   (the r2 pass that produces main_rtl.css), and there is no property to flip
   here — the direction is baked into which sprite symbol the <use> references
   (#angle-left / #angle-right). Mirroring the drawn glyph is the fix.

   SCOPED TO PAGINATION ON PURPOSE. A blanket "mirror every angle icon in RTL"
   would also flip carets that are not directional in the reading sense
   (accordion and dropdown chevrons) and the partner-strip arrows, which are our
   own inline SVGs and already correct. Both selector families below target the
   same element with the same value, so a match on both is not cumulative.

   VERIFIED BY LOOKING, not by computing: with this rule the right-hand
   (disabled, page 1) control draws `>` and the left-hand control draws `<`. */
[dir=rtl] .pagination [data-testid=prevArrow] .lexicon-icon,
[dir=rtl] .pagination [data-testid=nextArrow] .lexicon-icon,
[dir=rtl] .pagination .page-item .lexicon-icon-angle-left,
[dir=rtl] .pagination .page-item .lexicon-icon-angle-right,
[dir=rtl] .lfr-pagination-buttons .lexicon-icon-angle-left,
[dir=rtl] .lfr-pagination-buttons .lexicon-icon-angle-right {
  transform: scaleX(-1);
}

/* ── THE RESULTS COUNT AND THE PAGER SAT AT THE SAME END OF THE BAR ─────────
   Third defect in this bar, and the SAME root cause as the chevrons above, so
   it belongs beside them rather than in a fragment.

   Clay pushes the two halves of .pagination-bar apart with a PHYSICAL auto
   margin on the count: `margin-right: auto`. That is correct for LTR — free
   space collects to the right of the count, so the count sits at the left
   (reading start) and the pager is pushed to the right. Under RTL it does the
   exact opposite of what it is for: the free space still collects on the right,
   so the count is pushed LEFT and lands directly against the pager, both bunched
   at the far left of a 1120px bar. Measured:

       margin-right  806.648px (auto, resolved)   margin-left  0px
       bar      161..1281        results  297..474        nav  161..297

   Liferay's RTL pipeline would normally flip that property for us. It cannot
   here: the theme build logs `Unable to generate RTL version for /css/main.scss`
   on every run, so NO main_rtl.css is produced and every physical property Clay
   ships reaches an RTL page unflipped. Worth knowing before writing any other
   direction-sensitive rule in this theme — the flip is not happening.

   LOGICAL PROPERTIES, not a [dir='rtl'] override, because the correct value is
   direction-dependent and `margin-inline-end` already means "margin-left in RTL,
   margin-right in LTR". One rule is then right on the Arabic public site AND in
   the en_US back office (sweep §6c keeps that locale alive), where flipping it
   unconditionally would have broken the layout Clay intended.

   VERIFIED BY LOOKING: «عرض 1 - 9 من 12 نتائج.» now sits at the right-hand end
   and the ‹ 1 2 › controls at the left-hand end, still on one line — results
   1103..1281, pager 161..297, both centred on y 429. */
.pagination-bar .pagination-results {
  margin-inline-end: auto;
  margin-inline-start: 0;
}

/* ── CAROUSEL DOTS WERE A 12px TOUCH TARGET (WCAG 2.2 AA SC 2.5.8) ───────────
   Added 2026-07-23 (performance/accessibility agent).

   MEASURED on /home, not inferred. Lighthouse `target-size` failed with four
   nodes, and the live geometry was:

       .ddga-carousel__dot   getBoundingClientRect()  12 x 12 px
       .ddga-carousel__dots  gap                       8 px
       centre-to-centre                               20 px

   SC 2.5.8 (Target Size, Minimum) is satisfied EITHER by a 24x24 CSS px target
   OR, for an undersized target, by spacing: a 24px-diameter circle centred on
   each target must not intersect another's. 12 + 8 = 20 satisfies neither, so
   the audit was correct and it is a real defect for touch users, not a scoring
   artefact.

   WHY THE FIX IS HERE AND NOT WHERE THE 12px LIVES. The size comes from
   `.ddga-carousel__dots--md .ddga-carousel__dot` in _dga-components.scss, which
   is GENERATED by tools/dga-port/port-components.mjs and must never be
   hand-edited (docs/reference/THEME-BUILD.md) — a regeneration would silently drop the
   change. The hero fragment only re-maps the dot COLOURS for the dark scrim, so
   it is not the right home either. This is an additive theme override, which is
   what _custom.scss is for, and it fixes every carousel on the platform rather
   than one instance of the defect.

   THE VISUAL STAYS A 12px CIRCLE. `background-clip: content-box` paints the
   background only inside the content box (24 - 2*6 padding = 12px, box-sizing
   is border-box portal-wide). CSS Backgrounds 3 §5.3 shrinks the clip's corner
   radii by the padding rather than squaring them off, so `--ddga-radius-full`
   (computed 9999px) still yields a circle — VERIFIED BY LOOKING at the rendered
   hero, not by reading the spec alone.

   WHAT DOES CHANGE, stated rather than glossed: the row grows, because a 24px
   target cannot occupy 20px of space.

       dot rect          12 x 12  ->  24 x 24
       centre-to-centre       20  ->  32
       .ddga-carousel__dots  96 x 36  ->  144 x 48

   That is a deliberate departure from the Figma dot spacing. Golden rule 6 puts
   WCAG above pixel-parity with a frame drawn before the audit, and there is no
   geometry that satisfies 2.5.8 without spreading the dots — overlapping 24px
   targets fail the spacing clause just as 12px ones fail the size clause. If
   design wants the tighter row back, the DGA library owns the dot size and the
   conversation belongs there (README §17.3 rule: DGA is authoritative). */
.ddga-carousel__dots--md .ddga-carousel__dot {
  background-clip: content-box;
  block-size: 24px;
  inline-size: 24px;
  padding: 6px;
}

/* ═══════════════════════════════════════════════════════════════════════════
   TERMS-OF-USE INTERSTITIAL — suppress the language picker.
   Client decision A1a, 2026-07-24.

   The site is ARABIC ONLY by directive (hreflang ar-SA + x-default; "never
   reintroduce an English alternate") and offers no language switching anywhere
   in its own chrome. Liferay's terms-of-use screen nonetheless renders a locale
   dropdown in its sheet-header.

   The substantive fix is `locales.enabled=ar_SA,en_US` in portal-ext.properties,
   which took the picker from THIRTEEN locales to two (measured: Catalan,
   Chinese, Dutch, Finnish, French, German, Hungarian, Japanese, Portuguese,
   Spanish and Swedish are gone). This rule removes the remaining control, so the
   screen offers no language switching at all.

   WHY en_US IS NOT SIMPLY DROPPED from locales.enabled instead: Liferay's back
   office stays English on this project, every layout carries en_US name_i18n /
   friendlyURL_i18n, and HarfLayoutFriendlyURLReconciler matches layouts on the
   en_US name. Removing the locale would break the admin UI and friendly-URL
   reconciliation — trading a working capability for a cosmetic fix.

   SCOPED WITH :has() to the terms interstitial specifically, matched on the form
   that only that screen renders, so no other sheet-header anywhere in the
   platform is affected. Presentation only — the locale itself remains reachable
   at /c/portal/update_language, so nothing is disabled, only unadvertised.
   ═══════════════════════════════════════════════════════════════════════════ */
.sheet:has(form[action="/c/portal/update_terms_of_use"]) .sheet-header .dropdown.lfr-icon-menu {
  display: none;
}

/* ═══════════════════════════════════════════════════════════════════════════
   IN-PAGE ANCHORS MUST LAND CLEAR OF THE STICKY HEADER — added 2026-08-09
   ═══════════════════════════════════════════════════════════════════════════

   MEASURED DEFECT. `.harf-site-header` is `position: sticky; inset-block-start:
   0`, and every in-page nav target had `scroll-margin-top: 0`. Arriving at any
   of them put the heading at viewport top — i.e. UNDERNEATH the header, fully
   hidden. Measured on the deployed page before this rule existed: 91 arrivals
   (7 targets × 3 routes × the widths below) and 91 of them landed the heading
   at top ≈ 0 against a header bottom edge of 73–75. Zero passes.

   The seven targets, all on /home, from site-navigation-menus.json plus a
   repo-wide sweep for `/home#…`:
     #about-title  #about-harf-title  #goals-title  #fields-title
     #prizes-title  #partners-title   #journey-title

   WHY scroll-padding ON THE SCROLLER, NOT scroll-margin ON EACH TARGET.
   `scroll-padding-block-start` is a property of the scroll container, so it
   applies to EVERY scroll-into-view in the document at once — the browser's own
   fragment navigation, `:target`, `scrollIntoView()`, and find-in-page. Seven
   `scroll-margin` rules would have to be kept in step with a list of ids that
   grows whenever somebody adds a section, and the eighth anchor would silently
   arrive broken. This cannot go stale that way.

   THE HEIGHT IS NOT HARDCODED. `--harf-header-h` is published by main.js from
   the header's OWN measured height, re-measured by a ResizeObserver, so a
   restyle carries the offset with it. The literal below is a FIRST-PAINT
   FALLBACK for the few frames before that runs — deliberately the LARGEST
   measured header (75px, the ≤1024 bar; desktop is 73px), because overshooting
   by 2px is invisible while undershooting re-hides the heading, which is the
   whole defect.

   Measured header heights, this build:  ≥1280 → 73px    ≤1024 → 75px

   SCOPED TO PAGES THAT ACTUALLY HAVE THE HEADER. The bare `html` rule resolves
   to `0px`, so admin, login and utility pages — which carry no sticky header —
   get no phantom offset. `:has()` is already relied on elsewhere in this file
   and in site-header/index.css. main.js writes the measured value as an INLINE
   custom property on <html>, which outranks the fallback declared here.
   ═══════════════════════════════════════════════════════════════════════════ */
html {
  scroll-padding-block-start: var(--harf-header-h, 0px);
}

html:has(.harf-site-header) {
  --harf-header-h: 4.6875rem; /* 75px — see FIRST-PAINT FALLBACK above */
}