﻿@import url(vendor/bootstrap.min.css);
@import url(vendor/animate.min.css);
@import url(vendor/all.min.css);
@import url(vendor/icons.min.css);
@import url(vendor/gilroy.css);

/*----------------------------------------------
Root
----------------------------------------------*/

:root {
    --primary-font: "Gilroy", sans-serif;
    --secondary-font: "Poppins", sans-serif;
    --h1-size: 4.5rem;
    --h1-weight: 900;
    --h2-size: 3rem;
    --h2-weight: 700;
    --h3-size: 2rem;
    --h3-weight: 600;
    --h4-size: 1.5rem;
    --h4-weight: 600;
    --h5-size: 1.2rem;
    --h5-weight: 600;
    --h6-size: 1rem;
    --h6-weight: 600;
    --p-size: 1rem;
    --p-weight: 400;
    --header-bg-color: #121324;
    --nav-brand-height: 55px;
    --top-nav-item-color: #F5F5F5;
    --nav-item-color: #121324;
    --primary-color: #0047FF;
    --secondary-color: #57048A;
    --btn-text-color: #fff;
    --white-color: #F9F9F9;
    --black-color: #040402;
    --grey-color: #f3f5f7;
    --dark-grey-color: #191919;
    --primary-t-color: #F5F5F5;
    --secondary-t-color: #F5F5F5;
    --primary-p-color: #9CA0D2;
    --secondary-p-color: #E1E1E1;
    --primary-b-color: #F5F5F5;
    --primary-l-color: rgba(0, 0, 0, .12);
    --secondary-l-color: rgba(255, 255, 255, 0.12);
    --valid-color: #007A4D;
    --invalid-color: #E34F4F;
    --primary-bg-color: #090A1A;
    --primary-bg-color-2: #EEEEEE;
    --primary-bg-color-3: #E5E5E5;
    --secondary-bg-color: #040402;
    --secondary-bg-color-2: #111111;
    --secondary-bg-color-3: #191919;
    --card-bg-color: #16182D;
    --footer-bg-color: #121117;
    --hero-bg-color: #090A1A;
    --scrollbar-thumb-color: rgba(255, 255, 255, 0.18);
    --scrollbar-thumb-hover-color: rgba(255, 255, 255, 0.3);
    --scrollbar-track-color: rgba(255, 255, 255, 0.04);
    --card-border-color: rgba(255, 255, 255, 0.08);
}

:root[data-theme="light"] {
    --primary-color: #0047FF;
    --header-bg-color: #FFFFFF;
    --white-color: #14152B;
    --primary-t-color: #12132A;
    --secondary-t-color: #12132A;
    --primary-p-color: #5A5E82;
    --secondary-p-color: #2A2D42;
    --primary-b-color: #14152B;
    --primary-bg-color: #F5F6FA;
    --hero-bg-color: #F5F6FA;
    --card-bg-color: #FFFFFF;
    --secondary-l-color: rgba(0, 0, 0, 0.12);
    --scrollbar-thumb-color: rgba(0, 0, 0, 0.18);
    --scrollbar-thumb-hover-color: rgba(0, 0, 0, 0.3);
    --scrollbar-track-color: rgba(0, 0, 0, 0.04);
    --card-border-color: rgba(0, 0, 0, 0.08);
}

* {
    scrollbar-width: thin;
    scrollbar-color: var(--scrollbar-thumb-color) var(--scrollbar-track-color);
}

::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}

::-webkit-scrollbar-track {
    background-color: var(--scrollbar-track-color);
}

::-webkit-scrollbar-thumb {
    border-radius: 10px;
    background-color: var(--scrollbar-thumb-color);
    border: 2px solid transparent;
    background-clip: content-box;
}

::-webkit-scrollbar-thumb:hover {
    background-color: var(--scrollbar-thumb-hover-color);
}

::-webkit-scrollbar-corner {
    background-color: transparent;
}

/*----------------------------------------------
Reset
HTML5 display-role reset for older browsers
----------------------------------------------*/

/* #region Reset */

a,
abbr,
acronym,
address,
applet,
article,
aside,
audio,
b,
big,
blockquote,
body,
canvas,
caption,
center,
cite,
code,
dd,
del,
details,
dfn,
div,
dl,
dt,
em,
embed,
fieldset,
figcaption,
figure,
footer,
form,
h1,
h2,
h3,
h4,
h5,
h6,
header,
hgroup,
html,
i,
iframe,
img,
ins,
kbd,
label,
legend,
li,
mark,
menu,
nav,
object,
ol,
output,
p,
pre,
q,
ruby,
s,
samp,
section,
small,
span,
strike,
strong,
sub,
summary,
sup,
table,
tbody,
td,
tfoot,
th,
thead,
time,
tr,
tt,
u,
ul,
var,
video {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    vertical-align: baseline;
}

article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
    display: block;
}

body {
    font-family: var(--secondary-font);
    color: var(--primary-p-color);
    background-color: var(--primary-bg-color);
}

body.odd {
    background-color: var(--secondary-bg-color);
}

body:not(.page-template) .odd:not(.comment) {
    color: #8E8E8E;
}

body.page-template .odd {
    color: var(--white-color);
}

ol,
ul {
    padding-left: 20px;
}

ol {
    list-style: decimal;
}

ul {
    list-style: disc;
}

ul ul {
    list-style: circle;
}

pre,
code {
    display: block;
    margin: 1rem 0;
    color: var(--primary-color);
}

blockquote,
q {
    display: block;
    margin: 1rem 0;
    quotes: none;
    quotes: none;
    font-style: italic;
    padding: 1rem 1.5rem;
    border-left: 5px solid var(--primary-bg-color-3);
}

.odd blockquote,
q {
    border-left: 5px solid var(--secondary-bg-color-3);
}

blockquote:before,
blockquote:after,
q:before,
q:after {
    content: "";
    content: none;
}

blockquote p,
q p {
    margin: 0;
}

figure {
    margin-bottom: 1.5rem;
}

figcaption {
    margin-bottom: 1.5rem;
    font-style: italic;
    padding: 1rem 1.5rem;
    border-left: 5px solid var(--primary-bg-color-3);
}

.odd figcaption {
    border-left: 5px solid var(--secondary-bg-color-3);
}

table {
    border-collapse: collapse;
    border-spacing: 0;
}

/* #endregion Reset */

/*----------------------------------------------
General
----------------------------------------------*/

/* #region General */

::-moz-selection {
    background: rgba(166, 175, 189, 0.3);
}

::selection {
    background: rgba(166, 175, 189, 0.3);
}

::-moz-selection {
    background: rgba(166, 175, 189, 0.3);
}

*,
*:after,
*:before {
    box-sizing: border-box;
}

a:not(.btn),
a:link:not(.btn),
a:visited:not(.btn),
a:hover:not(.btn),
a:active:not(.btn) {
    font-size: 1rem;
    font-weight: 400;
    line-height: 1.5;
    color: var(--primary-color);
    text-decoration: none;
    transition: all 0.4s ease-out 0s;
}

a:not([href]),
a:not([href]):hover,
a:not([href]) i,
a:not([href]) i:hover {
    color: var(--primary-b-color);
}

p {
    margin: 1.5rem 0;
    font-size: var(--p-size);
    font-weight: var(--p-weight);
    line-height: 1.5;
    -ms-word-wrap: break-word;
    word-wrap: break-word;
}

p:first-child {
    margin-top: 0;
}

p:last-child {
    margin-bottom: 0;
}

.odd:not(.comment) p {
    color: var(--white-color);
}

.page-template .odd p {
    opacity: 0.7;
}

.swiper-wrapper.odd p {
    opacity: 0.8;
}

h1 {
    margin-bottom: 1.5rem;
    font-size: var(--h1-size);
    font-weight: var(--h1-weight);
    line-height: 1.2;
    font-family: var(--primary-font);
    color: var(--primary-color);
    -ms-word-wrap: break-word;
    word-wrap: break-word;
}

h1 em {
    display: block;
    font-size: var(--h2-size);
    font-weight: 300;
}

h2 {
    margin: 1.5rem 0;
    font-size: var(--h2-size);
    font-weight: var(--h2-weight);
    line-height: 1.2;
    font-family: var(--primary-font);
    color: var(--primary-t-color);
    -ms-word-wrap: break-word;
    word-wrap: break-word;
}

.odd h2 {
    color: var(--white-color);
}

h3 {
    margin: 1.5rem 0;
    font-size: 2rem;
    font-weight: 700;
    line-height: 1.2;
    font-family: var(--primary-font);
    color: var(--primary-t-color);
    -ms-word-wrap: break-word;
    word-wrap: break-word;
}

h4 {
    margin: 1.5rem 0;
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1.2;
    font-family: var(--primary-font);
    color: var(--primary-t-color);
    -ms-word-wrap: break-word;
    word-wrap: break-word;
}

.odd h4 {
    color: var(--secondary-t-color);
}

h5 {
    margin: 1.5rem 0;
    font-size: 1.2rem;
    font-weight: 600;
    line-height: 1.2;
    font-family: var(--primary-font);
    color: var(--primary-t-color);
    -ms-word-wrap: break-word;
    word-wrap: break-word;
}

h6 {
    margin: 1.5rem 0;
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.2;
    font-family: var(--primary-font);
    color: var(--primary-t-color);
    -ms-word-wrap: break-word;
    word-wrap: break-word;
}

b,
strong {
    font-weight: 700;
}

li {
    margin: 0.5rem 0;
    font-size: 1rem;
    font-weight: 400;
    line-height: 1.5;
    color: var(--primary-p-color);
}

img {
    max-width: 100%;
    height: auto;
    vertical-align: middle;
}

::placeholder {
    color: var(--primary-p-color) !important;
}

table {
    border-collapse: separate;
    border-spacing: 10px;
}

table td {
    padding: 10px 0;
}

table th {
    padding: 10px 0;
}

dt {
    margin: 15px 0;
}

address {
    margin-bottom: 1rem;
}

form {
    width: 100%;
}

input,
textarea,
select {
    width: 100%;
    height: 50px;
    background: no-repeat;
    box-shadow: none;
    padding: 0.7rem 1rem;
    border-color: var(--primary-l-color);
    border-width: 2px;
    border-radius: 2px;
}

input:focus,
textarea:focus,
select:focus {
    color: inherit;
    outline: none;
    border-color: inherit;
    box-shadow: none;
}

input {
    border-color: var(--primary-p-color);
    color: var(--primary-p-color);
}

input:focus {
    border-color: var(--primary-t-color);
    color: var(--primary-t-color);
}

input[type=checkbox] {
    height: 20px;
    width: 20px;
}

input[type=radio] {
    height: initial;
}

input[type=submit] {
    border: 1px solid;
    padding: 2.5px 10px;
    display: block;
    width: fit-content;
    max-width: 200px;
    text-align: center;
    color: var(--primary-color);
}

input[type=submit]:hover {
    background-color: var(--primary-color);
    color: var(--primary-b-color);
    border-color: var(--primary-color);
}

textarea {
    height: 100px;
    resize: none;
    border-color: var(--primary-p-color);
    color: var(--primary-t-color);
}

textarea:focus {
    border-color: var(--primary-t-color);
    color: var(--primary-t-color);
}

select {
    appearance: none;
    text-indent: 1px;
    text-overflow: "";
    line-height: 1.2;
    border-color: var(--primary-l-color);
    color: var(--primary-t-color);
}

select option {
    color: #2f323a;
}

select:focus {
    border-color: var(--primary-t-color);
    color: var(--primary-t-color);
}

hr {
    margin: 35px 0;
    border-top: 1px dashed var(--primary-l-color);
}

.odd hr {
    margin: 35px 15px;
    border-top: 1px dashed var(--secondary-l-color);
}

table {
    width: 100%;
}

tr:not(:last-child) {
    border-bottom: 1px solid;
    border-color: var(--primary-l-color);
}

.odd tr:not(:last-child) {
    border-bottom: 1px solid;
    border-color: var(--secondary-l-color);
}

td {
    padding: 10px 0;
}

/* #endregion General */

/*----------------------------------------------
Section
----------------------------------------------*/

/* #region Section */

section {
    width: 100%;
    padding: 130px 0;
    background-size: cover;
    background-attachment: fixed;
    background-position: center;
}

section.no-hero {
    padding: 150px 0 130px;
}

section#slider:not(.bg-inherit) {
    background-color: var(--hero-bg-color);
}

main {
    padding: 0;
}

aside {
    padding: 0;
}

.container {
    padding: 0;
    max-width: 1170px;
}

.container.header {
    max-width: 1140px;
    flex-wrap: nowrap;
}

.container.full {
    max-width: 100%;
}

.container.full-grid {
    padding: 0;
    max-width: calc(100% - 30px);
    margin: 0 15px;
}

.container.smaller {
    max-width: 970px;
}

.row {
    margin-left: 0;
    margin-right: 0;
}

.vh-100 {
    height: 100vh;
}

.vh-75 {
    height: 75vh;
}

.clearfix {
    display: block;
    content: "";
    clear: both;
}

/* #endregion Section */

/*----------------------------------------------
6. Helper Class
----------------------------------------------*/

/* #region Helper Class */

.gameon-preloader {
    position: fixed;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: default;
    z-index: 99999;
}

.gameon-preloader .preloader-animation {
    z-index: 1000;
}

.gameon-preloader .preloader-animation .loading-bar {
    position: relative;
    width: 240px;
    max-width: 50vw;
    height: 4px;
    margin: 0 auto 3.5em auto;
    background-color: var(--card-bg-color);
    border-radius: 4px;
    overflow: hidden;
}

.gameon-preloader .preloader-animation .loading-bar span {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 40%;
    background-color: var(--primary-color);
    border-radius: 4px;
    animation: loading-bar-slide 1.2s ease-in-out infinite alternate;
}

.gameon-preloader .preloader-animation p {
    letter-spacing: 8px;
}

.gameon-preloader .loader-animation {
    position: fixed;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
    z-index: 1;
    pointer-events: none;
}

.gameon-preloader .loader-animation .single-loader .loader-bg {
    height: 100%;
    width: 100%;
    left: 0;
    background-color: var(--primary-bg-color);
    transition: all 800ms cubic-bezier(0.77, 0, 0.175, 1);
}

.gameon-preloader.loaded {
    visibility: hidden;
}

.gameon-preloader.loaded .preloader-animation {
    opacity: 0;
    visibility: hidden;
    transition: 0.3s ease-out;
}

.gameon-preloader.loaded .single-loader .loader-bg {
    width: 0;
    transition: 0.7s all cubic-bezier(0.1, 0.1, 0.1, 1);
}

@keyframes loading-bar-slide {
    0% {
        transform: translateX(0%);
    }
    100% {
        transform: translateX(150%);
    }
}

@keyframes animated-letters {
    0%,
    75%,
    100% {
        opacity: 0;
        transform: rotateY(-90deg);
    }
    25%,
    50% {
        opacity: 1;
        transform: rotateY(0deg);
    }
}

.avatar-sm {
    height: 3rem;
    width: 3rem;
}

.avatar-md {
    height: 4rem;
    width: 4rem;
}

.avatar-lg {
    height: 5rem;
    width: 5rem;
}

.avatar-max-lg {
    height: 6rem;
    width: 6rem;
}

.media {
    display: flex;
    align-items: flex-start;
}

.intro {
    margin-bottom: 60px;
}

.intro .intro-text {
    position: relative;
    display: inline-block;
    font-weight: 600;
    color: var(--primary-color);
    text-transform: uppercase;
    letter-spacing: 3px;
}

.intro .intro-text::after {
    position: absolute;
    content: "";
    height: 3px;
    width: 45px;
    background-color: var(--primary-color);
    top: 50%;
    left: calc(100% + 20px);
    transform: translateY(-50%);
}

.intro h1:first-child,
.intro h2:first-child,
.intro h3:first-child {
    margin-top: 0;
}

.intro.text-center span::after {
    content: none;
}

.list-group-item {
    margin: 0;
    background: none;
    font-size: 1rem;
    padding-right: 0;
    padding-left: 0;
    background-color: transparent;
    border-color: var(--card-bg-color);
}

.list-group-item a {
    transition: 0.3s;
}

.list-group-item .badge.circle {
    height: 35px;
    width: 35px;
    background-color: var(--card-bg-color);
}

.post-holder {
    list-style: none;
    width: 100%;
    border-left: 5px solid var(--primary-color);
    background-color: var(--card-bg-color);
    padding: 25px;
    margin-top: 35px;
}

.posted-on a:not(.btn) {
    font-weight: 600;
}

.sidebar .item {
    margin-top: 45px;
}

.sidebar ol {
    list-style: none;
    padding: 0;
}

.sidebar ol ol {
    padding: 15px;
}

.sidebar ul {
    list-style: none;
    padding: 0;
}

.sidebar ul.children {
    padding: 0;
}

.sidebar ul li:not(.nav-item):not(.list-group-item) {
    position: relative;
    padding-left: 0;
}

.sidebar ul li a:not(.btn) {
    color: var(--primary-p-color);
    overflow-wrap: break-word;
}

.sidebar ul li a:not(.btn):hover {
    color: var(--primary-color);
}

.sidebar ul ul {
    padding: 15px;
}

.sidebar ul ul li:not(.nav-item):not(.list-group-item):not(.cat-item) {
    padding-left: 20px;
}

.sidebar li:hover::before {
    background-color: var(--primary-color);
}

.sidebar .sub-menu {
    padding: 0;
}

.sidebar .title {
    width: 100%;
    margin-top: 0;
    list-style: none;
}

.list-group .list-group-item .icon {
    color: var(--primary-color);
    margin-right: 15px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.post-details .blog-thumb img {
    border-radius: 4px;
}

.post-details blockquote {
    margin: 1rem 2rem;
    padding: 2rem 1.5rem;
    border-left: 5px solid var(--primary-color);
    font-size: 1.2rem;
    color: var(--primary-color);
    background-color: var(--card-bg-color);
}

.post-details .sidebar .title {
    position: relative;
    font-weight: 700;
}

.post-details .sidebar .title::before {
    position: absolute;
    content: "";
    height: 3px;
    width: 50px;
    background-color: var(--primary-color);
    left: 3px;
    top: calc(100% + 10px);
}

.btn {
    position: relative;
    font-size: 1rem;
    font-weight: 700;
    color: var(--btn-text-color);
    line-height: 1;
    text-align: center;
    padding: 16px 34px;
    border: 0 none;
    border-radius: 100px;
    outline: 0 none;
    cursor: pointer;
    z-index: 1;
}

.btn:hover,
.btn:focus,
.btn:active {
    color: var(--btn-text-color);
    box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
}

.btn.btn-bordered {
    background: transparent none repeat scroll 0 0;
    color: #444;
}

.btn.btn-bordered::before {
    position: absolute;
    content: "";
    height: calc(100% + 4px);
    width: calc(100% + 4px);
    background-image: linear-gradient(135deg, var(--primary-color) 10%, var(--secondary-color));
    top: -2px;
    left: -2px;
    border-radius: 100px;
    transition: all 0.3s ease 0s;
    z-index: -2;
}

.btn.btn-bordered:after {
    position: absolute;
    content: "";
    height: 100%;
    width: 100%;
    top: 0;
    left: 0;
    border-radius: 100px;
    background: #fff none repeat scroll 0 0;
    transition: all 0.3s ease 0s;
    z-index: -1;
}

.btn.btn-bordered:hover,
.btn.btn-bordered:focus,
.btn.btn-bordered.active {
    color: var(--btn-text-color);
}

.btn.btn-bordered:hover::after,
.btn.btn-bordered:focus::after,
.btn.btn-bordered.active::after {
    opacity: 0;
}

/* ── The secondary button: a gradient outline with nothing inside ───────────
   Plain `.btn-bordered` above fills its middle with a hard-coded white layer,
   drawn for the light pages the theme shipped with. On our dark cards it read
   as a white pill that looked like a bug. This keeps the gradient ring and
   leaves the middle genuinely empty, so whatever the button sits on — a card
   header, a dialog footer — shows through, in either theme.
   The ring is the theme's own gradient layer with its centre masked out (the
   2px of padding is what survives as the border). The top layer, white in the
   base class, becomes the gradient fill and fades in on hover, keeping the
   base class's transition. */
.btn.btn-bordered.is-outline {
    color: var(--white-color);
}

.btn.btn-bordered.is-outline::before {
    box-sizing: border-box;
    padding: 2px;
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
}

.btn.btn-bordered.is-outline::after {
    background: linear-gradient(135deg, var(--primary-color) 10%, var(--secondary-color));
    opacity: 0;
}

.btn.btn-bordered.is-outline:hover,
.btn.btn-bordered.is-outline:focus-visible {
    color: var(--btn-text-color);
}

.btn.btn-bordered.is-outline:hover::after,
.btn.btn-bordered.is-outline:focus-visible::after {
    opacity: 1;
}

/* Plain :focus filled the base button too, which on a button that stays
   focused after a click — "Indietro" in the wizard — left it looking pressed
   on the step it had just led to. Only keyboard focus fills this one. */
.btn.btn-bordered.is-outline:focus:not(:focus-visible):not(:hover) {
    color: var(--white-color);
}

/* Same solid blue-purple gradient + white text as .btn-bordered.active
   (above), rather than this family's old transparent/outline treatment —
   every button reads as one consistent brand style now, in both themes,
   since --primary-color/--secondary-color/--btn-text-color don't change
   between them. */
.btn.btn-bordered-white {
    background-image: linear-gradient(135deg, var(--primary-color) 10%, var(--secondary-color));
    border: none;
    color: var(--btn-text-color);
}

.btn.btn-bordered-white:hover,
.btn.btn-bordered-white:focus {
    color: var(--btn-text-color);
    filter: brightness(1.1);
}

.btn.btn-bordered-white:hover::after,
.btn.btn-bordered-white:focus::after {
    opacity: 1;
}

.btn.content-btn {
    padding: 0;
    font-weight: 600;
    color: var(--primary-t-color);
    text-align: left;
    line-height: 1.2;
    background: transparent;
    box-shadow: none;
    padding-right: 15px;
}

.btn.content-btn::before {
    position: absolute;
    content: "\f061";
    font-family: "Font Awesome 6 Free";
    font-weight: 900;
    top: 50%;
    right: 0;
    transform: translateY(-50%);
    opacity: 0;
    transition: all 0.2s cubic-bezier(0.25, 0.25, 0.75, 0.75);
}

.btn.content-btn::after {
    position: absolute;
    content: "\f061";
    font-family: "Font Awesome 6 Free";
    font-weight: 900;
    top: 50%;
    right: -10px;
    transform: translateY(-50%);
    opacity: 1;
    transition: all 0.2s cubic-bezier(0.25, 0.25, 0.75, 0.75);
}

.btn.content-btn:hover {
    color: var(--primary-color);
}

.btn.content-btn:hover::before {
    right: -10px;
    opacity: 1;
}

.btn.content-btn:hover::after {
    right: -20px;
    opacity: 0;
}

.btn-smaller {
    font-size: 0.9rem;
    padding: 12px 18px;
}

.button-group {
    margin-top: 30px;
}

.button-group a {
    margin-right: 10px;
}

.button-group a:last-child {
    margin-right: 0;
}

/* Same art as the hero, framed on its top edge (`top center`) so this shorter
   band shows the sky and moon rather than the conveyor belt the hero leads
   with — the two banners read as the same world without repeating the same
   crop.
   The light/dark switch is already handled for free here: the veil is
   `.overlay-dark::after`, whose colour is var(--primary-bg-color), so it
   darkens in dark mode and lightens in light mode on its own. Only the
   artwork itself needs a light counterpart. */
.breadcrumb-area {
    background: rgba(0, 0, 0, 0) url("../img/bg/hero_bg.jpg") no-repeat scroll top center/cover;
}

[data-theme="light"] .breadcrumb-area {
    background-image: url("../img/bg/hero_bg-white.jpg");
}

.breadcrumb-area.bg-overlay::after {
    opacity: 0.89;
}

/* #endregion Helper Class */

/*----------------------------------------------
7. Header
----------------------------------------------*/

/* #region Header */

header {
    position: relative;
    z-index: 5;
}

header .navbar-expand {
    position: fixed;
    top: 0;
    z-index: 2;
    width: 100%;
    padding: 20px 25px;
}

header .navbar-expand .navbar-brand {
    padding: 0;
    font-size: 1.5rem;
    font-weight: 600;
    line-height: 0;
    color: var(--nav-item-color);
}

header .navbar-expand .navbar-brand i {
    font-size: 1.8rem;
    font-weight: bold;
    font-style: initial;
    color: var(--primary-color);
}

header .navbar-expand .navbar-brand img {
    height: var(--nav-brand-height);
}

/* The logo asset is a white mark on transparent, with no dark variant
   shipped — invert it in light mode rather than adding a second file. */
[data-theme="light"] header .navbar-expand .navbar-brand img {
    filter: invert(1);
}

header .navbar-expand .navbar-nav.toggle {
    display: none;
}

header .navbar-expand .navbar-nav.toggle i {
    font-size: 20px;
}

header .navbar-expand .navbar-nav .nav-item {
    margin: 0;
}

header .navbar-expand .navbar-nav .nav-item a:not(.btn) {
    display: flex;
    align-items: center;
    padding-right: 1rem;
    padding-left: 1rem;
    font-weight: 600;
    color: var(--white-color);
}

header .navbar-expand .navbar-nav .nav-item .nav-link:not(.btn):not(.title):hover,
header .navbar-expand .navbar-nav .nav-item .nav-link.active:not(.btn):not(.title) {
    color: var(--primary-color);
}

header .navbar-expand .navbar-nav .dropdown .dropdown-menu {
    display: block;
    width: max-content;
    min-width: 14.375rem;
    padding: 0.625rem 0;
    border: none;
    border-radius: 0.75rem;
    background-color: var(--card-bg-color);
    box-shadow: 0 20px 40px rgba(0, 0, 0, 0.35);
    visibility: hidden;
    opacity: 0;
    transform: translateY(20px);
}

header .navbar-expand .navbar-nav .dropdown .dropdown-menu .nav-link:not(.btn) {
    justify-content: space-between;
    padding: 0.625rem 1.25rem;
    color: var(--white-color);
}

header .navbar-expand .navbar-nav .dropdown .dropdown-menu .nav-link.active:not(.btn):not(.title) {
    background-color: rgba(0, 71, 255, 0.12);
    color: var(--primary-color);
}

header .navbar-expand .navbar-nav .dropdown .dropdown-menu .nav-link.title {
    font-weight: 600;
    color: var(--primary-t-color);
    opacity: 0.8;
}

header .navbar-expand .navbar-nav .dropdown .dropdown-menu .nav-link:not(.btn):not(.title):hover {
    background-color: rgba(0, 71, 255, 0.12);
    color: var(--primary-color);
}

header .navbar-expand .navbar-nav .dropdown .dropdown-menu .dropdown-menu {
    top: -8px;
    left: 100%;
}

header .navbar-expand .navbar-nav .dropdown i.icon-arrow-down {
    position: relative;
    top: 1.5px;
    margin: 0 0 0 0.3rem;
    font-size: 12px;
    font-weight: 600;
}

header .navbar-expand .navbar-nav .dropdown i.icon-arrow-right {
    position: relative;
    top: 0;
    left: 5px;
    margin: 0 0 0 0.3rem;
    font-size: 10px;
    font-weight: 600;
}

header .navbar-expand .navbar-nav .dropdown:hover>.dropdown-menu {
    visibility: unset;
    opacity: 1;
    margin: 0;
    transform: translateY(0px);
    transition: opacity 0.4s ease, transform 0.4s ease;
}

header .navbar-expand .icons i {
    font-weight: 400;
}

header .navbar-expand .navbar-nav.icons {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
}

.locale-switcher .nav-link {
    padding-left: 0.75rem;
    padding-right: 0.75rem;
}

.locale-code {
    font-size: 0.9rem;
    font-weight: 700;
    letter-spacing: 0.5px;
}

.locale-switcher .dropdown-menu .nav-link {
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
}

/* Frontend/account nav variant: a plain <button> standing in for the <a> the
   other icons here use, so it needs its own reset (Bootstrap's .nav-link
   assumes a link, not a button element). The console/staff variant instead
   gets its sizing from .console-rail-toggle, applied alongside this class. */
.theme-toggle {
    background: none;
    border: none;
    cursor: pointer;
    font: inherit;
    font-size: 1.05rem;
}

.theme-toggle svg {
    display: block;
}

.theme-toggle.nav-link {
    display: flex;
    align-items: center;
    padding-left: 0.75rem;
    padding-right: 0.75rem;
    color: var(--primary-p-color);
}

.theme-toggle.nav-link:hover {
    color: var(--white-color);
}

/* Only one of the two icons is ever visible: which one is decided purely by
   the <html data-theme> attribute the root layout's inline script sets
   before hydration, never by React state, so there is nothing to
   rehydrate/mismatch and the same component works unmodified everywhere. */
:root:not([data-theme="light"]) .theme-toggle .theme-icon-light {
    display: none;
}

:root[data-theme="light"] .theme-toggle .theme-icon-dark {
    display: none;
}

header .navbar-sticky {
    background-color: var(--header-bg-color);
    animation: 500ms ease-in-out 0s normal none 1 running fadeInDown;
}

.menu .items {
    margin-left: -5px;
    width: calc(100% + 10px);
}

.menu .navbar-nav {
    font-size: 1.5rem;
    font-weight: 400;
    line-height: 1;
}

.menu .navbar-nav .nav-item {
    margin: 0;
}

.menu .navbar-nav .nav-item .nav-link:not(.btn) {
    width: calc(100% - 12px);
    padding: 10px 5px;
    margin: 0 5px;
}

.menu .navbar-nav .nav-item .nav-link:not(.btn):hover {
    color: var(--primary-color);
}

.menu .navbar-nav .nav-item .nav-link:first-child {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding-left: 0;
    padding-right: 0;
    border: none;
    font-size: 1.5rem;
    font-weight: 600;
    color: var(--primary-t-color);
}

.menu .navbar-nav .dropdown .dropdown-menu {
    display: none;
    width: 100%;
    padding: 0 0 0 20px;
    margin: 0 0 10px;
    background: none;
    visibility: visible;
    opacity: 1;
}

.menu .navbar-nav .dropdown .dropdown-menu.show {
    display: block;
}

.menu .navbar-nav .dropdown .dropdown-menu .nav-link {
    padding: 0.5rem 0;
    margin: 5px;
    font-size: 1rem;
    color: var(--primary-p-color);
    text-align: left;
}

.menu .navbar-nav .dropdown .dropdown-menu .nav-link:hover {
    color: var(--primary-color);
}

.menu .navbar-nav .dropdown .dropdown-menu .nav-link.title {
    font-weight: 600;
    color: var(--primary-t-color);
    border: none;
    opacity: 0.8;
}

.menu .navbar-nav .dropdown .dropdown-menu .dropdown-menu {
    position: relative;
    top: initial;
    left: initial;
}

.menu .navbar-nav .dropdown .dropdown-menu .left,
.menu .navbar-nav .dropdown .dropdown-menu .right {
    width: 50%;
}

.menu .navbar-nav .dropdown:first-child {
    margin-top: 0;
}

.menu .navbar-nav i.icon-arrow-down {
    font-size: 18px;
}

/* #endregion Header */

/*----------------------------------------------
8. Feature
----------------------------------------------*/

/* #region Feature */

.icon {
    width: 44px;
    height: 44px;
    line-height: 44px;
    text-align: center;
    font-size: 44px;
    display: block;
    margin: auto;
}

.icon.smaller {
    width: 24px;
    height: 24px;
    line-height: 24px;
    font-size: 24px;
}

.icon.bigger {
    width: 7rem;
    height: 7rem;
    margin: 0;
    font-size: 6.5rem;
    line-height: 7rem;
    font-weight: bold;
}

.icon.circle {
    border-radius: 100px;
    font-size: 28px;
}

.icons {
    display: inline-block;
    font-size: 4rem;
    line-height: 1;
}

.items .item {
    margin-top: 30px;
}

.clip-text,
.text-effect,
.share-list .nav-link i {
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}

.bg-text,
.blog .pagination>li.active>a,
.btn,
.text-effect,
.share-list .nav-link i,
.blog-details .pagination>li.active>a {
    background-image: linear-gradient(150deg, var(--secondary-color) 0%, var(--primary-color) 78%);
}

.swiper-container-horizontal>.swiper-pagination-bullets,
.swiper-pagination-custom,
.swiper-pagination-fraction {
    margin-top: 50px;
    position: relative;
}

.swiper-pagination-bullet {
    width: 40px !important;
    height: 5px !important;
    border-radius: 0 !important;
    background-color: var(--primary-p-color);
    border: none !important;
    opacity: 0.25 !important;
}

.swiper-pagination-bullet-active {
    background-color: var(--primary-color);
    opacity: 1 !important;
}

.card-columns {
    margin: 0 15px;
    column-gap: 30px;
}

.card-columns .card {
    margin-bottom: 30px;
}

.card {
    padding: 1.5rem;
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 8px;
    background-color: var(--card-bg-color);
    box-shadow: 0 12px 30px rgba(0, 0, 0, 0.35);
    transition-timing-function: cubic-bezier(0.25, 0.25, 0.75, 0.75);
    transition-duration: 0.3s;
    transition-property: opacity, transform;
}

[data-theme="light"] .card {
    border-color: rgba(20, 21, 43, 0.12);
    box-shadow: 0 12px 30px rgba(20, 21, 43, 0.12);
}

.card .card-img-top {
    border-radius: 6px;
}

.card .card-body {
    flex: 1 1 auto;
    min-height: 1px;
    padding: 35px 0 0;
}

.card .card-body h3,
.card .card-body h4,
.card .card-body h5,
.card .card-body h6 {
    margin-top: 0;
}

.card .card-body .card-bottom span {
    color: var(--white-color);
}

.card .card-footer {
    border-radius: 0;
    background: none;
    padding: 30px 0;
    margin: 0 30px;
    border-top: 1px solid var(--primary-l-color);
}

.card .card-footer a {
    margin: 0 10px;
}

.card .card-footer a:not(.btn) {
    color: var(--primary-p-color);
}

.card .card-footer .card-footer i {
    margin: 0 5px 2.5px;
}

.card:hover .card-footer {
    color: #f5f5f5;
    border-color: rgba(255, 255, 255, 0.25);
}

.card.no-hover {
    border: none;
    box-shadow: none;
}

.card.no-hover:hover {
    transform: inherit;
    box-shadow: none !important;
}

.card:not(.no-hover):hover {
    transform: translateY(-5px);
}

.card.project-card {
    padding: 2.5rem 2rem;
    border-radius: 2rem;
}

.card.project-card .card-img-top {
    border-radius: 8px;
}

.card.project-card .media-body h4 {
    transition: 0.4s;
}

.card.project-card .media-body a:hover h4 {
    color: var(--primary-color);
}

.card.project-card .single-item {
    display: inline-block;
    margin: 2px 0;
    padding: 0.5rem 0.8rem;
    background: var(--primary-bg-color);
    border-radius: 100px;
    font-size: 12px;
    font-weight: 600;
    color: var(--primary-p-color);
}

.card.project-card .single-item span:last-child {
    color: var(--white-color);
}

.card.project-card .single-item.prev-project {
    margin: 0 0.5rem;
    padding: 0.6rem 1rem;
    font-size: 13px;
}

.card.project-card .single-item.prev-project .single-item {
    margin: 0.25rem 0.5rem;
}

.card.project-card .progress {
    height: 1.8rem;
    background-color: var(--primary-bg-color);
    border-radius: 1rem;
}

.card.project-card .progress .progress-bar {
    background-color: var(--primary-color);
}

.card.project-card .progress-sale span {
    color: var(--white-color);
}

.card.project-card .project-footer .social-share li {
    margin: 0 0.5rem;
}

.card.project-card .project-footer .social-share li a {
    font-size: 1.2rem;
    color: var(--white-color);
}

.card.project-card .blockchain-icon:not(.prev-project) {
    position: absolute;
    top: 2rem;
    right: 2rem;
}

.card.project-card.prev-project-card {
    padding: 2rem;
    background-color: rgba(22, 24, 45, 0.69);
}

[data-theme="light"] .card.project-card.prev-project-card {
    background-color: rgba(255, 255, 255, 0.75);
}

.card.project-card .project-link {
    position: absolute;
    height: 100%;
    width: 100%;
    top: 0;
    left: 0;
    border-radius: inherit;
}

.card.team-card {
    border-radius: 1.5rem;
}

.card.team-card .team-photo {
    position: relative;
    height: 100px;
    width: 100px;
    text-align: center;
    margin: 0 auto;
    border: 3px solid var(--card-bg-color);
    -webkit-box-shadow: inset 0 0 0 2px rgba(22, 24, 45, 0.5);
    box-shadow: inset 0 0 0 2px rgba(22, 24, 45, 0.5);
}

.card.team-card .team-photo::before,
.card.team-card .team-photo::after {
    position: absolute;
    left: 0;
    right: 0;
    margin: auto;
    border-radius: 1rem;
    transition: all 0.3s ease 0s;
}

.card.team-card .team-photo::before {
    content: "";
    top: 0;
    width: 94px;
    height: 94px;
    opacity: 0;
    -webkit-box-shadow: 0 0 0 2px rgba(22, 24, 45, 0.5);
    box-shadow: 0 0 0 2px rgba(22, 24, 45, 0.5);
    -webkit-transform: scale(0.8);
    transform: scale(0.8);
}

.card.team-card .team-photo::after {
    content: "";
    top: 5px;
    width: 84px;
    height: 84px;
    background-color: rgba(22, 24, 45, 0.5);
    -webkit-box-shadow: 0 0 0 0 transparent;
    box-shadow: 0 0 0 0 transparent;
}

.card.team-card .team-photo img {
    border-radius: 1rem;
}

.card.team-card .team-content h4 {
    font-size: 1.3rem;
    transition: 0.4s;
}

.card.team-card .team-content span {
    color: var(--primary-p-color);
}

.card.team-card .team-content .social-share li {
    margin: 0 0.5rem;
}

.card.team-card .team-content .social-share li a {
    font-size: 1rem;
    color: var(--white-color);
}

.card.team-card:hover .team-photo::before {
    opacity: 1;
    -webkit-transform: scale(1);
    transform: scale(1);
}

.card.team-card:hover .team-photo::after {
    height: 104px;
    width: 104px;
    top: -5px;
    left: -5px;
    background-color: rgba(22, 24, 45, 0.2);
    -webkit-box-shadow: 0 5px 10px rgba(0, 71, 255, 0.2);
    box-shadow: 0 5px 10px rgba(0, 71, 255, 0.2);
}

.card.team-card:hover a h4 {
    color: var(--primary-color);
}

.card.blog-card {
    border-radius: 1.5rem;
}

.card.blog-card .blog-thumb img {
    border-radius: 6px;
}

.card.blog-card .blog-content a {
    color: var(--white-color);
    transition: 0.3s;
}

.card.blog-card .blog-content a h4 {
    transition: 0.3s;
}

.card.blog-card .blog-content a:hover {
    color: var(--primary-color);
}

.card.blog-card .blog-content a:hover h4 {
    color: var(--primary-color);
}

.card.blog-card .blog-content p {
    color: var(--primary-p-color);
}

.hero-section {
    position: relative;
    background-image: linear-gradient(0deg, #090919, rgba(9, 10, 26, 0.8)), url(../img/bg/hero_bg.jpg);
    background-position: 0 0, 0 0;
    background-size: auto, cover;
    background-repeat: repeat, no-repeat;
    background-attachment: scroll, fixed;
    z-index: 1;
}

/* Light theme is the mirror image of the rule above: hero_bg-white.jpg (the
   brighter exposure of the same art) under a veil of the page background
   instead of a veil of near-black — same two layers, same alphas, opposite
   direction, so the banner LIGHTENS here rather than darkening. Keeping the
   layer count at two means the position/size/repeat/attachment lists above
   still line up and only background-image needs restating.
   No text-role vars are re-pinned: the surface is now light, so the section
   inherits the light theme's dark-on-light text (--white-color: #14152B,
   --primary-p-color: #5A5E82) like every other light-mode section. */
[data-theme="light"] .hero-section {
    background-image: linear-gradient(0deg, #F5F6FA, rgba(245, 246, 250, 0.8)), url(../img/bg/hero_bg-white.jpg);
}

.hero-section::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 130px;
    background-image: linear-gradient(180deg, transparent, var(--primary-bg-color));
    pointer-events: none;
}

.hero-section .container {
    position: relative;
    z-index: 1;
}

.hero-section h1 {
    color: var(--white-color);
}

.hero-section p {
    font-size: 1.2rem;
}

.content-list .content-icon span {
    display: grid;
    place-items: center;
    height: 100px;
    width: 100px;
    background-color: var(--card-bg-color);
    border-radius: 2rem;
}

.content-list .content-icon span svg,
.content-list .content-icon span i {
    font-size: 2.75rem;
    color: var(--white-color);
}

.content-list .content-icon span.featured {
    background-color: var(--primary-color);
}

.wrapper-animation {
    margin: 8rem 0;
}

.wrapper-animation .blockchain-wrapper {
    position: relative;
    margin: 0 auto;
    transform-style: preserve-3d;
    height: 7.5rem;
    width: 7.5rem;
    transform-origin: 3.75rem 3.75rem;
    transform: rotateX(50deg) rotateZ(45deg);
    animation: rotate 4s linear infinite;
}

.wrapper-animation .blockchain-wrapper .pyramid {
    position: absolute;
    perspective: 500px;
    transform-style: preserve-3d;
}

.wrapper-animation .blockchain-wrapper .pyramid.inverse {
    transform: translateZ(-1.4285714286rem) rotateY(180deg);
}

.wrapper-animation .blockchain-wrapper .square {
    height: 7.5rem;
    width: 7.5rem;
    background: #3f65ff;
    transform-style: preserve-3d;
}

.wrapper-animation .blockchain-wrapper .triangle {
    position: absolute;
    height: 10rem;
    width: 10rem;
}

.wrapper-animation .blockchain-wrapper .triangle:nth-child(1) {
    width: 7.5rem;
    top: -33%;
    background: #728eff;
    clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
    transform-origin: 50% 100%;
    transform: rotateX(-68deg);
}

.wrapper-animation .blockchain-wrapper .triangle:nth-child(2) {
    width: 7.5rem;
    background: #728eff;
    clip-path: polygon(50% 100%, 0 0, 100% 0);
    transform-origin: 50% 0%;
    transform: rotateX(68deg);
}

.wrapper-animation .blockchain-wrapper .triangle:nth-child(3) {
    height: 7.5rem;
    left: -33%;
    background: #a5b7ff;
    transform-origin: 100% 50%;
    clip-path: polygon(100% 100%, 0 50%, 100% 0);
    transform: rotateY(68deg);
}

.wrapper-animation .blockchain-wrapper .triangle:nth-child(4) {
    height: 7.5rem;
    background: #a5b7ff;
    transform-origin: 0% 50%;
    clip-path: polygon(0 100%, 100% 50%, 0 0);
    transform: rotateY(-68deg);
}

@keyframes rotate {
    from {
        transform: rotateX(50deg) rotateZ(0deg) translateZ(-0.5rem);
    }
    50% {
        transform: rotateX(50deg) rotateZ(180deg) translateZ(0.5rem);
    }
    to {
        transform: rotateX(50deg) rotateZ(360deg) translateZ(-0.5rem);
    }
}

@keyframes bounceHero {
    0% {
        top: 0px;
    }
    50% {
        top: 25px;
    }
    100% {
        top: 0px;
    }
}

.countdown {
    text-transform: uppercase;
    color: var(--white-color);
}

.countdown>div {
    display: block;
}

.countdown .countdown-container {
    margin: 0 5px;
}

.countdown .countdown-container:first-child {
    margin-left: 0;
}

.countdown .countdown-container .countdown-heading {
    font-size: 12px !important;
    font-weight: 500;
}

.countdown .countdown-container .countdown-value {
    font-family: var(--primary-font);
    font-size: 16px;
    font-weight: 600;
    padding: 5px;
    text-shadow: 2px 2px 2px rgba(0, 0, 0, 0.4);
}

.countdown .countdown-container .countdown-value:first-child {
    padding-left: 0;
}

.load-more .item {
    display: none;
}

.filter-menu {
    flex-wrap: wrap;
    justify-content: center;
    margin-bottom: 30px;
}

.filter-menu .input-item {
    position: relative;
}

.filter-menu .input-item::before {
    position: absolute;
    content: "/";
    top: 50%;
    left: 100%;
    transform: translateY(-50%);
    color: var(--primary-p-color);
}

.filter-menu .input-item:last-of-type::before {
    content: none;
}

.filter-menu .input-item .btn {
    padding: 1rem 2rem;
    background: inherit;
    color: var(--white-color);
    font-weight: 500 !important;
    transition: color 0.3s ease-in-out;
}

.filter-menu .input-item .btn:hover {
    color: var(--primary-color);
}

.filter-menu .input-item label::after {
    position: absolute;
    content: "";
    height: 2px;
    width: 0;
    top: calc(100% - 0.5rem);
    left: 50%;
    background-color: var(--primary-color);
    transform: translateX(-50%);
    visibility: hidden;
    opacity: 0;
    transition: all 0.3s ease 0s;
}

.filter-menu .input-item .btn-check:checked+label::after {
    width: calc(100% - 4rem);
    visibility: visible;
    opacity: 1;
}

.filter-menu .input-item .count {
    position: absolute;
    top: 0.5rem;
    right: 0.8rem;
    font-family: var(--primary-font);
    font-size: 0.9rem;
    font-weight: 500;
    line-height: 0;
    transition: color 0.3s ease 0s;
}

.filter-menu .input-item:has(.btn-check:checked+label) .count {
    color: var(--primary-color);
}

.filter-menu .btn-check:checked+.btn,
.filter-menu .btn.active,
.filter-menu .btn.show,
.filter-menu .btn:first-child:active,
.filter-menu :not(.btn-check)+.btn:active {
    background-color: transparent;
    color: var(--primary-color);
}

.item-details-area .single-item-content:first-child {
    margin-top: 0;
}

.item-details-area .single-item-content .table.token-content {
    color: inherit;
    border-spacing: 0;
}

.item-details-area .single-item-content p {
    color: var(--primary-p-color);
}

.item-details-area .single-item-content p:last-child {
    margin: 0;
}

.item-details-area .single-item-content .table> :not(caption)>*>* {
    background-color: transparent;
    color: var(--primary-p-color);
}

.item-details-area .single-item-content.card {
    overflow: hidden;
}

.item-details-area .single-item-content.card .image-over {
    border-radius: 2px;
    overflow: hidden;
}

.item-details-area .single-item-content.card .image-over:before {
    position: absolute;
    content: "";
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 1;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.5);
}

.item-details-area .single-item-content.card .image-over img {
    position: relative;
    height: 400px;
    min-height: 350px;
    object-fit: cover;
    object-position: center;
}

.item-details-area .single-item-content.card .image-over img.card-img-top {
    border-radius: 0;
}

.item-details-area .single-item-content.card .card-caption {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 1;
    text-align: center;
}

.item-details-area .single-item-content.card .card-caption .play-btn a {
    display: inline-grid;
    place-items: center;
    padding: 1.5rem;
    background-color: var(--primary-color);
    color: var(--btn-text-color);
    border-radius: 14px;
    box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.12);
    transition: 0.3s ease-in-out;
}

.item-details-area .single-item-content.card .card-caption .play-btn a:hover {
    transform: scale(1.1);
}

.item-details-area .item-info img {
    border-radius: 8px;
}

.item-details-area .item-info .countdown-container {
    margin: 0 10px;
}

.item-details-area .item-info .countdown-container .countdown-heading {
    font-size: 14px !important;
}

.item-details-area .item-info .countdown-container .countdown-value {
    font-size: 20px;
}

.item-details-area .gameon-tab.nav-tabs {
    border-bottom: 2px solid var(--card-bg-color);
}

.item-details-area .gameon-tab li {
    margin: 0;
}

.item-details-area .gameon-tab li a {
    position: relative;
    display: inline-block;
    margin: 0 10px;
    padding: 10px 0;
}

.item-details-area .gameon-tab li a::after {
    position: absolute;
    content: "";
    height: 3px;
    width: 0;
    bottom: -2.5px;
    left: 0;
    background-color: var(--primary-color);
    visibility: hidden;
    opacity: 0;
    transition: all 0.3s ease 0s;
}

.item-details-area .gameon-tab li a.active h5 {
    color: var(--primary-color);
}

.item-details-area .gameon-tab li a.active::after {
    width: 100%;
    visibility: visible;
    opacity: 1;
}

.item-details-area .gameon-tab li:first-of-type a {
    margin-left: 0;
}

.item-details-area .tab-content .single-tab-list {
    margin: 1.5rem 0;
}

.item-details-area .tab-content .single-tab-list strong,
.item-details-area .tab-content .single-tab-list a {
    color: var(--white-color);
    transition: 0.3s;
}

.item-details-area .tab-content .single-tab-list a:hover {
    color: var(--primary-color);
}

.item-details-area .tab-content .owner h6 {
    transition: 0.3s;
}

.item-details-area .tab-content .owner:hover h6 {
    color: var(--primary-color);
}

.staking-area .card {
    padding: 3rem;
    border-radius: 2rem;
}

.staking-area .card .balance {
    font-family: var(--primary-font);
    font-size: 2rem;
    font-weight: 600;
    color: var(--white-color);
}

.staking-area .card span {
    color: var(--primary-p-color);
}

.staking-area .card .staking-tabs .nav-item {
    margin: 0.25rem 0.5rem 0.25rem 0;
}

.staking-area .card .staking-tabs .tab-link {
    display: inline-block;
    padding: 12px 24px;
    font-size: 15px;
    font-weight: 500;
    background-color: #2c2f4c;
    color: var(--white-color) !important;
    border: 0;
    border-radius: 10px;
}

.staking-area .card .staking-tabs .tab-link.active {
    background-color: var(--primary-color);
}

.staking-area .card .staking-tab-content .info-box .info-right span {
    font-family: var(--primary-font);
    font-weight: 600;
}

.staking-area .card .staking-tab-content .info-box .info-right span:first-child {
    font-size: 3rem;
    font-weight: 500;
}

.staking-area .staking-items .card p {
    font-weight: 600;
    color: var(--primary-p-color);
}

.staking-area .input-area .input-text {
    position: relative;
    width: 70%;
    z-index: 3;
}

.staking-area .input-area .input-text input {
    position: relative;
    border: 2px solid;
    border-radius: 10px;
    z-index: 3;
}

.staking-area .input-area .input-text a {
    position: absolute;
    top: 50%;
    right: 2px;
    transform: translateY(-50%);
    padding: 0.8rem 1rem;
    background-color: #2c2f4c;
    color: var(--white-color);
}

.staking-area .input-btn {
    font-size: 15px;
    border-radius: 10px;
}

.staking-area .single-accordion-item {
    background-color: var(--card-bg-color);
    border-radius: 2rem;
}

.staking-area .single-accordion-item:not(:first-child) {
    margin-top: 3rem;
}

.staking-area .single-accordion-item .staking-btn {
    position: relative;
    padding: 3rem 2rem !important;
    background-image: none !important;
    color: var(--primary-p-color);
    box-shadow: none !important;
}

.staking-area .single-accordion-item .staking-btn::after {
    position: absolute;
    content: "\f107";
    top: 3rem;
    right: 3rem;
    font-size: 2rem;
    font-weight: 900;
    font-family: "Font Awesome 5 Free";
}

.staking-area .single-accordion-item .staking-btn.collapsed {
    border-radius: 2rem;
}

.staking-area .single-accordion-item .staking-btn.collapsed::after {
    position: absolute;
    content: "\f106";
    top: 3rem;
    right: 3rem;
    font-size: 2rem;
    font-weight: 900;
    font-family: "Font Awesome 5 Free";
}

.staking-area .single-accordion-item .staking-btn img {
    border-radius: 8px;
}

.staking-area .single-accordion-item .staking-btn .content p {
    font-weight: 500;
}

.staking-area .single-accordion-item .staking-btn .staking-info .single-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
}

.staking-area .single-accordion-item .staking-btn .staking-info .single-item span {
    display: inline-block;
}

.staking-area .single-accordion-item .staking-btn .staking-info .single-item span:last-child {
    margin-top: 0.5rem;
}

.staking-area .single-accordion-item .card-body {
    position: relative;
    padding: 3rem 2rem !important;
}

.staking-area .single-accordion-item .card-body::before {
    position: absolute;
    content: "";
    top: 0;
    left: 3rem;
    right: 3rem;
    height: 2px;
    background-color: rgba(115, 115, 115, 0.3);
}

.staking-area .single-accordion-item .card-body .single-staking-item .item-title {
    display: inline-block;
    font-size: 0.9rem;
    font-weight: 600;
}

.staking-area .single-accordion-item .card-body .single-staking-item .price {
    font-weight: 700;
    color: var(--primary-p-color);
}

.staking-area .single-accordion-item .card-body .single-staking-item .reward {
    display: inline-block;
    font-size: 0.9rem;
}

.staking-area .single-accordion-item .input-area .input-text {
    width: 100%;
}

.leaderboard-area table {
    font-weight: 500;
    color: var(--primary-p-color);
    border-spacing: 0;
}

.leaderboard-area table tr th,
.leaderboard-area table tr td {
    display: inline-block;
    width: 20%;
    padding: 1.2rem;
    margin-bottom: 10px;
    background-color: var(--card-bg-color);
    color: var(--primary-p-color);
}

.leaderboard-area table tr th {
    background-color: transparent;
    color: var(--white-color);
    margin-bottom: 0;
    text-transform: uppercase;
}

.cta-area .card {
    background-image: linear-gradient(0deg, rgba(9, 10, 26, 0.9), rgba(9, 10, 26, 0.5)), url(../img/bg/hero_bg.jpg);
    /* frame the photo layer between its centre and right edge; without */
    /* this the default 0 0 position crops the image from the top left */
    background-position: 0 0, 85% 50%;
    background-repeat: repeat, no-repeat;
    padding: 3rem 2rem;
    border-radius: 2rem;
    box-shadow: none;
}

/* Same hero_bg.jpg art as .hero-section, and the same light treatment: the
   brighter exposure of the plate under a veil of the page background instead
   of one of near-black, so the card lightens here rather than darkening. Two
   layers either way, so the position/repeat lists above still line up.
   No text-role vars are re-pinned — on a light surface the card inherits the
   light theme's dark-on-light text like any other card. */
[data-theme="light"] .cta-area .card {
    background-image: linear-gradient(0deg, rgba(245, 246, 250, 0.9), rgba(245, 246, 250, 0.5)), url(../img/bg/hero_bg-white.jpg);
}

.cta-area .card p {
    color: var(--white-color);
}

.cta-area .cta-link {
    position: absolute;
    height: 100%;
    width: 100%;
    top: 0;
    left: 0;
    border-radius: inherit;
}

.wallet-connect-area .single-wallet {
    padding: 45px;
    border-radius: 2rem;
}

.wallet-connect-area .single-wallet h4 {
    transition: 0.3s;
}

.wallet-connect-area .single-wallet p {
    color: var(--primary-p-color);
}

.wallet-connect-area .single-wallet:hover h4 {
    color: var(--primary-color);
}

.help-center-area .card {
    padding: 45px;
    border-radius: 2rem;
    min-height: 300px;
    display: flex;
    justify-content: center;
}

.help-center-area .card h4 {
    transition: 0.3s;
}

.help-center-area .card p {
    color: var(--primary-p-color);
}

.help-center-area .card:hover h4 {
    color: var(--primary-color);
}

.faq-area .single-accordion-item .card-header .btn {
    position: relative;
}

.faq-area .single-accordion-item .card-header .btn::after {
    position: absolute;
    content: "\f107";
    top: 50%;
    left: calc(100% - 34px);
    transform: translateY(-50%);
    font-size: 18px;
    font-weight: 900;
    font-family: "Font Awesome 6 Free";
}

.faq-area .single-accordion-item .card-header .btn.collapsed::after {
    position: absolute;
    content: "\f105";
    top: 50%;
    left: calc(100% - 34px);
    transform: translateY(-50%);
    font-size: 18px;
    font-weight: 900;
    font-family: "Font Awesome 6 Free";
}

.apply-form {
    padding: 3rem;
    border-radius: 2rem;
}

.apply-form .form-group {
    margin-bottom: 1.5rem;
}

.apply-form .form-group label {
    margin-bottom: 0.5rem;
    font-size: 1.2rem;
    font-weight: 600;
    color: var(--white-color);
}

.apply-form .form-group .form-text {
    font-size: 0.9rem;
    color: var(--primary-p-color);
}

.apply-form .form-group.form-check .form-check-input {
    padding: 0;
}

.apply-form .form-group.form-check label {
    font-size: 0.9rem;
    margin-bottom: 0;
    margin: 2px 0px 0px 5px;
    color: var(--primary-p-color);
}

.apply-form .checkbox-area .reset-link {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--primary-p-color);
}

.apply-form span {
    font-size: 0.9rem;
    color: var(--primary-p-color);
}

.apply-form span.notice {
    font-weight: 500;
}

.apply-form span.notice a {
    font-size: 0.9rem;
    font-weight: 500;
}

.contact .contact-items .card {
    border-radius: 2rem;
}

.contact .contact-items .card .media-body p,
.contact .contact-items .card .media-body span {
    color: var(--primary-p-color);
}

ul.page-numbers {
    width: fit-content;
    display: flex;
    justify-content: center;
    margin: 35px auto;
    padding-left: 0;
    list-style: none;
    border-radius: 0.25rem;
    box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.1);
    transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
}

ul.page-numbers li {
    margin: 0 5px;
}

a.page-numbers,
span.page-numbers {
    width: 50px;
    height: 50px;
    line-height: 50px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 17px;
    font-weight: 400;
    border-radius: 10px;
    background-color: var(--card-bg-color);
    color: var(--white-color) !important;
    transition: 0.3s ease-in-out;
}

span.page-numbers.current {
    background-color: var(--primary-color);
    /* !important to win over the base a.page-numbers/span.page-numbers
       rule above, which also marks its color !important. */
    color: var(--btn-text-color) !important;
}

a.page-numbers:hover {
    background-color: var(--primary-color);
    color: var(--btn-text-color) !important;
}

.badge {
    font-weight: 500;
}

.badge.circle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    line-height: 30px;
    border-radius: 100%;
    background-color: var(--primary-bg-color-3);
}

.badge.tag {
    margin: 0.3rem;
    padding: 0.5rem 1rem;
    border-radius: 2px;
    font-size: 1rem;
    font-weight: 400;
    color: var(--primary-p-color) !important;
    border: 2px solid var(--card-bg-color);
    transition: 0.3s;
}

.badge.tag.active {
    color: var(--primary-color);
    border-color: var(--primary-color);
}

.badge.tag:hover {
    color: var(--primary-color) !important;
}

.share-list {
    display: -webkit-inline-box;
}

.share-list .nav-link i {
    margin: 0 1rem;
    font-size: 22px;
}

.breadcrumb {
    margin: 0;
    background: none;
    justify-content: center;
    color: inherit;
}

.breadcrumb-area {
    height: 450px;
    z-index: 1;
}

.breadcrumb-area::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 130px;
    background-image: linear-gradient(180deg, transparent, var(--primary-bg-color));
    pointer-events: none;
}

.breadcrumb-area .container {
    position: relative;
    z-index: 1;
}

.breadcrumb-area .breadcrumb-item {
    font-size: 1rem;
    font-weight: 600;
    margin: 0.3rem 0;
}

.breadcrumb-area .breadcrumb-item a:not(.btn) {
    font-weight: 600 !important;
    transition: color 0.3s ease-in-out;
}

.breadcrumb-area .breadcrumb-item a:not(.btn):not(:hover) {
    color: var(--white-color);
}

.breadcrumb-area .breadcrumb-item.active {
    color: var(--primary-color);
}

.breadcrumb-area .breadcrumb-item.active:hover {
    color: var(--primary-color);
}

.breadcrumb-area .breadcrumb-content h2 {
    font-weight: var(--h1-weight);
}

.breadcrumb-area .breadcrumb-content .breadcrumb {
    background-color: transparent;
    margin: 0;
}

.breadcrumb-area .breadcrumb-content .breadcrumb .breadcrumb-item+.breadcrumb-item::before {
    content: ">";
    color: var(--white-color);
}

.image-over {
    overflow: hidden;
    border-radius: 2px;
}

.overlay-dark {
    position: relative;
    z-index: 0;
}

.overlay-dark::after {
    position: absolute;
    content: "";
    height: 100%;
    width: 100%;
    top: 0;
    left: 0;
    background-color: var(--primary-bg-color);
    opacity: 0.84;
    z-index: -1;
}

.social-icons i {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    margin: 0 auto;
    transition: all 0.3s ease 0s;
}

.social-icons>a {
    margin: 5px;
    width: 45px;
    height: 45px;
    font-size: 22px;
    background: var(--card-bg-color);
    color: var(--white-color) !important;
    border-radius: 14px;
    overflow: hidden;
    transition: all 0.3s ease 0s;
}

.social-icons>a:hover i:first-child {
    margin-top: -45px;
}

/* #endregion Feature */

/*----------------------------------------------
9. Footer
----------------------------------------------*/

/* #region Footer */

.footer-area {
    padding: 50px 0;
}

.footer-area .footer-items .navbar-brand {
    margin-right: 0;
}

.footer-area .footer-items .navbar-brand img {
    height: 42px;
}

[data-theme="light"] .footer-area .footer-items .navbar-brand img {
    filter: invert(1);
}

.footer-area .footer-items ul {
    padding-left: 0;
}

.footer-area .footer-items ul li {
    margin: 0.5rem 1rem;
}

.footer-area .footer-items a {
    transition: 0.3s;
}

.footer-area .footer-items a:not(:hover) {
    font-weight: 500;
    color: var(--white-color);
}

.footer-area .footer-items a:hover {
    font-weight: 500;
}

/* #endregion Footer */

/*----------------------------------------------
10. Modal
----------------------------------------------*/

/* #region Modal */

.modal-open {
    overflow-x: hidden;
    overflow-y: hidden;
}

.modal-open .modal {
    overflow: hidden;
}

.dialog-animated {
    min-height: 100%;
    margin: 0 0 0 auto;
}

.modal.fade .modal-dialog.dialog-animated {
    transform: translate(100%, 0) scale(1);
    box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.1);
    height: 100%;
}

.modal.fade.show .modal-dialog.dialog-animated {
    height: 100%;
    transform: translate(0, 0);
}

.modal-content {
    background-color: var(--primary-bg-color);
    border: none;
    border-radius: 0;
    overflow-x: hidden;
}

.modal-header {
    justify-content: space-between;
    align-items: center;
    padding: 1rem;
    border: none;
    font-weight: 600;
    border-radius: 0;
}

.modal-header .icon-close {
    font-size: 24px;
    cursor: pointer;
}

.modal-body {
    display: flex;
    align-items: center;
    padding: 2rem;
}

.search-title {
    line-height: 1em;
    letter-spacing: -1.6px;
}

.modal-body .w-100 {
    max-height: 80vh;
    overflow-y: auto;
}

.search-status {
    color: #fff;
}

.search-results-label {
    display: block;
    font-size: 13px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    opacity: 0.6;
}

.search-result-link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.6rem 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.search-result-title {
    font-weight: 500;
}

.search-result-subtitle {
    font-size: 13px;
    opacity: 0.6;
    text-transform: capitalize;
}

/* #endregion Modal */

/*----------------------------------------------
12. Privacy Policy
----------------------------------------------*/

/* #region Privacy Policy */

.policy-card {
    color: var(--primary-p-color);
}

.policy-updated {
    color: var(--white-color);
    font-weight: 600;
    font-size: 0.9rem;
}

.policy-section:first-of-type {
    margin-top: 2rem !important;
}

.policy-section h3 {
    color: var(--white-color);
}

.policy-section h4 {
    color: var(--white-color);
    font-size: 1.05rem;
}

.policy-list {
    padding-left: 1.25rem;
    margin: 1rem 0 0;
}

.policy-list li {
    margin-bottom: 0.75rem;
}

.policy-list li:last-child {
    margin-bottom: 0;
}

.policy-table {
    --bs-table-bg: transparent;
    --bs-table-color: var(--primary-p-color);
    --bs-table-border-color: rgba(255, 255, 255, 0.12);
    --bs-table-hover-bg: rgba(255, 255, 255, 0.05);
    --bs-table-hover-color: var(--white-color);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 0.5rem;
    overflow: hidden;
}

.policy-table th,
.policy-table td {
    background-color: transparent;
    border-color: rgba(255, 255, 255, 0.12);
    padding: 0.75rem 1rem;
    vertical-align: top;
}

.policy-table th {
    color: var(--white-color);
    font-weight: 600;
    white-space: nowrap;
    background-color: rgba(255, 255, 255, 0.06);
}

.policy-table td {
    color: var(--primary-p-color);
    background-color: rgba(255, 255, 255, 0.03);
}

/* #endregion Privacy Policy */

/*----------------------------------------------
13. Auth & Account
----------------------------------------------*/

/* #region Auth & Account */

/* Show/hide toggle tucked inside a password input. The global input rule (Reset
   region) sets width: 100% and a 0.7rem/1rem padding, so the wrapper provides
   the positioning context and the input gets extra right padding to stop typed
   text from sliding under the icon. */
.password-field {
    position: relative;
}

.password-field input {
    padding-right: 3rem;
}

.password-toggle-btn {
    position: absolute;
    top: 50%;
    right: 0.5rem;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: none;
    color: var(--primary-p-color);
    font-size: 14px;
    transition: 0.3s;
}

.password-toggle-btn:hover,
.password-toggle-btn:focus-visible {
    color: var(--white-color);
    background-color: rgba(255, 255, 255, 0.08);
}

.form-message.error {
    color: #e74c3c;
}

.form-message.success {
    color: #2ecc71;
}

.account-username {
    max-width: 160px;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    font-weight: 600;
    color: var(--white-color);
}

@media (max-width: 767px) {
    .account-username {
        max-width: 100px;
    }
}

.account-avatar-menu {
    position: relative;
}

.account-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 40px;
    width: 40px;
    border: none;
    border-radius: 50%;
    background-color: var(--primary-color);
    color: var(--btn-text-color);
    font-weight: 600;
    flex-shrink: 0;
    cursor: pointer;
}

/* Showing a linked Discord avatar instead of the initial: drop the solid
   background so it can't show through a transparent PNG, and clip the image to
   the circle. */
.account-avatar.has-image {
    background-color: transparent;
    overflow: hidden;
    padding: 0;
}

.account-avatar.has-image img {
    height: 100%;
    width: 100%;
    object-fit: cover;
    border-radius: 50%;
}

.account-avatar-dropdown {
    position: absolute;
    top: calc(100% + 0.75rem);
    right: 0;
    min-width: 12rem;
    padding: 0.5rem 0;
    background-color: var(--card-bg-color);
    border-radius: 0.75rem;
    box-shadow: 0 20px 40px rgba(0, 0, 0, 0.35);
    display: flex;
    flex-direction: column;
    visibility: hidden;
    opacity: 0;
    transform: translateY(10px);
    transition: opacity 0.2s ease, transform 0.2s ease;
    z-index: 10;
}

.account-avatar-menu.open .account-avatar-dropdown {
    visibility: visible;
    opacity: 1;
    transform: translateY(0);
}

.account-avatar-dropdown a,
.account-avatar-dropdown button {
    display: block;
    width: 100%;
    padding: 0.625rem 1.25rem;
    text-align: left;
    background: none;
    border: none;
    color: var(--white-color);
    font-size: 14px;
    transition: 0.3s;
}

.account-avatar-dropdown a:hover,
.account-avatar-dropdown button:hover {
    color: var(--primary-color);
    background-color: rgba(255, 255, 255, 0.04);
}

/* Hero art again, framed on its top edge like .breadcrumb-area. */
.dashboard-header {
    position: relative;
    background-image: linear-gradient(180deg, rgba(9, 10, 26, 0.55), rgba(9, 10, 26, 0.9)), url(../img/bg/hero_bg.jpg);
    background-position: top center;
    background-size: cover;
    background-repeat: no-repeat;
    overflow: hidden;
}

/* Unlike .breadcrumb-area, this header's veil is baked into background-image
   as a hardcoded near-black gradient, so it does not follow the theme on its
   own — it stayed dark in light mode while the h2 below it resolved
   var(--white-color) to the light theme's #14152B, i.e. dark text on a dark
   band. Mirroring the gradient onto the page background gives it the same
   lighten-instead-of-darken behaviour as .hero-section, and the heading and
   breadcrumb then read correctly from the light theme's own tokens with no
   re-pinning. */
[data-theme="light"] .dashboard-header {
    background-image: linear-gradient(180deg, rgba(245, 246, 250, 0.55), rgba(245, 246, 250, 0.9)), url(../img/bg/hero_bg-white.jpg);
}

.dashboard-header::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 90px;
    background-image: linear-gradient(180deg, transparent, var(--primary-bg-color));
    pointer-events: none;
}

.dashboard-header .container {
    position: relative;
    z-index: 1;
}

.dashboard-header .dashboard-header-content {
    padding-top: 8rem;
    padding-bottom: 3.5rem;
}

@media (max-width: 767px) {
    .dashboard-header .dashboard-header-content {
        padding-top: 10rem;
    }
}

.dashboard-header h2 {
    color: var(--white-color);
}

.dashboard-breadcrumb {
    color: var(--primary-p-color);
    font-size: 14px;
}

.dashboard-breadcrumb a {
    color: var(--primary-p-color) !important;
    transition: 0.3s;
}

.dashboard-breadcrumb a:hover {
    color: var(--primary-color);
}

.account-area {
    padding: 2.5rem 0;
}

/* A row above a full-width card, holding the action that adds to it.
   Right-aligned by default so a lone button sits at the end of the row rather
   than the start; anything placed before it (a heading, a filter) is pushed to
   the far left by the auto margin, which keeps the rule working for both
   shapes. On a phone the button goes full width instead of sitting as a lone
   pill in the corner. */
.dashboard-section-toolbar {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: 1rem;
    margin-bottom: 1.25rem;
}

.dashboard-section-toolbar > :first-child:not(:last-child) {
    margin-right: auto;
}

@media (max-width: 575px) {
    .dashboard-section-toolbar > .btn {
        width: 100%;
    }
}

.dashboard-card {
    background-color: var(--card-bg-color);
    border-radius: 0.75rem;
    overflow: hidden;
}

.dashboard-card-header {
    /* One height for every card header, declared once. A header is otherwise
       as tall as whatever it happens to contain, so the moment one of them
       carries a button and its neighbour carries only text, two cards side by
       side start their bodies at different heights. The value is the natural
       height of a text-only header, so this floors the short ones and changes
       nothing about the ones that already looked right. */
    --card-header-height: 3.5625rem;
    min-height: var(--card-header-height);
    padding: 1rem 1.5rem;
    font-weight: 600;
    color: var(--white-color);
    background-color: rgba(255, 255, 255, 0.04);
    border-bottom: 1px solid var(--card-border-color);
}

/* A header carrying a button has to stay the height of one carrying only a
   title: these cards sit side by side, and a taller header on one of them
   starts its body lower than its neighbour's for no reason the reader can
   see. The button is taller than the text, so the padding gives way to it. */
/* The button is taller than the text line, so the padding gives way to it —
   the min-height above is what keeps the result level with a plain header. */
.dashboard-card-header.has-action {
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
}

.dashboard-card-header.has-action > .btn {
    margin: 0;
    white-space: nowrap;
}

/* More than one action: the same rules, applied one level down. The group
   wraps under the title rather than squeezing it on a phone, where these
   cards stack anyway and there is no neighbour for the header to line up with. */
.dashboard-card-header-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.dashboard-card-header-actions > .btn {
    margin: 0;
    white-space: nowrap;
}

/* How many there are, beside the title of a list that shows all of them. */
.dashboard-card-header-count {
    display: inline-block;
    margin-left: 0.6rem;
    padding: 0.1rem 0.55rem;
    border-radius: 100px;
    background-color: rgba(255, 255, 255, 0.06);
    color: var(--primary-p-color);
    font-size: 12px;
    font-weight: 600;
    vertical-align: middle;
}

.dashboard-card-body {
    padding: 1.5rem;
    color: var(--primary-p-color);
}

/* The revealed PIN is the real content, so it reads near-white; the masked
   dots (and the "no PIN" placeholder) drop to the same muted colour as the
   stat-card labels like "Rewards Purchased". */
.dashboard-pin-value {
    letter-spacing: 4px;
    color: var(--secondary-p-color);
}

.dashboard-pin-value.dashboard-pin-muted {
    color: var(--primary-p-color);
}

.support-pin-row {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.support-pin-actions {
    display: flex;
    gap: 0.5rem;
}

.support-pin-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 8px;
    font-size: 13px;
    color: var(--white-color);
    background-color: rgba(255, 255, 255, 0.06);
    transition: 0.3s;
}

.support-pin-btn:hover {
    background-color: var(--primary-color);
    border-color: var(--primary-color);
    color: var(--btn-text-color);
}

.dashboard-shortcuts {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

/* No palette token sits between --secondary-p-color (#E1E1E1) and the purple-
   tinted --primary-p-color (#9CA0D2), so this is a literal neutral grey. */
.dashboard-shortcuts a,
.dashboard-shortcut-btn {
    color: var(--primary-p-color);
    background: none;
    border: none;
    padding: 0;
    text-align: left;
    font-size: inherit;
    transition: 0.3s;
}

/* The rule above is only (0,1,1) and loses to the global `a:link:not(.btn)` /
   `a:visited:not(.btn)` reset (0,2,1), which repaints the links the primary
   blue â€” the Log Out <button> beside them was never affected, so the list came
   out half blue and half not. Repeating the pseudo-classes here clears the
   reset. Same specificity trap as .dashboard-purchase-server-link. */
.dashboard-shortcuts a:link,
.dashboard-shortcuts a:visited {
    color: var(--primary-p-color);
}

.dashboard-shortcuts a:hover,
.dashboard-shortcuts a:link:hover,
.dashboard-shortcuts a:visited:hover,
.dashboard-shortcut-btn:hover {
    color: var(--primary-color);
}

.dashboard-stat-card {
    background-color: var(--card-bg-color);
    border-radius: 0.75rem;
    padding: 1.5rem 1rem;
}

.dashboard-stat-card i {
    font-size: 1.75rem;
    color: var(--primary-color);
}

.dashboard-stat-card h3 {
    color: var(--white-color);
    margin: 0.75rem 0 0.25rem;
    font-size: 1.25rem;
}

.dashboard-stat-card span {
    color: var(--primary-p-color);
    font-size: 13px;
}

/* A stat card that does something when pressed. Two of them are anchors and one
   is a button (AdBits opens a dialog, there being no balances page to link to),
   so this resets the button chrome as well - from the outside they have to be
   indistinguishable. */
.dashboard-stat-card.is-link {
    position: relative;
    display: block;
    width: 100%;
    padding: 1.5rem 1rem;
    border: 1px solid transparent;
    transition: background-color 0.15s, border-color 0.15s, transform 0.15s;
    cursor: pointer;
}

/* A step lighter than --card-bg-color (#16182d), not darker: the card is
   already dark, and dimming it on hover reads as "disabled" rather than
   "clickable". A solid colour rather than a translucent white, which would let
   the page behind show through instead of lifting the card off it. */
.dashboard-stat-card.is-link:hover {
    background-color: #212445;
    border-color: rgba(255, 255, 255, 0.14);
    transform: translateY(-2px);
}

[data-theme="light"] .dashboard-stat-card.is-link:hover {
    background-color: #F0F1F7;
    border-color: rgba(20, 21, 43, 0.14);
}

/* The corner arrow. Dim until the pointer arrives, so it hints without
   competing with the figure it sits beside. */
.dashboard-stat-go {
    position: absolute;
    top: 0.85rem;
    right: 0.95rem;
    font-size: 12px !important;
    color: var(--primary-p-color) !important;
    opacity: 0.5;
    transition: opacity 0.15s, color 0.15s;
}

.dashboard-stat-card.is-link:hover .dashboard-stat-go {
    opacity: 1;
    color: var(--white-color) !important;
}

/* The theme restyles every link through
     a:link:not(.btn), a:visited:not(.btn), a:hover:not(.btn), a:active:not(.btn)
   at specificity (0,2,1), setting colour, font-size, font-weight and
   line-height. These pages are not inside `.console-shell`, so region 15's
   overrides do not reach them; scoping to `.account-area` gets to (0,3,1),
   which clears it.

   All four states are listed on purpose: declaring only :link and :visited
   would leave the card flashing the theme's blue the moment it is hovered. */
.account-area a.dashboard-stat-card:link,
.account-area a.dashboard-stat-card:visited,
.account-area a.dashboard-stat-card:hover,
.account-area a.dashboard-stat-card:active {
    color: inherit;
    font-size: inherit;
    font-weight: inherit;
    line-height: inherit;
    text-decoration: none;
}

/* -- AdBits balance dialog -------------------------------------------------
   Where the AdBits actually are: the global pot, then whatever is earmarked per
   server. */

.balance-modal .modal-content {
    border: 2px solid var(--primary-p-color);
    border-radius: 16px;
    background-color: #13152e;
}

[data-theme="light"] .balance-modal .modal-content {
    background-color: #FFFFFF;
}

/* `display: block` undoes the theme's `.modal-body { display: flex }`, which
   otherwise lays every child out in a row. */
.balance-body {
    display: block;
    padding: 2rem 1.75rem;
    text-align: center;
}

.balance-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 54px;
    height: 54px;
    border-radius: 50%;
    background-image: linear-gradient(135deg, var(--primary-color) 10%, var(--secondary-color));
    color: var(--btn-text-color);
    font-size: 20px;
}

.balance-title {
    margin: 1rem 0 0.4rem;
    color: var(--white-color);
}

.balance-text {
    margin-bottom: 1.5rem;
    font-size: 13px;
    color: var(--primary-p-color);
}

.balance-row {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    width: 100%;
    padding: 0.85rem 1rem;
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 12px;
    background-color: rgba(255, 255, 255, 0.02);
    text-align: left;
}

.balance-row.is-global {
    border-color: rgba(37, 99, 235, 0.45);
    background-color: rgba(37, 99, 235, 0.1);
}

.balance-row-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    flex-shrink: 0;
    border-radius: 10px;
    background-color: rgba(255, 255, 255, 0.06);
    color: var(--white-color);
    font-size: 14px;
}

.balance-row-text {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.balance-row-text strong {
    color: var(--white-color);
    font-size: 14px;
}

.balance-row-text span {
    font-size: 12px;
    color: var(--primary-p-color);
}

/* The figure is the reason the row exists, so it is the one thing set in the
   theme's display face rather than the body one. */
.balance-row-value {
    flex-shrink: 0;
    font-size: 15px;
    font-weight: 700;
    color: var(--white-color);
    white-space: nowrap;
}

.balance-divider {
    margin: 1.25rem 0 0.75rem;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--primary-p-color);
}

.balance-rows {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    margin: 0;
}

.balance-total,
.balance-empty {
    margin: 1.25rem 0 0;
    font-size: 12px;
    color: var(--primary-p-color);
}

.balance-close {
    margin-top: 1.5rem;
}

.dashboard-promo-icon {
    font-size: 2rem;
    color: var(--primary-color);
}

.dashboard-promo-card {
    transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.dashboard-promo-card:hover {
    transform: translateY(-4px);
    box-shadow: 0 12px 30px rgba(0, 0, 0, 0.25);
}

.dashboard-promo-card .dashboard-card-body {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100%;
    padding: 1rem 1.5rem;
}

/* The global `p { margin: 1.5rem 0 }` (Reset region) puts 24px above this
   paragraph, and .dashboard-card-body is a flex column so that margin doesn't
   collapse into the heading's â€” it has to be zeroed explicitly to sit tight
   under the card title. */
.dashboard-promo-text {
    margin-top: 0;
    color: var(--primary-p-color);
    font-size: 14px;
    line-height: 1.6;
}

/* The numbered "what happens next" list on /account/requests. The global
   list reset strips the markers, so the counter is drawn by hand — which is
   what lets the number sit in the accent colour beside the text rather than
   in the browser's own grey outside the card padding. */
.dashboard-steps {
    counter-reset: dashboard-step;
    margin: 0;
    padding: 0;
    list-style: none;
}

.dashboard-steps li {
    counter-increment: dashboard-step;
    position: relative;
    padding-left: 2rem;
    color: var(--primary-p-color);
    font-size: 14px;
    line-height: 1.6;
}

.dashboard-steps li + li {
    margin-top: 0.85rem;
}

.dashboard-steps li::before {
    content: counter(dashboard-step);
    position: absolute;
    left: 0;
    top: 0.1rem;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 1.4rem;
    height: 1.4rem;
    border-radius: 50%;
    background-color: var(--primary-color);
    color: var(--white-color);
    font-size: 11px;
    font-weight: 700;
}

/* ── The store-catalogue picker on /account/requests ───────────────────────
   The reward field turns into a list of what the pasted store actually sells
   (see ServerRequestForm). These entries are read as a group and compared
   against each other, so the price is pinned to the right edge of every row
   rather than flowing after the name — a column of prices is scannable, an
   inline one is not. */
.store-read-row {
    display: flex;
    align-items: stretch;
    gap: 0.75rem;
}

.store-read-row input {
    flex: 1 1 auto;
    min-width: 0;
}

/* The button matches the height of the input beside it rather than its own
   content, or the row ends up with two different baselines. */
.store-read-btn {
    flex: 0 0 auto;
    white-space: nowrap;
    margin: 0;
}

.store-status {
    display: flex;
    align-items: flex-start;
    gap: 0.25rem;
    margin: 0 0 1.25rem;
    font-size: 13px;
    line-height: 1.5;
    color: var(--primary-p-color);
}

.store-status.is-warning {
    color: var(--invalid-color);
}

/* Capped and scrollable: a catalogue can run to a hundred packages, and a
   form that grows to five screens hides its own submit button. */
.store-picker {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    max-height: 15rem;
    overflow-y: auto;
    padding: 0.25rem;
    margin-bottom: 0.75rem;
}

.store-pick {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    width: 100%;
    padding: 0.6rem 0.85rem;
    text-align: left;
    border: 1px solid var(--card-border-color);
    border-radius: 10px;
    background-color: transparent;
    color: var(--white-color);
    transition: border-color 0.2s ease, background-color 0.2s ease;
}

.store-pick:hover {
    border-color: var(--primary-color);
}

.store-pick.is-selected {
    border-color: var(--primary-color);
    background-color: rgba(0, 71, 255, 0.08);
}

.store-pick-image {
    flex: 0 0 auto;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 8px;
    object-fit: contain;
}

.store-pick-image.is-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: rgba(127, 127, 127, 0.12);
    color: var(--primary-p-color);
}

/* min-width: 0 is what lets the ellipsis below actually happen: without it a
   flex item refuses to shrink under its content and pushes the price out. */
.store-pick-body {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    flex: 1 1 auto;
    min-width: 0;
}

.store-pick-name {
    font-size: 13px;
    font-weight: 600;
    line-height: 1.35;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ── A store's categories ──────────────────────────────────────────────────
   The account-section pill bar, smaller: it sits inside a dialog or above a
   grid rather than at the top of a page. Unlike that bar it wraps instead of
   scrolling sideways — the scrollbar is hidden, so on a desktop with a mouse
   Hypixel's last three categories were cut off with no way to reach them.
   A second row of pills is visible; a sideways scroll nobody can see is not.
   The smaller radius is what keeps two rows from reading as a lozenge. */
.store-category-bar {
    margin-bottom: 1rem;
}

.details-tabs.store-category-tabs {
    flex-wrap: wrap;
    overflow: visible;
    margin-bottom: 0;
    padding: 0.3rem;
    border-radius: 1.4rem;
}

/* Tighter than a page tab: these are filters, and in the request wizard's
   narrow dialog the roomier size took three rows away from the list itself. */
.store-category-tabs .details-tab {
    gap: 0.4rem;
    padding: 0.42rem 0.8rem;
    font-size: 12px;
}

.store-category-count {
    font-size: 11px;
    opacity: 0.65;
}

/* In the showcase window the bar stays put while the rewards scroll under it:
   with forty-odd of them, switching category from the bottom of the list
   should not mean scrolling back up to find the pills.
   It is the square wrapper that sticks, not the pill: it reaches out over the
   body's padding in the dialog's own colour, so cards passing underneath are
   covered edge to edge. A shadow ring round the pill itself would follow its
   rounded ends and leave the corners open. The negative `top` lets the padding
   above the pills scroll away before it pins, so only the bar stays behind. */
.dashboard-dialog-body > .store-category-bar {
    position: sticky;
    top: -1.35rem;
    z-index: 2;
    margin: -1.35rem -1.35rem 0.4rem;
    padding: 1.35rem 1.35rem 0.75rem;
    background-color: #13152e;
}

[data-theme="light"] .dashboard-dialog-body > .store-category-bar {
    background-color: #FFFFFF;
}

.store-category-heading {
    margin: 0 0 0.65rem;
    color: var(--primary-p-color);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.store-category-section + .store-category-section {
    margin-top: 1.4rem;
}

/* Inside the wizard's picker the sections are rows of a gap-spaced column,
   so they carry the same gap themselves and a tighter break between them. */
.store-picker .store-category-section {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.store-picker .store-category-section + .store-category-section {
    margin-top: 0.6rem;
}

.store-picker .store-category-heading {
    margin: 0.25rem 0 0;
}

.store-pick-price {
    flex: 0 0 auto;
    font-size: 13px;
    font-weight: 700;
    white-space: nowrap;
}

/* A link in behaviour, so it looks like one rather than competing with the
   submit button for the eye. */
.store-manual-toggle {
    padding: 0;
    border: 0;
    background: none;
    color: var(--primary-color);
    font-size: 12px;
    text-decoration: underline;
}

/* The promo card is much smaller than the Discovery cards ServerLogo was
   sized for â€” shrink the logo (and round it) when shown here. */
.dashboard-promo-card .avatar-max-lg {
    height: 3.5rem;
    width: 3.5rem;
    border-radius: 12px;
    object-fit: cover;
}

.dashboard-promo-card.effect-active,
.console-platform-head.effect-active,
.console-hero.effect-active {
    position: relative;
    isolation: isolate;
    overflow: hidden;
}

.dashboard-promo-card.effect-active .dashboard-card-body,
.console-platform-head.effect-active .console-platform-head-content {
    position: relative;
    z-index: 1;
}

.dashboard-promo-card.card-minecraft::before,
.console-platform-head.card-minecraft::before,
.console-hero.card-minecraft::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    border-radius: inherit;
    background:
        linear-gradient(180deg, rgba(0, 0, 0, 0.45) 0 100%),
        repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.15) 0 4px, transparent 4px 8px),
        repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.15) 0 4px, transparent 4px 8px),
        linear-gradient(180deg, #6fbf3a 0 16%, #7a4a2a 16% 100%);
    background-size: 100% 100%, 8px 8px, 8px 8px, 100% 100%;
    image-rendering: pixelated;
}

/* Paler grass/dirt, lighter pixelation stripes, and a much weaker darkening
   overlay — this banner is always-on (no hover/opacity toggle like the
   discovery card's version), so on a light surface the dark overlay alone
   would keep it looking like a black patch even with lighter block colors. */
[data-theme="light"] .dashboard-promo-card.card-minecraft::before,
[data-theme="light"] .console-platform-head.card-minecraft::before,
[data-theme="light"] .console-hero.card-minecraft::before {
    background:
        linear-gradient(180deg, rgba(0, 0, 0, 0.12) 0 100%),
        repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.08) 0 4px, transparent 4px 8px),
        repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.08) 0 4px, transparent 4px 8px),
        linear-gradient(180deg, #9fe080 0 16%, #c9976a 16% 100%);
}

.dashboard-promo-card.card-minecraft .dashboard-card-body,
.console-platform-head.card-minecraft .console-platform-head-content,
.console-hero.card-minecraft .console-hero-text {
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.7);
}

.dashboard-promo-card.card-discord::before,
.console-platform-head.card-discord::before,
.console-hero.card-discord::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    border-radius: inherit;
    background-color: rgba(88, 101, 242, 0.1);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 200' preserveAspectRatio='none'%3E%3Cpath d='M0,120 C60,60 100,180 160,110 C220,40 260,160 320,100 C350,70 380,90 400,80 L400,200 L0,200 Z' fill='%234f6df5' fill-opacity='0.35'/%3E%3C/svg%3E");
    background-size: 100% 100%;
    background-repeat: no-repeat;
    background-position: 0 0;
}

/* Website: the shimmer held at mid-sweep instead of looping across. */
.dashboard-promo-card.card-website::after,
.console-platform-head.card-website::after,
.console-hero.card-website::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    border-radius: inherit;
    background: linear-gradient(120deg, transparent 30%, rgba(52, 152, 219, 0.18) 50%, transparent 70%);
    background-size: 250% 100%;
    background-position: 50% 0;
}

/* Platform watermarks. Both are siblings of .dashboard-card-body, so they stay
   behind the card's text (which .effect-active lifts to z-index 1) while the
   left-fading mask keeps them from looking pasted on â€” same treatment as the
   Discovery cards, just sized down for this much smaller card. The icon sits
   above the wave/shimmer layer above by virtue of being a real child element. */
.dashboard-promo-card .discord-logo-icon,
.dashboard-promo-card .website-globe-icon,
.console-platform-head .discord-logo-icon,
.console-platform-head .website-globe-icon,
.console-hero .discord-logo-icon,
.console-hero .website-globe-icon {
    position: absolute;
    top: 50%;
    right: -10px;
    z-index: 0;
    transform: translateY(-50%);
    -webkit-mask-image: linear-gradient(to left, black 35%, transparent 85%);
    mask-image: linear-gradient(to left, black 35%, transparent 85%);
    pointer-events: none;
}

.dashboard-promo-card .discord-logo-icon,
.console-platform-head .discord-logo-icon {
    font-size: 7rem;
    color: #5865f2;
    opacity: 0.85;
}

.dashboard-promo-card .website-globe-icon,
.console-platform-head .website-globe-icon {
    font-size: 6rem;
    color: #3498db;
    opacity: 0.55;
}

/* The hero is far wider than either card, so its watermark is scaled up to
   stay proportional rather than reading as a stray icon in the corner. */
.console-hero .discord-logo-icon {
    font-size: 11rem;
    color: #5865f2;
    opacity: 0.75;
}

.console-hero .website-globe-icon {
    font-size: 10rem;
    color: #3498db;
    opacity: 0.45;
}

/* Prev/next + dots for the promo card when the user owns several platforms
   (see PlatformCarousel). Sits inside .dashboard-card-body, so it's already
   above the per-platform effect layer via that element's z-index. */
.platform-carousel-nav {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
}

.platform-carousel-arrow {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 50%;
    background-color: rgba(0, 0, 0, 0.35);
    color: white;
    font-size: 12px;
    line-height: 1;
    cursor: pointer;
    transition: background-color 0.2s ease, border-color 0.2s ease;
}

.platform-carousel-arrow:hover,
.platform-carousel-arrow:focus-visible {
    background-color: var(--primary-color);
    border-color: var(--primary-color);
}

.platform-carousel-dots {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.platform-carousel-dot {
    width: 8px;
    height: 8px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background-color: rgba(255, 255, 255, 0.3);
    cursor: pointer;
    transition: background-color 0.2s ease, transform 0.2s ease;
}

[data-theme="light"] .platform-carousel-dot {
    background-color: rgba(20, 21, 43, 0.3);
}

.platform-carousel-dot:hover {
    background-color: rgba(255, 255, 255, 0.6);
}

[data-theme="light"] .platform-carousel-dot:hover {
    background-color: rgba(20, 21, 43, 0.6);
}

/* Fixed #fff would be wrong here (unlike the toggle knob above): this dot
   should read as "the active one" against the theme's own foreground, which
   --white-color already provides correctly in both themes. */
.platform-carousel-dot.active {
    background-color: var(--white-color);
    transform: scale(1.25);
}

.dashboard-integrations {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.dashboard-integration {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.dashboard-integration-info {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    color: var(--white-color);
    font-weight: 500;
}

.dashboard-integration-info i {
    font-size: 1.25rem;
    color: var(--primary-color);
}

.dashboard-integration-dot {
    display: inline-block;
    height: 10px;
    width: 10px;
    border-radius: 50%;
    background-color: #e74c3c;
    flex-shrink: 0;
}

/* Linked: the dot alone carries the state, so no "Connected" label is rendered
   next to it any more. */
.dashboard-integration-dot.connected {
    background-color: #2ecc71;
}

/* The linked account's Discord display name. */
.dashboard-integration-account {
    color: #2ecc71;
    font-size: 13px;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 10rem;
}

/* Icon-only unlink control, sized to match the connect pill's height. */
.dashboard-integration-unlink {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    padding: 0;
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 50%;
    background-color: rgba(255, 255, 255, 0.06);
    color: var(--primary-p-color);
    font-size: 13px;
    transition: 0.3s;
}

.dashboard-integration-unlink:hover:not(:disabled),
.dashboard-integration-unlink:focus-visible {
    color: var(--white-color);
    border-color: #e74c3c;
    background-color: rgba(231, 76, 60, 0.2);
}

.dashboard-integration-unlink:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

[data-theme="light"] .dashboard-integration-unlink {
    border-color: rgba(20, 21, 43, 0.15);
    background-color: rgba(20, 21, 43, 0.05);
}

/* Same icon-only treatment as the unlink control, but for a non-destructive
   action (changing the linked Minecraft username), so hover goes to the
   primary color instead of the unlink control's red. */
.dashboard-integration-edit {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    padding: 0;
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 50%;
    background-color: rgba(255, 255, 255, 0.06);
    color: var(--primary-p-color);
    font-size: 13px;
    transition: 0.3s;
}

.dashboard-integration-edit:hover:not(:disabled),
.dashboard-integration-edit:focus-visible {
    color: var(--white-color);
    border-color: var(--primary-color);
    background-color: rgba(0, 71, 255, 0.2);
}

.dashboard-integration-edit:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

[data-theme="light"] .dashboard-integration-edit {
    border-color: rgba(20, 21, 43, 0.15);
    background-color: rgba(20, 21, 43, 0.05);
}

.dashboard-integration-connect {
    border: none;
    padding: 0.4rem 1rem;
    font-size: 13px;
    font-weight: 600;
    font-family: inherit;
    color: white;
    background-color: var(--primary-color);
    border-radius: 2rem;
    transition: transform 0.3s ease, box-shadow 0.3s ease, filter 0.3s ease;
}

.dashboard-integration-connect:hover {
    filter: brightness(1.15);
    transform: translateY(-2px) scale(1.05);
    box-shadow: 0 8px 20px rgba(0, 71, 255, 0.35);
}

.dashboard-integration-connect:active {
    transform: translateY(0) scale(0.97);
    box-shadow: none;
}

.dashboard-integration-connect:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

/* The Discord "Connect" control is an <a> (the OAuth round trip must be a
   top-level navigation), so it needs the anchor treatment: inline-flex for the
   padding to sit right, and the pseudo-classes repeated to beat the global
   `a:link:not(.btn)` reset (0,2,1), which would otherwise paint the label the
   primary blue â€” invisible on this blue pill. Same trap as
   .dashboard-purchase-server-link. */
a.dashboard-integration-connect,
a.dashboard-integration-connect:link,
a.dashboard-integration-connect:visited,
a.dashboard-integration-connect:hover,
a.dashboard-integration-connect:active {
    display: inline-flex;
    align-items: center;
    color: var(--white-color);
    font-size: 13px;
}

/* Outcome banner after returning from Discord's consent screen. */
.discord-status-banner {
    display: flex;
    align-items: center;
    margin-bottom: 1.5rem;
    padding: 0.85rem 1.1rem;
    border-radius: 10px;
    border: 1px solid rgba(88, 101, 242, 0.35);
    background-color: rgba(88, 101, 242, 0.12);
    color: var(--secondary-p-color);
    font-size: 14px;
}

.discord-status-banner.success {
    border-color: rgba(46, 204, 113, 0.35);
    background-color: rgba(46, 204, 113, 0.12);
    color: #2ecc71;
}

/* Small "View All" link in a dashboard card header. The ancestor + class
   selector matches the global `a:not(.btn)` reset's specificity and, being
   later in the file, wins the tie â€” a bare class here would lose font-size
   and color to that reset. */
.dashboard-card-header a.dashboard-card-header-link {
    display: inline-flex;
    align-items: center;
    font-size: 13px;
    font-weight: 600;
    color: var(--primary-p-color);
    white-space: nowrap;
}

.dashboard-card-header a.dashboard-card-header-link:hover {
    color: var(--primary-color);
}

.dashboard-purchase-history .table-responsive {
    overflow-x: auto;
}

/* Opt-in, not applied to every .dashboard-card.h-100: the promo cards already
   centre their own body a different way, and widening this would fight them. */
.dashboard-card-stretch {
    display: flex;
    flex-direction: column;
}

.dashboard-card-stretch .dashboard-card-body {
    flex: 1 1 auto;
}

/* ── The showcase at /showcase ─────────────────────────────────────────────
   A list of servers that are NOT on RewardsX, each opening onto the rewards
   you can ask us to go and get. Reuses the request-card grid below, because a
   reward here becomes one of those the moment it is picked. */
.showcase-intro {
    max-width: 46rem;
    margin: 0;
    color: var(--primary-p-color);
    line-height: 1.6;
}

.showcase-block {
    margin-top: 2rem;
}

.showcase-block-title {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    margin: 0 0 1rem;
    font-size: 15px;
}

.showcase-block-title span {
    color: var(--primary-p-color);
    font-size: 12px;
    font-weight: 400;
}

/* ── The showcase grid ─────────────────────────────────────────────────────
   Three across, not four: at four the names ran into the card edge and every
   second one wrapped, which left the rows ragged and the whole page looking
   broken. The open server breaks out to the full width underneath, which is
   why the grid holds cells rather than cards — a panel of rewards squeezed
   into one column of three would be unreadable. */
.showcase-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(19rem, 1fr));
    gap: 1rem;
    margin-top: 1.5rem;
}

/* Equal heights across a row, with the button on the bottom edge whatever the
   name above it did. Without this a two-line name made its card taller than
   its neighbours and the row of buttons came out as a staircase. */
/* `.card.showcase-card`, not `.showcase-card`: the theme's `.card.project-card`
   carries two classes and so outranked a single-class rule. It was applying
   2.5rem/2rem of padding, which against the fixed height below left a content
   box far shorter than the content — so the button pushed through the bottom
   padding and came to rest on the card's rounded edge, reading as though it
   sat outside the card. Matching the theme's specificity is the whole fix. */
.card.showcase-card {
    display: flex;
    /* Fixed, not 100%: stretching only equalises a card against the others in
       its own row, so a two-line tag list on row three made that whole row
       taller than the two above it. One height for all 26. */
    height: 13.5rem;
    margin: 0;
    padding: 1.25rem 1.35rem;
    /* The theme's 2rem is drawn for a card three times this tall; at this size
       the corner curved in over the full-width button beneath it. */
    border-radius: 1.25rem;
}

/* align-self, not just width: the card is a flex row and this is its only
   item, but it was sizing to its own content and stopping short of the card's
   full height. `margin-top: auto` on the button then pinned it to the bottom
   of *that* box, leaving it floating well above the card's bottom padding. */
.showcase-card .project-content {
    display: flex;
    flex-direction: column;
    align-self: stretch;
    width: 100%;
    padding: 0;
}

/* The accent is a wash behind the logo, not a stripe down the card. Twenty-six
   cards each with a 3px edge in its own brand colour read as a paint chart. */
.showcase-card .item-header {
    gap: 0.9rem;
    margin-bottom: 0.9rem;
}

.showcase-card .avatar-max-lg {
    flex: 0 0 auto;
    width: 3.5rem;
    height: 3.5rem;
    margin: 0;
    padding: 0.4rem;
    border-radius: 12px;
    /* contain, never cover: these logos are every shape from a square mark to
       a wide banner, and cover would crop the name out of half of them while
       fill would squash them. Letterboxing inside the tinted square is the
       only option that leaves every one of them readable. */
    object-fit: contain;
    background-color: color-mix(in srgb, var(--showcase-accent, var(--primary-color)) 14%, transparent);
}

/* min-width: 0 is what lets the clamp below bite: a flex item refuses to
   shrink under its content, so without it a long name pushed itself straight
   through the card edge instead of wrapping. */
.showcase-card .content {
    flex: 1 1 auto;
    min-width: 0;
    margin: 0 !important;
}

.showcase-card .server-name-text {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: 15px;
    line-height: 1.25;
    word-break: break-word;
}

.showcase-card .tags {
    gap: 0.35rem !important;
    margin: 0;
    /* No wrapping: a pill that does not fit is truncated rather than pushing
       the card taller than its neighbours. */
    flex-wrap: nowrap;
    overflow: hidden;
}

.showcase-card .status-pill {
    display: inline-block;
    padding: 0.2rem 0.6rem;
    border: 1px solid currentColor;
    border-radius: 100px;
    background: transparent;
    font-size: 10px;
    font-weight: 600;
    white-space: nowrap;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* The bottom margin is a floor, not decoration: the button below is pinned
   with `margin-top: auto`, which only takes up space that is left over — and
   the contents now fill the card almost exactly, so the leftover was about
   2px and the button came to rest against this line. Flex item margins never
   collapse, so this survives whatever `auto` resolves to. */
.showcase-card-ip {
    margin: 0.7rem 0 0.95rem;
    color: var(--primary-p-color);
    font-size: 11px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* margin-top: auto is what pins this to the bottom edge — see the equal-heights
   note above. The shorthand sets the other three and must come first, or it
   would reset the auto it is there to preserve. */
/* border-box explicitly: the theme sizes .btn as content-box, so a width of
   100% plus its 34px of horizontal padding came out wider than the card and
   the button hung off the right edge. */
.showcase-card-btn {
    box-sizing: border-box;
    width: 100%;
    margin: 1rem 0 0 !important;
    margin-top: auto !important;
    padding: 0.55rem 0.9rem;
    font-size: 12px;
}

/* ── The rewards window ────────────────────────────────────────────────── */
/* Its own width rather than borrowing `.is-wide`: that modifier is declared
   further down this file at the same specificity, so it won the tie and capped
   this at 560px — two columns of rewards where three fit. */
/* One size for every server: `height`, not the base dialog's `max-height`
   alone, so a shop with three rewards opens the same window as one with sixty
   and the window does not jump in size between servers. The body is the part
   that scrolls, and the empty state centres itself in whatever it is given.
   The `min()` keeps it inside a short screen. */
.dashboard-dialog.showcase-dialog {
    max-width: 46rem;
    height: min(42rem, calc(100vh - 2rem));
}

/* The logo rides in the title bar, so it has to stop being a card avatar. */
.showcase-dialog .avatar-max-lg {
    width: 2.5rem;
    height: 2.5rem;
    margin: 0;
    border-radius: 8px;
    object-fit: contain;
}

.showcase-dialog-name {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
    font-size: 15px;
}

.showcase-dialog-name > span {
    color: var(--primary-p-color);
    font-size: 11px;
    font-weight: 400;
}

.showcase-reward-empty {
    grid-column: 1 / -1;
    margin: 0;
    color: var(--primary-p-color);
    font-size: 12px;
}

/* The form is only a wrapper for the button, so it must not add a row of its
   own to the card column. */
.request-card-form {
    display: contents;
}

/* /discovery's search field and its "Read" button (see style.css's
   .showcase-finder / .showcase-search-btn rules): stacked on a narrow phone
   rather than the two squeezed onto one row. */
@media (max-width: 575px) {
    .showcase-search {
        flex-direction: column;
        align-items: stretch;
    }
}

/* ── Requested-reward cards on /account/requests ───────────────────────────
   Small upright rectangles: picture, name, status, the two prices, then the
   action. Sized so a row of them scans as a shelf rather than as a few large
   panels — the point of the grid is comparing them at a glance. */
.request-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(10.5rem, 1fr));
    gap: 0.75rem;
}

/* ── More than four requests ───────────────────────────────────────────────
   `RequestGridPreview` clips the grid just past the fourth card and lays the
   fade, and the link to the full list, over the strip of the next row that
   still shows. The grid is positioned so the component can measure its cards'
   offsets from it. */
.request-list {
    position: relative;
}

.request-list > .request-card-grid {
    position: relative;
}

.request-list.is-collapsed > .request-card-grid {
    overflow: hidden;
}

/* Exactly as tall as the strip left showing (PEEK in the component), so it
   never reaches up over the fourth card's own buy button. It fades to the
   card's background, which is what makes the cut read as "more below" rather
   than as cards chopped in half. */
.request-list-fade {
    position: absolute;
    right: 0;
    bottom: 0;
    left: 0;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    height: 80px;
    background: linear-gradient(
        to bottom,
        color-mix(in srgb, var(--card-bg-color) 0%, transparent),
        color-mix(in srgb, var(--card-bg-color) 85%, transparent) 55%,
        var(--card-bg-color)
    );
    pointer-events: none;
}

/* `a.` in the selector for the same reason as `.dashboard-card-header-link`:
   the theme's own rule for links outranks a bare class and turned this blue. */
.request-list-fade a.request-list-toggle {
    display: inline-flex;
    align-items: center;
    padding: 0.35rem 0.75rem;
    border: 0;
    border-radius: 100px;
    background: none;
    color: var(--white-color);
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
    pointer-events: auto;
    transition: color 0.2s ease, background-color 0.2s ease;
}

.request-list-fade a.request-list-toggle:hover {
    color: var(--primary-color);
    background-color: rgba(255, 255, 255, 0.04);
}

.request-list-fade a.request-list-toggle:focus-visible {
    outline: 2px solid var(--primary-color);
    outline-offset: 2px;
}

.request-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.55rem;
    padding: 1rem 0.8rem;
    border: 1px solid var(--card-border-color);
    border-radius: 12px;
    background-color: rgba(255, 255, 255, 0.02);
    text-align: center;
    transition: border-color 0.2s ease;
}

.request-card:hover {
    border-color: rgba(255, 255, 255, 0.16);
}

/* A fixed square whatever the shop served, so a row keeps one baseline;
   contain rather than cover because these are product art with their own
   margins, and cropping them cuts the subject out. */
.request-card-image {
    width: 3.75rem;
    height: 3.75rem;
    border-radius: 10px;
    object-fit: contain;
    background-color: rgba(255, 255, 255, 0.04);
}

/* Two lines, then an ellipsis: a long package name must not push the button
   down and break the alignment across the row. */
.request-card-name {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    margin: 0;
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1.35;
    color: var(--white-color);
}

.request-card .status-pill {
    padding: 0.2rem 0.6rem;
    font-size: 11px;
}

/* The two figures, stacked above the action. margin-top: auto is what pins
   this block and the button under it to the bottom edge, so cards with a
   one-line name and a two-line name still line up. */
.request-card-prices {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.1rem;
    margin-top: auto;
    padding-top: 0.25rem;
}

.request-card-bits {
    display: flex;
    align-items: baseline;
    gap: 0.25rem;
    color: var(--white-color);
    font-size: 16px;
    font-weight: 700;
    line-height: 1.1;
}

.request-card-bits em {
    font-size: 10px;
    font-style: normal;
    font-weight: 400;
    color: var(--primary-p-color);
}

/* The shop own figure, quieter than the AdBits one: it is there to make the
   conversion traceable, not to be the number acted on. */
.request-card-eur {
    color: var(--primary-p-color);
    font-size: 11px;
    line-height: 1.3;
}

.request-card-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
    width: 100%;
    margin: 0;
    padding: 0.6rem 0.7rem;
    font-size: 12px;
    white-space: nowrap;
}

/* The current goal keeps the same gradient — dimming the only action on the
   card to say "already chosen" reads as "disabled". The ring is the marker,
   and the icon inside has already swapped to a tick. */
.request-card-btn.is-goal {
    box-shadow: 0 0 0 2px rgba(0, 71, 255, 0.35);
}

/* A reward typed by hand carries no store price, so there is nothing to save
   up towards and no button to press. */
.request-card-nogoal {
    color: var(--primary-p-color);
    font-size: 10px;
    line-height: 1.35;
}

/* Price and currency are one question, so they sit on one line — the number
   takes the room it needs and the code stays the width of three letters. */
.request-price-row {
    display: flex;
    gap: 0.5rem;
}

.request-price-row input {
    flex: 1 1 auto;
    min-width: 0;
}

.request-price-row select {
    flex: 0 0 auto;
    width: 6rem;
}

/* ── The buy dialog for a requested reward ─────────────────────────────────*/
.request-buy-summary {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 1.15rem;
    text-align: left;
}

.request-buy-summary > div {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
}

.request-buy-summary strong {
    font-size: 13px;
    line-height: 1.3;
    color: var(--white-color);
}

.request-buy-summary span {
    color: var(--primary-p-color);
    font-size: 11px;
}

/* A stepper, not a number field: the two buttons are the whole interaction. */
.request-buy-qty {
    display: flex;
    align-items: center;
    gap: 0.85rem;
}

.request-buy-qty button {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border: 1px solid var(--card-border-color);
    border-radius: 8px;
    background: transparent;
    color: var(--white-color);
    font-size: 11px;
    transition: border-color 0.15s ease, opacity 0.15s ease;
}

.request-buy-qty button:hover:not(:disabled) {
    border-color: var(--primary-color);
}

.request-buy-qty button:disabled {
    opacity: 0.35;
    cursor: not-allowed;
}

/* Tabular figures so the number does not jostle the buttons as it grows. */
.request-buy-qty > span {
    min-width: 2.5rem;
    text-align: center;
    font-size: 15px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--white-color);
}

/* Label left, figure right — the shape a receipt is read in. */
.request-buy-total {
    margin: 0 0 1.15rem;
    padding: 0.75rem 0.9rem;
    border: 1px solid var(--card-border-color);
    border-radius: 10px;
}

.request-buy-total > div {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
}

.request-buy-total > div + div {
    margin-top: 0.4rem;
    padding-top: 0.4rem;
    border-top: 1px solid var(--card-border-color);
}

.request-buy-total dt {
    margin: 0;
    color: var(--primary-p-color);
    font-size: 12px;
    font-weight: 400;
}

.request-buy-total dd {
    margin: 0;
    color: var(--white-color);
    font-size: 14px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* The shortfall. Red because it is the reason the purchase cannot happen, not
   just another figure in the list. */
.request-buy-total dd.is-short {
    color: var(--invalid-color);
}

/* The one thing somebody must read before paying for a reward whose server
   has not joined yet, so it gets a tint rather than being one more line. */
.request-buy-note {
    display: flex;
    align-items: flex-start;
    margin: 0;
    padding: 0.65rem 0.8rem;
    border: 1px solid rgba(0, 71, 255, 0.28);
    border-radius: 10px;
    background-color: rgba(0, 71, 255, 0.08);
    color: var(--primary-p-color);
    font-size: 11px;
    line-height: 1.5;
    text-align: left;
}

/* A paid card carries a receipt where the button was. */
.request-card-paid {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.2rem;
    width: 100%;
    padding: 0.5rem 0.6rem;
    border-radius: 100px;
    background-color: rgba(46, 204, 113, 0.12);
    color: #2ecc71;
    font-size: 11px;
    font-weight: 600;
}

/* A card whose height is matched to a neighbour needs its empty state to own
   the space rather than sit at the top of it — see CustomRewardList. */
.dashboard-empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100%;
    min-height: 12rem;
    padding: 1.5rem 1rem;
    text-align: center;
}

.dashboard-empty-mark {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    margin-bottom: 1rem;
    border-radius: 50%;
    background-color: rgba(0, 71, 255, 0.12);
    color: var(--primary-color);
    font-size: 18px;
}

.dashboard-empty-title {
    margin: 0;
    font-size: 14px;
    font-weight: 600;
    color: var(--white-color);
}

.dashboard-empty-hint {
    max-width: 22rem;
    margin: 0.4rem 0 0;
    font-size: 13px;
    line-height: 1.55;
    color: var(--primary-p-color);
}

.dashboard-purchase-empty {
    margin: 0;
    text-align: center;
    color: var(--primary-p-color);
}

/* Plain table chrome, shared with the login-history table on the details page â€”
   these rules are generic, only the cell content below them is purchase-specific. */
.dashboard-purchase-table,
.details-history-table {
    width: 100%;
    border-collapse: collapse;
}

.dashboard-purchase-table th,
.dashboard-purchase-table td,
.details-history-table th,
.details-history-table td {
    padding: 0.75rem 1rem;
    text-align: left;
    font-size: 14px;
    white-space: nowrap;
    border-bottom: 1px solid var(--card-border-color);
}

.dashboard-purchase-table th,
.details-history-table th {
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--primary-p-color);
}

.dashboard-purchase-table td,
.details-history-table td {
    color: var(--white-color);
}

.dashboard-purchase-table td:last-child {
    color: var(--primary-p-color);
}

.dashboard-purchase-table tbody tr:last-child td,
.details-history-table tbody tr:last-child td {
    border-bottom: none;
}

/* The card body already pads the table, so its outer cells sit flush with the
   copy above and below it. */
.details-history-table th:first-child,
.details-history-table td:first-child {
    padding-left: 0;
}

.details-history-table th:last-child,
.details-history-table td:last-child {
    padding-right: 0;
}

.dashboard-purchase-reward strong {
    display: block;
    color: var(--white-color);
}

.dashboard-purchase-reward-desc {
    display: block;
    margin-top: 0.15rem;
    max-width: 320px;
    font-size: 12px;
    white-space: normal;
    color: var(--primary-p-color);
}

.dashboard-purchase-server-link {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.9rem;
    border-radius: 2rem;
    border: 1px solid rgba(255, 255, 255, 0.15);
    font-size: 12px;
    font-weight: 600;
    background-color: rgba(255, 255, 255, 0.06);
    white-space: nowrap;
    transition: transform 0.3s ease, box-shadow 0.3s ease, background-color 0.3s ease, border-color 0.3s ease;
}

.dashboard-purchase-server-link i {
    transition: transform 0.3s ease;
}

/* Keep the server name white like the rest of the table cells, instead of the
   blue link color. This has to out-specify the global `a:link:not(.btn)` /
   `a:hover:not(.btn)` reset (Reset region), which is (0,2,1) â€” an ancestor
   class plus the bare class only gets to (0,2,0) and silently loses, so the
   pseudo-classes have to be repeated here to clear it. Same specificity trap as
   the .dashboard-header-content bug. */
.dashboard-purchase-table a.dashboard-purchase-server-link,
.dashboard-purchase-table a.dashboard-purchase-server-link:link,
.dashboard-purchase-table a.dashboard-purchase-server-link:visited,
.dashboard-purchase-table a.dashboard-purchase-server-link:hover,
.dashboard-purchase-table a.dashboard-purchase-server-link:active {
    color: var(--white-color);
}

.dashboard-purchase-server-link:hover {
    background-color: var(--primary-color);
    border-color: var(--primary-color);
    transform: translateY(-2px);
    box-shadow: 0 8px 20px rgba(0, 71, 255, 0.35);
}

.dashboard-purchase-server-link:hover i {
    transform: translateX(3px);
}

.dashboard-purchase-server-link:active {
    transform: translateY(0);
    box-shadow: none;
}

.minecraft-connect-modal .modal-dialog {
    width: calc(100% - 2rem);
    max-width: 580px;
    margin-left: auto;
    margin-right: auto;
}

.minecraft-connect-modal .modal-content {
    background-color: var(--card-bg-color);
    border-radius: 0.75rem;
}

.minecraft-connect-modal .modal-header {
    background-color: rgba(255, 255, 255, 0.04);
    border-bottom: 1px solid var(--card-border-color);
}

[data-theme="light"] .minecraft-connect-modal .modal-header {
    background-color: rgba(20, 21, 43, 0.03);
    border-bottom-color: rgba(20, 21, 43, 0.1);
}

.minecraft-connect-modal-title {
    display: flex;
    align-items: center;
    cursor: pointer;
}

.minecraft-connect-intro {
    margin: 0 0 1.25rem;
    font-size: 14px;
    color: var(--primary-p-color);
}

.minecraft-connect-input-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.minecraft-connect-input-row input {
    flex: 1;
    min-width: 0;
}

.minecraft-connect-input-row button {
    flex-shrink: 0;
    white-space: nowrap;
}

/* --- Account details page ------------------------------------------------ */

.details-profile {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
}

/* Same treatment as the navbar's .account-avatar, scaled up to a page-level
   profile badge. */
.details-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 72px;
    width: 72px;
    border-radius: 50%;
    background-image: linear-gradient(135deg, var(--primary-color) 10%, var(--secondary-color));
    color: var(--btn-text-color);
    font-size: 1.75rem;
    font-weight: 600;
    line-height: 1;
}

/* Discord avatar variant of .details-avatar â€” same 72px circle, image instead
   of the initial. */
.details-avatar-img {
    height: 72px;
    width: 72px;
    border-radius: 50%;
    object-fit: cover;
}

.details-profile-name {
    color: var(--white-color);
    overflow-wrap: anywhere;
}

.details-profile-email {
    font-size: 14px;
    color: var(--primary-p-color);
    overflow-wrap: anywhere;
}

/* The base .status-pill chrome (padding/border/radius) is scoped to
   .card.project-card, so pills used outside a Discovery card render as bare
   coloured text â€” re-declare it for the pills on this page. */
.details-security-info .status-pill,
.details-notify-text .status-pill,
.details-platform .status-pill,
.dashboard-ticket-status .status-pill,
.request-card .status-pill {
    display: inline-block;
    padding: 0.3rem 0.8rem;
    border-radius: 100px;
    font-size: 12px;
    font-weight: 600;
    background: transparent;
    border: 1px solid currentColor;
    white-space: nowrap;
}

.details-info-list {
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
}

.details-info-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
}

.details-info-label {
    font-size: 13px;
    color: var(--primary-p-color);
    flex-shrink: 0;
}

.details-info-value {
    font-size: 14px;
    text-align: right;
    color: var(--white-color);
    overflow-wrap: anywhere;
}

.details-info-mono {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 13px;
}

/* Section selector above the details column. The bar is a card in its own
   right, so it carries the same surface and radius language as the blocks it
   switches between. */
.details-sections {
    display: flex;
    flex-direction: column;
    flex-grow: 1;
}

.details-tabs {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    margin-bottom: 1.5rem;
    padding: 0.35rem;
    background-color: var(--card-bg-color);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 100px;
    /* Two tabs fit anywhere, but the bar scrolls rather than wraps so adding a
       third one later can never stack pills into a second row. */
    overflow-x: auto;
    scrollbar-width: none;
}

.details-tabs::-webkit-scrollbar {
    display: none;
}

.details-tab {
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
    gap: 0.55rem;
    padding: 0.65rem 1.25rem;
    border: 0;
    border-radius: 100px;
    background-color: transparent;
    color: var(--primary-p-color);
    font-size: 14px;
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    transition: background-color 0.2s ease, color 0.2s ease;
}

.details-tab i {
    font-size: 15px;
}

.details-tab:hover {
    background-color: rgba(255, 255, 255, 0.05);
    color: var(--white-color);
}

/* Same gradient as .details-avatar and the theme's filled buttons, so the
   selected section reads as active the way every other accent on the page
   does. */
.details-tab.active,
.details-tab.active:hover {
    background-image: linear-gradient(135deg, var(--primary-color) 10%, var(--secondary-color));
    color: var(--btn-text-color);
}

.details-tab:focus-visible {
    outline: 2px solid var(--primary-color);
    outline-offset: 2px;
}

/* The panel takes over the column's leftover height so the card inside it can
   still stretch â€” but only the shown one, or [hidden] would stop working. */
.details-panel:not([hidden]) {
    display: flex;
    flex-direction: column;
    flex-grow: 1;
}

.details-section-intro {
    margin: 0 0 1.5rem;
    font-size: 14px;
    color: var(--primary-p-color);
}

.details-form .form-group {
    margin-bottom: 1.25rem;
}

.details-form .form-group label {
    display: block;
    margin-bottom: 0.5rem;
    font-size: 13px;
    font-weight: 600;
    color: var(--white-color);
}

.details-form input:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

/* Native <select> popups are drawn by the OS from the control's own colours,
   and the theme's Reset region paints every `select option` #2f323a for a light
   popup - which is right on the marketing pages and wrong on these, where the
   control sits on a dark card. Without this the closed select looks correct and
   the list that drops out of it is white.

   `color-scheme` is what makes the browser paint the rest of that native list -
   its highlight and its scrollbar - to match; the option colours alone are not
   enough. The same pair, for the same reason, appears in region 15 for
   `.console-input`.

   Scoped to `.details-form` rather than to `select` at large: that class is the
   app's own form chrome (the account pages and the support forms), so the
   site's public marketing forms keep the theme's light popup. */
/* One outline for all three fields.

   The theme sets border-color and border-width on `input, textarea, select` but
   never border-style, and it corrects the colour to --primary-p-color for
   `input` and `textarea` only. Two consequences show up side by side in a
   ticket form: a select keeps --primary-l-color (rgba(0,0,0,.12), invisible on
   a dark card), and an input keeps the browser's default `inset`, which fakes a
   bevel and reads differently from the `solid` on its neighbours. */
.details-form input,
.details-form textarea,
.details-form select {
    border-style: solid;
    border-color: var(--primary-p-color);
}

/* The theme sets `appearance: none` on every select and `background: no-repeat`
   with no image, so the native dropdown arrow is removed and nothing replaces
   it - a select ends up looking exactly like the text inputs above and below
   it. This puts a chevron back, as an inline SVG so it needs no asset and takes
   the same --primary-p-color as the border.

   `padding-right` is widened to match, or a long option runs under the arrow. */
.details-form select {
    color-scheme: dark;
    padding-right: 2.75rem;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%239CA0D2' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 1rem center;
    background-size: 14px 14px;
}

/* Until something is picked the control reads as a prompt, not as an answer. */
.details-form select:invalid {
    color: var(--primary-p-color);
}

.details-form select option,
.details-form select optgroup {
    background-color: #1b1e35;
    color: var(--white-color);
}

/* In light mode `.details-form` sits on a light card, so the native popup
   should match the theme's default light popup (the same one the public
   marketing forms already use) instead of staying forced dark. */
[data-theme="light"] .details-form select {
    color-scheme: light;
}

[data-theme="light"] .details-form select option,
[data-theme="light"] .details-form select optgroup {
    background-color: #FFFFFF;
    color: var(--white-color);
}

/* The weight is stated because this class is worn by both <p> and <small>,
   and <small> inherits 600 from the base typography — same class, two
   different-looking hints on the same dialog until it is pinned here. */
.details-form-hint {
    display: block;
    margin-top: 0.5rem;
    font-size: 12px;
    font-weight: 400;
    line-height: 1.5;
    color: var(--primary-p-color);
}

.details-form-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: 1rem;
}

.details-form-actions .form-message {
    font-size: 14px;
}

/* Tighter than the default 1.5rem card padding â€” the card is just a frame
   around one button. */
.details-back-card .dashboard-card-body {
    padding: 0.75rem;
}

/* --- 2FA window (visual preview, see TwoFactorModal) --- */

.twofa-modal .modal-dialog {
    width: calc(100% - 2rem);
    max-width: 620px;
    margin-left: auto;
    margin-right: auto;
}

.twofa-modal .modal-content {
    background-color: var(--card-bg-color);
    border-radius: 0.75rem;
}

.twofa-modal .modal-header {
    background-color: rgba(255, 255, 255, 0.04);
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

[data-theme="light"] .twofa-modal .modal-header {
    background-color: rgba(20, 21, 43, 0.03);
    border-bottom-color: rgba(20, 21, 43, 0.1);
}

.twofa-modal-title {
    display: flex;
    align-items: center;
    font-weight: 600;
    color: var(--white-color);
    cursor: pointer;
}

.twofa-modal-title i {
    color: var(--primary-color);
}

.twofa-status-banner {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    padding: 0.85rem 1.1rem;
    border-radius: 10px;
    border: 1px solid rgba(231, 76, 60, 0.35);
    background-color: rgba(231, 76, 60, 0.12);
    color: #e74c3c;
    font-size: 14px;
}

.twofa-status-banner.enabled {
    border-color: rgba(46, 204, 113, 0.35);
    background-color: rgba(46, 204, 113, 0.12);
    color: #2ecc71;
}

.twofa-description {
    margin: 1.25rem 0;
    font-size: 14px;
    line-height: 1.6;
    color: var(--secondary-p-color);
}

.twofa-setup-btn {
    display: inline-flex;
    align-items: center;
    padding: 0.6rem 1.2rem;
    border: none;
    /* Pill, matching the theme's .btn (border-radius: 100px). */
    border-radius: 100px;
    background-color: var(--primary-color);
    color: var(--btn-text-color);
    font-size: 14px;
    font-weight: 600;
    transition: 0.3s;
}

.twofa-setup-btn:hover {
    filter: brightness(1.15);
}

.twofa-setup {
    margin-top: 1.25rem;
}

.twofa-field-label {
    display: flex;
    align-items: center;
    margin: 1.25rem 0 0.6rem;
    font-size: 13px;
    color: var(--primary-p-color);
}

.twofa-setup > .twofa-field-label:first-child {
    margin-top: 0;
}

.twofa-qr-box {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    width: 180px;
    height: 180px;
    margin: 0 auto;
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 10px;
    background-color: rgba(255, 255, 255, 0.03);
}

[data-theme="light"] .twofa-qr-box {
    border-color: rgba(20, 21, 43, 0.12);
    background-color: rgba(20, 21, 43, 0.03);
}

.twofa-qr-icon {
    font-size: 3rem;
    color: rgba(255, 255, 255, 0.25);
}

[data-theme="light"] .twofa-qr-icon {
    color: rgba(20, 21, 43, 0.18);
}

.twofa-qr-caption {
    font-size: 12px;
    color: var(--primary-p-color);
}

.twofa-key-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.75rem 1rem;
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 8px;
    background-color: rgba(255, 255, 255, 0.03);
}

[data-theme="light"] .twofa-key-row {
    border-color: rgba(20, 21, 43, 0.12);
    background-color: rgba(20, 21, 43, 0.03);
}

.twofa-key-value {
    flex: 1 1 auto;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-weight: 600;
    color: var(--white-color);
    overflow-wrap: anywhere;
}

.twofa-copy-btn {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    padding: 0;
    border: none;
    border-radius: 6px;
    background: none;
    color: var(--primary-p-color);
    transition: 0.3s;
}

.twofa-copy-btn:hover {
    color: var(--white-color);
    background-color: rgba(255, 255, 255, 0.08);
}

[data-theme="light"] .twofa-copy-btn:hover {
    background-color: rgba(20, 21, 43, 0.08);
}

/* The theme's global input rule sets a 2px border in --primary-p-color, which
   reads as a bright outline against this dark panel â€” match the key row above
   instead. Narrower and centered under its label, rather than the theme's
   default full-width input: a 6-digit code stretched across the whole modal
   reads as a text field waiting for a sentence, not a short code. */
.twofa-modal input.twofa-code-input {
    width: 100%;
    height: 48px;
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 8px;
    background-color: rgba(255, 255, 255, 0.03);
    color: var(--white-color);
    font-size: 15px;
    letter-spacing: 4px;
}

[data-theme="light"] .twofa-modal input.twofa-code-input {
    border-color: rgba(20, 21, 43, 0.12);
    background-color: rgba(20, 21, 43, 0.03);
}

.twofa-modal input.twofa-code-input::placeholder {
    color: rgba(255, 255, 255, 0.25);
    letter-spacing: 2px;
}

[data-theme="light"] .twofa-modal input.twofa-code-input::placeholder {
    color: rgba(20, 21, 43, 0.25);
}

.twofa-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 1.5rem;
    padding-top: 1.15rem;
    border-top: 1px solid rgba(255, 255, 255, 0.08);
}

[data-theme="light"] .twofa-actions {
    border-top-color: rgba(20, 21, 43, 0.1);
}

.twofa-cancel-btn,
.twofa-enable-btn {
    display: inline-flex;
    align-items: center;
    padding: 0.6rem 1.2rem;
    border: none;
    border-radius: 100px;
    font-size: 14px;
    font-weight: 600;
    transition: 0.3s;
}

.twofa-cancel-btn {
    background-color: rgba(255, 255, 255, 0.08);
    color: var(--secondary-p-color);
}

[data-theme="light"] .twofa-cancel-btn {
    background-color: rgba(20, 21, 43, 0.06);
}

.twofa-cancel-btn:hover {
    background-color: rgba(255, 255, 255, 0.14);
    color: var(--white-color);
}

[data-theme="light"] .twofa-cancel-btn:hover {
    background-color: rgba(20, 21, 43, 0.12);
}

.twofa-enable-btn {
    background-color: var(--primary-color);
    color: var(--white-color);
}

.twofa-enable-btn:hover:not(:disabled) {
    filter: brightness(1.15);
}

.twofa-enable-btn:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

/* Disabling 2FA is destructive enough to warrant its own color, same red as
   the unlink control and the "disabled" status banner - previously inlined as
   a one-off `style` prop on the button. */
.twofa-enable-btn.is-danger {
    background-color: #dc3545;
    color: white;
}

.twofa-enable-btn.is-danger:hover:not(:disabled) {
    background-color: #c82333;
    filter: none;
}

/* Was previously unstyled - a bare, unindented line of text after the input
   read as broken layout rather than a validation message. */
.twofa-error {
    display: flex;
    align-items: center;
    margin: 1rem 0 0;
    padding: 0.65rem 0.9rem;
    border-radius: 8px;
    border: 1px solid rgba(231, 76, 60, 0.35);
    background-color: rgba(231, 76, 60, 0.12);
    color: #e74c3c !important;
    font-size: 13px;
}

.twofa-preview-notice {
    display: flex;
    align-items: flex-start;
    margin: 1.25rem 0 0;
    padding: 0.75rem 1rem;
    border-radius: 8px;
    border: 1px solid rgba(245, 166, 35, 0.3);
    background-color: rgba(245, 166, 35, 0.1);
    font-size: 13px;
    line-height: 1.5;
    color: #f5a623;
}

.details-security-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 1rem;
}

.details-security-info {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.details-security-name {
    font-weight: 600;
    color: var(--white-color);
}

.details-security-form {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
    width: auto;
}

.details-security-message {
    font-size: 13px;
}

.details-security-divider {
    margin: 1.5rem 0;
    border: 0;
    border-top: 1px solid rgba(255, 255, 255, 0.08);
    opacity: 1;
}

.reset-hint {
    font-size: 14px;
    line-height: 1.6;
    color: var(--primary-p-color);
}

/* The 2FA button is intentionally inert until the enrolment flow exists â€”
   make that unmistakable instead of leaving it looking clickable. */
.details-security-row .btn:disabled {
    opacity: 0.45;
    cursor: not-allowed;
    pointer-events: none;
}

/* --- Notification channels ------------------------------------------------ */

/* Left to the inherited flex-wrap, whether a channel keeps its switch on the
   same line depends on how long its address happens to be â€” a short Discord
   name stays inline while a long email address pushes its switch down, so the
   two rows disagree. Below 576px both stack. */
@media (max-width: 575.98px) {
    .details-notify-row {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.85rem;
    }
}

.details-notify-channel {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    min-width: 0;
}

/* Shared by the notification channels and the active-session row. */
.details-icon-plate {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    flex-shrink: 0;
    border-radius: 12px;
    background-color: rgba(255, 255, 255, 0.05);
    color: var(--white-color);
    font-size: 16px;
}

.details-notify-text {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}

.details-notify-target {
    font-size: 13px;
    color: var(--primary-p-color);
    overflow-wrap: anywhere;
}

/* A channel with nowhere to deliver to reads as unset rather than as an
   address, so it is never mistaken for a real destination. */
.details-notify-target.is-missing {
    font-style: italic;
    opacity: 0.75;
}

/* When the session's expiry has to sit under the device rather than beside it,
   it lines up with the device name instead of hanging off the icon. */
.details-session-meta {
    font-size: 13px;
    color: var(--primary-p-color);
}

/* Same geometry as the console's .console-toggle, in this page's palette â€”
   the two prefixes stay separate because the stylesheet is global. */
.details-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.65rem;
    cursor: pointer;
    user-select: none;
}

.details-toggle.is-disabled {
    cursor: not-allowed;
    opacity: 0.45;
}

.details-toggle-input {
    position: absolute;
    width: 0;
    height: 0;
    opacity: 0;
}

.details-toggle-track {
    position: relative;
    width: 44px;
    height: 24px;
    flex-shrink: 0;
    border-radius: 999px;
    background-color: rgba(255, 255, 255, 0.16);
    transition: background-color 0.2s ease;
}

.details-toggle-thumb {
    position: absolute;
    top: 2px;
    left: 2px;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background-color: #fff;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
    transition: left 0.2s ease;
}

.details-toggle-input:checked + .details-toggle-track {
    background-image: linear-gradient(135deg, var(--primary-color) 10%, var(--secondary-color));
}

.details-toggle-input:checked + .details-toggle-track .details-toggle-thumb {
    left: 22px;
}

.details-toggle-input:focus-visible + .details-toggle-track {
    box-shadow: 0 0 0 3px rgba(0, 71, 255, 0.35);
}

.details-toggle-text {
    min-width: 4.5rem;
    font-size: 13px;
    font-weight: 600;
    color: var(--secondary-p-color);
}

.details-platform-list {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.details-platform {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.9rem 1rem;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 0.75rem;
    background-color: rgba(255, 255, 255, 0.03);
}

.details-platform .avatar-max-lg {
    height: 2.75rem;
    width: 2.75rem;
    border-radius: 10px;
    object-fit: cover;
    flex-shrink: 0;
}

.details-platform-info {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
    margin-right: auto;
}

.details-platform-name {
    font-weight: 600;
    color: var(--white-color);
    overflow-wrap: anywhere;
}

.details-platform-id {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 12px;
    color: var(--primary-p-color);
    overflow-wrap: anywhere;
}

.details-platform-empty {
    text-align: center;
    padding: 1rem 0;
}

/* --- Top Buyers leaderboard (server page) ------------------------------- */

/* Positioning context for the rail: it wraps the "need more AdBits?" banner, so
   anchoring the rail to its top edge is what lines the two up. */
.server-rail-anchor {
    position: relative;
}

.top-buyers-rail {
    margin-bottom: 0rem;
}

/* Below the rail breakpoint there is no room in the margin, so the rail is
   hidden and .top-buyers-mobile (rendered after the rewards) takes over. */
.top-buyers-mobile {
    display: none;
}

@media (max-width: 1899.98px) {
    .server-rail-anchor {
        display: none;
    }

    .top-buyers-mobile {
        display: block;
    }
}

/* Wide screens: lift it out into the empty page margin to the left of the
   container, so the rewards keep the full 1170px.
   `right: calc(100% + â€¦)` puts the rail's right edge that far to the left of the
   container's left edge. The breakpoint is not arbitrary: the container is
   1170px, so each margin is (viewport âˆ’ 1170) / 2, and the rail only fits once
   that exceeds its own width plus the gap â€” at 1900px the margin is 365px
   against the 344px needed. Any narrower and it would hang off the viewport. */
@media (min-width: 1900px) {
    .top-buyers-rail {
        position: absolute;
        top: 0;
        right: calc(100% + 1.5rem);
        width: 320px;
        margin-bottom: 0;
    }
}

.top-buyers {
    display: block;
    padding: 1.5rem;
    border-radius: 1rem;
    border: 1px solid rgba(255, 255, 255, 0.08);
    background-color: var(--card-bg-color);
}

.top-buyers-eyebrow {
    display: block;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: var(--primary-color);
}

.top-buyers-title {
    margin: 0.5rem 0 0.35rem;
    color: var(--white-color);
}

.top-buyers-subtitle {
    margin: 0 0 1.25rem;
    font-size: 13px;
    color: var(--primary-p-color);
}

.top-buyers-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
}

.top-buyer {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    padding: 0.85rem 1rem;
    border-radius: 12px;
    border: 1px solid transparent;
    background-color: rgba(255, 255, 255, 0.04);
}

/* Podium colours: the medal tints the rank disc, its border and the score. */
.top-buyer.gold {
    border-color: rgba(245, 166, 35, 0.5);
    background-color: rgba(245, 166, 35, 0.08);
}

.top-buyer-rank {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    flex-shrink: 0;
    border-radius: 50%;
    background-color: rgba(255, 255, 255, 0.1);
    color: var(--primary-p-color);
    font-size: 13px;
    font-weight: 700;
}

.top-buyer.gold .top-buyer-rank {
    background-color: #f5a623;
    color: #2b1c00;
}

.top-buyer.silver .top-buyer-rank {
    background-color: #c3c9d4;
    color: #23262e;
}

.top-buyer.bronze .top-buyer-rank {
    background-color: #c8823c;
    color: #2b1600;
}

/* min-width: 0 is what lets the name ellipsis actually engage â€” without it the
   flex item refuses to shrink and pushes the score out of the row. */
.top-buyer-body {
    flex: 1 1 auto;
    min-width: 0;
}

.top-buyer-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
}

.top-buyer-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 600;
    color: var(--white-color);
}

.top-buyer-score {
    flex-shrink: 0;
    font-weight: 700;
    color: var(--primary-color);
}

.top-buyer.gold .top-buyer-score {
    color: #f5a623;
}

.top-buyer-bar {
    height: 6px;
    margin: 0.5rem 0 0.4rem;
    border-radius: 3px;
    background-color: rgba(255, 255, 255, 0.08);
    overflow: hidden;
}

.top-buyer-bar-fill {
    display: block;
    height: 100%;
    border-radius: 3px;
    background-color: var(--primary-color);
}

.top-buyer.gold .top-buyer-bar-fill {
    background-image: linear-gradient(90deg, #f5a623, #ffcf6b);
}

.top-buyer.silver .top-buyer-bar-fill {
    background-color: #c3c9d4;
}

.top-buyer.bronze .top-buyer-bar-fill {
    background-color: #c8823c;
}

.top-buyer-meta {
    display: block;
    font-size: 12px;
    color: var(--primary-p-color);
}

.top-buyers-note {
    margin-top: 1.5rem;
    padding: 0.85rem 1rem;
    border-radius: 12px;
    border: 1px solid rgba(0, 71, 255, 0.35);
    background-color: rgba(0, 71, 255, 0.1);
    font-size: 13px;
    line-height: 1.5;
    color: var(--secondary-p-color);
}

/* --- Gaming task details modal (step rewards + QR) ---------------------- */

.task-details-modal .modal-dialog {
    width: calc(100% - 2rem);
    max-width: 470px;
    margin-left: auto;
    margin-right: auto;
}

.task-details-modal .modal-content {
    background-color: var(--card-bg-color);
    border-radius: 1rem;
    overflow: hidden;
}

.task-details-hero {
    position: relative;
    height: 190px;
    flex-shrink: 0;
    background-color: rgba(255, 255, 255, 0.04);
}

.task-details-hero-img {
    object-fit: cover;
}

.task-details-close {
    position: absolute;
    top: 0.75rem;
    right: 0.75rem;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    padding: 0;
    border: none;
    border-radius: 10px;
    background-color: rgba(0, 0, 0, 0.55);
    color: var(--white-color);
    font-size: 15px;
    transition: 0.3s;
}

.task-details-close:hover {
    background-color: rgba(0, 0, 0, 0.8);
}

/* The theme's global `.modal-body { display: flex; align-items: center }`
   (Modal region) would lay these blocks out side by side â€” which is exactly
   what it did: the title wrapped one letter per line and the rewards panel sat
   off-screen to the right. The other modals dodge this with a `.w-100` child;
   here the stack is reset outright. */
.task-details-modal .modal-body {
    display: block;
    padding: 1.25rem 1.5rem 1.75rem;
}

.task-details-heading {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    min-width: 0;
}

.task-details-heading h4 {
    color: var(--white-color);
    font-size: 1.15rem;
    line-height: 1.3;
    min-width: 0;
    overflow-wrap: anywhere;
}

.task-details-icon {
    border-radius: 12px;
    object-fit: cover;
    flex-shrink: 0;
}

/* Provider descriptions run long and unstructured; clamp them so the rewards
   panel stays visible without scrolling. */
.task-details-description {
    margin: 1rem 0 0;
    font-size: 13px;
    line-height: 1.6;
    color: var(--primary-p-color);
    display: -webkit-box;
    -webkit-line-clamp: 5;
    line-clamp: 5;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.task-details-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 1rem;
}

.task-details-chip {
    display: inline-flex;
    align-items: center;
    padding: 0.3rem 0.75rem;
    border-radius: 8px;
    background-color: rgba(255, 255, 255, 0.06);
    color: var(--secondary-p-color);
    font-size: 12px;
    font-weight: 600;
}

.task-details-rewards {
    margin-top: 1.25rem;
    padding: 0.85rem;
    border-radius: 12px;
    background-color: rgba(255, 255, 255, 0.04);
}

.task-details-rewards-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0 0.3rem 0.75rem;
    font-size: 13px;
    color: var(--primary-p-color);
}

.task-details-rewards-total {
    color: var(--secondary-p-color);
    font-weight: 600;
    white-space: nowrap;
}

.task-details-reward-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.task-details-reward {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.6rem 0.75rem;
    border-radius: 10px;
    background-color: rgba(255, 255, 255, 0.04);
    font-size: 13px;
    color: var(--white-color);
}

.task-details-reward-index {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    flex-shrink: 0;
    border-radius: 50%;
    background-color: rgba(255, 255, 255, 0.1);
    color: var(--primary-p-color);
    font-size: 11px;
    font-weight: 600;
}

/* min-width: 0 is what actually lets the ellipsis kick in â€” without it a flex
   item refuses to shrink below its content and pushes the time and amount
   columns out of the row. */
.task-details-reward-label {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.task-details-reward-time {
    flex-shrink: 0;
    color: var(--primary-p-color);
    font-size: 12px;
    white-space: nowrap;
}

.task-details-reward-amount {
    flex-shrink: 0;
    color: var(--white-color);
    font-weight: 700;
    white-space: nowrap;
}

.task-details-reward-amount i {
    color: var(--primary-color);
}

.task-details-toggle {
    width: 100%;
    margin-top: 0.75rem;
    padding: 0.55rem;
    border: none;
    border-radius: 10px;
    background-color: rgba(255, 255, 255, 0.06);
    color: var(--secondary-p-color);
    font-size: 13px;
    font-weight: 600;
    transition: 0.3s;
}

.task-details-toggle:hover {
    background-color: rgba(255, 255, 255, 0.12);
    color: var(--white-color);
}

.task-details-scan {
    margin: 1.5rem 0 0.75rem;
    text-align: center;
    font-size: 13px;
    color: var(--primary-p-color);
}

.task-details-qr {
    display: block;
    margin: 0 auto;
    width: 160px;
    height: 160px;
    border-radius: 8px;
    background-color: #ffffff;
    padding: 6px;
}

.task-details-cta {
    display: block;
    width: fit-content;
    margin: 1.25rem auto 0;
}

/* â”€â”€ Support tickets â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

/* The player's side of the ticket system: /account/support and one thread.
   Everything else on those pages reuses the account chrome already defined
   above (.dashboard-card, .dashboard-purchase-table, .details-form), so this
   block is only the conversation itself.

   The pill chrome these rows need is handled by adding
   .dashboard-ticket-status to the scoped .status-pill selector further up â€”
   only the colour modifiers of .status-pill are global. */

.dashboard-ticket-number {
    font-family: var(--bs-font-monospace, monospace);
    color: var(--primary-p-color);
    white-space: nowrap;
}

.dashboard-ticket-unread {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    margin-left: 0.6rem;
    font-size: 11px;
    font-weight: 600;
    color: var(--secondary-color);
}

.dashboard-ticket-unread i {
    font-size: 6px;
}

/* The conversation scrolls inside the card rather than stretching it. A long
   thread used to push the page down until the reply box and the ticket details
   beside it were off screen - the two things you actually came to use. The
   cap is in `vh` so it adapts to the window instead of being a guess in pixels,
   with a floor so a short window still shows more than one message. */
.dashboard-ticket-thread {
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
    margin: 0;
    padding: 0 0.5rem 0 0;
    list-style: none;
    max-height: max(320px, 52vh);
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
}

.dashboard-ticket-thread::-webkit-scrollbar {
    width: 8px;
}

.dashboard-ticket-thread::-webkit-scrollbar-thumb {
    border-radius: 100px;
    background-color: rgba(255, 255, 255, 0.18);
}

.dashboard-ticket-thread::-webkit-scrollbar-thumb:hover {
    background-color: rgba(255, 255, 255, 0.3);
}

.dashboard-ticket-message {
    padding: 0.95rem 1.1rem;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 14px;
    background-color: rgba(255, 255, 255, 0.02);
}

/* Staff replies are tinted and inset, so a long thread reads as two sides of a
   conversation rather than a stack of identical boxes. Same treatment as the
   staff panel's own thread in region 15 — one product, two areas. */
.dashboard-ticket-message.is-agent {
    margin-left: 1.75rem;
    background-color: rgba(37, 99, 235, 0.08);
    border-color: rgba(37, 99, 235, 0.28);
}

.dashboard-ticket-author {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-bottom: 0.6rem;
    color: var(--white-color);
    font-size: 14px;
}

.dashboard-ticket-avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    flex-shrink: 0;
    border-radius: 50%;
    background-color: rgba(255, 255, 255, 0.1);
    color: var(--white-color);
    font-size: 12px;
}

/* Carrying a picture rather than a glyph: the tint goes, or it shows through
   anything transparent, and `overflow: hidden` is what rounds it. */
.dashboard-ticket-avatar.has-image {
    overflow: hidden;
    background-color: transparent;
}

.dashboard-ticket-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* `:not(.has-image)` so a staff message only keeps the blue plate while it is
   showing the headset glyph. */
.dashboard-ticket-message.is-agent .dashboard-ticket-avatar:not(.has-image) {
    background-color: #2563eb;
    color: #ffffff;
}

.dashboard-ticket-name {
    flex: 1;
    min-width: 0;
    font-size: 13px;
    font-weight: 600;
}

.dashboard-ticket-time {
    flex-shrink: 0;
    font-size: 11px;
    color: var(--primary-p-color);
    white-space: nowrap;
}

@media (max-width: 575px) {
    .dashboard-ticket-message.is-agent {
        margin-left: 0.75rem;
    }
}

/* Message bodies are plain text that keeps the author's own line breaks â€”
   nothing is stored or rendered as HTML, so pre-wrap is the whole formatting
   story and there is no sanitiser involved. */
.dashboard-ticket-body {
    margin: 0;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    line-height: 1.6;
}

/* -- Closing a ticket ------------------------------------------------------
   Its own card under the ticket details, and a confirmation dialog in front of
   it: for the requester this is irreversible - only an agent can reopen - so it
   is deliberately not one click inside the reply form.

   The dialog is hand-rolled rather than ConsoleModal: that component and its
   .console-modal-* classes belong to region 15, and these pages are region 13.
   Mixing the two prefixes is exactly what the note at the top of this file
   warns about. */

.dashboard-close-text {
    margin-bottom: 1rem;
    font-size: 13px;
    line-height: 1.6;
    color: var(--primary-p-color);
}

/* The composer is a second body inside the thread's card, not a card of its
   own. A rule rather than a gap: the two belong together, and the separation
   only has to say "this part is yours to type in". The thread's own bottom
   padding is dropped so the rule sits tight under the last message. */
.dashboard-ticket-composer {
    border-top: 1px solid rgba(255, 255, 255, 0.08);
    padding-top: 1.25rem;
}

/* -- Reply composer --------------------------------------------------------
   The send control is an icon beside the box, not a full-width button under
   it: replying is the obvious thing to do on this page, so the affordance does
   not need a label taking up a row of its own. The label survives as the
   accessible name and the tooltip. */

.dashboard-reply-row {
    display: flex;
    align-items: flex-start;
    flex-wrap: wrap;
    gap: 0.75rem;
}

/* Matched to the send button beside it - the theme's default `height: 100px`
   left a tall box next to a small round one and the pair read as unrelated.
   `resize: vertical` overrides the theme's `resize: none` so a long reply is
   not written through a letterbox: it starts at one line's worth and the
   person can drag it open. */
.dashboard-reply-row textarea {
    flex: 1;
    min-width: 0;
    height: 50px;
    min-height: 50px;
    resize: vertical;
}

.dashboard-send-btn {
    flex-shrink: 0;
    width: 50px;
    height: 50px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0 none;
    border-radius: 50%;
    background-image: linear-gradient(135deg, var(--primary-color) 10%, var(--secondary-color));
    color: var(--btn-text-color);
    font-size: 15px;
    cursor: pointer;
    transition: filter 0.15s, transform 0.15s;
}

.dashboard-send-btn:hover:not(:disabled) {
    filter: brightness(1.15);
    transform: translateY(-1px);
}

.dashboard-send-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* -- Attachments ----------------------------------------------------------
   The paperclip beside the send button, the chips for what it picked, and the
   files already on a message.

   The picker emits its file input, its button and its chip list as siblings,
   because the button has to sit inside the reply row while the chips belong
   under it. That is what `flex-wrap` above plus `flex-basis: 100%` here buys:
   the list drops to its own line without the component having to be split in
   two, and `order` keeps it after the send button rather than between the box
   and the paperclip. */

/* Visually hidden, NOT `display: none`: a display-none file input is skipped by
   some browsers' form submission, and this one carries the payload. */
.dashboard-attach-input {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0 none;
}

/* Same 50px circle as the send button beside it, but quiet: sending is the
   action, attaching is an option. A gradient on both would make them read as a
   pair of equals. */
.dashboard-attach-btn {
    flex-shrink: 0;
    width: 50px;
    height: 50px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 50%;
    background-color: #212445;
    color: var(--secondary-p-color);
    font-size: 15px;
    cursor: pointer;
    transition: color 0.15s, border-color 0.15s, transform 0.15s, background-color 0.15s;
}

[data-theme="light"] .dashboard-attach-btn {
    background-color: #F0F1F7;
}

.dashboard-attach-btn:hover:not(:disabled) {
    color: var(--white-color);
    border-color: rgba(255, 255, 255, 0.3);
    transform: translateY(-1px);
}

[data-theme="light"] .dashboard-attach-btn:hover:not(:disabled) {
    border-color: rgba(20, 21, 43, 0.3);
}

.dashboard-attach-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.dashboard-attach-list {
    order: 2;
    flex-basis: 100%;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.dashboard-attach-chip {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    max-width: 100%;
    padding: 0.4rem 0.6rem;
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 8px;
    background-color: #212445;
    font-size: 12px;
    color: var(--secondary-p-color);
}

[data-theme="light"] .dashboard-attach-chip {
    background-color: #F0F1F7;
}

.dashboard-attach-chip > i {
    flex-shrink: 0;
    color: var(--primary-color);
}

/* The name is the part that can be long, so it is the only part allowed to
   shrink; the size and the remove control keep their width. */
.dashboard-attach-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--white-color);
}

.dashboard-attach-size {
    flex-shrink: 0;
    font-size: 11px;
    color: var(--primary-p-color);
}

.dashboard-attach-remove {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    padding: 0;
    border: 0 none;
    border-radius: 50%;
    background: transparent;
    color: var(--primary-p-color);
    font-size: 11px;
    cursor: pointer;
    transition: color 0.15s, background-color 0.15s;
}

.dashboard-attach-remove:hover:not(:disabled) {
    background-color: rgba(255, 255, 255, 0.1);
    color: var(--white-color);
}

.dashboard-attach-error {
    flex-basis: 100%;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 12px;
    color: #ff6b81;
}

/* On the two forms that open a ticket there is no send icon to sit beside, so
   the paperclip gets a labelled row of its own with the limits spelled out. */
.dashboard-attach-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.dashboard-attach-hint {
    font-size: 12px;
    color: var(--primary-p-color);
}

/* -- Files on a message ---------------------------------------------------
   Images become a thumbnail that opens full size; everything else is a row you
   download. Both are anchors, so all four link states are restated below to
   clear the theme's `a:link:not(.btn)` rule -- see the note at the top of this
   file. Declaring only :link would leave them flashing blue on hover. */

.dashboard-ticket-files {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0.7rem 0 0;
    padding: 0;
    list-style: none;
}

.dashboard-ticket-file a {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    max-width: 320px;
    padding: 0.45rem 0.7rem;
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 8px;
    background-color: rgba(0, 0, 0, 0.2);
    transition: border-color 0.15s, background-color 0.15s;
}

.dashboard-ticket-files .dashboard-ticket-file a:link,
.dashboard-ticket-files .dashboard-ticket-file a:visited,
.dashboard-ticket-files .dashboard-ticket-file a:hover,
.dashboard-ticket-files .dashboard-ticket-file a:active {
    font-size: 12px;
    font-weight: 400;
    line-height: 1.4;
    color: var(--secondary-p-color);
    text-decoration: none;
}

.dashboard-ticket-files .dashboard-ticket-file a:hover {
    border-color: rgba(255, 255, 255, 0.28);
    background-color: #212445;
    color: var(--white-color);
}

[data-theme="light"] .dashboard-ticket-files .dashboard-ticket-file a:hover {
    border-color: rgba(20, 21, 43, 0.28);
    background-color: #F0F1F7;
}

/* An image needs no chrome of its own -- the picture is the control. */
.dashboard-ticket-file.is-image a {
    max-width: none;
    padding: 0;
    background-color: transparent;
    overflow: hidden;
}

/* The min sizes are for the degenerate case: an image only a few pixels across
   would otherwise render a few pixels across, and read as a rendering fault
   rather than as a tiny picture. Normal screenshots are governed by the max. */
.dashboard-ticket-file.is-image img {
    display: block;
    width: auto;
    height: auto;
    min-width: 56px;
    min-height: 56px;
    max-width: 220px;
    max-height: 160px;
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 7px;
    object-fit: cover;
}

.dashboard-ticket-file-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dashboard-ticket-file-size {
    flex-shrink: 0;
    font-size: 11px;
    color: var(--primary-p-color);
}

/* Its own button rather than `.btn.btn-bordered`. That class paints a gradient
   rim in a ::before and covers it with a WHITE ::after, which only lifts when
   `.active` is present - so a bordered button without `.active` is a white pill,
   and overriding `border-color`/`color` cannot touch either pseudo-element.
   A destructive secondary action needs to be quiet and dark, so it is built
   from scratch instead of fought with !important. */
/* Full width and the same height as the theme's other form controls: as a small
   pill it sat in the corner of its card looking like an afterthought, when it
   is the only thing that card is for. */
.dashboard-danger-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.55rem;
    width: 100%;
    min-height: 46px;
    padding: 0.75rem 1.25rem;
    border: 1px solid rgba(239, 68, 68, 0.45);
    border-radius: 100px;
    background-color: rgba(239, 68, 68, 0.08);
    color: #f87171;
    font-size: 14px;
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
    transition: background-color 0.15s, border-color 0.15s, color 0.15s;
}

.dashboard-danger-btn:hover:not(:disabled) {
    border-color: rgba(239, 68, 68, 0.75);
    background-color: rgba(239, 68, 68, 0.16);
    color: #fca5a5;
}

.dashboard-danger-btn:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

.dashboard-dialog-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    background-color: rgba(4, 5, 15, 0.75);
    backdrop-filter: blur(2px);
}

/* The same outline the writing boxes wear - 2px of --primary-p-color, set on
   `input, textarea, select` up in the Typography region. A hairline white
   border left the dialog looking less defined than the textarea sitting inside
   it, which is backwards: the panel should read as the outer edge of the same
   form, not as something fainter behind it.

   The corner radius stays at the card value rather than the inputs' 2px - that
   radius is right on a 50px-tall field and wrong on a panel this size, and it
   is the border, not the corners, that ties the two together. */
.dashboard-dialog {
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: 460px;
    max-height: calc(100vh - 2rem);
    overflow: hidden;
    border: 2px solid var(--primary-p-color);
    border-radius: 16px;
    background-color: #13152e;
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.6);
}

[data-theme="light"] .dashboard-dialog {
    background-color: #FFFFFF;
    box-shadow: 0 24px 60px rgba(20, 21, 43, 0.18);
}

.dashboard-dialog-head {
    flex: 0 0 auto;
    padding: 1.15rem 1.35rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

/* A form dialog is dismissed, not decided: it gets an X as well as a Cancel
   button. The confirmation dialog beside it deliberately has neither -- there
   the two buttons ARE the question. */
.dashboard-dialog-head.has-close {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.dashboard-dialog-close {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    padding: 0;
    border: 0 none;
    border-radius: 50%;
    background: transparent;
    color: var(--primary-p-color);
    font-size: 14px;
    cursor: pointer;
    transition: background-color 0.15s, color 0.15s;
}

.dashboard-dialog-close:hover {
    background-color: #212445;
    color: var(--white-color);
}

[data-theme="light"] .dashboard-dialog-close:hover {
    background-color: #F0F1F7;
}

/* The close confirmation asks one question; this one holds a whole form, so it
   gets more room. Still capped well under a laptop's width -- a modal as wide
   as the page reads as a second page. */
.dashboard-dialog.is-wide {
    max-width: 560px;
}

.dashboard-dialog-head h4 {
    font-size: 1rem;
    color: var(--white-color);
}

.dashboard-dialog-warn {
    color: #f5a623;
}

/* The wizard footer: dismiss/back on the left, the way forward on the right. */
.dialog-actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 1.5rem;
}

/* Pushes everything after it to the right edge. A spacer element rather than
   justify-content: space-between, which would spread the two forward buttons
   apart from each other as well. */
.dialog-actions-split {
    flex: 1 1 auto;
}

.dialog-actions .btn {
    margin: 0;
}

/* Below this the three buttons of step 1 no longer fit on one line; stacking
   them full width beats letting them wrap into a ragged two-and-one. */
@media (max-width: 480px) {
    .dialog-actions {
        flex-direction: column-reverse;
        align-items: stretch;
    }

    .dialog-actions-split {
        display: none;
    }
}

/* A label that carries a count as well as its text. */
.details-form .form-group label.field-label-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
}

/* Marks a field that will not let you past. Only the required ones are
   marked: labelling the optional ones instead put the longest note on the
   field that needed the least attention. */
.field-required {
    margin-left: 0.25rem;
    color: var(--invalid-color);
    font-weight: 700;
}

.field-label-count {
    flex: 0 0 auto;
    color: var(--primary-p-color);
    font-size: 11px;
    font-weight: 400;
}

/* ── The "?" beside a field label ──────────────────────────────────────────
   Replaces the line of small print each field used to carry. The bubble is
   positioned against this wrapper, so it follows the mark wherever the label
   sits. */
.field-hint {
    position: relative;
    display: inline-flex;
    vertical-align: middle;
    margin-left: 0.4rem;
}

.field-hint-mark {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 1.05rem;
    height: 1.05rem;
    padding: 0;
    border: 1px solid var(--primary-p-color);
    border-radius: 50%;
    background: transparent;
    color: var(--primary-p-color);
    font-size: 8px;
    line-height: 1;
    cursor: help;
    transition: color 0.15s ease, border-color 0.15s ease;
}

.field-hint-mark:hover,
.field-hint-mark:focus-visible {
    border-color: var(--primary-color);
    color: var(--primary-color);
}

/* Hidden by clipping rather than display:none, so the text stays in the
   accessibility tree for the aria-describedby above to point at. */
.field-hint-bubble {
    position: absolute;
    top: calc(100% + 0.45rem);
    /* Anchored to the mark and opening rightwards: the dialog body is a
       scroll container, so a bubble centred on the mark would be clipped by
       its left edge on the first field of a row. */
    left: -0.4rem;
    z-index: 5;
    width: max-content;
    max-width: 15rem;
    padding: 0.55rem 0.7rem;
    border: 1px solid var(--card-border-color);
    border-radius: 8px;
    background-color: #1b1e3a;
    box-shadow: 0 10px 24px rgba(0, 0, 0, 0.45);
    color: var(--primary-p-color);
    font-size: 12px;
    font-weight: 400;
    line-height: 1.5;
    text-transform: none;
    letter-spacing: normal;
    white-space: normal;
    opacity: 0;
    visibility: hidden;
    transform: translateY(-3px);
    transition: opacity 0.15s ease, transform 0.15s ease, visibility 0.15s;
}

[data-theme="light"] .field-hint-bubble {
    background-color: #FFFFFF;
    color: var(--nav-item-color);
}

/* focus-within covers the keyboard and the touch tap; hover covers the mouse. */
.field-hint:hover .field-hint-bubble,
.field-hint:focus-within .field-hint-bubble {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

/* The step rail in the request dialog. Sits between the fixed head and the
   scrolling body, so where you are stays visible while the fields move. */
.dialog-steps {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0;
    padding: 0.85rem 1.35rem;
    list-style: none;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.dialog-step {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
    color: var(--primary-p-color);
    font-size: 12px;
}

/* The connector between steps. A pseudo-element on the item rather than a
   separate node, so the markup stays an ordered list of three steps. */
.dialog-step + .dialog-step::before {
    content: "";
    width: 1.25rem;
    height: 1px;
    margin-right: 0.25rem;
    background-color: rgba(255, 255, 255, 0.14);
}

.dialog-step-mark {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 1.35rem;
    height: 1.35rem;
    border: 1px solid currentColor;
    border-radius: 50%;
    font-size: 10px;
    font-weight: 700;
}

.dialog-step-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dialog-step.is-current {
    color: var(--white-color);
    font-weight: 600;
}

.dialog-step.is-current .dialog-step-mark {
    border-color: var(--primary-color);
    background-color: var(--primary-color);
    color: var(--white-color);
}

/* A finished step keeps the accent but drops the fill: done, not current. */
.dialog-step.is-done {
    color: var(--primary-color);
}

/* On a narrow screen the labels are the first thing to go — the numbers and
   the ticks still say how far along the reader is. */
@media (max-width: 480px) {
    .dialog-step:not(.is-current) .dialog-step-label {
        display: none;
    }
}

/* The head is fixed and this scrolls: on a long form the title has to stay
   visible, and a body that scrolls inside the shell is one scrollbar rather
   than the shell and the package picker each having their own. */
.dashboard-dialog-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 1.35rem;
}

/* The sentence that says this cannot be undone. Given a border and a tint
   rather than being one more paragraph, because it is the whole reason the
   dialog exists. */
.dashboard-dialog-warning {
    margin: 0 0 1.25rem;
    padding: 0.75rem 0.9rem;
    border-left: 3px solid #f5a623;
    border-radius: 8px;
    background-color: rgba(245, 166, 35, 0.08);
    font-size: 13px;
    line-height: 1.6;
    color: var(--white-color);
}

.dashboard-dialog-reasons {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    margin: 0;
    padding: 0;
    border: none;
}

.dashboard-dialog-legend {
    float: none;
    width: auto;
    margin-bottom: 0.6rem;
    padding: 0;
    font-size: 13px;
    font-weight: 600;
    color: var(--white-color);
}

.dashboard-radio {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.65rem 0.85rem;
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 10px;
    background-color: rgba(255, 255, 255, 0.02);
    font-size: 13px;
    color: var(--primary-p-color);
    cursor: pointer;
    transition: border-color 0.15s, background-color 0.15s;
}

.dashboard-radio:hover {
    border-color: rgba(255, 255, 255, 0.2);
}

.dashboard-radio input {
    width: auto;
    margin: 0;
    accent-color: #2563eb;
}

.dashboard-radio:has(input:checked) {
    border-color: rgba(37, 99, 235, 0.5);
    background-color: rgba(37, 99, 235, 0.1);
    color: var(--white-color);
}

.dashboard-dialog-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 1.5rem;
    padding-top: 1.15rem;
    border-top: 1px solid rgba(255, 255, 255, 0.08);
}

/* -- Public support page ---------------------------------------------------
   /support: the front door anybody can write through, account or not. It sits
   inside the (frontend) route group and borrows that area's form chrome
   (.apply-form, .details-form), so this is only the handful of pieces the
   ticket flow adds on top. */

.support-intro {
    margin-bottom: 1.5rem;
    font-size: 14px;
    line-height: 1.6;
    color: var(--primary-p-color);
}

/* Stands in for the name and email fields when the visitor is signed in: they
   are not asked for details the app already has, but they should still be able
   to see which identity they are writing under. */
.support-as-user {
    display: flex;
    align-items: center;
    margin-bottom: 1.5rem;
    padding: 0.75rem 1rem;
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 10px;
    background-color: rgba(255, 255, 255, 0.03);
    font-size: 13px;
    line-height: 1.5;
    color: var(--primary-p-color);
    overflow-wrap: anywhere;
}

/* Replaces the form once a guest has written, and repeats the link that was
   emailed - for somebody with no account that link is the only way back, so it
   is shown on screen as well as sent. */
.support-sent {
    padding: 1.5rem 0.5rem 0.5rem;
    text-align: center;
}

.support-sent-icon {
    font-size: 34px;
    color: var(--console-success, #2ecc71);
}

.support-sent-text {
    margin: 0 auto 0.75rem;
    max-width: 42ch;
    font-size: 14px;
    line-height: 1.6;
    color: var(--primary-p-color);
    overflow-wrap: anywhere;
}

.support-thread-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    font-size: 13px;
    color: var(--primary-p-color);
}

/* The base .status-pill chrome is scoped to a list of wrappers (see the note
   further up); this is one more of them, or the pill renders as bare coloured
   text. */
.support-thread-meta .status-pill {
    display: inline-block;
    padding: 0.3rem 0.8rem;
    border-radius: 100px;
    font-size: 12px;
    font-weight: 600;
    background: transparent;
    border: 1px solid currentColor;
    white-space: nowrap;
}

.support-thread-reply {
    margin-top: 1.75rem;
    padding-top: 1.5rem;
    border-top: 1px solid rgba(255, 255, 255, 0.08);
}

/* â”€â”€ Account notification bell â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

/* Sits in the account navbar's icon list, beside search and the locale
   switcher. Its own rules rather than the console's .console-bell-* because
   the account pages are not inside .console-shell, so none of region 15's
   selectors reach here. */

/* `header .navbar-expand .icons i { font-weight: 400 }` (region 6) wins over
   `.fa-solid`'s own `font-weight: 900` at (0,2,2) vs (0,1,0). That rule is
   written for the theme's icon font, which does not care about weight - but
   Font Awesome picks its FACE by weight, and 400 is `fa-regular`, which this
   project does not ship. The result is an empty box, and the browser quietly
   404s on fa-regular-400.woff2 while producing it.

   So any Font Awesome icon placed in that list has to say 900 again, louder. */
#header .navbar-expand .icons .dashboard-bell i {
    font-weight: 900;
}

.dashboard-bell {
    position: relative;
}

.dashboard-bell > .nav-link {
    position: relative;
}

.dashboard-bell-dot {
    position: absolute;
    top: 6px;
    right: 2px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background-color: #ef4444;
    box-shadow: 0 0 0 2px rgba(11, 12, 30, 0.9);
}

.dashboard-bell-menu {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    z-index: 30;
    min-width: 280px;
    max-width: min(340px, calc(100vw - 24px));
    padding: 0.5rem 0;
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 12px;
    background-color: #13152e;
    box-shadow: 0 16px 32px -12px rgba(0, 0, 0, 0.6);
}

[data-theme="light"] .dashboard-bell-menu {
    border-color: rgba(20, 21, 43, 0.1);
    background-color: #FFFFFF;
    box-shadow: 0 16px 32px -12px rgba(20, 21, 43, 0.25);
}

.dashboard-bell-title {
    margin: 0;
    padding: 0.5rem 1rem 0.75rem;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--primary-p-color);
}

.dashboard-bell-empty {
    margin: 0;
    padding: 0.5rem 1rem 0.75rem;
    font-size: 13px;
    color: var(--primary-p-color);
}

.dashboard-bell-item {
    display: flex;
    align-items: flex-start;
    gap: 0.65rem;
    padding: 0.65rem 1rem;
}

.dashboard-bell-item:hover {
    background-color: rgba(255, 255, 255, 0.05);
}

.dashboard-bell-item.is-unread {
    background-color: rgba(37, 99, 235, 0.1);
}

.dashboard-bell-item-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.dashboard-bell-item-text span {
    font-size: 11px;
    color: var(--primary-p-color);
}

.dashboard-bell-foot {
    margin-top: 0.25rem;
    border-top: 1px solid rgba(255, 255, 255, 0.08);
}

/* The theme's `a:link:not(.btn), a:visited:not(.btn), …` block sets colour,
   font-size, font-weight and line-height at specificity (0,2,1), which beats
   any single class. Region 15 clears that for the console under
   `.console-shell`; this bell lives in the site header instead, so its override
   has to be scoped to #header or it simply does not apply.

   All four states are listed deliberately: declaring only :link and :visited
   leaves the row flashing the theme's blue on hover. */
#header a.dashboard-bell-item:link,
#header a.dashboard-bell-item:visited,
#header a.dashboard-bell-item:hover,
#header a.dashboard-bell-item:active {
    color: var(--white-color);
    font-size: 13px;
    font-weight: 500;
    line-height: 1.4;
    text-decoration: none;
}

/* #endregion Auth & Account */

/*----------------------------------------------
14. Cookie Consent
----------------------------------------------*/

/* #region Cookie Consent */

.cookie-consent-banner {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 99998;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 1rem;
    padding: 1.25rem 2rem;
    background-color: var(--card-bg-color);
    box-shadow: 0 -10px 30px rgba(0, 0, 0, 0.35);
}

.cookie-consent-text {
    color: var(--primary-p-color);
    font-size: 14px;
    max-width: 640px;
}

.cookie-consent-text a {
    color: var(--primary-color);
    transition: 0.3s;
}

.cookie-consent-text a:hover {
    color: var(--white-color);
}

.cookie-consent-actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.cookie-category {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 1rem 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.cookie-category:last-of-type {
    border-bottom: none;
}

.cookie-category-info h4 {
    color: var(--white-color);
    font-size: 1rem;
}

.cookie-category-info p {
    color: var(--primary-p-color);
    font-size: 13px;
}

.cookie-category-locked {
    flex-shrink: 0;
    font-size: 12px;
    font-weight: 600;
    color: var(--primary-p-color);
}

.cookie-category-switch {
    position: relative;
    display: inline-block;
    flex-shrink: 0;
    height: 26px;
    width: 46px;
}

.cookie-category-switch input {
    position: absolute;
    height: 0;
    width: 0;
    opacity: 0;
}

.cookie-category-switch span {
    position: absolute;
    inset: 0;
    background-color: rgba(255, 255, 255, 0.15);
    border-radius: 2rem;
    transition: 0.3s;
}

[data-theme="light"] .cookie-category-switch span {
    background-color: rgba(20, 21, 43, 0.15);
}

/* Fixed #fff, not var(--white-color): the knob should always read as a
   white toggle circle, in both themes, not follow --white-color's flipped
   text-color role. */
.cookie-category-switch span::before {
    position: absolute;
    content: "";
    height: 20px;
    width: 20px;
    left: 3px;
    top: 3px;
    background-color: #fff;
    border-radius: 50%;
    transition: 0.3s;
}

.cookie-category-switch input:checked + span {
    background-color: var(--primary-color);
}

.cookie-category-switch input:checked + span::before {
    transform: translateX(20px);
}

.twofa-qr-image {
    display: block;
    max-width: 100%;
    height: auto;
    border-color: transparent;
}

/* #endregion Cookie Consent */

/*----------------------------------------------
15. Platform Console
----------------------------------------------*/

/* #region Platform Console

The platform management console at /dashboard: a full-height app shell with its
own navigation rail and top bar, not a page of the marketing site.

Every class here is prefixed `console-` on purpose. Two other prefixes are
already taken and neither can be reused without collisions:
  `.dashboard-*` belongs to the player-facing /account pages (see region 13),
  `.dash-*`      belongs to the hero's dashboard mockup (ServerDashboard.tsx).
This stylesheet is global, so an unprefixed `.card` or `.metric` here would
silently restyle either of those.

The console owns a small set of local custom properties so its surfaces can sit
a step darker than the site's cards without repeating literal colours. It
deliberately does not redefine any of the theme's own variables: accents are
built from --primary-color / --secondary-color, so the console stays visibly
part of the same product. */

:root {
    --console-rail: 264px;
    --console-rail-collapsed: 76px;
    --console-topbar: 60px;
    --console-bg: #0a0b18;
    --console-panel: #0e1020;
    --console-surface: #14162a;
    --console-surface-2: #1b1e35;
    --console-line: rgba(255, 255, 255, 0.07);
    --console-line-strong: rgba(255, 255, 255, 0.14);
    --console-accent: #6d4aff;
    --console-accent-soft: rgba(109, 74, 255, 0.16);
    --console-danger: #e4574c;
    --console-success: #2ecc71;
    --console-warning: #f5a623;
    /* Matches `.dashboard-card` on the account pages, so a card looks the same
       on both sides of the product. */
    --console-radius: 0.75rem;
    /* The floor under every card body. Roughly three list rows: tall enough
       that an empty card still reads as a card, short enough that the small
       aside cards (balance, best seller) aren't mostly dead space. */
    --console-card-body-min: 168px;
}

/* Light theme: dashboard and staff panel share these vars (StaffTopbar's own
   comment notes it reuses "the same shape and classes as the console's"), so
   this one block covers both surfaces. Accent/status colors are left as-is. */
:root[data-theme="light"] {
    --console-bg: #F0F1F7;
    --console-panel: #FFFFFF;
    --console-surface: #FFFFFF;
    --console-surface-2: #F3F4F9;
    --console-line: rgba(20, 21, 43, 0.08);
    --console-line-strong: rgba(20, 21, 43, 0.16);
}

.console-shell {
    display: flex;
    min-height: 100vh;
    background-color: var(--console-bg);
}

.console-main {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    margin-left: var(--console-rail);
    transition: margin-left 0.22s ease;
}

.console-shell.is-collapsed .console-main {
    margin-left: var(--console-rail-collapsed);
}

.console-content {
    min-width: 0;
    padding: 1.5rem 1.75rem 4rem;
}

.console-drawer-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 44;
    padding: 0;
    border: none;
    background-color: rgba(4, 4, 2, 0.65);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
}

/* â”€â”€ Navigation rail â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.console-sidebar {
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 46;
    display: flex;
    flex-direction: column;
    width: var(--console-rail);
    background-color: var(--console-panel);
    border-right: 1px solid var(--console-line);
    transition: width 0.22s ease, transform 0.22s ease;
}

.console-shell.is-collapsed .console-sidebar {
    width: var(--console-rail-collapsed);
}

.console-sidebar-brand {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    height: var(--console-topbar);
    padding: 0 1.1rem;
    flex-shrink: 0;
}

/* Sized to the same 34px slot as the workspace mark below it, so the brand, the
   platform initial and the nav icons all share one left edge. The logo itself is
   square (381x381) and already white, so it needs no plate or tinting. */
.console-brand-mark {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    flex-shrink: 0;
}

.console-brand-mark img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

[data-theme="light"] .console-brand-mark img {
    filter: invert(1);
}

.console-brand-text {
    display: flex;
    flex-direction: column;
    line-height: 1.2;
    min-width: 0;
}

.console-brand-text strong {
    font-size: 14px;
    color: var(--white-color);
}

.console-brand-text small {
    font-size: 10px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--primary-p-color);
}

/* Everything that is text-beside-an-icon collapses the same way, so the rail
   narrows in one step instead of each component hiding its own label. */
.console-shell.is-collapsed .console-brand-text,
.console-shell.is-collapsed .console-nav-label,
.console-shell.is-collapsed .console-nav-value,
.console-shell.is-collapsed .console-nav-caret,
.console-shell.is-collapsed .console-workspace-text,
.console-shell.is-collapsed .console-workspace-caret,
.console-shell.is-collapsed .console-user-text,
.console-shell.is-collapsed .console-user-caret,
.console-shell.is-collapsed .console-help-card {
    display: none;
}

.console-shell.is-collapsed .console-sidebar-brand,
.console-shell.is-collapsed .console-workspace-toggle,
.console-shell.is-collapsed .console-nav-item,
.console-shell.is-collapsed .console-back-link,
.console-shell.is-collapsed .console-user-toggle {
    justify-content: center;
    padding-left: 0;
    padding-right: 0;
}

/* Workspace (platform) switcher */

.console-workspace {
    position: relative;
    padding: 0 0.75rem 0.75rem;
}

.console-workspace-toggle {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    width: 100%;
    padding: 0.55rem 0.65rem;
    border: 1px solid var(--console-line);
    border-radius: 12px;
    background-color: var(--console-surface);
    color: var(--white-color);
    text-align: left;
    transition: border-color 0.15s, background-color 0.15s;
}

.console-workspace-toggle:hover:not(:disabled),
.console-workspace.is-open .console-workspace-toggle {
    border-color: var(--console-line-strong);
    background-color: var(--console-surface-2);
}

.console-workspace-toggle:disabled {
    opacity: 0.6;
}

.console-workspace-mark {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    flex-shrink: 0;
    border-radius: 9px;
    background-image: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
    color: var(--btn-text-color);
    font-size: 13px;
    font-weight: 700;
}

.console-workspace-mark.is-small {
    width: 24px;
    height: 24px;
    border-radius: 7px;
    font-size: 11px;
}

/* Showing the platform's logo instead of its initial. The gradient goes, or it
   shows through a logo with transparency — which most of them have. */
.console-workspace-mark.has-image {
    overflow: hidden;
    background-image: none;
}

.console-workspace-mark img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.console-workspace-text {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    line-height: 1.25;
}

.console-workspace-text strong {
    font-size: 13px;
    color: var(--white-color);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.console-workspace-text small {
    font-size: 11px;
    color: var(--primary-p-color);
}

.console-workspace-caret {
    flex-shrink: 0;
    font-size: 10px;
    color: var(--primary-p-color);
    transition: transform 0.2s;
}

.console-workspace.is-open .console-workspace-caret {
    transform: rotate(180deg);
}

.console-workspace-menu,
.console-user-menu {
    position: absolute;
    left: 0.75rem;
    right: 0.75rem;
    z-index: 50;
    padding: 0.35rem;
    border: 1px solid var(--console-line-strong);
    border-radius: 14px;
    background-color: var(--console-surface-2);
    box-shadow: 0 16px 40px rgba(0, 0, 0, 0.55);
}

.console-workspace-menu {
    top: calc(100% - 0.4rem);
}

.console-user-menu {
    bottom: calc(100% + 0.4rem);
}

.console-menu-title {
    margin: 0;
    padding: 0.4rem 0.6rem 0.5rem;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--primary-p-color);
}

.console-menu-item {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    width: 100%;
    padding: 0.5rem 0.6rem;
    border: none;
    border-radius: 9px;
    background-color: transparent;
    color: var(--secondary-p-color);
    font-size: 13px;
    text-align: left;
    transition: background-color 0.12s, color 0.12s;
}

.console-menu-item i {
    width: 14px;
    flex-shrink: 0;
    font-size: 12px;
    text-align: center;
}

.console-menu-item:hover {
    background-color: rgba(255, 255, 255, 0.06);
    color: var(--white-color);
}

.console-menu-item.active {
    background-color: var(--console-accent-soft);
    color: var(--white-color);
    font-weight: 600;
}

.console-menu-item.is-danger {
    color: #ffb4ae;
}

.console-menu-item.is-danger:hover {
    background-color: rgba(228, 87, 76, 0.14);
    color: #ffb4ae;
}

.console-menu-item-text {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.console-menu-foot {
    margin-top: 0.3rem;
    padding-top: 0.55rem;
    border-top: 1px solid var(--console-line);
    border-radius: 0 0 9px 9px;
    color: var(--primary-p-color);
}

.console-menu-form {
    margin: 0;
}

/* Nav rows */

.console-sidebar-nav {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.25rem 0.75rem 1rem;
    overflow-y: auto;
}

.console-nav-section {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.console-nav-section + .console-nav-section {
    padding-top: 0.5rem;
    border-top: 1px solid var(--console-line);
}

.console-nav-item {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    width: 100%;
    padding: 0.55rem 0.7rem;
    border: none;
    border-radius: 10px;
    background-color: transparent;
    color: var(--primary-p-color);
    font-size: 13.5px;
    font-weight: 500;
    text-align: left;
    transition: background-color 0.15s, color 0.15s;
}

.console-nav-item > i:first-child {
    width: 18px;
    flex-shrink: 0;
    font-size: 13px;
    text-align: center;
}

.console-nav-item:hover,
.console-nav-item:focus-visible {
    background-color: rgba(255, 255, 255, 0.05);
    color: var(--white-color);
}

.console-nav-item.active {
    background-image: linear-gradient(90deg, rgba(0, 71, 255, 0.32), rgba(87, 4, 138, 0.24));
    color: var(--white-color);
    font-weight: 600;
}

.console-nav-label {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.console-nav-value {
    flex-shrink: 0;
    font-size: 12px;
    font-weight: 600;
    color: var(--console-success);
}

.console-nav-caret {
    flex-shrink: 0;
    font-size: 10px;
    transition: transform 0.2s;
}

.console-nav-group.is-open .console-nav-caret {
    transform: rotate(90deg);
}

.console-nav-children {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin: 2px 0 2px 1.45rem;
    padding-left: 0.55rem;
    border-left: 1px solid var(--console-line);
}

.console-nav-item.is-nested {
    padding-top: 0.42rem;
    padding-bottom: 0.42rem;
    font-size: 13px;
}

/* Rail footer */

.console-sidebar-foot {
    position: relative;
    flex-shrink: 0;
    padding: 0.75rem;
    border-top: 1px solid var(--console-line);
}

.console-back-link {
    margin-bottom: 0.6rem;
}

/* Same seam as .console-btn: the border is translucent, so the tiled gradient
   under it would show through as a mismatched 1px edge. */
.console-help-card {
    margin-bottom: 0.6rem;
    padding: 0.85rem;
    border: 1px solid var(--console-line);
    background-origin: border-box;
    border-radius: 14px;
    background-image: linear-gradient(160deg, rgba(0, 71, 255, 0.16), rgba(87, 4, 138, 0.1));
}

.console-help-title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin: 0 0 0.65rem;
    font-size: 13px;
    font-weight: 600;
    color: var(--white-color);
}

.console-help-title i {
    color: var(--primary-p-color);
    font-size: 12px;
}

.console-user {
    position: relative;
}

.console-user-toggle {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    width: 100%;
    padding: 0.45rem 0.55rem;
    border: none;
    border-radius: 11px;
    background-color: transparent;
    text-align: left;
    transition: background-color 0.15s;
}

.console-user-toggle:hover,
.console-user.is-open .console-user-toggle {
    background-color: rgba(255, 255, 255, 0.06);
}

.console-user-avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    flex-shrink: 0;
    border-radius: 50%;
    background-image: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
    color: var(--btn-text-color);
    font-size: 13px;
    font-weight: 700;
}

.console-user-avatar.is-sm {
    width: 26px;
    height: 26px;
    font-size: 11px;
    color: white;
}

/* Discord picture variant: the gradient plate would show through a transparent
   avatar, so it is dropped when there is an image to show. */
.console-user-avatar.has-image {
    overflow: hidden;
    background-image: none;
}

.console-user-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.console-user-text {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    line-height: 1.25;
}

.console-user-text strong {
    font-size: 13px;
    color: var(--white-color);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.console-user-text small {
    font-size: 11px;
    color: var(--primary-p-color);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.console-user-caret {
    flex-shrink: 0;
    font-size: 10px;
    color: var(--primary-p-color);
}

/* â”€â”€ Top bar â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.console-topbar {
    position: sticky;
    top: 0;
    z-index: 30;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    height: var(--console-topbar);
    padding: 0 1.75rem;
    background-color: rgba(10, 11, 24, 0.85);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--console-line);
}

[data-theme="light"] .console-topbar {
    background-color: rgba(255, 255, 255, 0.85);
}

.console-topbar-left,
.console-topbar-right {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    min-width: 0;
}

.console-rail-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border: none;
    border-radius: 9px;
    background-color: transparent;
    color: var(--primary-p-color);
    font-size: 14px;
    transition: background-color 0.15s, color 0.15s;
}

.console-rail-toggle:hover {
    background-color: rgba(255, 255, 255, 0.07);
    color: var(--white-color);
}

[data-theme="light"] .console-rail-toggle:hover {
    background-color: rgba(20, 21, 43, 0.07);
}

.console-breadcrumb {
    min-width: 0;
}

.console-breadcrumb ol {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    margin: 0;
    padding: 0;
    list-style: none;
    min-width: 0;
}

.console-breadcrumb li {
    display: flex;
    align-items: center;
    min-width: 0;
    font-size: 13px;
    color: var(--primary-p-color);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The page you are on is the one worth reading; ancestors stay muted. */
.console-breadcrumb li [aria-current="page"] {
    font-weight: 600;
    color: var(--white-color);
}

.console-breadcrumb-sep i {
    font-size: 9px;
    opacity: 0.55;
}

/* Step indicator at the top of a multi-step dialog. */
.console-steps {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    margin: 0 0 1.25rem;
    padding: 0 0 1rem;
    border-bottom: 1px solid var(--console-line);
}

.console-steps li {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 13px;
    font-weight: 600;
    color: var(--primary-p-color);
}

.console-steps li.is-current,
.console-steps li.is-done {
    color: var(--white-color);
}

.console-step-mark {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    flex-shrink: 0;
    border: 1px solid var(--console-line-strong);
    border-radius: 50%;
    font-size: 11px;
}

.console-steps li.is-current .console-step-mark,
.console-steps li.is-done .console-step-mark {
    border-color: transparent;
    background-image: linear-gradient(120deg, var(--primary-color), var(--secondary-color));
    background-origin: border-box;
    color: var(--btn-text-color);
}

.console-topbar-bell {
    position: relative;
    display: flex;
}

.console-topbar-bell .console-rail-toggle {
    position: relative;
}

.console-topbar-bell.is-open .console-rail-toggle {
    background-color: rgba(255, 255, 255, 0.07);
    color: var(--white-color);
}

/* Unread marker. Ringed in the bar's own colour so it reads as sitting on top
   of the bell rather than touching it. */
.console-bell-dot {
    position: absolute;
    top: 5px;
    right: 6px;
    width: 8px;
    height: 8px;
    border: 2px solid var(--console-panel);
    border-radius: 50%;
    background-color: var(--console-danger);
}

.console-topbar-bell .console-bell-menu {
    top: calc(100% + 0.5rem);
    right: 0;
    bottom: auto;
    left: auto;
    width: 19rem;
    max-width: calc(100vw - 2rem);
}

.console-bell-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    margin: 0;
    padding: 1.5rem 1rem;
    font-size: 13px;
    text-align: center;
    color: var(--primary-p-color);
}

.console-bell-empty i {
    font-size: 20px;
    opacity: 0.5;
}

.console-bell-menu {
    max-height: 22rem;
    overflow-y: auto;
}

.console-bell-item {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    padding: 0.6rem 0.7rem;
    border-radius: 10px;
    font-size: 13px;
}

.console-bell-item:hover {
    background-color: rgba(255, 255, 255, 0.06);
}

.console-bell-item > i {
    margin-top: 2px;
    font-size: 12px;
    color: var(--primary-p-color);
}

.console-bell-item.is-unread > i {
    color: var(--console-accent);
}

.console-bell-item-text {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
}

.console-bell-item-text .console-muted {
    font-size: 11px;
}

/* The items are anchors, so they restate their own colour and type to clear the
   theme's a:link block — see the note at the top of this region. */
.console-shell a.console-bell-item:link,
.console-shell a.console-bell-item:visited,
.console-shell a.console-bell-item:hover,
.console-shell a.console-bell-item:active {
    font-size: 13px;
    font-weight: 400;
    line-height: 1.4;
    color: var(--secondary-p-color);
}

.console-shell a.console-bell-item strong {
    font-weight: 600;
    color: var(--white-color);
}

.console-topbar-user {
    position: relative;
    display: flex;
}

/* Unlike the rail's avatar, which is a <span>, this one is a <button> â€” so it
   carries the UA's default `buttonface` background, which showed as a pale ring
   through the transparent parts of a Discord picture. `.has-image` only clears
   the gradient, which is a background-image. */
.console-topbar-avatar {
    padding: 0;
    border: 1px solid transparent;
    background-color: transparent;
    cursor: pointer;
    transition: border-color 0.15s, filter 0.15s;
}

.console-topbar-avatar:hover,
.console-topbar-user.is-open .console-topbar-avatar {
    border-color: var(--console-line-strong);
    filter: brightness(1.1);
}

/* Same menu as the rail's, opening downward from the right edge instead of
   upward â€” the shared entries come from ConsoleUserMenuItems. Scoped to the
   wrapper so it beats .console-user-menu's own placement whatever the order. */
.console-topbar-user .console-topbar-user-menu {
    top: calc(100% + 0.5rem);
    right: 0;
    bottom: auto;
    left: auto;
    min-width: 12rem;
}

/* The locale switcher is the site's own navbar component, reused rather than
   forked. The theme only ever reveals its menu through
   `header .navbar-expand .navbar-nav .dropdown:hover > .dropdown-menu` â€” a
   chain the console's top bar does not have â€” so here the menu stayed at
   Bootstrap's `display: none` and the control did nothing when clicked. These
   rules restate the same open-on-hover behaviour in the console's own surface
   colours.
   All of them out-specify the theme's `a:link:not(.btn)` block (0,2,1), which
   is why the colour and type are repeated rather than inherited. */
.console-topbar-locale {
    display: flex;
    align-items: center;
}

.console-topbar-locale .locale-switcher {
    position: relative;
    list-style: none;
}

.console-topbar-locale .locale-switcher .locale-toggle {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.4rem 0.7rem;
    border-radius: 100px;
    font-size: 13px;
    color: var(--primary-p-color);
    cursor: pointer;
    transition: background-color 0.15s, color 0.15s;
}

.console-topbar-locale .locale-switcher .locale-toggle:hover {
    background-color: rgba(255, 255, 255, 0.06);
    color: var(--white-color);
}

.console-topbar-locale .locale-switcher .locale-toggle i {
    font-size: 11px;
}

.console-topbar-locale .locale-switcher .dropdown-menu {
    display: block;
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    left: auto;
    z-index: 30;
    width: max-content;
    min-width: 9rem;
    margin: 0;
    padding: 0.35rem;
    border: 1px solid var(--console-line);
    border-radius: 12px;
    background-color: var(--console-surface-2);
    box-shadow: 0 20px 40px rgba(0, 0, 0, 0.45);
    visibility: hidden;
    opacity: 0;
    transform: translateY(8px);
}

/* The <li> wraps the toggle and the menu both, so the pointer never leaves it
   on the way down. `focus-within` is what makes the same control reachable by
   keyboard, which the hover-only original never was. */
.console-topbar-locale .locale-switcher:hover .dropdown-menu,
.console-topbar-locale .locale-switcher:focus-within .dropdown-menu {
    visibility: visible;
    opacity: 1;
    transform: translateY(0);
    transition: opacity 0.2s ease, transform 0.2s ease;
}

.console-topbar-locale .locale-switcher .dropdown-menu li {
    list-style: none;
}

.console-topbar-locale .locale-switcher .dropdown-menu .nav-link {
    display: block;
    padding: 0.5rem 0.75rem;
    border-radius: 8px;
    font-size: 13px;
    font-weight: 500;
    line-height: 1.3;
    color: var(--secondary-p-color);
}

.console-topbar-locale .locale-switcher .dropdown-menu .nav-link:hover {
    background-color: rgba(255, 255, 255, 0.06);
    color: var(--white-color);
}

.console-topbar-locale .locale-switcher .dropdown-menu .nav-link.active {
    background-image: linear-gradient(120deg, var(--primary-color), var(--secondary-color));
    background-origin: border-box;
    color: var(--btn-text-color);
}

/* â”€â”€ Hero â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.console-hero {
    position: relative;
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1.5rem;
    flex-wrap: wrap;
    margin-bottom: 1.25rem;
    padding: 2rem 2rem 1.85rem;
    border-radius: var(--console-radius);
    background-color: var(--console-surface);
    overflow: hidden;
}

/* The glow is decorative and must never sit above the buttons.
 *
 * Suppressed once a platform-type effect is on the hero: the effect already
 * paints the whole banner, and `card-website`'s shimmer is an `::after` of its
 * own — written as `:not()` rather than as an override so the two never race on
 * equal specificity, where source order alone would decide the winner. */
.console-hero:not(.effect-active)::after {
    content: "";
    position: absolute;
    top: -60%;
    right: -10%;
    width: 460px;
    height: 460px;
    border-radius: 50%;
    background-image: radial-gradient(circle, rgba(109, 74, 255, 0.28), transparent 62%);
    pointer-events: none;
}

.console-hero-text,
.console-hero-actions {
    position: relative;
    z-index: 1;
}

.console-hero-text {
    min-width: 0;
}

.console-hero-date {
    margin: 0 0 0.35rem;
    font-size: 13px;
    color: var(--secondary-p-color);
    text-transform: capitalize;
    min-height: 1.2em;
}

.console-hero h1 {
    margin: 0 0 0.4rem;
    font-size: 2.35rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--white-color);
}

.console-hero-sub {
    margin: 0;
    font-size: 14px;
    color: var(--secondary-p-color);
}

.console-hero-actions {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
}

/* â”€â”€ KPI tiles â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

/* Wider tracks than the old bare tiles needed: each card now carries a title
   beside its icon in the header band, and 180px wrapped labels like
   "Tasks completed" onto a second line. */
.console-kpi-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
    gap: 1.25rem;
    margin-bottom: 1.25rem;
}

/* The metric tiles are ordinary `.console-card`s — icon and title in the header
   band, figure in the body — so the top row belongs to the same family as
   every card under it rather than being its own kind of object. */
.console-kpi-row > .console-card {
    margin-bottom: 0;
}

/* No floor here: the shared `--console-card-body-min` is sized for a card
   holding a list, and a single number would sit in the middle of far too much
   empty space. These size to their content and centre in it. */
.console-kpi-row > .console-card > .console-card-body {
    min-height: 0;
    justify-content: center;
    padding: 1.15rem 1.35rem 1.25rem;
}

.console-kpi-value {
    margin: 0;
    font-size: 1.85rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--white-color);
}

.console-kpi-change {
    display: inline-flex;
    align-items: center;
    align-self: flex-start;
    gap: 0.3rem;
    margin-top: 0.5rem;
    font-size: 12px;
    font-weight: 600;
    color: var(--console-success);
}

.console-kpi-change.is-down {
    color: var(--console-danger);
}

/* â”€â”€ Page layout â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

/* Rows stretch rather than sitting at their natural heights: a card's size is
   set by the row it is in, not by how much data it happened to receive, so the
   grid keeps its shape on a platform with no purchases, no team and no rewards
   yet. `align-items: start` used to leave every row ragged along the bottom. */
.console-split {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
    gap: 1.25rem;
    align-items: stretch;
    margin-bottom: 1.25rem;
}

.console-split-main,
.console-split-aside,
.console-stack {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

/* A column of stacked cards is as tall as the row; the last card takes up the
   slack so the column ends flush with its neighbour instead of trailing off. */
.console-split-main > .console-card:last-child,
.console-split-aside > .console-card:last-child {
    flex: 1;
}

.console-grid-2 {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.25rem;
    align-items: stretch;
}

.console-narrow {
    max-width: 560px;
}

/* Pushes a lone card-body button down to the card's bottom edge, so a card
   whose form is shorter than the body's min-height still keeps its save
   action pinned to the corner rather than floating under the last field.
   Pair with `.is-self-end` for the bottom-right corner. */
.console-card-body > .console-btn.is-self-bottom {
    margin-top: auto;
}

.console-metric-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
    gap: 1rem;
    margin-bottom: 1.25rem;
}

.console-muted {
    color: var(--primary-p-color);
    font-size: 13px;
}

.console-mono {
    font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
    font-size: 12px;
}

.console-hint {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    margin-bottom: 1rem;
    padding: 0.7rem 1rem;
    border: 1px solid rgba(109, 74, 255, 0.3);
    border-radius: 12px;
    background-color: rgba(109, 74, 255, 0.09);
    font-size: 13px;
    color: var(--secondary-p-color);
}

.console-error-note {
    padding: 0.85rem 1.1rem;
    border: 1px solid rgba(228, 87, 76, 0.35);
    border-radius: 12px;
    background-color: rgba(228, 87, 76, 0.1);
    font-size: 13px;
    color: #ffb4ae;
}

.console-error-note a {
    color: var(--console-accent);
    text-decoration: underline;
}

.console-visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* â”€â”€ Page headings (list pages) â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.console-heading {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1.35rem;
}

.console-heading + .console-heading {
    margin-top: 2.25rem;
}

.console-heading-text h1 {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin: 0 0 0.25rem;
    font-size: 1.5rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--white-color);
}

.console-heading-text h1 i {
    font-size: 1rem;
    color: var(--console-accent);
}

.console-heading-text p {
    margin: 0;
    font-size: 13px;
    color: var(--primary-p-color);
}

.console-heading-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}

/* â”€â”€ Cards â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

/* Cards and the hero are <section> elements, and the theme gives every bare
   section `padding: 130px 0` plus a fixed, cover-sized background (see the
   Section region). A class beats an element selector, so the properties each of
   these sets already win â€” but padding is only declared on the hero, which left
   every card with 130px of dead space above its header. Both are reset here
   rather than at each call site. */
.console-card,
.console-hero,
.console-catalog-group {
    background-attachment: scroll;
    background-size: auto;
}

/* The card follows the account pages' `.dashboard-card` idiom (region 13): a
   tinted header band with a divider under it, a 0.75rem radius, and no outer
   border — the surface is light enough against the console canvas to stand on
   its own, exactly as it does on `/account`. The palette stays `--console-*`;
   only the shape is shared. */
.console-card {
    display: flex;
    flex-direction: column;
    padding: 0;
    margin-bottom: 1.25rem;
    border-radius: var(--console-radius);
    background-color: var(--console-surface);
    overflow: hidden;
}

.console-split-main > .console-card:last-child,
.console-split-aside > .console-card:last-child {
    margin-bottom: 0;
}

/* The only card that keeps an outline: the border is what carries the warning,
   since a danger card is otherwise identical to its neighbours. */
.console-card-danger {
    border: 1px solid rgba(228, 87, 76, 0.35);
}

/* The header icon carries the same warning as the outline, so it drops the
   accent colour the other cards use. */
.console-card-danger .console-card-head h2 i {
    color: var(--console-danger);
}

/* No floor here either, for the same reason the KPI tiles drop it: the shared
   `--console-card-body-min` is sized for a card holding a list, and this one
   holds a single button. Left at 168px the destructive action floats at the
   top of a card that is mostly empty, which makes the most serious card on the
   page look like the one nobody finished.

   `align-items: flex-start` because the body is a flex column: without it the
   button would stretch to the full width of the card, and a full-bleed
   "Delete platform" is a much easier thing to hit by accident than a button
   the size of its own label. */
.console-card-danger > .console-card-body {
    min-height: 0;
    align-items: flex-start;
}

/* `flex-shrink: 0` because the card is a flex column now: the band is a fixed
   part of the card's chrome and must never be squeezed to make room for the
   body. */
.console-card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-shrink: 0;
    padding: 1rem 1.35rem;
    background-color: rgba(255, 255, 255, 0.04);
    border-bottom: 1px solid var(--console-line);
}

.console-card-head h2 {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    margin: 0;
    font-size: 15px;
    font-weight: 600;
    color: var(--white-color);
}

.console-card-head h2 i {
    font-size: 13px;
    color: var(--console-accent);
}

.console-card-head p {
    margin: 0.2rem 0 0;
    font-size: 12px;
    color: var(--primary-p-color);
}

/* Only when there is an icon: the subtitle lines up under the title's text
   rather than under the icon. A card without one keeps its subtitle flush. */
.console-card-head-text.has-icon p {
    padding-left: 1.55rem;
}

.console-card-link {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    flex-shrink: 0;
    font-size: 12px;
    font-weight: 600;
    color: var(--primary-p-color);
    transition: color 0.15s;
}

.console-card-link:hover {
    color: var(--white-color);
}

.console-card-link i {
    font-size: 10px;
}

/* The body takes the height the card was given, and never falls below the
   floor — that floor is what keeps a card with nothing in it the same size as
   one that is full, which is the whole point of stretching the rows above.
   A flex column so short content can centre itself in the leftover space
   rather than clinging to the top edge. */
.console-card-body {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: var(--console-card-body-min);
    padding: 1.35rem;
}

/* Everything a card shows in place of data centres in whatever height it
   ended up with, so an empty card reads as deliberate rather than broken.
   `.console-muted` can't be used for this: Bootstrap's `m-0` utility sits on
   those elements with `!important` and would win against any margin here. */
.console-card-body > .console-card-nodata,
.console-card-body > .console-inline-empty,
.console-card-body > .console-empty {
    margin-top: auto;
    margin-bottom: auto;
}

.console-card-nodata {
    text-align: center;
    font-size: 13px;
    color: var(--primary-p-color);
}

/* A flex column stretches its items across the cross axis, which would pull
   every button sitting directly in a card (Settings' "Save changes", the
   danger zone) out to the full card width. `.console-btn-block` is the one
   that genuinely wants that, so it keeps the stretch. */
.console-card-body > .console-btn:not(.console-btn-block) {
    align-self: flex-start;
}

/* The list pages (rewards, categories, team) open with a toolbar instead of a
   header, so it wears the same band as `.console-card-head` — otherwise those
   cards would be the only ones starting flush against their content. */
.console-card-toolbar {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
    flex-shrink: 0;
    padding: 1rem 1.35rem;
    background-color: rgba(255, 255, 255, 0.04);
    border-bottom: 1px solid var(--console-line);
}


.console-rows {
    display: flex;
    flex-direction: column;
    margin: 0;
}

.console-rows > li {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.7rem 0;
    border-bottom: 1px solid var(--console-line);
}

.console-rows > li:first-child {
    padding-top: 0;
}

.console-rows > li:last-child {
    padding-bottom: 0;
    border-bottom: none;
}

.console-rows img {
    flex-shrink: 0;
    border-radius: 10px;
    background-color: rgba(255, 255, 255, 0.05);
    object-fit: cover;
}

.console-row-text {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    line-height: 1.3;
}

.console-row-text strong {
    font-size: 13.5px;
    color: var(--white-color);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.console-row-text small {
    font-size: 11.5px;
    color: var(--primary-p-color);
}

.console-row-value {
    flex-shrink: 0;
    font-size: 13px;
    font-weight: 600;
    color: var(--secondary-p-color);
}

.console-row-meta {
    flex-shrink: 0;
    font-size: 11.5px;
    color: var(--primary-p-color);
}

.console-avatars {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.75rem;
    margin: 0;
}

/* Past two members the roster pairs up instead of running down one long
   column, which is what let the card show six names in the height that used to
   hold three. `auto-fit` rather than a hard `repeat(2, …)`: the card sits in
   the narrow aside column, and below roughly 300px two columns would truncate
   every name to a few characters — there it falls back to one. */
.console-avatars.is-split {
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    column-gap: 1rem;
}

.console-avatars > li {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    min-width: 0;
}

/* The prompt under a roster that is still only its owner. `margin-top: auto`
   pushes it to the bottom of the card, so it fills the space a one-line roster
   leaves instead of crowding the name above it — the card body is a flex
   column, which is what makes that work. */
.console-card-cta {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.7rem;
    margin-top: auto;
    padding-top: 1.2rem;
}

.console-card-cta p {
    margin: 0;
    font-size: 12.5px;
    color: var(--primary-p-color);
}

.console-icon-tile {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    flex-shrink: 0;
    border-radius: 11px;
    background-color: var(--console-accent-soft);
    color: var(--console-accent);
    font-size: 14px;
}

.console-icon-tile.is-lg {
    width: 54px;
    height: 54px;
    border-radius: 16px;
    font-size: 20px;
}

.console-figure {
    display: flex;
    align-items: center;
    gap: 0.85rem;
}

.console-figure-img {
    flex-shrink: 0;
    border-radius: 11px;
    background-color: rgba(255, 255, 255, 0.05);
    object-fit: contain;
    padding: 4px;
}

.console-figure-label {
    display: block;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--primary-p-color);
}

.console-figure-value {
    margin: 0.2rem 0 0;
    font-size: 1.75rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--white-color);
}

.console-figure-value.is-sm {
    font-size: 1.1rem;
}

/* A figure that is all the card holds grows into it rather than sitting at the
   top of a card whose height was set by a taller neighbour. It centres in the
   space and steps its icon and number up to match — this is what the balance
   and featured-product cards are, and at the row's height the default sizes
   left most of the card empty.
   `:only-child` is the test on purpose: the platform card puts badges and a
   button under its figure, already fills its card, and must not be scaled. */
.console-card-body > .console-figure:only-child {
    flex: 1;
    gap: 1.15rem;
}

.console-card-body > .console-figure:only-child .console-icon-tile {
    width: 56px;
    height: 56px;
    border-radius: 16px;
    font-size: 21px;
}

.console-card-body > .console-figure:only-child .console-figure-label {
    font-size: 12px;
}

.console-card-body > .console-figure:only-child .console-figure-value {
    margin-top: 0.35rem;
    font-size: 2.15rem;
}

.console-card-body > .console-figure:only-child .console-figure-value.is-sm {
    font-size: 1.45rem;
}

.console-inline-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    padding: 1.75rem 1rem;
    text-align: center;
}

.console-inline-empty h3 {
    margin: 0.4rem 0 0;
    font-size: 1rem;
    color: var(--white-color);
}

.console-inline-empty p {
    margin: 0 0 0.75rem;
    max-width: 380px;
    font-size: 13px;
    color: var(--primary-p-color);
}

/* â”€â”€ Buttons â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

/* The transparent border keeps the filled and ghost variants the same size, but
   it costs a rendering detail: a background is sized to the padding box and
   painted out to the border box by default, so on the gradient variants that
   1px ring showed the gradient tiling â€” a stripe of the start colour down the
   right edge and of the end colour down the left. Sizing the gradient to the
   border box instead makes the ring a continuation of it. */
.console-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.45rem;
    padding: 0.6rem 1.2rem;
    border: 1px solid transparent;
    background-origin: border-box;
    border-radius: 100px;
    font-size: 13px;
    font-weight: 600;
    line-height: 1.2;
    /* .console-btn-light/-ghost/-danger all set their own color; this base
       value is only ever actually used by .console-btn-primary, whose
       gradient background is fixed in both themes and needs fixed white
       text to match — not var(--white-color), which flips dark in light
       mode and would go dark-on-gradient there. */
    color: var(--btn-text-color);
    background-color: transparent;
    transition: filter 0.15s, background-color 0.15s, border-color 0.15s, color 0.15s, opacity 0.15s;
}

.console-btn:disabled,
.console-btn.is-disabled {
    opacity: 0.5;
    pointer-events: none;
}

/* Same specificity as `.console-card-body > .console-btn:not(.console-btn-block)`
   above (which pins every lone card-body button to `flex-start`) so that,
   coming later in the file, this wins the tie instead of losing to it — a
   bare `.console-btn.is-self-end` rule has only two classes and was losing
   that fight silently. */
.console-card-body > .console-btn.is-self-end {
    align-self: flex-end;
}

.console-btn-primary {
    background-image: linear-gradient(120deg, var(--primary-color), var(--secondary-color));
}

.console-btn-primary:hover {
    filter: brightness(1.15);
    color: var(--btn-text-color);
}

/* Fixed #fff rather than var(--white-color): this variant is meant to read
   as a bright, high-contrast button against the console's own surfaces in
   both themes, not to follow --white-color's dark/light text-color role
   (which would make it invisible-on-invisible in light mode, since
   --black-color stays dark in both themes). */
.console-btn-light {
    background-color: #fff;
    color: var(--black-color);
}

.console-btn-light:hover {
    background-color: #fff;
    color: var(--black-color);
}

.console-btn-ghost {
    border-color: var(--console-line-strong);
    color: var(--secondary-p-color);
}

.console-btn-ghost:hover {
    background-color: rgba(255, 255, 255, 0.06);
    color: var(--white-color);
}

.console-btn-ghost.is-danger {
    color: #ffb4ae;
    border-color: rgba(228, 87, 76, 0.35);
}

.console-btn-ghost.is-danger:hover {
    background-color: rgba(228, 87, 76, 0.14);
    color: #ffb4ae;
}

.console-btn-danger {
    background-color: var(--console-danger);
}

.console-btn-danger:hover {
    filter: brightness(1.1);
    color: var(--white-color);
}

.console-btn-sm {
    padding: 0.38rem 0.85rem;
    font-size: 12px;
}

.console-btn-block {
    width: 100%;
}

.console-btn-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 1rem;
}

/* Pushes the row's buttons to the right edge — the primary action sits last in
   the DOM so it lands in the corner. */
.console-btn-row.is-end {
    justify-content: flex-end;
}

.console-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border: 1px solid var(--console-line-strong);
    border-radius: 9px;
    background-color: transparent;
    color: var(--primary-p-color);
    font-size: 12px;
    transition: background-color 0.15s, color 0.15s, border-color 0.15s;
}

.console-icon-btn:hover:not(:disabled) {
    background-color: rgba(255, 255, 255, 0.07);
    color: var(--white-color);
}

.console-icon-btn:disabled {
    opacity: 0.5;
}

.console-icon-btn.is-danger:hover:not(:disabled) {
    background-color: rgba(228, 87, 76, 0.16);
    border-color: rgba(228, 87, 76, 0.4);
    color: #ffb4ae;
}

.console-row-actions {
    display: flex;
    align-items: center;
    gap: 0.35rem;
}

.console-segmented {
    display: inline-flex;
    gap: 2px;
    padding: 3px;
    border: 1px solid var(--console-line-strong);
    border-radius: 11px;
    background-color: var(--console-surface-2);
}

.console-segmented button {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.42rem 0.9rem;
    border: none;
    border-radius: 8px;
    background-color: transparent;
    color: var(--primary-p-color);
    font-size: 12px;
    font-weight: 600;
    transition: background-color 0.15s, color 0.15s;
}

.console-segmented button.active {
    background-image: linear-gradient(120deg, var(--primary-color), var(--secondary-color));
    color: var(--btn-text-color);
}

/* â”€â”€ Metrics (reports) â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.console-metric {
    padding: 1.15rem 1.25rem;
    border: 1px solid var(--console-line);
    border-radius: 14px;
    background-color: var(--console-surface);
}

.console-metric-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 0.9rem;
}

.console-metric-label {
    font-size: 12px;
    font-weight: 500;
    color: var(--primary-p-color);
}

.console-metric-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    flex-shrink: 0;
    border-radius: 10px;
    background-color: rgba(46, 204, 113, 0.14);
    color: var(--console-success);
    font-size: 14px;
}

.console-metric-icon.is-down {
    background-color: rgba(228, 87, 76, 0.14);
    color: var(--console-danger);
}

.console-metric-icon.is-star {
    background-color: rgba(245, 166, 35, 0.14);
    color: var(--console-warning);
}

.console-metric-value {
    margin: 0 0 0.4rem;
    font-size: 1.6rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--white-color);
}

.console-metric-change {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    margin: 0;
    font-size: 12px;
    font-weight: 600;
    color: var(--console-success);
}

.console-metric-change.is-down {
    color: var(--console-danger);
}

.console-metric-period {
    font-weight: 400;
    color: var(--primary-p-color);
}

/* â”€â”€ Charts â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.console-chart {
    display: flex;
    flex-direction: column;
}

.console-plot {
    position: relative;
    flex: 1;
    min-height: 0;
    padding-left: 2.6rem;
}

.console-gridline {
    position: absolute;
    left: 2.6rem;
    right: 0;
    height: 1px;
    background-color: var(--console-line);
}

.console-tick {
    position: absolute;
    right: calc(100% + 0.5rem);
    top: -0.55em;
    font-size: 10px;
    color: var(--primary-p-color);
    white-space: nowrap;
}

.console-area {
    position: absolute;
    inset: 0 0 0 2.6rem;
    width: calc(100% - 2.6rem);
    height: 100%;
    overflow: visible;
}

.console-hover-zones {
    position: absolute;
    inset: 0 0 0 2.6rem;
    display: flex;
}

.console-hover-zone {
    position: relative;
    flex: 1;
    padding: 0;
    border: none;
    background-color: transparent;
}

.console-hover-zone.active,
.console-hover-zone:focus-visible {
    background-color: rgba(255, 255, 255, 0.04);
    outline: none;
}

/* `left` is set inline by AreaChart, to the vertex's offset within this zone —
   it is deliberately not `50%` here, since the centre of a zone is not where
   the vertex is. The negative margins pull the 8px dot back by half its own
   size on both axes, so `left`/`bottom` place its centre rather than its
   corner. */
.console-hover-dot {
    position: absolute;
    width: 8px;
    height: 8px;
    margin: 0 0 -4px -4px;
    border-radius: 50%;
    opacity: 0;
    transition: opacity 0.15s;
}

.console-hover-zone.active .console-hover-dot,
.console-hover-zone:focus-visible .console-hover-dot {
    opacity: 1;
}

.console-tooltip {
    position: absolute;
    top: 0.4rem;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--console-line-strong);
    border-radius: 10px;
    background-color: var(--console-surface-2);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
    pointer-events: none;
    transform: translateX(-50%);
    white-space: nowrap;
    z-index: 2;
}

.console-tooltip-label {
    font-size: 10px;
    color: var(--primary-p-color);
}

.console-tooltip-value,
.console-tooltip-row {
    font-size: 12px;
    font-weight: 600;
}

.console-xaxis {
    display: flex;
    margin-top: 0.5rem;
    padding-left: 2.6rem;
}

.console-xaxis span {
    flex: 1;
    font-size: 10px;
    color: var(--primary-p-color);
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Thinned labels keep their slot so the remaining ones stay aligned with the
   data points above them â€” display:none would reflow the row. */
.console-xaxis span.is-hidden {
    visibility: hidden;
}

.console-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.85rem;
    margin-top: 0.75rem;
}

.console-legend span {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 11px;
    color: var(--primary-p-color);
}

.console-legend i {
    width: 10px;
    height: 3px;
    border-radius: 2px;
}

.console-bars {
    position: absolute;
    inset: 0 0 0 2.6rem;
    display: flex;
    align-items: flex-end;
    gap: 6px;
    padding: 0 4px;
}

.console-bar-slot {
    position: relative;
    flex: 1;
    height: 100%;
    display: flex;
    align-items: flex-end;
    justify-content: center;
}

.console-bar {
    width: 100%;
    max-width: 46px;
    min-height: 2px;
    border-radius: 5px 5px 0 0;
    transition: filter 0.15s;
}

.console-bar-slot:hover .console-bar {
    filter: brightness(1.25);
}

.console-bar-tooltip {
    position: absolute;
    bottom: 100%;
    left: 50%;
    transform: translateX(-50%);
    margin-bottom: 4px;
    padding: 2px 7px;
    border-radius: 6px;
    background-color: var(--console-surface-2);
    border: 1px solid var(--console-line-strong);
    font-size: 10px;
    color: var(--white-color);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s;
    white-space: nowrap;
}

.console-bar-slot:hover .console-bar-tooltip {
    opacity: 1;
}

.console-bar-list {
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
}

.console-bar-list-head {
    display: flex;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 0.35rem;
    font-size: 13px;
    color: var(--secondary-p-color);
}

.console-bar-list-track {
    height: 6px;
    border-radius: 4px;
    background-color: var(--console-line);
    overflow: hidden;
}

.console-bar-list-track span {
    display: block;
    height: 100%;
    border-radius: 4px;
}

.console-chart-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    color: var(--primary-p-color);
    font-size: 13px;
}

.console-chart-empty i {
    font-size: 1.5rem;
    opacity: 0.45;
}

/* â”€â”€ Forms â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.console-field {
    margin-bottom: 1.1rem;
}

.console-label {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 0.4rem;
    font-size: 12px;
    font-weight: 600;
    color: var(--secondary-p-color);
}

.console-label i {
    font-size: 11px;
    color: var(--primary-p-color);
}

.console-field-hint {
    margin: 0.35rem 0 0;
    font-size: 11px;
    color: var(--primary-p-color);
}

.console-input {
    width: 100%;
    padding: 0.6rem 0.85rem;
    border: 1px solid var(--console-line-strong);
    border-radius: 10px;
    background-color: var(--console-surface-2);
    color: var(--white-color);
    font-size: 13px;
    transition: border-color 0.15s, box-shadow 0.15s;
}

.console-input::placeholder {
    color: var(--primary-p-color);
    opacity: 0.7;
}

.console-input:focus {
    outline: none;
    border-color: var(--console-accent);
    box-shadow: 0 0 0 3px rgba(109, 74, 255, 0.2);
}

.console-input:disabled,
.console-input[readonly] {
    opacity: 0.75;
}

.console-textarea {
    resize: vertical;
    min-height: 90px;
}

/* A MODIFIER, not a control: it only narrows and tightens, and expects
   `.console-input` alongside it for the surface, border and text colour.
   Writing it on its own leaves a browser-default control with a white native
   popup - see the rule below, which covers that mistake anyway. */
.console-select-sm {
    width: auto;
    min-width: 200px;
    padding: 0.45rem 0.75rem;
    margin-bottom: 0.2rem;
}

/* Native <select> popups take their background from the control itself, and
   `.console-input` gives that a dark surface — while the theme's Reset region
   colours every `select option` #2f323a for a light popup. Dark grey on dark
   is what made the options unreadable. Both halves are set here so they cannot
   disagree, and `color-scheme` tells the browser to paint the rest of the
   native list (highlight, scrollbar) to match.

   Scoped to the console on purpose: the site's own selects still use the
   theme's light popup, which the Reset rule is right about. */
.console-input,
.console-select-sm {
    color-scheme: dark;
}

/* The option/optgroup colours below already flow through --console-surface-2
   and --white-color, both redefined for light mode, so only the raw
   color-scheme literal needs its own override here. */
[data-theme="light"] .console-input,
[data-theme="light"] .console-select-sm {
    color-scheme: light;
}

.console-input option,
.console-input optgroup,
.console-select-sm option,
.console-select-sm optgroup {
    background-color: var(--console-surface-2);
    color: var(--white-color);
}

.console-input-row {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

/* Address field: the editable label with the fixed root domain beside it. The
   suffix is text rather than part of the control, so what the user types is
   exactly what gets submitted — no stripping a domain back off on save. */
.console-input-suffix {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.console-input-suffix .console-input {
    flex: 1 1 auto;
    min-width: 0;
}

.console-input-suffix-text {
    flex: 0 0 auto;
    font-size: 13px;
    color: var(--primary-p-color);
    white-space: nowrap;
}

.console-input-suffix-link {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    margin-top: 0.45rem;
    word-break: break-all;
}

.console-form-row {
    display: grid;
    grid-template-columns: 4fr 1fr;
    gap: 1rem;
}

.console-form-split {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 260px;
    gap: 1.5rem;
}

.console-form-aside {
    padding-left: 1.5rem;
    border-left: 1px solid var(--console-line);
}

/* Reward commands editor: one card per command — its position in the run
   order, the server that runs it, and the command line itself. Carries no
   explanatory copy; the ordinal, the prompt glyph and the dashed add slot are
   meant to do that work on their own. */

.console-command-cards {
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
}

.console-command-card {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas:
        "index select remove"
        "line  line   line";
    align-items: center;
    gap: 0.45rem 0.55rem;
    padding: 0.6rem;
    border: 1px solid var(--console-line);
    border-radius: var(--console-radius);
    background-color: var(--console-surface-2);
    transition: border-color 0.15s;
}

/* The card takes the focus ring for whichever control inside it has focus, so
   the two fields read as one object instead of lighting up separately. */
.console-command-card:focus-within {
    border-color: var(--console-accent);
}

/* Commands run top to bottom, so the position is information, not decoration —
   it is what tells you `give` happens before the `alert` announcing it. */
.console-command-index {
    grid-area: index;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background-color: var(--console-accent-soft);
    color: var(--console-accent);
    font-size: 10px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* Sized to its content rather than stretched: it is a tag on the card, and a
   full-width select would outweigh the command it belongs to. Takes the same
   surface as the command line below it, so the two read as the card's contents
   against the card's own background. Keeps `.console-input` alongside for the
   native popup colours — see the `color-scheme` note above. */
.console-command-select {
    grid-area: select;
    width: auto;
    justify-self: start;
    max-width: 100%;
    height: 28px;
    /* Right side widened for the chevron below, or a long server name runs
       under it. */
    padding: 0 1.5rem 0 0.5rem;
    border-color: var(--console-line);
    border-radius: 8px;
    background-color: var(--console-surface);
    font-size: 12px;
}

/* The theme's Reset sets `appearance: none` on every select, which takes the
   native dropdown arrow with it — the chip would read as a static label rather
   than something you can open. Same inline-SVG chevron `.details-form select`
   uses, sized down for this control. The stroke has to be baked into the data
   URI (a var() cannot reach inside one), so the two themes get one rule each:
   --primary-p-color is #9CA0D2 dark, #5A5E82 light. */
.console-command-select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%239CA0D2' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.45rem center;
    background-size: 11px 11px;
}

[data-theme="light"] .console-command-select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%235A5E82' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
}

.console-command-remove {
    grid-area: remove;
    width: 28px;
    height: 28px;
    font-size: 11px;
}

/* The command itself, dressed as a terminal line. The border lives here rather
   than on the input so the prompt glyph sits inside the field. */
.console-command-line {
    grid-area: line;
    display: flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0 0.6rem;
    border: 1px solid var(--console-line);
    border-radius: 8px;
    background-color: var(--console-surface);
}

.console-command-line > i {
    flex: 0 0 auto;
    font-size: 9px;
    color: var(--console-accent);
}

/* Monospace because these are read back for typos: proportional digits and
   `l`/`1` ambiguity make an argument list hard to check at a glance. Strips
   `.console-input`'s own frame — the wrapper is the frame now. */
.console-command-input {
    height: 30px;
    padding: 0;
    border: none;
    border-radius: 0;
    background-color: transparent;
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
    font-size: 12px;
}

.console-command-input:focus {
    outline: none;
    border: none;
    box-shadow: none;
}

/* Shaped like a card so the column reads as one stack, and dashed so it reads
   as a slot rather than a filled row. With no commands yet it is the whole
   control, which is what keeps the empty state from needing a sentence. */
.console-command-add {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    padding: 0.5rem;
    border: 1px dashed var(--console-line-strong);
    border-radius: var(--console-radius);
    background-color: transparent;
    color: var(--primary-p-color);
    font-size: 13px;
    transition: border-color 0.15s, color 0.15s, background-color 0.15s;
}

.console-command-add:hover:not(:disabled),
.console-command-add:focus-visible:not(:disabled) {
    border-color: var(--console-accent);
    background-color: var(--console-accent-soft);
    color: var(--console-accent);
    outline: none;
}

.console-command-add:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.console-filters {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}

.console-filter-group {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.console-search {
    position: relative;
    flex: 1;
    max-width: 340px;
    min-width: 200px;
}

.console-search i {
    position: absolute;
    top: 50%;
    left: 0.85rem;
    transform: translateY(-50%);
    font-size: 12px;
    color: var(--primary-p-color);
    pointer-events: none;
}

.console-search .console-input {
    padding-left: 2.25rem;
}

.console-checkbox {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    margin-bottom: 1.1rem;
    font-size: 13px;
    color: var(--secondary-p-color);
}

.console-checkbox input {
    margin-top: 2px;
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    accent-color: var(--console-accent);
}

.console-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.65rem;
    cursor: pointer;
    user-select: none;
}

/* In the reward modal the visibility toggle follows the category select in a
   stacked field, and reads as cramped against it without a little breathing
   room. Scoped to `.console-form-split`, which only that modal uses. */
.console-form-split .console-toggle {
    margin-top: 0.6rem;
}

.console-toggle-input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

.console-toggle-track {
    position: relative;
    width: 44px;
    height: 24px;
    flex-shrink: 0;
    border-radius: 999px;
    background-color: var(--console-line-strong);
    transition: background-color 0.2s;
}

.console-toggle-thumb {
    position: absolute;
    top: 2px;
    left: 2px;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background-color: #fff;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
    transition: left 0.2s;
}

.console-toggle-input:checked + .console-toggle-track {
    background-color: var(--console-success);
}

.console-toggle-input:checked + .console-toggle-track .console-toggle-thumb {
    left: 22px;
}

.console-toggle-input:focus-visible + .console-toggle-track {
    box-shadow: 0 0 0 3px rgba(109, 74, 255, 0.3);
}

.console-toggle-text {
    font-size: 13px;
    font-weight: 600;
    color: var(--secondary-p-color);
}

.console-image-drop {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.25rem;
    width: 100%;
    max-width: 200px;
    padding: 1.4rem 1rem;
    border: 1px dashed var(--console-line-strong);
    border-radius: 12px;
    background-color: var(--console-surface-2);
    cursor: pointer;
    overflow: hidden;
    transition: border-color 0.2s, background-color 0.2s;
}

/* Filled: a square the size of the logo, and a solid edge — the dashes say
   "drop something here", which is no longer the thing being asked for. */
.console-image-drop.has-image {
    aspect-ratio: 1;
    padding: 0;
    border-style: solid;
    border-color: var(--console-line-strong);
    border-radius: 14px;
}

.console-image-drop.is-dragging {
    border-color: var(--console-accent);
    background-color: rgba(109, 74, 255, 0.12);
}

.console-image-drop img {
    object-fit: cover;
}

.console-image-drop > i {
    font-size: 1.15rem;
    color: var(--primary-p-color);
}

/* The replace affordance. Hidden until the pointer or the keyboard is on the
   control: an image that is permanently veiled reads as disabled, and the
   whole point of dropping the second box was to let the logo be seen. */
.console-image-overlay {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    font-size: 12px;
    font-weight: 600;
    color: var(--white-color);
    background-color: rgba(4, 4, 2, 0.62);
    opacity: 0;
    transition: opacity 0.18s;
}

.console-image-overlay i {
    font-size: 1.2rem;
}

.console-image-drop:hover .console-image-overlay,
.console-image-drop:focus-within .console-image-overlay,
.console-image-drop.is-dragging .console-image-overlay {
    opacity: 1;
}

.console-dropzone-title {
    font-size: 13px;
    font-weight: 600;
    color: var(--secondary-p-color);
}

.console-dropzone-hint {
    font-size: 11px;
    color: var(--primary-p-color);
}

/* â”€â”€ Tables and list pages â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.console-table-wrap {
    overflow-x: auto;
}

.console-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}

.console-table th,
.console-table td {
    padding: 0.75rem 1.35rem;
    text-align: left;
    vertical-align: middle;
    white-space: nowrap;
}

.console-table th {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--primary-p-color);
    border-bottom: 1px solid var(--console-line);
}

.console-table td {
    color: var(--secondary-p-color);
    border-bottom: 1px solid var(--console-line);
}

.console-table tbody tr:last-child td {
    border-bottom: none;
}

.console-table tbody tr.is-selected {
    background-color: var(--console-accent-soft);
}

.console-table-check {
    width: 44px;
    padding-right: 0 !important;
}

.console-table input[type="checkbox"] {
    width: 15px;
    height: 15px;
    accent-color: var(--console-accent);
}

.console-cell-strong {
    font-weight: 600;
    color: var(--white-color);
}

.console-cell-muted {
    color: var(--primary-p-color);
}

.console-cell-clamp {
    max-width: 260px;
    overflow: hidden;
    text-overflow: ellipsis;
}

.console-cell-media {
    display: flex;
    align-items: center;
    gap: 0.65rem;
}

.console-cell-media img {
    flex-shrink: 0;
    border-radius: 10px;
    background-color: rgba(255, 255, 255, 0.05);
    object-fit: cover;
}

.console-cell-media strong {
    color: var(--white-color);
    font-weight: 600;
}

.console-perm-table th,
.console-perm-table td {
    padding: 0.5rem 0.75rem;
}

.console-perm-table td:not(:first-child),
.console-perm-table th:not(:first-child) {
    text-align: center;
}

.console-bulkbar {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.65rem 1.35rem;
    border-bottom: 1px solid var(--console-line);
    background-color: var(--console-accent-soft);
    font-size: 13px;
    font-weight: 600;
    color: var(--secondary-p-color);
}

.console-bulkbar > span:first-child {
    flex: 1;
}

.console-list {
    margin: 0;
    padding: 0;
}

.console-list-card {
    padding: 1rem 1.25rem;
    border-bottom: 1px solid var(--console-line);
}

/* On a flush list the last row sits against the card's bottom edge, so its
   divider is just a line hugging the border — drop it. */
.console-list-flush > .console-list-card:last-child {
    border-bottom: none;
}

.console-list-card.is-selected {
    background-color: var(--console-accent-soft);
}

/* A row you can press anywhere.

   The whole card is NOT wrapped in a <Link>: it contains the "Open" link
   already, and an anchor inside an anchor is invalid HTML that browsers repair
   by splitting the outer one. Instead the existing link grows an invisible
   ::after over the whole card — the row becomes one big target, the button
   keeps its own affordance, and there is still exactly one anchor.

   That also sidesteps the theme's `a:link:not(.btn)` rule at (0,2,1): the
   thing being stretched is a `.console-btn`, which region 15's anchor
   overrides already cover. A bare <Link> here would flash blue on hover. */
.console-list-card.is-linked {
    position: relative;
    transition: background-color 0.15s;
}

.console-list-card.is-linked:hover {
    background-color: rgba(255, 255, 255, 0.03);
}

.console-list-card.is-linked .console-row-link::after {
    content: "";
    position: absolute;
    inset: 0;
    /* Under the badges and buttons that sit in the row, over everything else,
       so a real control is still clickable in its own right. */
    z-index: 0;
}

/* Anything genuinely interactive has to stay above the overlay. */
.console-list-card.is-linked .console-row-actions,
.console-list-card.is-linked .console-badge-row {
    position: relative;
    z-index: 1;
}

.console-list-main {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.console-list-main img {
    flex-shrink: 0;
    border-radius: 12px;
    background-color: rgba(255, 255, 255, 0.05);
    object-fit: cover;
}

.console-list-main input[type="checkbox"] {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    accent-color: var(--console-accent);
}

.console-list-text {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.console-list-text strong {
    color: var(--white-color);
    font-size: 14px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.console-list-value {
    flex-shrink: 0;
    font-size: 15px;
    font-weight: 700;
    color: var(--white-color);
}

.console-list-desc {
    margin: 0.6rem 0 0;
    font-size: 12px;
    line-height: 1.5;
    color: var(--primary-p-color);
}

.console-list-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin-top: 0.75rem;
}

.console-member {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    padding: 1rem 1.35rem;
    border-bottom: 1px solid var(--console-line);
}

.console-member:last-child {
    border-bottom: none;
}

.console-member-avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    flex-shrink: 0;
    border-radius: 50%;
    background-image: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
    color: var(--btn-text-color);
    font-weight: 700;
}

/* Carries a picture instead of an initial. The gradient has to go, or it shows
   through anything with transparency; `overflow: hidden` is what makes a square
   avatar round. Same pair as `.console-user-avatar.has-image`. */
.console-member-avatar.has-image {
    overflow: hidden;
    background-image: none;
}

.console-member-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* The server software's own mark — Paper's plane, Forge's anvil, Purpur's
   crystal — served from /assets/img/gameservers as single-colour SVGs.

   Painted as a mask rather than dropped in with an <img>: those files draw
   themselves in `currentColor`, and a standalone SVG document resolves that to
   black, which is invisible on the console's dark surfaces. A mask takes only
   the shape and lets the colour behind it through, so one file reads correctly
   wherever it is placed and sits at the same weight as every Font Awesome glyph
   next to it. The mask-image itself is set inline, from the type's own record —
   one rule here rather than thirteen. */
.console-server-logo {
    width: 20px;
    height: 20px;
    background-color: currentColor;
    -webkit-mask-position: center;
    mask-position: center;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-size: contain;
    mask-size: contain;
}

.console-member-text {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

.console-member-text strong {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;
    font-size: 14px;
    color: var(--white-color);
}

.console-member-meta {
    font-size: 12px;
    color: var(--primary-p-color);
}

.console-member-perms {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
}

.console-member-perms em {
    font-style: normal;
    opacity: 0.65;
    margin-left: 0.3rem;
}

.console-link-list {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    margin: 0;
}

.console-link-list li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.65rem 0.85rem;
    border: 1px solid var(--console-line);
    border-radius: 10px;
    background-color: var(--console-surface-2);
}

.console-link-text {
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.console-link-text strong {
    font-size: 13px;
    color: var(--white-color);
}

.console-link-text a {
    font-size: 11px;
    color: var(--console-accent);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Same look as the <a> above, on a <button> for values that aren't a real
   URL — see isNavigableLink. Reset because a bare <button> carries its own
   font/background/border. */
.console-link-text .console-link-value-btn {
    display: inline-flex;
    align-items: center;
    max-width: 100%;
    padding: 0;
    border: none;
    background: transparent;
    font: inherit;
    font-size: 11px;
    color: var(--console-accent);
    cursor: pointer;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.console-link-text .console-link-value-btn i {
    flex-shrink: 0;
}

.console-tile-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 1rem;
    margin: 0;
    padding: 1.35rem;
}

.console-tile {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    padding: 0.9rem 1rem;
    border: 1px solid var(--console-line);
    border-radius: 12px;
    background-color: var(--console-surface-2);
}

.console-tile img {
    flex-shrink: 0;
    border-radius: 12px;
    background-color: rgba(255, 255, 255, 0.05);
    object-fit: cover;
}

.console-tile-text {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

.console-tile-text strong {
    font-size: 14px;
    color: var(--white-color);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.console-copy-id {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    max-width: 100%;
    padding: 0;
    border: none;
    background-color: transparent;
    color: var(--primary-p-color);
    font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
    font-size: 11px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    transition: color 0.15s;
}

.console-copy-id:hover {
    color: var(--console-accent);
}

.console-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.22rem 0.6rem;
    border: 1px solid var(--console-line-strong);
    border-radius: 100px;
    font-size: 11px;
    font-weight: 600;
    color: var(--secondary-p-color);
    white-space: nowrap;
    margin-left: 0.25rem;
}

.console-badge i {
    font-size: 9px;
}

.console-badge-sm {
    padding: 0.15rem 0.5rem;
    font-size: 10px;
}

.console-badge-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}

.console-badge-primary {
    border-color: transparent;
    background-image: linear-gradient(120deg, var(--primary-color), var(--secondary-color));
    color: var(--btn-text-color);
}

.console-badge-success {
    border-color: rgba(46, 204, 113, 0.4);
    color: var(--console-success);
}

/* The variant this family was missing. `.console-btn-danger` and
   `.console-card-danger` already existed, so a caller reasonably assumed a
   badge did too - and a missing variant class is not a visible failure, it
   renders as unstyled text that looks almost right. Added for the outreach
   list's "declined", which is a genuinely negative state rather than a
   merely finished one. */
.console-badge-danger {
    border-color: rgba(228, 87, 76, 0.4);
    color: var(--console-danger);
}

.console-badge-warning {
    border-color: rgba(245, 166, 35, 0.4);
    color: var(--console-warning);
}

.console-badge-verified {
    border-color: rgba(52, 152, 219, 0.45);
    color: #3498db;
}

.console-badge-owner {
    border-color: rgba(228, 87, 76, 0.45);
    color: #ff9c93;
}

.console-badge-muted {
    color: var(--primary-p-color);
}

/* â”€â”€ Empty / loading â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.console-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 3rem 1.5rem;
    text-align: center;
}

.console-empty i {
    font-size: 1.9rem;
    color: var(--primary-p-color);
    opacity: 0.5;
}

.console-empty h3 {
    margin: 0.35rem 0 0;
    font-size: 1.05rem;
    color: var(--white-color);
}

.console-empty p {
    margin: 0 0 0.5rem;
    max-width: 460px;
    font-size: 13px;
    color: var(--primary-p-color);
}

.console-loading {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    padding: 3rem 1.5rem;
    font-size: 13px;
    color: var(--primary-p-color);
}

/* ── Catalogue ─────────────────────────────────────────────────────────────
   Categories as stacked, collapsible sections with their rewards inside, both
   levels draggable. Each section is a `.console-card` in everything but name —
   same surface, radius and header band — so the page still reads as the rest
   of the console. */
.console-catalog {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}

.console-catalog-toolbar {
    justify-content: space-between;
    /* Matches the gap between the sections below, so the page has one rhythm
       instead of a wider seam under the toolbar than between the cards. */
    margin-bottom: 0.85rem;
    border-radius: var(--console-radius);
    border-bottom: none;
}

/* The search fills whatever the select-all and the collapse button leave.
   `max-width: none` is the point of this rule: `.console-search` caps itself at
   340px for the list pages' toolbars, and under `space-between` that cap left
   it stranded in the middle of the bar with a gap on either side. */
.console-catalog-toolbar .console-search {
    flex: 1;
    min-width: 180px;
    max-width: none;
}

/* `padding: 0` is not decoration: this is a bare <section>, and the theme gives
   every one of those `padding: 130px 0` (region 5). A class only beats an
   element selector for properties it actually declares, so without this line
   each category renders with 130px of dead space above its header and below
   its rewards — the same trap `.console-card` documents. */
.console-catalog-group {
    padding: 0;
    border-radius: var(--console-radius);
    background-color: var(--console-surface);
    overflow: hidden;
    /* A hairline rather than a border: it reads as depth against the console
       canvas without adding a box that competes with the drag markers. */
    box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.04);
    transition: box-shadow 0.2s, opacity 0.15s;
}

.console-catalog-group:hover {
    box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.09), 0 6px 18px rgba(0, 0, 0, 0.22);
}

/* The row being carried, and the row it would land on. Kept deliberately loud:
   a drag with no feedback reads as a broken click. */
.console-catalog-group[data-drag="source"],
.console-catalog-reward[data-drag="source"] {
    opacity: 0.4;
}

/* The marker sits on the side the item would land on, so "after the last one"
   is something the reader can see and aim at rather than guess. */
.console-catalog-group[data-drag="target"][data-edge="before"] {
    box-shadow: inset 0 3px 0 var(--console-accent);
}

.console-catalog-group[data-drag="target"][data-edge="after"] {
    box-shadow: inset 0 -3px 0 var(--console-accent);
}

.console-catalog-reward[data-drag="target"][data-edge="before"] {
    box-shadow: inset 0 2px 0 var(--console-accent);
}

.console-catalog-reward[data-drag="target"][data-edge="after"] {
    box-shadow: inset 0 -2px 0 var(--console-accent);
}

/* The dashed outline replaces the hairline rather than doubling it — this
   section is a leftovers bin, not a category, and should look provisional. */
.console-catalog-group.is-orphan,
.console-catalog-group.is-orphan:hover {
    background-color: transparent;
    border: 1px dashed var(--console-line-strong);
    box-shadow: none;
}

.console-catalog-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.85rem 1.1rem;
    background-color: rgba(255, 255, 255, 0.04);
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.console-catalog-group.is-orphan .console-catalog-head {
    background-color: transparent;
    border-bottom-color: var(--console-line);
}

/* The whole title block is the disclosure control, so the hit area matches
   what it looks like — a header you click to open. */
.console-catalog-toggle {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex: 1;
    min-width: 0;
    padding: 0;
    border: none;
    background: none;
    text-align: left;
    color: inherit;
}

/* One chevron that turns, rather than two icons swapping: the rotation shows
   the section opening instead of just reporting that it did. */
.console-catalog-toggle > i {
    width: 12px;
    flex-shrink: 0;
    font-size: 11px;
    color: var(--primary-p-color);
    transition: color 0.15s, transform 0.2s ease;
}

.console-catalog-toggle[aria-expanded="true"] > i {
    transform: rotate(90deg);
}

.console-catalog-toggle:hover > i {
    color: var(--white-color);
}

.console-catalog-toggle img {
    flex-shrink: 0;
    border-radius: 10px;
    background-color: rgba(255, 255, 255, 0.05);
    box-shadow: 0 0 0 1px var(--console-line-strong);
    object-fit: cover;
}

.console-catalog-title {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    min-width: 0;
    line-height: 1.3;
}

/* `min-width: 0` as well as `overflow: hidden`: a flex item refuses to shrink
   below its content width without it, so the ellipsis would never appear. */
.console-catalog-title strong {
    min-width: 0;
    font-size: 14px;
    font-weight: 600;
    color: var(--white-color);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    transition: color 0.15s;
}

/* The count sits beside the name as a quiet pill instead of under it: the
   header is a single line again, which is what lets a long catalogue be
   scanned by name alone. */
.console-catalog-title small {
    flex-shrink: 0;
    padding: 0.12rem 0.5rem;
    border-radius: 100px;
    background-color: rgba(255, 255, 255, 0.06);
    font-size: 11px;
    font-weight: 600;
    color: var(--primary-p-color);
    white-space: nowrap;
}

.console-catalog-toggle:hover .console-catalog-title strong {
    color: var(--console-accent);
}

.console-catalog-head-meta {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    flex-shrink: 0;
}

/* `cursor: grab` is the only affordance a native drag gets — there is no
   platform chrome telling the user the row can be picked up.
 *
 * Nearly invisible until the row is hovered: a grip on every row at full
 * strength turns a catalogue into a column of dots, and the handle only
 * matters once the pointer is already on the row it belongs to. It never goes
 * to zero, so the rows still read as movable at a glance. */
.console-drag-handle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    flex-shrink: 0;
    font-size: 13px;
    color: var(--primary-p-color);
    opacity: 0.22;
    cursor: grab;
    transition: opacity 0.15s, color 0.15s;
}

.console-catalog-head:hover .console-drag-handle,
.console-catalog-reward:hover .console-drag-handle {
    opacity: 0.7;
}

.console-drag-handle:hover {
    opacity: 1;
    color: var(--white-color);
}

.console-drag-handle:active {
    cursor: grabbing;
}

/* 0.7rem, not 1.1rem: each reward row adds 0.4rem of its own padding, and the
   two together have to land on the same 1.1rem the header sits at — otherwise
   the checkbox column jogs sideways between a category and its contents. */
.console-catalog-body {
    padding: 0.85rem 0.7rem 1.1rem;
    transition: background-color 0.15s;
}

/* The whole open area accepts a reward, which is the only way into a category
   that has none — reordering works by aiming at a sibling, and an empty
   category has no sibling to aim at. */
.console-catalog-body.is-drop-target {
    background-color: var(--console-accent-soft);
    box-shadow: inset 0 0 0 1px var(--console-accent);
}

.console-catalog-note {
    margin: 0;
    padding: 0.35rem 0;
    font-size: 12.5px;
    color: var(--primary-p-color);
}

/* The toolbar and the bulk bar are siblings above the list, not children of a
   card, so the bar carries its own rounding. */
.console-catalog-bulkbar {
    margin-bottom: 1.25rem;
    border-radius: var(--console-radius);
    border-bottom: none;
    flex-wrap: wrap;
}

/* A native checkbox paints as a filled white square on this dark surface —
   `accent-color` only tints the *checked* state, so the unchecked box was the
   brightest thing in the row. Drawn from scratch instead: `appearance: none`
   strips the platform control, the box is the input itself, and the tick is a
   rotated border on its ::after.
 *
 * Written as `input[type="checkbox"].console-catalog-check` — specificity
 * (0,2,1) — because the theme's Reset region carries
 * `input[type=checkbox] { height: 20px; width: 20px }` at (0,1,1), which
 * outranks a bare class and would fix the size. `padding` matters just as
 * much: `input, textarea, select` sets `0.7rem 1rem`, and with border-box that
 * padding alone forced the box out to a wide rounded rectangle. Both have to be
 * restated here, not merely overridden in spirit. */
input[type="checkbox"].console-catalog-check {
    position: relative;
    box-sizing: border-box;
    width: 17px;
    height: 17px;
    flex-shrink: 0;
    margin: 0;
    padding: 0;
    appearance: none;
    -webkit-appearance: none;
    border: 1.5px solid var(--console-line-strong);
    border-radius: 5px;
    background-color: rgba(255, 255, 255, 0.03);
    cursor: pointer;
    transition: background-color 0.15s, border-color 0.15s;
}

input[type="checkbox"].console-catalog-check:hover {
    border-color: var(--console-accent);
    background-color: var(--console-accent-soft);
}

input[type="checkbox"].console-catalog-check:checked {
    border-color: var(--console-accent);
    background-color: var(--console-accent);
}

input[type="checkbox"].console-catalog-check:disabled {
    opacity: 0.3;
    cursor: default;
}

input[type="checkbox"].console-catalog-check:disabled:hover {
    border-color: var(--console-line-strong);
    background-color: rgba(255, 255, 255, 0.03);
}

/* "Some" must not look like "all".
 *
 * The box keeps the resting border and background of an *unchecked* control —
 * only the dash inside is accented. Selecting one reward out of twenty should
 * leave select-all looking untouched apart from a small mark, and at 17px an
 * accent border was near enough to an accent fill that the box read as
 * switched on. */
input[type="checkbox"].console-catalog-check:indeterminate {
    border-color: var(--console-line-strong);
    background-color: rgba(255, 255, 255, 0.03);
}

.console-catalog-check:checked::after {
    content: "";
    position: absolute;
    top: 1px;
    left: 5px;
    width: 4px;
    height: 9px;
    border: solid #fff;
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}

/* "Some, but not all" — an accent dash on the tinted box, not a white tick on
   a solid one. */
.console-catalog-check:indeterminate::after {
    content: "";
    position: absolute;
    top: 6px;
    left: 3px;
    width: 8px;
    height: 2px;
    border-radius: 1px;
    background-color: var(--console-accent);
}

.console-catalog-selectall {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0;
    font-size: 12.5px;
    color: var(--primary-p-color);
    cursor: pointer;
    user-select: none;
    transition: color 0.15s;
}

.console-catalog-selectall:hover {
    color: var(--white-color);
}

.console-catalog-check:focus-visible {
    outline: 2px solid var(--console-accent);
    outline-offset: 2px;
}

/* ── Bulk actions menu ─────────────────────────────────────────────────────── */

.console-bulk-actions {
    position: relative;
}

.console-btn-caret {
    margin-left: 0.15rem;
    font-size: 9px;
    opacity: 0.75;
}

/* Reuses `.console-menu-item` from the rail's menus; only the shell differs,
   because that one is positioned against the sidebar. */
.console-bulk-menu {
    position: absolute;
    top: calc(100% + 0.4rem);
    right: 0;
    z-index: 50;
    min-width: 210px;
    max-width: 280px;
    padding: 0.35rem;
    border: 1px solid var(--console-line-strong);
    border-radius: 14px;
    background-color: var(--console-surface-2);
    box-shadow: 0 16px 40px rgba(0, 0, 0, 0.55);
}

.console-bulk-menu-scroll {
    max-height: 220px;
    overflow-y: auto;
}

.console-bulk-menu-sep {
    height: 1px;
    margin: 0.3rem 0.2rem;
    background-color: var(--console-line);
}

/* An accent rule down the left, not just a tint: a selected row has to be
   countable at a glance when the bulk bar says "6 selected". */
.console-catalog-reward.is-selected {
    background-color: var(--console-accent-soft);
    box-shadow: inset 3px 0 0 var(--console-accent);
}

/* Nothing reaches the database until this is used, so it has to stay in view
   however far the catalogue scrolls — a save button that scrolled away with
   the list would leave the work looking done when it is not. */
.console-savebar {
    position: sticky;
    bottom: 1rem;
    z-index: 5;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-top: 1.25rem;
    padding: 0.85rem 1.1rem;
    border: 1px solid rgba(245, 166, 35, 0.35);
    border-radius: var(--console-radius);
    background-color: var(--console-surface-2);
    box-shadow: 0 14px 34px rgba(0, 0, 0, 0.5);
    font-size: 13px;
    color: var(--secondary-p-color);
    /* Arrives from below the first time it appears, so a change that has not
       been written announces itself instead of materialising silently. */
    animation: console-savebar-in 0.22s ease-out;
}

@keyframes console-savebar-in {
    from {
        opacity: 0;
        transform: translateY(10px);
    }
}

@media (prefers-reduced-motion: reduce) {
    .console-savebar {
        animation: none;
    }
}

.console-savebar > i {
    color: var(--console-warning);
}

.console-savebar > span {
    flex: 1;
    min-width: 0;
}

@media (max-width: 575px) {
    .console-savebar {
        flex-wrap: wrap;
    }

    .console-savebar > span {
        flex-basis: 100%;
    }
}

/* An empty category reads as a target rather than as a dead end. */
.console-catalog-dropnote {
    padding: 1.1rem;
    border: 1px dashed var(--console-line-strong);
    border-radius: 10px;
    text-align: center;
}

.console-catalog-rewards {
    display: flex;
    flex-direction: column;
    margin: 0;
}

.console-catalog-reward {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.6rem 0.4rem;
    border-radius: 10px;
    border-bottom: 1px solid var(--console-line);
    transition: background-color 0.15s;
}

.console-catalog-reward:last-child {
    border-bottom: none;
}

.console-catalog-reward:hover {
    background-color: rgba(255, 255, 255, 0.05);
}

/* The row's controls are dim until it is hovered, for the same reason the drag
   handle is: three icon buttons on every row at full strength turn the list
   into a wall of chrome. They never disappear — a control you cannot see is a
   control nobody finds. */
.console-catalog-reward .console-row-actions {
    opacity: 0.45;
    transition: opacity 0.15s;
}

.console-catalog-reward:hover .console-row-actions,
.console-catalog-reward:focus-within .console-row-actions {
    opacity: 1;
}

.console-catalog-reward img {
    flex-shrink: 0;
    border-radius: 10px;
    background-color: rgba(255, 255, 255, 0.05);
    object-fit: cover;
}

.console-catalog-reward-text {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    flex: 1;
    min-width: 0;
    line-height: 1.35;
}

.console-catalog-reward-text strong {
    font-size: 13.5px;
    color: var(--white-color);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.console-catalog-reward-text p {
    display: -webkit-box;
    -webkit-line-clamp: 1;
    line-clamp: 1;
    -webkit-box-orient: vertical;
    overflow: hidden;
    margin: 0;
    font-size: 11.5px;
    color: var(--primary-p-color);
}

/* The identifier is reference material, not part of reading the row: it drops
   back to a near-whisper and only comes up when the row is hovered, which is
   when someone is actually reaching for it. */
.console-catalog-reward-text .console-copy-id {
    font-size: 10.5px;
    opacity: 0.5;
    transition: opacity 0.15s, color 0.15s;
}

.console-catalog-reward:hover .console-copy-id,
.console-catalog-reward-text .console-copy-id:hover,
.console-catalog-reward-text .console-copy-id:focus-visible {
    opacity: 1;
}

.console-catalog-reward-cost {
    flex-shrink: 0;
    font-size: 13px;
    font-weight: 600;
    color: var(--secondary-p-color);
}

/* Below the rail breakpoint the row runs out of horizontal room long before
   the description does: the metadata wraps under the name instead. */
@media (max-width: 767px) {
    .console-catalog-reward {
        flex-wrap: wrap;
    }

    .console-catalog-reward-text {
        flex-basis: 100%;
        order: 1;
    }

    .console-catalog-reward-cost,
    .console-catalog-reward .console-badge {
        order: 2;
    }

    .console-catalog-reward .console-row-actions {
        order: 3;
        margin-left: auto;
    }

    .console-catalog-head-meta .console-badge {
        display: none;
    }
}

/* ── Skeletons ─────────────────────────────────────────────────────────────
   Placeholder shapes drawn in the layout the data is about to occupy, so a
   loading page fills in rather than swapping a spinner for a different shape.
   The sweep is one wide gradient scrolled across an oversized background box —
   no extra element and nothing to lay out. */
@keyframes console-skel-sweep {
    from {
        background-position: 100% 50%;
    }
    to {
        background-position: 0 50%;
    }
}

.console-skel {
    display: block;
    border-radius: 6px;
    background-color: rgba(255, 255, 255, 0.05);
    background-image: linear-gradient(
        90deg,
        rgba(255, 255, 255, 0.05) 25%,
        rgba(255, 255, 255, 0.11) 37%,
        rgba(255, 255, 255, 0.05) 63%
    );
    background-size: 400% 100%;
    animation: console-skel-sweep 1.5s ease infinite;
}

[data-theme="light"] .console-skel {
    background-color: rgba(20, 21, 43, 0.05);
    background-image: linear-gradient(
        90deg,
        rgba(20, 21, 43, 0.05) 25%,
        rgba(20, 21, 43, 0.11) 37%,
        rgba(20, 21, 43, 0.05) 63%
    );
}

/* The sweep is pure decoration; the shapes still read without it. */
@media (prefers-reduced-motion: reduce) {
    .console-skel {
        animation: none;
    }
}

.console-skel-rows {
    display: flex;
    flex-direction: column;
    gap: 1.15rem;
}

.console-skel-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.console-skel-row-text {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    flex: 1;
    min-width: 0;
}

/* Fills whatever height the card was stretched to, the way a real chart does. */
.console-skel-chart {
    width: 100%;
    flex: 1;
    min-height: 150px;
    border-radius: 10px;
}

.console-skel-kpi-change {
    margin-top: 0.6rem;
}

.console-spinner {
    width: 34px;
    height: 34px;
    border: 3px solid var(--console-line-strong);
    border-top-color: var(--console-accent);
    border-radius: 50%;
    animation: console-spin 0.8s linear infinite;
}

@keyframes console-spin {
    to {
        transform: rotate(360deg);
    }
}

/* â”€â”€ Platform picker page â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

/* `grid-auto-rows: 1fr` is what makes every row the same height, not just the
   cards within one row — otherwise a card whose badges wrap onto a second line
   makes its whole row taller than the others. */
.console-platform-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    grid-auto-rows: 1fr;
    gap: 1rem;
    margin: 0;
}

/* The <li> is the grid item; the card has to fill it to inherit that height. */
.console-platform-grid > li {
    display: flex;
}

/* Two bands: a header carrying the platform's type effect, and a body with the
   description and status. The card is a <button>, so it also resets the padding
   and text alignment a button would otherwise impose. */
.console-platform-card {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    width: 100%;
    height: 100%;
    padding: 0;
    overflow: hidden;
    border: 1px solid var(--console-line);
    border-radius: var(--console-radius);
    background-color: var(--console-surface);
    text-align: left;
    transition: border-color 0.15s, background-color 0.15s, transform 0.15s;
}

.console-platform-card:hover:not(:disabled) {
    border-color: var(--console-line-strong);
    transform: translateY(-2px);
}

.console-platform-card.is-active {
    border-color: var(--console-accent);
}

.console-platform-head {
    display: block;
    padding: 1rem 1.15rem;
    border-bottom: 1px solid var(--console-line);
    /* The effect layers fill this band; without a base colour a type with no
       effect (or an unknown one) would show the card's surface unchanged. */
    background-color: var(--console-surface-2);
}

.console-platform-head-content {
    display: flex;
    align-items: center;
    gap: 0.85rem;
}

/* Pinned to a square: the theme's global `img { height: auto }` otherwise lets a
   non-square logo set its own height, and the header band — and with it the
   divider between the two halves — ends up at a different height per card. */
.console-platform-head-content img {
    width: 48px;
    height: 48px;
    flex-shrink: 0;
    border-radius: 12px;
    background-color: rgba(0, 0, 0, 0.35);
    object-fit: contain;
    padding: 4px;
}

.console-platform-title {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.console-platform-title strong {
    font-size: 15px;
    color: var(--white-color);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.console-platform-type {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.75);
}

/* The shared watermarks are sized for the account page's tall promo card; in
   this short band a 6–7rem glyph is almost entirely clipped away. */
.console-platform-head .discord-logo-icon {
    font-size: 4rem;
}

.console-platform-head .website-globe-icon {
    font-size: 3.5rem;
}

/* Absorbs the leftover height so the header band lines up across every card
   whatever the body holds. */
.console-platform-body {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    flex: 1;
    padding: 0.9rem 1.15rem 1rem;
}

.console-platform-body .console-muted {
    font-size: 12px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.console-platform-card-active {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    flex-shrink: 0;
    padding: 0.25rem 0.6rem;
    border-radius: 100px;
    background-color: rgba(0, 0, 0, 0.45);
    font-size: 11px;
    font-weight: 600;
    color: white;
}

/* â”€â”€ Payments â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.console-balance-card .console-card-body,
.console-withdraw-amount {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.25rem;
}

.console-balance-label {
    font-size: 12px;
    font-weight: 500;
    color: var(--primary-p-color);
}

.console-balance-value {
    margin: 0;
    font-size: 2.3rem;
    font-weight: 700;
    letter-spacing: -0.03em;
    color: var(--white-color);
}

.console-balance-note {
    margin: 0 0 1rem;
    font-size: 12px;
    color: var(--primary-p-color);
}

/* "Next payout" — the date this platform's held balance is scheduled to be
   sent, sitting just under the balance figure. */
.console-balance-next {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    margin: 0.5rem 0 0.15rem;
}

.console-balance-next > strong {
    font-size: 15px;
    font-weight: 700;
    color: var(--white-color);
}

/* The standing net-45 explainer under the balance figure. */
.console-balance-fineprint {
    margin: 0.35rem 0 1rem;
    font-size: 11.5px;
    line-height: 1.5;
    color: var(--primary-p-color);
    opacity: 0.85;
}

/* Shown only while a balance is still serving its 45-day term. */
.console-balance-hold {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    margin: 0 0 1rem;
    padding: 0.6rem 0.75rem;
    border-radius: 8px;
    font-size: 12px;
    line-height: 1.45;
    color: var(--console-warning);
    background-color: rgba(245, 166, 35, 0.1);
}

.console-balance-hold > i {
    margin-top: 0.15rem;
}

/* The term has elapsed: the balance is queued for its automatic payout. */
.console-balance-hold.is-due {
    color: var(--console-success);
    background-color: rgba(46, 204, 113, 0.12);
}

.console-withdraw-amount {
    margin-bottom: 1.25rem;
}

/* ── Stripe account card ─────────────────────────────────────────────────── */

.console-stripe {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

/* A tinted status panel — the connection state reads at a glance from the
   colour and icon, the same language the balance hold/due notes use. */
.console-stripe-state {
    display: flex;
    gap: 0.85rem;
    padding: 0.9rem 1rem;
    border: 1px solid var(--console-line);
    border-radius: 10px;
    background-color: rgba(255, 255, 255, 0.02);
}

.console-stripe-state-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 36px;
    height: 36px;
    border-radius: 10px;
    font-size: 15px;
    color: var(--primary-p-color);
    background-color: rgba(255, 255, 255, 0.06);
}

.console-stripe-state-text {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}

.console-stripe-state-text strong {
    font-size: 13.5px;
    font-weight: 600;
    color: var(--white-color);
}

.console-stripe-state-text p {
    margin: 0;
    font-size: 12px;
    line-height: 1.5;
    color: var(--primary-p-color);
}

.console-stripe-state.is-ready {
    border-color: rgba(46, 204, 113, 0.35);
    background-color: rgba(46, 204, 113, 0.08);
}

.console-stripe-state.is-ready .console-stripe-state-icon {
    color: var(--console-success);
    background-color: rgba(46, 204, 113, 0.16);
}

.console-stripe-state.is-pending {
    border-color: rgba(245, 166, 35, 0.35);
    background-color: rgba(245, 166, 35, 0.08);
}

.console-stripe-state.is-pending .console-stripe-state-icon {
    color: var(--console-warning);
    background-color: rgba(245, 166, 35, 0.16);
}

.console-stripe-account {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

/* The row of buttons is the last thing in the card and `.console-stripe`
   already owns the vertical rhythm, so drop the standalone top margin. */
.console-stripe .console-btn-row {
    margin-top: 0;
}

/* â”€â”€ Page editor â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.console-editor-card {
    padding: 0;
}

.console-editor-frame {
    display: block;
    width: 100%;
    height: 70vh;
    border: none;
    background-color: #fff;
}

/* â”€â”€ Modals â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.console-modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1050;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
    background-color: rgba(4, 4, 2, 0.72);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
}

.console-modal {
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: 560px;
    max-height: 90vh;
    border: 1px solid var(--console-line-strong);
    border-radius: 18px;
    background-color: var(--console-surface);
    box-shadow: 0 24px 64px rgba(0, 0, 0, 0.6);
    overflow: hidden;
}

.console-modal:focus {
    outline: none;
}

.console-modal-sm {
    max-width: 420px;
}

.console-modal-lg {
    max-width: 880px;
}

.console-modal-grip {
    display: none;
}

.console-modal-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 1.1rem 1.35rem;
    border-bottom: 1px solid var(--console-line);
}

.console-modal-head h2 {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0;
    font-size: 16px;
    font-weight: 700;
    color: var(--white-color);
}

.console-modal-head h2 i {
    font-size: 13px;
    color: var(--console-accent);
}

.console-modal-close {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border: none;
    border-radius: 8px;
    background-color: transparent;
    color: var(--primary-p-color);
    transition: background-color 0.15s, color 0.15s;
}

.console-modal-close:hover {
    background-color: rgba(255, 255, 255, 0.07);
    color: var(--white-color);
}

.console-modal-body {
    flex: 1;
    min-height: 0;
    padding: 1.35rem;
    overflow-y: auto;
}

.console-modal-foot {
    display: flex;
    justify-content: flex-end;
    gap: 0.6rem;
    padding: 1rem 1.35rem;
    border-top: 1px solid var(--console-line);
}

.console-modal-text {
    margin: 0;
    font-size: 13px;
    line-height: 1.6;
    color: var(--secondary-p-color);
}

/* â”€â”€ Toasts â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.console-toast-stack {
    position: fixed;
    right: 24px;
    bottom: 24px;
    z-index: 1100;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.5rem;
    pointer-events: none;
}

.console-toast {
    display: flex;
    align-items: flex-start;
    gap: 0.65rem;
    min-width: 280px;
    max-width: 380px;
    padding: 0.8rem 0.9rem;
    border: 1px solid var(--console-line-strong);
    border-left-width: 3px;
    border-radius: 12px;
    background-color: var(--console-surface-2);
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
    pointer-events: auto;
    opacity: 0;
    transform: translateX(16px) scale(0.96);
    transition: opacity 0.26s ease, transform 0.26s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.console-toast.is-visible {
    opacity: 1;
    transform: translateX(0) scale(1);
}

.console-toast-success {
    border-left-color: var(--console-success);
}

.console-toast-error {
    border-left-color: var(--console-danger);
}

.console-toast-info {
    border-left-color: var(--console-accent);
}

.console-toast-warning {
    border-left-color: var(--console-warning);
}

.console-toast-icon {
    margin-top: 1px;
    font-size: 14px;
}

.console-toast-success .console-toast-icon {
    color: var(--console-success);
}

.console-toast-error .console-toast-icon {
    color: var(--console-danger);
}

.console-toast-info .console-toast-icon {
    color: var(--console-accent);
}

.console-toast-warning .console-toast-icon {
    color: var(--console-warning);
}

.console-toast-body {
    flex: 1;
    min-width: 0;
}

.console-toast-message {
    margin: 0;
    font-size: 13px;
    line-height: 1.45;
    color: var(--white-color);
}

.console-toast-actions {
    display: flex;
    gap: 0.4rem;
    margin-top: 0.65rem;
}

.console-toast-close {
    padding: 2px;
    border: none;
    background-color: transparent;
    color: var(--primary-p-color);
    font-size: 12px;
    transition: color 0.15s;
}

.console-toast-close:hover {
    color: var(--white-color);
}

/* â”€â”€ Support tickets â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

/* The staff panel at /staff. It reuses this region wholesale - the same shell,
   rail, cards, lists, badges, metrics and modals - so the only rules here are
   the ones the ticket conversation needs on top of that.

   Written with ASCII rules rather than box-drawing characters on purpose: this
   stylesheet is stored double-encoded, so every existing box-drawing comment
   renders as mojibake, and adding more of it would only deepen the mess.

   No anchor-override entries are required below, because every clickable thing
   in /staff already uses a class that has one: .console-nav-item, .console-btn
   (and its -ghost/-sm variants), .console-menu-item, .console-bell-item and
   .console-breadcrumb-link. If a whole-row <Link> is ever added to the queue,
   it needs all four states adding down there or it will flash the theme's blue
   on hover. */

/* The conversation. A flat list of bordered rows reads as a table; a support
   thread has two sides and needs to look like it, so staff messages are tinted
   and inset while the requester's stay flush left. */
.console-thread {
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.console-thread-msg {
    padding: 0.95rem 1.1rem;
    border: 1px solid var(--console-line);
    border-radius: 14px;
    background-color: var(--console-surface-2);
}

.console-thread-msg.is-agent {
    margin-left: 2rem;
    border-color: rgba(109, 74, 255, 0.32);
    background-color: var(--console-accent-soft);
}

/* An internal note must never be mistakable for something the requester can
   see, so it gets its own colour and a dashed edge rather than only a badge. */
.console-thread-msg.is-internal {
    margin-left: 2rem;
    border-style: dashed;
    border-color: rgba(245, 166, 35, 0.45);
    background-color: rgba(245, 166, 35, 0.08);
}

.console-thread-head {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-bottom: 0.6rem;
}

.console-thread-avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    flex-shrink: 0;
    border-radius: 50%;
    background-color: var(--console-line-strong);
    color: var(--white-color);
    font-size: 12px;
}

/* Carrying a picture rather than a glyph. The tint has to go or it shows
   through a transparent avatar, and `overflow: hidden` is what rounds it. */
.console-thread-avatar.has-image,
.console-icon-tile.has-image {
    overflow: hidden;
    background-color: transparent;
}

.console-thread-avatar img,
.console-icon-tile img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* The `.has-image` rules above sit before this one on purpose: an agent's own
   message keeps the accent tint only while it is showing a glyph. */
.console-thread-msg.is-agent .console-thread-avatar:not(.has-image) {
    background-color: var(--console-accent);
    color: #ffffff;
}

.console-thread-msg.is-internal .console-thread-avatar {
    background-color: var(--console-warning);
    color: var(--console-surface);
}

.console-thread-author {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    color: var(--white-color);
    font-size: 13px;
    font-weight: 600;
}

.console-thread-time {
    flex-shrink: 0;
    font-size: 11px;
    color: var(--primary-p-color);
    white-space: nowrap;
}

/* A ticket message is the author's own text, so it keeps their line breaks.
   Nothing is stored or rendered as HTML, which is what makes pre-wrap the
   entire formatting story - there is no sanitiser involved. */
.console-thread-body {
    margin: 0;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    line-height: 1.65;
    font-size: 13px;
    color: var(--secondary-p-color);
}

/* The reply box's action row: the visibility toggle at one end, send at the
   other, so the control that decides who sees a message is never crowded
   against the one that sends it. */
.console-composer-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 0.9rem;
}

/* A thread that scrolls inside its card instead of stretching the page, opt-in
   because the staff panel's own thread is the page's main column and is fine
   growing. Same cap and the same reasoning as `.dashboard-ticket-thread`. */
.console-thread.is-scrollable {
    max-height: max(320px, 50vh);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding-right: 0.5rem;
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
}

.console-thread.is-scrollable::-webkit-scrollbar {
    width: 8px;
}

.console-thread.is-scrollable::-webkit-scrollbar-thumb {
    border-radius: 100px;
    background-color: rgba(255, 255, 255, 0.18);
}

/* The composer as a second body in the thread's card rather than a card of its
   own: they are one thing, and a gap read as two unrelated panels. */
.console-thread-composer {
    border-top: 1px solid var(--console-line);
    padding-top: 1.15rem;
}

.console-reply-row {
    display: flex;
    align-items: flex-start;
    flex-wrap: wrap;
    gap: 0.75rem;
}

/* Matched to the send button beside it. `.console-textarea`'s 90px min-height
   would otherwise leave a tall box next to a small round one. */
.console-reply-row .console-textarea.is-compact {
    flex: 1;
    min-width: 0;
    height: 46px;
    min-height: 46px;
    resize: vertical;
}

.console-send-btn {
    flex-shrink: 0;
    width: 46px;
    height: 46px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0 none;
    border-radius: 50%;
    background-image: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
    color: var(--btn-text-color);
    font-size: 14px;
    cursor: pointer;
    transition: filter 0.15s, transform 0.15s;
}

.console-send-btn:hover:not(:disabled) {
    filter: brightness(1.15);
    transform: translateY(-1px);
}

.console-send-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* -- Attachments (console + staff) ----------------------------------------
   Region 13's rules in this region's tokens. Same component emits both, with a
   prefix chosen by a `variant` prop, because the two panels are two stylesheet
   regions and mixing the prefixes is what the note at the top of this file
   warns about.

   The staff composer puts the paperclip in `.console-composer-actions`, which
   is space-between with two children. A third would spread the three evenly, so
   the row becomes right-aligned with the first child pushed away by an auto
   margin -- the toggle stays at one end and the paperclip lands beside send,
   which is what it belongs to. */
.console-composer-actions {
    justify-content: flex-end;
}

.console-composer-actions > :first-child {
    margin-right: auto;
}

.console-attach-input {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0 none;
}

.console-attach-btn {
    flex-shrink: 0;
    width: 46px;
    height: 46px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--console-line);
    border-radius: 50%;
    background-color: var(--console-surface-2);
    color: var(--secondary-p-color);
    font-size: 14px;
    cursor: pointer;
    transition: color 0.15s, border-color 0.15s, transform 0.15s;
}

.console-attach-btn:hover:not(:disabled) {
    color: var(--white-color);
    border-color: var(--console-line-strong);
    transform: translateY(-1px);
}

.console-attach-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.console-attach-list {
    order: 2;
    flex-basis: 100%;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.console-attach-chip {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    max-width: 100%;
    padding: 0.35rem 0.55rem;
    border: 1px solid var(--console-line);
    border-radius: 8px;
    background-color: var(--console-surface-2);
    font-size: 12px;
    color: var(--secondary-p-color);
}

.console-attach-chip > i {
    flex-shrink: 0;
    color: var(--primary-color);
}

.console-attach-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--white-color);
}

.console-attach-size {
    flex-shrink: 0;
    font-size: 11px;
    color: var(--secondary-p-color);
}

.console-attach-remove {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    padding: 0;
    border: 0 none;
    border-radius: 50%;
    background: transparent;
    color: var(--secondary-p-color);
    font-size: 11px;
    cursor: pointer;
    transition: color 0.15s, background-color 0.15s;
}

.console-attach-remove:hover:not(:disabled) {
    background-color: var(--console-line-strong);
    color: var(--white-color);
}

.console-attach-error {
    flex-basis: 100%;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 12px;
    color: var(--console-danger);
}

/* -- Files on a message (console + staff) --------------------------------- */

.console-thread-files {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0.65rem 0 0;
    padding: 0;
    list-style: none;
}

.console-thread-file a {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    max-width: 300px;
    padding: 0.4rem 0.65rem;
    border: 1px solid var(--console-line);
    border-radius: 8px;
    background-color: var(--console-surface-2);
    transition: border-color 0.15s, background-color 0.15s;
}

/* All four states, at (0,3,1), to clear the theme's a:link:not(.btn) rule. */
.console-shell .console-thread-file a:link,
.console-shell .console-thread-file a:visited,
.console-shell .console-thread-file a:hover,
.console-shell .console-thread-file a:active {
    font-size: 12px;
    font-weight: 400;
    line-height: 1.4;
    color: var(--secondary-p-color);
    text-decoration: none;
}

.console-shell .console-thread-file a:hover {
    border-color: var(--console-line-strong);
    color: var(--white-color);
}

.console-thread-file.is-image a {
    max-width: none;
    padding: 0;
    background-color: transparent;
    overflow: hidden;
}

.console-thread-file.is-image img {
    display: block;
    width: auto;
    height: auto;
    min-width: 52px;
    min-height: 52px;
    max-width: 200px;
    max-height: 150px;
    border: 1px solid var(--console-line-strong);
    border-radius: 7px;
    object-fit: cover;
}

.console-thread-file-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.console-thread-file-size {
    flex-shrink: 0;
    font-size: 11px;
    color: var(--secondary-p-color);
}

/* Radios in a console dialog. The theme styles checkboxes but not these, and a
   bare radio on a dark card is nearly invisible. */
.console-radio-group {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.console-radio {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.6rem 0.85rem;
    border: 1px solid var(--console-line);
    border-radius: 10px;
    background-color: var(--console-surface-2);
    font-size: 13px;
    color: var(--secondary-p-color);
    cursor: pointer;
    transition: border-color 0.15s, background-color 0.15s;
}

.console-radio:hover {
    border-color: var(--console-line-strong);
}

.console-radio input {
    width: auto;
    height: auto;
    margin: 0;
    accent-color: var(--console-accent);
}

.console-radio:has(input:checked) {
    border-color: var(--console-accent);
    background-color: var(--console-accent-soft);
    color: var(--white-color);
}

/* A destructive action in the console. `.console-btn-ghost.is-danger` already
   exists for icon buttons; this is the filled counterpart for a confirm. */
.console-btn-danger {
    border: 1px solid rgba(228, 87, 76, 0.5);
    background-color: rgba(228, 87, 76, 0.14);
    color: #f08a80;
}

.console-btn-danger:hover:not(:disabled) {
    border-color: rgba(228, 87, 76, 0.8);
    background-color: rgba(228, 87, 76, 0.24);
    color: #ffb4ac;
}

.console-queue-pager {
    justify-content: space-between;
    align-items: center;
}

/* `.console-split` stretches both columns to the same height, which is right
   when the main column is a conversation and wrong when it is a short list or
   an empty state - there the card grows to match the sidebar and leaves a lake
   of dead space. */
.console-split.is-top {
    align-items: start;
}

/* Queue rows carry several badges plus an action; without a group the
   space-between on .console-list-foot spreads them across the whole row. */
.console-list-foot .console-badge-row {
    flex: 1;
    min-width: 0;
}

/* A neutral metric tile. The existing variants are semantic (green by default,
   is-down red, is-star amber); a count that is neither good nor bad needs one
   that does not editorialise. */
.console-metric-icon.is-accent {
    background-color: var(--console-accent-soft);
    color: var(--console-accent);
}

.console-metric-icon.is-neutral {
    background-color: var(--console-line-strong);
    color: var(--secondary-p-color);
}

.console-metric-note {
    margin: 0;
    font-size: 12px;
    color: var(--primary-p-color);
}

/* A message somebody typed, shown as they typed it. Without pre-wrap the
   paragraph breaks in a Contact Us enquiry collapse into one run-on block,
   which is both harder to read and a silent change to what they wrote. */
.console-contact-body {
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

/* ---- Rail section headings ------------------------------------------------
   The staff panel groups its rail entries under named categories. The heading
   is the separator, so a section carrying one drops the divider that
   .console-nav-section + .console-nav-section would otherwise draw above it -
   a rule and a label one on top of the other reads as two separators. */
.console-nav-heading {
    margin: 0.35rem 0 0.3rem;
    padding: 0 0.7rem;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--primary-p-color);
    opacity: 0.75;
}

.console-nav-section:has(.console-nav-heading) {
    border-top: none;
}

/* Collapsed to icons there is no room for the words, but the groups still have
   to be told apart - so the heading is replaced by the divider it suppressed
   above, rather than simply vanishing and running the icons together. */
.console-shell.is-collapsed .console-nav-heading {
    display: none;
}

.console-shell.is-collapsed .console-nav-section:has(.console-nav-heading) {
    border-top: 1px solid var(--console-line);
}

/* â”€â”€ Anchor overrides â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

/* The theme restyles every link through
     a:link:not(.btn), a:visited:not(.btn), a:hover:not(.btn), a:active:not(.btn)
   setting colour, font-size, font-weight and line-height at specificity
   (0,2,1) â€” which outranks any single-class rule above. The console is built
   almost entirely from anchors (nav rows, menu entries, card links, buttons),
   so each of them restates its own type and colour here at (0,3,1), scoped
   under .console-shell to clear that bar.

   Every component needs all four states listed: the theme sets :hover and
   :active too, so declaring only :link/:visited would leave the link flashing
   the theme's blue on hover. */

.console-shell a.console-nav-item:link,
.console-shell a.console-nav-item:visited,
.console-shell a.console-nav-item:hover,
.console-shell a.console-nav-item:active {
    font-size: 13.5px;
    font-weight: 500;
    line-height: 1.4;
    color: var(--primary-p-color);
}

.console-shell a.console-nav-item.is-nested:link,
.console-shell a.console-nav-item.is-nested:visited,
.console-shell a.console-nav-item.is-nested:hover,
.console-shell a.console-nav-item.is-nested:active {
    font-size: 13px;
}

.console-shell a.console-nav-item:hover,
.console-shell a.console-nav-item:active,
.console-shell a.console-nav-item.active:link,
.console-shell a.console-nav-item.active:visited,
.console-shell a.console-nav-item.active:hover,
.console-shell a.console-nav-item.active:active {
    color: var(--white-color);
}

.console-shell a.console-nav-item.active:link,
.console-shell a.console-nav-item.active:visited,
.console-shell a.console-nav-item.active:hover,
.console-shell a.console-nav-item.active:active {
    font-weight: 600;
}

/* This is the fallback every a.console-btn* variant inherits (equal
   specificity to the more specific a.console-btn-light/-ghost rules below,
   which win only because they come later in the file) — so it's what
   a.console-btn-primary actually renders with, since that variant has no
   override of its own. Its gradient background is fixed in both themes and
   needs fixed white text, not var(--white-color) (which the -light and
   -ghost variants override anyway, so this only ever reaches -primary). */
.console-shell a.console-btn:link,
.console-shell a.console-btn:visited,
.console-shell a.console-btn:hover,
.console-shell a.console-btn:active {
    font-size: 13px;
    font-weight: 600;
    line-height: 1.2;
    color: var(--btn-text-color);
}

.console-shell a.console-btn-sm:link,
.console-shell a.console-btn-sm:visited,
.console-shell a.console-btn-sm:hover,
.console-shell a.console-btn-sm:active {
    font-size: 12px;
}

.console-shell a.console-btn-light:link,
.console-shell a.console-btn-light:visited,
.console-shell a.console-btn-light:hover,
.console-shell a.console-btn-light:active {
    color: var(--black-color);
}

.console-shell a.console-btn-ghost:link,
.console-shell a.console-btn-ghost:visited {
    color: var(--secondary-p-color);
}

.console-shell a.console-btn-ghost:hover,
.console-shell a.console-btn-ghost:active {
    color: var(--white-color);
}

.console-shell a.console-menu-item:link,
.console-shell a.console-menu-item:visited {
    font-size: 13px;
    font-weight: 400;
    line-height: 1.4;
    color: var(--secondary-p-color);
}

.console-shell a.console-menu-item:hover,
.console-shell a.console-menu-item:active {
    font-size: 13px;
    font-weight: 400;
    line-height: 1.4;
    color: var(--white-color);
}

.console-shell a.console-card-link:link,
.console-shell a.console-card-link:visited {
    font-size: 12px;
    font-weight: 600;
    line-height: 1.4;
    color: var(--primary-p-color);
}

.console-shell a.console-card-link:hover,
.console-shell a.console-card-link:active {
    font-size: 12px;
    font-weight: 600;
    line-height: 1.4;
    color: var(--white-color);
}

.console-shell a.console-breadcrumb-link:link,
.console-shell a.console-breadcrumb-link:visited {
    font-size: 13px;
    font-weight: 400;
    line-height: 1.4;
    color: var(--primary-p-color);
}

.console-shell a.console-breadcrumb-link:hover,
.console-shell a.console-breadcrumb-link:active {
    font-size: 13px;
    font-weight: 400;
    line-height: 1.4;
    color: var(--white-color);
}

.console-shell .console-link-text a:link,
.console-shell .console-link-text a:visited,
.console-shell .console-link-text a:hover,
.console-shell .console-link-text a:active {
    font-size: 11px;
    font-weight: 400;
    line-height: 1.4;
    color: var(--console-accent);
}

.console-shell .console-error-note a:link,
.console-shell .console-error-note a:visited,
.console-shell .console-error-note a:hover,
.console-shell .console-error-note a:active {
    font-size: inherit;
    font-weight: 600;
    color: var(--console-accent);
    text-decoration: underline;
}

/* â”€â”€ Responsive â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

.console-only-mobile {
    display: none;
}

@media (max-width: 1399px) {
    .console-split {
        grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
    }
}

@media (max-width: 1199px) {
    .console-split,
    .console-grid-2,
    .console-form-split,
    .console-form-row {
        grid-template-columns: minmax(0, 1fr);
    }

    .console-form-aside {
        padding-left: 0;
        border-left: none;
    }

    .console-hero h1 {
        font-size: 2rem;
    }
}

@media (max-width: 991px) {
    /* The rail becomes a drawer: same element, slid off-canvas until opened. */
    .console-sidebar {
        transform: translateX(-100%);
        box-shadow: none;
    }

    .console-shell.is-drawer-open .console-sidebar {
        transform: translateX(0);
        box-shadow: 0 0 60px rgba(0, 0, 0, 0.6);
    }

    /* Width is the drawer's, never the collapsed rail's, whatever the desktop
       preference happened to be. */
    .console-shell.is-collapsed .console-sidebar {
        width: var(--console-rail);
    }

    .console-shell.is-collapsed .console-brand-text,
    .console-shell.is-collapsed .console-nav-label,
    .console-shell.is-collapsed .console-nav-value,
    .console-shell.is-collapsed .console-nav-caret,
    .console-shell.is-collapsed .console-nav-heading,
    .console-shell.is-collapsed .console-workspace-text,
    .console-shell.is-collapsed .console-workspace-caret,
    .console-shell.is-collapsed .console-user-text,
    .console-shell.is-collapsed .console-user-caret,
    .console-shell.is-collapsed .console-help-card {
        display: revert;
    }

    /* The drawer shows the full rail, so the headings are back and the divider
       they stand in for goes away again. */
    .console-shell.is-collapsed .console-nav-section:has(.console-nav-heading) {
        border-top: none;
    }

    .console-shell.is-collapsed .console-sidebar-brand,
    .console-shell.is-collapsed .console-workspace-toggle,
    .console-shell.is-collapsed .console-nav-item,
    .console-shell.is-collapsed .console-back-link,
    .console-shell.is-collapsed .console-user-toggle {
        justify-content: flex-start;
        padding-left: 0.7rem;
        padding-right: 0.7rem;
    }

    .console-main,
    .console-shell.is-collapsed .console-main {
        margin-left: 0;
    }

    .console-shell.is-drawer-open .console-drawer-backdrop {
        display: block;
    }

    /* ---- The drawer opens UNDER the top bar, not over it -------------------
       The bar carries the breadcrumb, the notification bell and the very
       button that just opened the drawer. Sliding a panel over it and dimming
       what is left hides where you are and takes away the control you would
       use to get back, so at drawer widths the bar stays put, at full
       brightness, and the panel and its backdrop both start below it.

       Stacking: backdrop 44, sidebar 46, so the bar has to clear both.
       Neither .console-shell nor .console-main creates a stacking context
       (no transform, no opacity, no z-index of their own), so the sticky bar
       and the fixed sidebar are ranked against each other directly and this
       is enough. */
    .console-topbar {
        padding: 0 1rem;
        z-index: 47;
    }

    /* The panel deliberately gets NO top padding of its own.

       It still starts at the top of the viewport, so its background runs
       continuously behind the bar and no strip of dimmed page can appear
       between the two — that property is the one that matters, and it holds
       whatever the bar's real height turns out to be.

       Reserving a bar's worth of space on top of that is the version that
       reads as correct and measured wrong in practice: it pushed the brand row
       about one bar too far down, which is the empty band this replaced. The
       only vertical spacing left is the brand row's own padding, below.

       The backdrop still starts below the bar, so the bar stays undimmed. */

    /* The brand row is the first thing in the panel and the drawer's only
       identity. Its fixed one-topbar height goes: on desktop that height is
       what lines the rail's header up with the bar beside it, and in the
       drawer there is nothing beside it to line up with, so it takes the space
       it needs and no more. */
    .console-sidebar-brand {
        height: auto;
        padding-top: 0.9rem;
        padding-bottom: 0.9rem;
    }

    .console-shell.is-drawer-open .console-drawer-backdrop {
        top: var(--console-topbar);
    }

    .console-content {
        padding: 1.25rem 1rem 3rem;
    }

    .console-hero {
        padding: 1.5rem 1.35rem;
    }

    .console-hero h1 {
        font-size: 1.7rem;
    }

    .console-hero-actions .console-btn {
        flex: 1;
    }

    .console-only-desktop {
        display: none;
    }

    .console-only-mobile {
        display: block;
    }

    /* Dialogs become bottom sheets: full width, anchored to the bottom edge,
       with the grip that only makes sense in that form. */
    .console-modal-backdrop {
        padding: 0;
        align-items: flex-end;
    }

    .console-modal,
    .console-modal-sm,
    .console-modal-lg {
        max-width: 100%;
        max-height: 92dvh;
        border-radius: 20px 20px 0 0;
        border-bottom: none;
    }

    .console-modal-grip {
        display: block;
        width: 36px;
        height: 4px;
        margin: 10px auto 2px;
        border-radius: 999px;
        background-color: var(--console-line-strong);
    }

    .console-modal-foot {
        padding-bottom: max(1rem, env(safe-area-inset-bottom));
    }

    .console-modal-foot .console-btn {
        flex: 1;
    }

    .console-toast-stack {
        right: 12px;
        left: 12px;
        bottom: 16px;
        align-items: stretch;
    }

    .console-toast {
        min-width: 0;
        max-width: none;
    }

    .console-heading {
        flex-direction: column;
        align-items: stretch;
    }
}

@media (max-width: 575px) {
    .console-kpi-row,
    .console-metric-grid,
    .console-tile-grid,
    .console-platform-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    .console-hero-actions {
        width: 100%;
    }

    /* Phone widths are the only ones with genuinely no room for the trail: the
       page you are on is kept, the rail is one tap away for the rest. This is
       deliberately NOT tied to the 992px rail breakpoint â€” below it the rail
       becomes a drawer, so the bar has more room, not less. */
    .console-breadcrumb li:not(:last-child) {
        display: none;
    }
}

/* #endregion Platform Console */

/*----------------------------------------------
11. Miscellaneous
----------------------------------------------*/

/* #region Miscellaneous */

.scroll-to-top {
    height: 45px;
    width: 45px;
    line-height: 45px;
    margin: 0 auto;
    text-align: center;
    background-color: var(--card-bg-color);
    box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
    border-radius: 14px;
    transition: 0.3s ease-out;
}

.scroll-to-top a {
    display: block;
    height: 100%;
    width: 100%;
    line-height: 45px !important;
}

.scroll-to-top a svg {
    font-size: 20px;
}

.scroll-to-top:hover {
    background-color: var(--primary-color);
}

.scroll-to-top:hover,
.scroll-to-top:focus {
    box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);
}

/* #endregion Miscellaneous */

/*----------------------------------------------
12. Blog
----------------------------------------------*/

/* #region Blog */

.single-widget {
    margin-bottom: 35px;
}

.single-widget h4 {
    font-weight: 700;
    border-bottom: 2px solid var(--card-bg-color);
}

.sidebar .single-widget:last-child {
    margin-bottom: 0;
}

.blog .single-widget ul li {
    margin: 1.2rem 0;
}

.blog .single-widget .tags-widget a {
    border: 1px solid var(--primary-bg-color-3);
}

.blog .single-widget .post-widget h6 {
    font-size: var(--h5-size);
}

.blog .pagination>li>a {
    display: inline-block;
    height: 45px;
    width: 45px;
    line-height: 45px;
    text-align: center;
    color: var(--primary-p-color);
    border: 1px solid var(--primary-bg-color-3);
}

.blog .pagination>li.active>a {
    color: var(--btn-text-color);
    border: none;
}

/* #endregion Blog */

/*----------------------------------------------
13. All Media Queries
----------------------------------------------*/

/* #region All Media Queries */

@media (max-width: 1199px) {
    /* #region Section */
    body .container {
        padding: 0 10px;
        max-width: 100%;
    }
    /* #endregion Section */
    /* #region Header */
    header .navbar-expand .navbar-nav.toggle {
        display: flex;
    }
    header .navbar-expand .navbar-nav.contacts,
    header .navbar-expand .navbar-nav.items,
    header .navbar-expand .navbar-nav.icons .social {
        display: none;
    }
    /* #endregion Header */
    /* #region Feature */
    .card-footer {
        margin: 0;
    }
    /* #endregion Feature */
}

@media (min-width: 992px) {
    /* #region Feature */
    .inner .card.project-card {
        padding: 2.5rem 1.7rem;
    }
    /* #region Feature */
    /* #region Blog */
    .sidebar .item:first-child {
        margin-top: 0;
    }
    /* #endregion Blog */
    /* #region Modal */
    .search-title {
        font-size: 45px;
    }
    /* #endregion Modal */
}

@media (max-width: 991px) {
    /* #region General */
    body h1 {
        font-size: 4rem;
    }
    body h2 {
        font-size: 2.5rem;
    }
    /* #endregion General */
    /* #region Section */
    body aside {
        margin-top: 60px;
    }
    /* #endregion Section */
    /* #region Helper Class */
    .intro {
        margin-bottom: 25px;
    }
    /* #endregion Helper Class */
    /* #region Feature */
    .res-margin {
        margin-bottom: 30px;
    }
    .locale-switcher .locale-toggle {
        padding-left: 0.5rem;
        padding-right: 0.5rem;
    }
    /* #endregion Feature */
}

@media (max-width: 767px) {
    /* #region General */
    /* `body { overflow-x: hidden }` used to sit here, clipping anything that
       stuck out on phones instead of letting it wrap. Removed with the same
       reasoning as the html rule above. */
    body h1 {
        font-size: 3rem;
    }
    /* #endregion General */
    /* #region Section */
    body section {
        padding: 90px 0;
    }
    /* #endregion Section */
    /* #region Helper Class */
    .gameon-preloader .preloader-animation .loading-bar {
        width: 200px;
    }
    .gameon-preloader .preloader-animation .loader {
        font-size: var(--h2-size);
    }
    /* #endregion Helper Class

  /* #region Header */
    header .navbar-expand .navbar-brand {
        margin: 0;
    }
    header .navbar-expand .navbar-nav.action .btn {
        padding: 5px 10px;
        font-size: 0;
    }
    header .navbar-expand .navbar-nav.action .btn i {
        font-size: initial;
        margin: 0;
    }
    /* #endregion Header */
    /* #region Features */
    .icon.bigger {
        width: 5rem;
        height: 5rem;
        margin: 0;
        font-size: 4.5rem;
        line-height: 5rem;
        font-weight: bold;
    }
    .staking-area .input-area .input-text {
        width: 100%;
    }
    /* #endregion Features */
    /* #region Footer */
    body footer .contacts {
        left: 0;
        margin-bottom: 30px;
    }
    body footer .contacts:before {
        left: 0;
        width: 100%;
    }
    body footer .contacts:after {
        left: 0;
        width: 100%;
    }
    body .footer-area .items .item {
        margin-bottom: 30px;
    }
    /* #endregion Footer */
}

@media (max-width: 576px) {
    /* #region Helper Class */
    .gameon-preloader .preloader-animation .loading-bar {
        width: 160px;
    }
    .gameon-preloader .preloader-animation .loader {
        font-size: var(--h3-size);
    }
    .avatar-max-lg {
        height: 5rem;
        width: 5rem;
    }
    .btn.content-btn {
        margin-bottom: 5px;
    }
    .button-group a {
        margin-top: 0;
        margin-right: 5px;
    }
    .button-group a:last-child {
        margin-top: 0.5rem;
    }
    .button-group a .btn {
        padding: 12px 20px;
    }
    .cta-area .card h2 {
        font-size: 2rem;
    }
    .card.project-card .single-item.prev-project {
        font-size: 12px;
    }
    .card.project-card .project-footer .social-share li {
        margin: 0 0.3rem;
    }
    /* #endregion Helper Class */
    /* #region Feature */
    .content-list .content-icon span {
        height: 80px;
        width: 80px;
        border-radius: 1.8rem;
    }
    .content-list .content-icon span svg,
    .content-list .content-icon span i {
        font-size: 2rem;
    }
    .countdown .countdown-container .countdown-value {
        font-size: 18px;
    }
    .item-details-area .countdown-value {
        font-size: 18px !important;
    }
    .item-details-area .single-item-content.card .image-over img {
        height: 350px;
    }
    .item-details-area .item-info img {
        border-radius: 8px;
    }
    .staking-area .card {
        padding: 2.5rem 2rem;
    }
    .staking-area .card .balance {
        font-size: 2rem;
    }
    .staking-area .card .staking-tabs .tab-link {
        padding: 12px 18px;
        font-size: 14px;
    }
    .staking-area .single-accordion-item .staking-btn {
        padding: 2.5rem 1.5rem !important;
    }
    .staking-area .single-accordion-item .staking-btn .staking-info .single-item {
        align-items: start;
        margin: 0.6rem;
    }
    .staking-area .single-accordion-item .card-body {
        padding: 2.5rem 1.5rem !important;
    }
    .staking-area .single-accordion-item .card-body .single-staking-item:not(:first-child) {
        margin-top: 25px;
    }
    .leaderboard-area table tr th,
    .leaderboard-area table tr td {
        display: table-cell;
        padding: 1rem;
    }
    .cta-area img {
        max-width: 120px;
    }
    .faq-area .single-accordion-item:not(:last-child) {
        margin-bottom: 1rem;
    }
    .apply-form {
        padding: 2rem;
    }
    /* #endregion Feature */
    /* #region Footer */
    .footer-area .footer-items ul li {
        display: block;
        margin: 1rem;
    }
    /* #endregion Footer */
    /* #region Modal */
    body .modal-body {
        align-items: start;
    }
    /* #endregion Modal */
    /* #region Blog */
    .post-details blockquote {
        font-size: 100%;
    }
    .blog .col-12.col-sm-6 {
        padding: 0;
    }
    .blog .single-comments {
        flex-direction: column;
    }
    /* #endregion Blog */
}

/* #endregion All Media Queries */

/*----------------------------------------------
14. Next.js migration compat shims
----------------------------------------------*/

/* The theme's pagination rule targets the old Swiper's root class
   (.swiper-container-horizontal). The npm "swiper" package used in the
   Next.js rewrite renders a different root (.swiper / .swiper-horizontal),
   so that rule never matches and Swiper's own default (position: absolute)
   makes the pagination dots overlap the slide content instead of sitting
   below it. Restore the intended layout for our slider wrappers. */
.swiper-container .swiper-pagination {
    position: relative;
    margin-top: 50px;
}

/* Route-transition preloader: the theme's own .loader-bg rule always carries
   an 800ms transition, so re-showing the loader before a page change would
   otherwise animate it "closing" back to full width first, then "opening"
   again to reveal the new page. We only want the opening animation, so this
   briefly disables the transition while the loader snaps back into view. */
.gameon-preloader.no-anim .loader-animation .single-loader .loader-bg,
.gameon-preloader.no-anim .preloader-animation {
    transition: none !important;
}

/* Project card status dot: replaces the blockchain logo in .blockchain-icon
   with a simple green/red availability indicator. */
.status-dot {
    display: inline-block;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    box-shadow: 0 0 0 3px rgba(22, 24, 45, 0.5);
}

.status-dot-green {
    background-color: #2ecc71;
}

.status-dot-red {
    background-color: #e74c3c;
}

.card.project-card .blockchain-icon.status-icon {
    top: 1.25rem;
}

/* Hashtag pills: same rounded pill look as the theme's original stat pills
   (.card.project-card .single-item), just smaller and set closer together
   for a denser tag list. */
.card.project-card .tag-pill {
    display: inline-block;
    margin: 2px 3px 2px 0;
    padding: 0.3rem 0.6rem;
    background: var(--primary-bg-color);
    border-radius: 100px;
    font-size: 11px;
    font-weight: 600;
    color: var(--white-color);
}

/* Status pill: identical shape, but outline-only (no fill), colored by status. */
.card.project-card .status-pill {
    display: inline-block;
    padding: 0.3rem 0.8rem;
    border-radius: 100px;
    font-size: 12px;
    font-weight: 600;
    background: transparent;
    border: 1px solid currentColor;
}

.status-pill-green {
    color: #2ecc71;
}

.status-pill-red {
    color: #e74c3c;
}

.status-pill-verified {
    color: #3498db;
}

.status-pill-platform {
    color: #9b59b6;
}

.status-pill-partner {
    color: #f5a623;
}

.status-pill-gold {
    color: #eab308;
}

/* Only variant that's a real link — same pill shape, but underline-free with
   a hover state so it still reads as clickable. A non-navigable link (see
   isNavigableLink) renders this on a <button> instead of an <a> — reset to
   match, since a bare <button> carries its own font/cursor/background. */
a.status-pill-link,
button.status-pill-link {
    color: var(--primary-p-color);
    text-decoration: none;
    font: inherit;
    cursor: pointer;
    transition: 0.2s;
}

a.status-pill-link:hover,
button.status-pill-link:hover {
    color: var(--primary-color);
}

/* The hero card's tags (platform/verified/partner/link) sit directly on a
   dark, sometimes-textured background — an outline-only pill with 12px text
   read too faintly there. A background tint in each pill's own colour keeps
   the outline look but gives the text something to stand out against. */
.item-details-area .status-pill-platform {
    background-color: rgba(155, 89, 182, 0.16);
}

.item-details-area .status-pill-verified {
    background-color: rgba(52, 152, 219, 0.16);
}

.item-details-area .status-pill-partner {
    background-color: rgba(245, 166, 35, 0.16);
}

.item-details-area .status-pill-link {
    background-color: rgba(255, 255, 255, 0.08);
}

.card.project-card .project-description {
    font-size: 14px;
    line-height: 1.6;
    color: var(--primary-p-color);
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    overflow: hidden;
}

/* Server discovery cards (Platform Discovery): every platform (Minecraft,
   Discord, Website) must render at the same size, and the row must never
   wrap on small screens â€” the View button always stays on the same line as
   the server info, even if it ends up overlapping a decorative logo. */
/* Discovery list cards: three stacked rows â€” logo + name, then all the badges
   on a row of their own, then a full-width call to action.
   The badges and the button get the card's entire width instead of the column
   beside the logo, which on a 320px screen is only about 140px wide. That
   column is why the old layout failed: the name shared a single non-wrapping
   line with the partner badge, and since the badge could not shrink the name
   took the whole squeeze and rendered as two characters plus an ellipsis. */
.card.project-card.prev-project-card {
    min-height: 130px;
}

.card.project-card.prev-project-card .project-content {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.card.project-card.prev-project-card .item-header,
.card.project-card.prev-project-card .item-header .content {
    min-width: 0;
}

/* Two lines before truncating, so a name only ever gets cut when it is
   genuinely long rather than because a badge sat next to it. */
/* break-word, not anywhere: a name should only ever be split when the word
   itself is wider than the line, never just because the row got tight. */
.card.project-card.prev-project-card .item-header .content .server-name-text {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
    overflow-wrap: break-word;
}

.card.project-card.prev-project-card .server-card-cta {
    display: block;
    width: 100%;
    text-align: center;
}

/* Partner status is a mark beside the name rather than a badge in the tag row:
   it is a rare distinction and spelling it out in full took more room from that
   row than it was worth, especially on a phone where the row is tightest.
   The name itself keeps the whole line â€” the mark is a fixed ~14px and does not
   shrink, so there is no repeat of the old problem where a full-width pill and
   the name fought over the same line and the name lost. */
.server-name-heading {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.partner-mark {
    position: relative;
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
    color: #f5a623;
    font-size: 0.875rem;
    line-height: 1;
    cursor: help;
}

/* The label the mark stands in for, revealed on hover: a pill-shaped bubble
   with a caret, picking up the crown's gold so the two read as one object.
   ::after is the bubble and ::before the caret â€” two pseudo-elements is exactly
   what the mark has, which is why the caret is a rotated square rather than a
   third element. The text comes from the data attribute so it stays translated
   in the component instead of being hard-coded here. */
.partner-mark::after,
.partner-mark::before {
    position: absolute;
    left: 50%;
    z-index: 6;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.18s ease, transform 0.18s ease;
}

.partner-mark::after {
    content: attr(data-tooltip);
    bottom: calc(100% + 0.55rem);
    transform: translate(-50%, 0.25rem);
    padding: 0.35rem 0.75rem;
    border-radius: 100px;
    border: 1px solid rgba(247, 183, 51, 0.45);
    background-image: linear-gradient(180deg, #1b2030 0%, #12151f 100%);
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.55), 0 0 0 4px rgba(247, 183, 51, 0.07);
    color: #f7b733;
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: none;
    white-space: nowrap;
}

.partner-mark::before {
    content: "";
    bottom: calc(100% + 0.3rem);
    width: 0.45rem;
    height: 0.45rem;
    transform: translate(-50%, 0.25rem) rotate(45deg);
    border-right: 1px solid rgba(247, 183, 51, 0.45);
    border-bottom: 1px solid rgba(247, 183, 51, 0.45);
    background-color: #12151f;
}

.partner-mark:hover::after,
.partner-mark:hover::before {
    opacity: 1;
    visibility: visible;
}

.partner-mark:hover::after {
    transform: translate(-50%, 0);
}

.partner-mark:hover::before {
    transform: translate(-50%, 0) rotate(45deg);
}

/* The crown answers the hover too, so the whole thing feels like one control
   rather than a label that happens to appear. */
.partner-mark i {
    transition: transform 0.18s ease, filter 0.18s ease;
}

.partner-mark:hover i {
    transform: scale(1.15);
    filter: drop-shadow(0 0 6px rgba(247, 183, 51, 0.55));
}

@media (prefers-reduced-motion: reduce) {

    .partner-mark::after,
    .partner-mark::before,
    .partner-mark i {
        transition: none;
    }

    .partner-mark:hover i {
        transform: none;
    }
}

/* The stacked layout is a phone layout. On a desktop the same card is over a
   thousand pixels wide, where a full-width button reads as a stretched banner
   and the rows waste the horizontal space â€” so from tablet up the three rows
   become one: logo and name on the left, badges beside them, action on the
   right at its natural size. */
@media (min-width: 768px) {
    .card.project-card.prev-project-card .project-content {
        flex-direction: row;
        align-items: center;
        gap: 1.5rem;
    }

    .card.project-card.prev-project-card .item-header {
        flex: 0 1 auto;
    }

    /* Floor the name column so the row cannot squeeze it down to a couple of
       characters â€” the badges wrap to a second line instead, which costs
       nothing since they already wrap. */
    .card.project-card.prev-project-card .item-header .content {
        min-width: 8rem;
    }

    .card.project-card.prev-project-card .tags {
        flex: 1 1 auto;
        min-width: 0;
    }

    .card.project-card.prev-project-card .server-card-cta {
        width: auto;
        min-width: 7.5rem;
        flex-shrink: 0;
        margin-left: auto;
    }
}

/* Minecraft server cards: on hover/focus, a dirt-and-grass block "grows" up
   from the bottom of the card (built from plain CSS gradients, no game
   assets), with a little blocky pop so it feels like a block being placed. */
.card.project-card.card-minecraft {
    position: relative;
    isolation: isolate;
}

.card.project-card.card-minecraft > * {
    position: relative;
    z-index: 1;
}

.card.project-card.card-minecraft::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    opacity: 0;
    border-radius: inherit;
    background:
        repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.15) 0 4px, transparent 4px 8px),
        repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.15) 0 4px, transparent 4px 8px),
        linear-gradient(180deg, #6fbf3a 0 16%, #7a4a2a 16% 100%);
    background-size: 8px 8px, 8px 8px, 100% 100%;
    image-rendering: pixelated;
    transform: scaleY(0);
    transform-origin: bottom;
    transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.2s ease;
}

/* Paler grass/dirt and lighter pixelation stripes, so the block reads as
   part of the light theme's palette instead of a dark patch dropped onto a
   white card. */
[data-theme="light"] .card.project-card.card-minecraft::before {
    background:
        repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.08) 0 4px, transparent 4px 8px),
        repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.08) 0 4px, transparent 4px 8px),
        linear-gradient(180deg, #9fe080 0 16%, #c9976a 16% 100%);
}

.card.project-card.card-minecraft:hover::before,
.card.project-card.card-minecraft:focus-within::before,
.card.project-card.card-minecraft.effect-active::before {
    opacity: 1;
    transform: scaleY(1);
}

.card.project-card.card-minecraft:hover,
.card.project-card.card-minecraft:focus-within {
    animation: minecraft-pop 0.3s ease;
}

.card.project-card.card-minecraft:hover h4,
.card.project-card.card-minecraft:focus-within h4,
.card.project-card.card-minecraft.effect-active h4 {
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.7);
}

@keyframes minecraft-pop {
    0% {
        transform: scale(1);
    }
    40% {
        transform: scale(0.96) rotate(-0.5deg);
    }
    70% {
        transform: scale(1.03) rotate(0.5deg);
    }
    100% {
        transform: scale(1);
    }
}

/* Discord server cards: a blurple glow washes in and the card gives a
   little notification-style bounce, with a ping dot in the corner like an
   incoming Discord notification. */
.card.project-card.card-discord {
    position: relative;
    isolation: isolate;
    overflow: hidden;
}

.card.project-card.card-discord > * {
    position: relative;
    z-index: 1;
}

/* Blue wave sweeping in, echoing Discord's own brand illustration style. */
.card.project-card.card-discord::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    opacity: 0;
    border-radius: inherit;
    background-color: rgba(88, 101, 242, 0.1);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 200' preserveAspectRatio='none'%3E%3Cpath d='M0,120 C60,60 100,180 160,110 C220,40 260,160 320,100 C350,70 380,90 400,80 L400,200 L0,200 Z' fill='%234f6df5' fill-opacity='0.35'/%3E%3C/svg%3E");
    background-size: 100% 100%;
    background-repeat: no-repeat;
    background-position: 0 15%;
    transition: opacity 0.3s ease, background-position 0.6s ease;
}

.card.project-card.card-discord:hover::before,
.card.project-card.card-discord:focus-within::before,
.card.project-card.card-discord.effect-active::before {
    opacity: 1;
    background-position: 0 0%;
}

/* Big Discord logo watermark, absolutely positioned above the wave (but
   behind the real card content) so the wave never washes it out. */
.card.project-card.card-discord .discord-logo-icon {
    position: absolute;
    top: 50%;
    right: -10px;
    z-index: 1;
    font-size: 11rem;
    color: #5865f2;
    opacity: 0;
    transform: translateY(-50%) scale(0.7);
    -webkit-mask-image: linear-gradient(to left, black 35%, transparent 85%);
    mask-image: linear-gradient(to left, black 35%, transparent 85%);
    transition: opacity 0.35s ease, transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
    pointer-events: none;
}

.card.project-card.card-discord:hover .discord-logo-icon,
.card.project-card.card-discord:focus-within .discord-logo-icon,
.card.project-card.card-discord.effect-active .discord-logo-icon {
    opacity: 0.85;
    transform: translateY(-50%) scale(1);
}

.card.project-card.card-discord:hover,
.card.project-card.card-discord:focus-within {
    animation: discord-bounce 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}

@keyframes discord-bounce {
    0% {
        transform: translateY(0);
    }
    30% {
        transform: translateY(-6px);
    }
    50% {
        transform: translateY(0);
    }
    70% {
        transform: translateY(-3px);
    }
    100% {
        transform: translateY(0);
    }
}

/* Website server cards: a light shimmer sweeps across the card, and a large
   globe icon peeks in from the right edge, masked so only its right side
   shows and it fades into the card on its left rather than looking pasted on. */
.card.project-card.card-website {
    position: relative;
    isolation: isolate;
    overflow: hidden;
}

.card.project-card.card-website > * {
    position: relative;
    z-index: 1;
}

.card.project-card.card-website .website-globe-icon {
    position: absolute;
    top: 50%;
    right: -10px;
    z-index: 0;
    font-size: 9rem;
    color: #3498db;
    opacity: 0;
    transform: translateY(-50%) scale(0.7);
    -webkit-mask-image: linear-gradient(to left, black 35%, transparent 85%);
    mask-image: linear-gradient(to left, black 35%, transparent 85%);
    transition: opacity 0.35s ease, transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
    pointer-events: none;
}

.card.project-card.card-website:hover .website-globe-icon,
.card.project-card.card-website:focus-within .website-globe-icon,
.card.project-card.card-website.effect-active .website-globe-icon {
    opacity: 0.55;
    transform: translateY(-50%) scale(1);
}

.card.project-card.card-website::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    border-radius: inherit;
    background: linear-gradient(120deg, transparent 30%, rgba(52, 152, 219, 0.18) 50%, transparent 70%);
    background-size: 250% 100%;
    background-position: 150% 0;
    opacity: 0;
    transition: opacity 0.2s ease;
}

.card.project-card.card-website:hover::after,
.card.project-card.card-website:focus-within::after {
    opacity: 1;
    animation: website-shimmer 0.9s ease;
}

.card.project-card.card-website.effect-active::after {
    opacity: 1;
    background-position: 50% 0;
}

@keyframes website-shimmer {
    from {
        background-position: 150% 0;
    }
    to {
        background-position: -50% 0;
    }
}

/* The theme only styles <a>/<span> page-numbers; the client-side pagination
   on /discovery uses real <button> elements (no page reload), so extend the
   same look to them. */
button.page-numbers {
    width: 50px;
    height: 50px;
    line-height: 50px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 17px;
    font-weight: 400;
    border-radius: 10px;
    background-color: var(--card-bg-color);
    color: var(--white-color) !important;
    border: none;
    transition: 0.3s ease-in-out;
}

button.page-numbers:hover {
    background-color: var(--primary-color);
    color: var(--btn-text-color) !important;
}

/* Discovery grid-view cards: fixed height so every card is the same size
   regardless of name length or tag count, with the name truncated to a
   single line (ellipsis) instead of growing the card. */
.card.project-card.grid-card {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 260px;
}

.card.project-card.grid-card .media {
    max-width: 100%;
}

.card.project-card.grid-card .media-body {
    min-width: 0;
    flex: 1 1 auto;
}

.card.project-card.grid-card .grid-card-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.card.project-card.grid-card .card-body {
    flex-grow: 1;
}

.card.project-card.grid-card .project-footer {
    margin-top: auto;
}

/* /discovery toolbar (search + platform filter + view toggle): all three
   sit on a single row on desktop (search left, filter and view toggle
   spread across the rest), and wrap/center-stack on tablet and mobile
   instead of overflowing or leaving pieces stranded off to one side. */
.discovery-toolbar {
    gap: 1rem 2rem;
    margin-top: 2.5rem;
    margin-bottom: 2rem;
    margin-left: 1rem;
    margin-right: 1rem;
}

.discovery-search {
    width: 100%;
    max-width: 420px;
}

@media (max-width: 991px) {
    .discovery-search {
        max-width: 100%;
    }
}

/* /discovery's search box (the field plus its "Read" button, once a pasted
   link shows one — see .showcase-finder / .showcase-search-btn), sized like
   `.discovery-search` above (/earn's) once it sits in the toolbar row
   alongside the filter buttons, rather than stretching to fill it. */
.showcase-search {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex: 1 1 260px;
    max-width: 420px;
}

.showcase-search .showcase-finder {
    flex: 1 1 auto;
    min-width: 0;
}

@media (max-width: 991px) {
    .showcase-search {
        max-width: 100%;
    }
}

@media (max-width: 767px) {
    .filter-menu .input-item .btn {
        padding: 0.75rem 1.25rem;
        font-size: 0.9rem;
    }

    .filter-menu .input-item .count {
        right: 0.5rem;
        font-size: 0.75rem;
    }
}

/* /earn task cards: gradient icon tile standing in for the server logo,
   sized by the same avatar-max-lg class the logos use. */
.task-icon-tile {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    border-radius: 1rem;
    background-image: linear-gradient(135deg, var(--primary-color) 10%, var(--secondary-color));
    color: var(--btn-text-color);
    font-size: 2rem;
}

.task-card-description {
    font-size: 14px;
    line-height: 1.6;
    color: var(--primary-p-color);
    max-width: 480px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Let the flex chain shrink below the nowrap text's natural width, otherwise
   a long single-line description widens the card instead of truncating. */
.task-card-info,
.task-card-info .content {
    min-width: 0;
}

/* Gold reward effect on task cards: on hover a gold beam sweeps across the
   card while a "+N <coin>" flash slides in at the top-left. */
.card.project-card.task-card {
    position: relative;
    overflow: hidden;
}

.card.project-card.task-card > * {
    position: relative;
    z-index: 1;
}

.card.project-card.task-card::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    border-radius: inherit;
    pointer-events: none;
    background: linear-gradient(115deg, transparent 30%, rgba(245, 197, 66, 0.22) 50%, transparent 70%);
    background-size: 250% 100%;
    background-position: 150% 0;
    opacity: 0;
    transition: opacity 0.2s ease;
}

.card.project-card.task-card:hover::after {
    opacity: 1;
    animation: task-gold-beam 0.9s ease;
}

@keyframes task-gold-beam {
    from {
        background-position: 150% 0;
    }
    to {
        background-position: -50% 0;
    }
}

.task-reward-flash {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 1.1rem;
    font-weight: 700;
    color: #f5c542;
    text-shadow: 0 0 12px rgba(245, 197, 66, 0.55);
    opacity: 0;
    transform: translateX(-14px);
    transition: opacity 0.35s ease, transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
    pointer-events: none;
}

/* Grid (square) cards: small overlay pinned to the top-left corner. Must
   out-rank the `.task-card > *` positioning reset above, which would
   otherwise force this back to position: relative. */
.card.project-card.task-card > .task-reward-flash {
    position: absolute;
    top: 1rem;
    left: 1.25rem;
    z-index: 2;
}

.card.project-card.task-card:hover .task-reward-flash {
    opacity: 1;
    transform: translateX(0);
}

/* Gold "Earn AdBits" banner between a server's card and its rewards list. */
.earn-banner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 1rem;
    padding: 1.25rem 1.5rem;
    border-radius: 1rem;
    background-color: var(--card-bg-color);
    border: 1px solid rgba(245, 197, 66, 0.25);
    transition: border-color 0.3s ease, box-shadow 0.3s ease;
}

.earn-banner:hover {
    border-color: rgba(245, 197, 66, 0.5);
    box-shadow: 0 8px 24px rgba(245, 197, 66, 0.12);
}

.earn-banner-info {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.earn-banner-info > i {
    font-size: 1.75rem;
    color: #f5c542;
    text-shadow: 0 0 12px rgba(245, 197, 66, 0.4);
}

.earn-banner-info p {
    font-size: 14px;
    color: var(--primary-p-color);
}

.task-logo-img {
    border-radius: 1rem;
    object-fit: cover;
}

/* ─── Rewards list, grouped by category ───────────────────────────────────── */

.reward-groups {
    display: flex;
    flex-direction: column;
    gap: 3rem;
}

/* Sits inside its own .row/.col-12 (see the server page) so it lines up exactly
   with the "Available Rewards" heading and the cards below. */
.reward-group-head {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    padding-bottom: 0.85rem;
    margin-bottom: 1.5rem;
    border-bottom: 1px solid var(--card-border-color);
}

.reward-group-img {
    width: 40px;
    height: 40px;
    border-radius: 10px;
    object-fit: cover;
    flex-shrink: 0;
}

.reward-group-img.is-fallback {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--card-border-color);
    background-color: var(--card-bg-color);
    color: var(--primary-color);
    font-size: 0.95rem;
}

.reward-group-title {
    margin: 0;
    font-family: var(--primary-font);
    font-size: 1.1rem;
    font-weight: 700;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: var(--primary-p-color);
}

/* ─── Reward card ─────────────────────────────────────────────────────────── */

.reward-card {
    position: relative;
    display: flex;
    flex-direction: column;
    height: 100%;
    padding: 1.75rem 1.5rem 1.5rem;
    border-radius: 1.25rem;
    text-align: center;
    transition: transform 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease;
}

.reward-card:hover {
    border-color: rgba(0, 71, 255, 0.4);
    box-shadow: 0 14px 34px rgba(0, 0, 0, 0.28);
}

.reward-card-body {
    display: flex;
    flex-direction: column;
    align-items: center;
    /* Takes up the slack so the footer sits on the bottom edge whatever the
       description length. */
    flex: 1 1 auto;
}

.reward-card .reward-logo {
    width: 72px;
    height: 72px;
    border-radius: 14px;
    object-fit: cover;
}

.reward-card-title {
    margin: 1rem 0 0;
    font-family: var(--primary-font);
    font-size: 1.15rem;
    font-weight: 800;
    letter-spacing: 0.5px;
    color: var(--white-color);
}

.reward-card-desc {
    margin: 0.6rem 0 0;
    color: var(--primary-p-color);
    font-size: 0.9rem;
    line-height: 1.5;
    /* Keep the cards even: the whole description lives in the popup. */
    display: -webkit-box;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.reward-card-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-top: 1.5rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--card-border-color);
}

.reward-cost {
    display: inline-flex;
    align-items: center;
    padding: 0.35rem 0.9rem;
    border-radius: 100px;
    background-color: var(--primary-color);
    color: #fff;
    font-weight: 700;
    font-size: 0.85rem;
    white-space: nowrap;
}

.reward-buy-btn {
    flex-shrink: 0;
}

/* Details affordance, pinned to the card's top-right corner. */
.reward-details-btn {
    position: absolute;
    top: 0.9rem;
    right: 0.9rem;
    z-index: 2;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 1px solid var(--secondary-l-color);
    border-radius: 50%;
    background-color: transparent;
    color: var(--primary-p-color);
    font-size: 0.9rem;
    transition: 0.25s;
}

.reward-details-btn:hover {
    border-color: var(--primary-color);
    color: var(--primary-color);
    transform: translateY(-2px);
}

/* ─── Reward details popup ───────────────────────────────────────────────── */

.reward-modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 99999;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
    background-color: rgba(9, 10, 26, 0.72);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    animation: reward-modal-in 0.2s ease-out;
}

.reward-modal {
    position: relative;
    width: 100%;
    max-width: 460px;
    padding: 2rem;
    border: 1px solid var(--secondary-l-color);
    border-radius: 1.25rem;
    background-color: var(--card-bg-color);
    animation: reward-modal-pop 0.35s cubic-bezier(0.2, 0.9, 0.3, 1.4);
}

.reward-modal-close {
    position: absolute;
    top: 1rem;
    right: 1rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background-color: transparent;
    color: var(--primary-p-color);
    font-size: 1rem;
    transition: 0.25s;
}

.reward-modal-close:hover {
    color: var(--white-color);
}

.reward-modal-head {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-bottom: 1.25rem;
    padding-right: 2rem;
}

.reward-modal-head .reward-logo {
    width: 60px;
    height: 60px;
    border-radius: 12px;
    object-fit: cover;
    flex-shrink: 0;
}

.reward-modal-title {
    margin: 0;
    font-family: var(--primary-font);
    font-size: 1.2rem;
    font-weight: 800;
    color: var(--white-color);
}

.reward-modal-category {
    display: inline-block;
    margin-top: 0.35rem;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: var(--primary-p-color);
}

.reward-modal-desc {
    margin: 0 0 1.25rem;
    color: var(--secondary-p-color);
    font-size: 0.95rem;
    line-height: 1.6;
    white-space: pre-line;
}

.reward-modal-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-top: 1.5rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--card-border-color);
}

/* ─── Purchase confirmation ───────────────────────────────────────────────── */

.reward-buy-qty {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 1.25rem;
}

.reward-buy-qty-label {
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    color: var(--secondary-p-color);
}

.reward-buy-qty-control {
    display: flex;
    align-items: center;
    gap: 0.85rem;
}

/* Same circular-button treatment as .reward-details-btn / .reward-modal-close. */
.reward-buy-qty-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    padding: 0;
    border: 1px solid var(--secondary-l-color);
    border-radius: 50%;
    background-color: transparent;
    color: var(--primary-p-color);
    font-size: 0.8rem;
    transition: 0.25s;
}

.reward-buy-qty-btn:hover:not(:disabled) {
    border-color: var(--primary-color);
    color: var(--primary-color);
    transform: translateY(-1px);
}

.reward-buy-qty-btn:disabled {
    opacity: 0.35;
    cursor: not-allowed;
}

.reward-buy-qty-value {
    min-width: 1.5ch;
    text-align: center;
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--white-color);
}

.reward-buy-balance {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 1.25rem;
    padding: 0.7rem 1rem;
    border: 1px solid var(--card-border-color);
    border-radius: 0.75rem;
    background-color: rgba(255, 255, 255, 0.03);
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    color: var(--secondary-p-color);
}

.reward-buy-balance strong {
    font-size: 0.95rem;
    letter-spacing: normal;
    text-transform: none;
    color: var(--white-color);
}

.reward-modal .form-message.error {
    margin: -0.5rem 0 1.25rem;
    font-size: 0.85rem;
}

/* `.request-buy-note` is `margin: 0` by default and relies on an
   adjacent-sibling rule elsewhere for the gap before what follows it — a rule
   written for `.details-form-actions`, not this modal's `.reward-modal-foot`.
   Without its own margin here the note sat flush against the footer above. */
.reward-buy-modal .request-buy-note {
    margin: 0 0 1rem;
}

/* The "set/change Minecraft username" link: a plain button made to read as
   text, small enough that it never competes with Confirm/Cancel below it. */
.reward-modal-mc-change {
    display: block;
    width: 100%;
    margin: 0 0 1rem;
    padding: 0;
    border: 0;
    background: none;
    color: var(--primary-p-color);
    font-size: 12px;
    text-align: left;
    cursor: pointer;
}

.reward-modal-mc-change:hover {
    color: var(--primary-color);
}

.reward-buy-success {
    padding-top: 0.25rem;
    text-align: center;
}

.reward-buy-success-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    margin-bottom: 1rem;
    border-radius: 50%;
    background-color: rgba(46, 204, 113, 0.12);
    color: #2ecc71;
    font-size: 1.75rem;
}

.reward-buy-success .reward-modal-title {
    margin-bottom: 0.5rem;
}

.reward-buy-success .reward-modal-desc {
    margin-bottom: 1.5rem;
}

.reward-buy-success .btn {
    width: 100%;
}

@keyframes reward-modal-in {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes reward-modal-pop {
    from { opacity: 0; transform: translateY(16px) scale(0.9); }
    to { opacity: 1; transform: translateY(0) scale(1); }
}

@media (prefers-reduced-motion: reduce) {
    .reward-modal-backdrop,
    .reward-modal {
        animation: none;
    }
}

/* ─── Goal bar, pinned to the bottom of /earn ─────────────────────────────── */

/* Reserves the collapsed bar's height in normal flow, so the last row of tasks
   is not left under it. The expanded list is allowed to overlay — that is a
   transient interaction, not something the page has to make room for. */
.reward-goal-bar-spacer {
    height: 92px;
}

.reward-goal-bar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    /* Under .cookie-consent-banner (99998), which also docks here and has to
       win while it is up. */
    z-index: 90;
    border-top: 1px solid var(--secondary-l-color);
    background-color: var(--card-bg-color);
    box-shadow: 0 -12px 32px rgba(0, 0, 0, 0.35);
}

.reward-goal-bar.is-unlocked {
    border-top-color: rgba(46, 204, 113, 0.45);
}

.reward-goal-bar-row {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    max-width: 1170px;
    margin: 0 auto;
    padding: 1rem 15px;
}

.reward-goal-bar-row .reward-logo {
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    border-radius: 10px;
}

.reward-goal-bar-title {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    flex: 0 1 190px;
    min-width: 0;
}

.reward-goal-bar-title strong {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--white-color);
    font-size: 0.95rem;
}

.reward-goal-bar-title span {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.75rem;
    color: var(--primary-p-color);
}

/* The meter takes the slack, so the bar grows with the viewport instead of the
   name doing it. */
.reward-goal-bar-meter {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex: 1;
    min-width: 0;
}

.reward-goal-bar-numbers {
    flex: 0 0 auto;
    font-size: 0.85rem;
    color: var(--primary-p-color);
    font-variant-numeric: tabular-nums;
}

.reward-goal-bar-numbers > strong {
    color: var(--white-color);
    font-size: 1rem;
}

.reward-goal-bar-percent {
    margin-left: 0.6rem;
    font-weight: 700;
    color: var(--white-color);
}

.reward-goal-bar-preview-text {
    display: inline-flex;
    align-items: center;
    font-weight: 700;
    color: #2ecc71;
}

.reward-goal-bar-done {
    display: inline-flex;
    align-items: center;
    font-weight: 700;
    color: #2ecc71;
}

.reward-goal-bar-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    flex: 0 0 auto;
    padding: 0.45rem 0.9rem;
    border: 1px solid var(--secondary-l-color);
    border-radius: 100px;
    background-color: transparent;
    color: var(--primary-p-color);
    font-size: 0.8rem;
    font-weight: 600;
    transition: 0.3s;
}

.reward-goal-bar-toggle:hover {
    border-color: var(--primary-color);
    color: var(--primary-color);
}

.reward-goal-clear {
    flex: 0 0 auto;
    padding: 0.35rem 0.55rem;
    border: none;
    border-radius: 8px;
    background-color: transparent;
    color: var(--primary-p-color);
    transition: 0.3s;
}

.reward-goal-clear:hover {
    background-color: var(--secondary-l-color);
    color: var(--white-color);
}

/* The track is `position: relative` because the preview segment is placed
   inside it by offset — see .reward-goal-preview. */
.reward-goal-track {
    position: relative;
    flex: 1;
    min-width: 0;
    height: 8px;
    border-radius: 4px;
    overflow: hidden;
    background-color: var(--secondary-l-color);
}

.reward-goal-fill {
    display: block;
    height: 100%;
    border-radius: inherit;
    background-image: linear-gradient(135deg, var(--primary-color) 10%, var(--secondary-color));
    transition: width 0.6s ease;
}

.is-unlocked .reward-goal-fill {
    background-image: linear-gradient(135deg, #2ecc71, #27ae60);
}

/* What the hovered task would add. Starts where the real fill ends and is
   hatched rather than solid, so it never reads as progress already earned. */
.reward-goal-preview {
    position: absolute;
    top: 0;
    bottom: 0;
    background-color: rgba(46, 204, 113, 0.55);
    background-image: repeating-linear-gradient(
        135deg,
        rgba(255, 255, 255, 0.35) 0 4px,
        transparent 4px 8px
    );
    transition: width 0.25s ease, left 0.25s ease;
}

.reward-goal-bar-tasks {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    max-width: 1170px;
    margin: 0 auto;
    padding: 1.25rem 15px 0;
    max-height: 45vh;
    overflow-y: auto;
}

.reward-goal-task {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.75rem 1rem;
    border: 1px solid var(--secondary-l-color);
    border-radius: 12px;
    background-color: var(--primary-bg-color);
}

.reward-goal-task .task-logo {
    flex: 0 0 auto;
}

.reward-goal-task-text {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
    flex: 1;
}

.reward-goal-task-text strong {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--white-color);
    font-size: 0.9rem;
}

.reward-goal-task-text small {
    font-size: 0.75rem;
    color: var(--primary-p-color);
}

.reward-goal-task-bits {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    flex: 0 0 auto;
    padding: 0.25rem 0.7rem;
    border-radius: 100px;
    background-color: rgba(46, 204, 113, 0.15);
    color: #2ecc71;
    font-size: 0.8rem;
    font-weight: 700;
}

@media (max-width: 991px) {
    /* Narrow: the reward's name and server go, the meter stays. What the bar is
       for at a glance is the progress; which reward it belongs to is one tap
       away in the suggested list, and the logo still identifies it. */
    .reward-goal-bar-title {
        display: none;
    }

    /* The toggle keeps only its chevron — the expanded list says what it is. */
    .reward-goal-bar-toggle span {
        display: none;
    }

    .reward-goal-bar-row {
        gap: 0.85rem;
    }
}

@media (max-width: 575px) {
    /* Numbers drop under the track rather than competing with it for the row. */
    .reward-goal-bar-meter {
        flex-wrap: wrap;
        gap: 0.4rem;
    }

    .reward-goal-track {
        flex: 1 0 100%;
    }

    .reward-goal-bar-spacer {
        height: 104px;
    }

    /* The bits pill drops under the name rather than squeezing it; the start
       button stays on the first row so the row still has an obvious action. */
    .reward-goal-task {
        flex-wrap: wrap;
        gap: 0.6rem 0.75rem;
    }

    .reward-goal-task-bits {
        order: 3;
    }
}

/*----------------------------------------------
15. Hero Server Dashboard
----------------------------------------------*/

/* #region Hero Server Dashboard */

/* A browser-window frame under the hero copy, holding a static mockup of the
   server performance dashboard. Every rule is scoped under .server-dashboard â€”
   the window lives inside .hero-section, whose `.hero-section p` and the theme's
   bare h3 rule would otherwise reach into it.

   Colour tokens below are measured, not eyeballed. Marks need >= 3:1 and text
   >= 4.5:1 against the card surface (#262e40):
     --dash-series #3d7bff  3.54:1  (the brand #0047FF is only 2.16:1 here â€” too
                                     dark for a mark on this surface, so this is
                                     a lighter step of the same hue)
     --dash-good   #2ecc71  6.46:1  (the status green already used by .status-dot-green)
     --dash-ink    #e8ecf5 11.47:1
     --dash-ink-2  #a3b0cc  6.23:1
     --dash-muted  #8f9ab4  4.81:1  (axis ticks are small text, so 4.5:1 applies)
     --dash-grid   #333c52  1.23:1  (deliberately recessive â€” a hairline, not text) */
.server-dashboard {
    --dash-plane: #1e2434;
    --dash-surface: #262e40;
    --dash-chrome: #2e3749;
    --dash-sidebar: #232a3c;
    --dash-line: rgba(255, 255, 255, 0.08);
    --dash-grid: #333c52;
    --dash-ink: #e8ecf5;
    --dash-ink-2: #a3b0cc;
    --dash-muted: #8f9ab4;
    --dash-series: #3d7bff;
    --dash-good: #2ecc71;
    max-width: 1080px;
    margin: 4.5rem auto 0;
    border: 1px solid var(--dash-line);
    border-radius: 12px;
    background-color: var(--dash-plane);
    box-shadow: 0 30px 70px rgba(0, 0, 0, 0.5);
    overflow: hidden;
}

/* Light theme. The mockup is a self-contained surface with its own token set,
   so re-pointing those tokens flips the whole window; only the handful of
   values the tokens don't reach (window chrome, EARN scrim, drop shadow) are
   restated below.

   Measured against the card surface (#FFFFFF), same bars as the dark set —
   marks >= 3:1, text >= 4.5:1:
     --dash-series #0047FF  6.28:1  (the brand blue itself: it was too dark for
                                     the dark surface, but on white it is the
                                     correct and strongest choice)
     --dash-good   #177F42  5.06:1  (#2ecc71 is only 2.10:1 on white — nowhere
                                     near enough for the 0.75rem delta text, so
                                     this is a darker step of the same 145° hue)
     --dash-ink    #14152B 17.92:1  (the light theme's --white-color)
     --dash-ink-2  #4A4F6B  8.01:1
     --dash-muted  #5A5E82  6.25:1  (5.53:1 on the #EEF1F7 sidebar, where the
                                     nav labels sit — still above 4.5:1)
     --dash-grid   #DDE2EC  1.30:1  (recessive hairline, matching the dark
                                     set's 1.23:1) */
[data-theme="light"] .server-dashboard {
    --dash-plane: #F4F6FA;
    --dash-surface: #FFFFFF;
    --dash-chrome: #E8EBF2;
    --dash-sidebar: #EEF1F7;
    --dash-line: rgba(20, 21, 43, 0.10);
    --dash-grid: #DDE2EC;
    --dash-ink: #14152B;
    --dash-ink-2: #4A4F6B;
    --dash-muted: #5A5E82;
    --dash-series: #0047FF;
    --dash-good: #177F42;
    box-shadow: 0 24px 60px rgba(20, 21, 43, 0.14);
}

/* Traffic lights at rest: same 1.6:1 against their own chrome as the dark
   set's #4d5568, so they stay a hint rather than a feature until :hover gives
   them their real (theme-independent) colours. */
[data-theme="light"] .server-dashboard .dash-lights span {
    background-color: #B6BCCC;
}

[data-theme="light"] .server-dashboard .dash-address {
    background-color: #FFFFFF;
    color: #4A4F6B;
}

/* The scrim tints towards the window's own plane, so it reads as the
   dashboard fading back rather than a grey sheet dropped over it. */
[data-theme="light"] .server-dashboard .dash-earn {
    background-color: rgba(244, 246, 250, 0.55);
}

@supports not ((backdrop-filter: blur(6px)) or (-webkit-backdrop-filter: blur(6px))) {
    [data-theme="light"] .server-dashboard .dash-earn {
        background-color: rgba(244, 246, 250, 0.88);
    }
}

/* The button keeps its gradient in both themes, but a white focus ring would
   disappear against this scrim. */
[data-theme="light"] .server-dashboard .dash-earn-btn:focus-visible {
    outline-color: #14152B;
}

/* Tighten the hero â†’ projects seam. The hero now ends with the dashboard window
   instead of the button group, and the theme's stock `section { padding: 130px 0 }`
   applies on both sides of that seam â€” 260px of dead space between the window and
   the projects heading. Halved here rather than in the theme's own section rule so
   only this seam changes. `.project-area` is also used by the server detail page,
   but there it carries `pt-0`, whose !important keeps it at zero. */
.hero-section {
    padding-bottom: 60px;
}

.project-area {
    padding-top: 60px;
}

@media (max-width: 767px) {
    .hero-section {
        padding-bottom: 45px;
    }

    .project-area {
        padding-top: 45px;
    }
}

/* Window chrome */

.server-dashboard .dash-titlebar {
    position: relative;
    display: flex;
    align-items: center;
    padding: 0.7rem 1rem;
    background-color: var(--dash-chrome);
    border-bottom: 1px solid var(--dash-line);
}

.server-dashboard .dash-lights {
    display: flex;
    gap: 6px;
}

.server-dashboard .dash-lights span {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background-color: #4d5568;
    transition: 0.3s;
}

/* Hovering the window wakes it up: the traffic lights take their real colours and
   the address bar reveals its open-link affordance. Scoped to the whole
   .server-dashboard rather than the title bar so the effect fires wherever the
   pointer enters the window. */
.server-dashboard:hover .dash-lights span:nth-child(1) {
    background-color: #ff5f57;
}

.server-dashboard:hover .dash-lights span:nth-child(2) {
    background-color: #febc2e;
}

.server-dashboard:hover .dash-lights span:nth-child(3) {
    background-color: #28c840;
}

/* Absolutely centred so the address bar sits in the middle of the window
   regardless of how wide the traffic lights are. */
.server-dashboard .dash-address {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 55%;
    padding: 0.3rem 0.75rem;
    border-radius: 7px;
    background-color: #39415a;
    color: #cdd4e2;
    font-size: 0.8rem;
    line-height: 1.5;
}

.server-dashboard .dash-address-text {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    text-align: center;
}

/* The icon keeps its slot in the layout while invisible, so revealing it on hover
   fades it in instead of nudging the address text sideways. */
.server-dashboard .dash-address i {
    flex: 0 0 auto;
    font-size: 0.75rem;
    opacity: 0;
    transition: 0.3s;
}

.server-dashboard:hover .dash-address-text {
    text-decoration: underline;
}

.server-dashboard:hover .dash-address i {
    opacity: 1;
}

.server-dashboard .dash-window {
    position: relative;
    display: flex;
    align-items: stretch;
}

/* Sidebar */

.server-dashboard .dash-sidebar {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 2rem;
    flex: 0 0 190px;
    padding: 1.5rem 0;
    background-color: var(--dash-sidebar);
    border-right: 1px solid var(--dash-line);
}

.server-dashboard .dash-nav {
    margin: 0;
}

.server-dashboard .dash-nav li {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.6rem 1.5rem;
    font-size: 0.85rem;
    color: var(--dash-muted);
}

.server-dashboard .dash-nav li.active {
    color: var(--dash-ink);
    background-color: rgba(61, 123, 255, 0.12);
    box-shadow: inset 2px 0 0 var(--dash-series);
}

.server-dashboard .dash-nav i {
    width: 16px;
    font-size: 0.85rem;
    text-align: center;
}

.server-dashboard .dash-demo-note {
    padding: 0 1.5rem;
    font-size: 0.4rem;
    letter-spacing: 1px;
    font-style: italic;
    color: var(--dash-muted);
}

.server-dashboard .dash-main {
    flex: 1;
    min-width: 0;
    padding: 1.5rem;
}

/* KPI row â€” stat tiles, not a one-bar chart */

.server-dashboard .dash-kpis {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1rem;
    margin: 0 0 1rem;
}

.server-dashboard .dash-kpi {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    padding: 1rem 1.15rem;
    border: 1px solid var(--dash-line);
    border-radius: 10px;
    background-color: var(--dash-surface);
}

.server-dashboard .dash-kpi-label {
    font-size: 0.75rem;
    color: var(--dash-muted);
}

/* Proportional figures on purpose: tabular-nums makes a standalone value like
   1.284 look loose at this size. */
.server-dashboard .dash-kpi-value {
    font-size: 1.5rem;
    font-weight: 600;
    line-height: 1.2;
    color: var(--dash-ink);
}

/* The delta ships with an arrow icon and a named period, so direction never
   rests on colour alone. */
.server-dashboard .dash-kpi-delta {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--dash-good);
}

.server-dashboard .dash-kpi-period {
    font-weight: 400;
    color: var(--dash-muted);
}

/* Chart cards */

.server-dashboard .dash-card {
    padding: 1.15rem 1.25rem;
    border: 1px solid var(--dash-line);
    border-radius: 10px;
    background-color: var(--dash-surface);
}

.server-dashboard .dash-card + .dash-card {
    margin-top: 1rem;
}

.server-dashboard .dash-card-head {
    position: static;
    z-index: auto;
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 1.5rem;
}

.server-dashboard .dash-card-head h3 {
    margin: 0;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--dash-ink);
}

.server-dashboard .dash-card-head span {
    font-size: 0.75rem;
    color: var(--dash-muted);
}

/* Plot area shared by the area chart and the column chart. The left margin is
   the gutter the y-axis tick labels hang in. */

.server-dashboard .dash-plot {
    position: relative;
    height: 150px;
    margin-left: 42px;
}

.server-dashboard .dash-gridline {
    position: absolute;
    left: 0;
    right: 0;
    height: 1px;
    background-color: var(--dash-grid);
}

.server-dashboard .dash-tick {
    position: absolute;
    right: calc(100% + 8px);
    top: 50%;
    transform: translateY(-50%);
    font-size: 0.7rem;
    font-variant-numeric: tabular-nums;
    color: var(--dash-muted);
}

.server-dashboard .dash-xaxis {
    display: flex;
    justify-content: space-between;
    margin: 0.6rem 0 0 42px;
    font-size: 0.7rem;
    font-variant-numeric: tabular-nums;
    color: var(--dash-muted);
}

/* Area chart. The SVG stretches non-uniformly to the plot box, so the stroke is
   drawn with vector-effect: non-scaling-stroke to stay a true 2px. */

.server-dashboard .dash-area {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
}

.server-dashboard .dash-area-fill {
    fill: var(--dash-series);
    opacity: 0.1;
}

.server-dashboard .dash-area-line {
    fill: none;
    stroke: var(--dash-series);
    stroke-width: 2;
    stroke-linejoin: round;
    stroke-linecap: round;
}

/* End marker: 10px, with a 2px surface ring so it stays legible over the line. */
.server-dashboard .dash-endpoint {
    position: absolute;
    right: 0;
    width: 10px;
    height: 10px;
    transform: translate(50%, 50%);
    border-radius: 50%;
    background-color: var(--dash-series);
    box-shadow: 0 0 0 2px var(--dash-surface);
}

.server-dashboard .dash-endpoint-value {
    position: absolute;
    right: calc(100% + 10px);
    top: 50%;
    transform: translateY(-50%);
    font-size: 0.7rem;
    font-weight: 600;
    white-space: nowrap;
    color: var(--dash-ink);
}

/* Reveal animation. `--dash-anim` is set inline by the component from the same
   constant that drives the JS count-up, so the chart can never finish drawing
   out of step with the numbers. `.is-revealing` is only on the element while the
   reveal runs; dropping it leaves every rule below inert and the chart in its
   natural, fully-drawn state. Nothing here runs under prefers-reduced-motion â€”
   the hook simply never sets the class. */

.server-dashboard.is-revealing .dash-area {
    animation: dash-area-grow var(--dash-anim) ease-out both;
}

@keyframes dash-area-grow {
    from {
        clip-path: inset(0 100% 0 0);
    }
    to {
        clip-path: inset(0 0 0 0);
    }
}

/* The end marker lands once the line reaches it. Both keyframes carry the base
   rule's translate, which positions the dot on its data point â€” dropping it here
   would fling the dot a few pixels while it animates. */
.server-dashboard.is-revealing .dash-endpoint {
    animation: dash-endpoint-in 0.4s ease-out var(--dash-anim) both;
}

@keyframes dash-endpoint-in {
    from {
        opacity: 0;
        transform: translate(50%, 50%) scale(0.3);
    }
    to {
        opacity: 1;
        transform: translate(50%, 50%) scale(1);
    }
}

/* EARN call to action: a glass overlay across the dashboard body, revealed once
   the count-up lands and dismissed by claiming it. It covers .dash-window rather
   than the whole component so the title bar stays sharp and keeps its hover
   behaviour.
   `backdrop-filter` is what blurs the dashboard behind it â€” the element's own
   background only tints. Three separate elements on purpose: the overlay fades,
   the inner span does the pop, and the button keeps its transform free for
   :hover. Collapsing any two would make one of them fight the others, since an
   animation's value outranks a normal declaration. */

.server-dashboard .dash-earn {
    position: absolute;
    inset: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: rgba(30, 36, 52, 0.55);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    /* No fill-mode: once it has played the element falls back to these base
       styles, which is what lets the transition below drive the exit. */
    animation: dash-earn-fade 0.45s ease-out;
    transition: opacity 0.35s ease, backdrop-filter 0.35s ease, visibility 0.35s;
}

/* Without backdrop-filter the blur silently does nothing, so lean harder on the
   tint to keep the button readable against the chart behind it. */
@supports not ((backdrop-filter: blur(6px)) or (-webkit-backdrop-filter: blur(6px))) {
    .server-dashboard .dash-earn {
        background-color: rgba(30, 36, 52, 0.88);
    }
}

.server-dashboard .dash-earn.is-claimed {
    opacity: 0;
    visibility: hidden;
    backdrop-filter: blur(0);
    -webkit-backdrop-filter: blur(0);
    pointer-events: none;
}

@keyframes dash-earn-fade {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

.server-dashboard .dash-earn-pop {
    display: inline-flex;
    animation: dash-earn-pop 0.5s cubic-bezier(0.2, 0.9, 0.3, 1.4);
}

@keyframes dash-earn-pop {
    from {
        transform: translateY(14px) scale(0.85);
    }
    to {
        transform: translateY(0) scale(1);
    }
}

.server-dashboard .dash-earn-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.7rem 2.2rem;
    border: none;
    border-radius: 100px;
    background-image: linear-gradient(135deg, #3d7bff, #6f5bff);
    color: #ffffff;
    font-size: 0.8rem;
    font-weight: 700;
    letter-spacing: 2px;
    text-transform: uppercase;
    cursor: pointer;
    transition: 0.3s;
}

.server-dashboard .dash-earn-btn:hover {
    transform: translateY(-2px);
    box-shadow: 0 12px 26px rgba(61, 123, 255, 0.45);
}

.server-dashboard .dash-earn-btn:focus-visible {
    outline: 2px solid #ffffff;
    outline-offset: 3px;
}

/* Responsive */

@media (max-width: 767px) {
    .server-dashboard .dash-sidebar {
        display: none;
    }

    .server-dashboard .dash-main {
        padding: 1.25rem;
    }
}

@media (max-width: 575px) {
    .server-dashboard {
        margin-top: 3rem;
    }

    .server-dashboard .dash-kpis {
        grid-template-columns: 1fr;
    }
}

@media (prefers-reduced-motion: reduce) {
    .server-dashboard .dash-earn,
    .server-dashboard .dash-earn-pop {
        animation: none;
    }

    .server-dashboard .dash-earn-btn {
        transition: none;
    }

    .server-dashboard .dash-earn-btn:hover {
        transform: none;
    }
}

/* #endregion Hero Server Dashboard */

/* #region Hero Video */

/* The how-it-works video under the hero copy, framed as a browser window with
   the same chrome as .server-dashboard so the two read as one family. */
.home-video {
    --video-chrome: #2e3749;
    --video-line: rgba(255, 255, 255, 0.08);
    max-width: 1080px;
    margin: 4.5rem auto 0;
    border: 1px solid var(--video-line);
    border-radius: 12px;
    background-color: #1e2434;
    box-shadow: 0 30px 70px rgba(0, 0, 0, 0.5);
    overflow: hidden;
}

.home-video-bar {
    position: relative;
    display: flex;
    align-items: center;
    min-height: 2.6rem;
    padding: 0.7rem 1rem;
    background-color: var(--video-chrome);
    border-bottom: 1px solid var(--video-line);
}

.home-video-lights {
    display: flex;
    gap: 6px;
}

.home-video-lights span {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background-color: #4d5568;
    transition: 0.3s;
}

.home-video:hover .home-video-lights span:nth-child(1) {
    background-color: #ff5f57;
}

.home-video:hover .home-video-lights span:nth-child(2) {
    background-color: #febc2e;
}

.home-video:hover .home-video-lights span:nth-child(3) {
    background-color: #28c840;
}

.home-video-address {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    width: 55%;
    padding: 0.3rem 0.75rem;
    border-radius: 7px;
    background-color: #39415a;
    color: #cdd4e2;
    font-size: 0.8rem;
    line-height: 1.5;
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.home-video-screen {
    position: relative;
    line-height: 0;
}

.home-video-screen video {
    display: block;
    width: 100%;
    height: auto;
}

.home-video-shield {
    position: absolute;
    inset: 0;
}

[data-theme="light"] .home-video {
    --video-chrome: #E8EBF2;
    --video-line: rgba(20, 21, 43, 0.10);
    background-color: #F4F6FA;
    box-shadow: 0 24px 60px rgba(20, 21, 43, 0.14);
}

[data-theme="light"] .home-video-lights span {
    background-color: #B6BCCC;
}

[data-theme="light"] .home-video-address {
    background-color: #FFFFFF;
    color: #4A4F6B;
}

@media (max-width: 575px) {
    .home-video {
        margin-top: 3rem;
    }

    .home-video-address {
        width: 60%;
    }
}

/* #endregion Hero Video */

/*----------------------------------------------
16. Coin & Confetti Burst
----------------------------------------------*/

/* #region Coin & Confetti Burst */

/* Full-screen celebration fired by the dashboard's EARN button. Portalled onto
   document.body, so it can't be clipped by the dashboard's `overflow: hidden`. */
.coin-confetti {
    position: fixed;
    inset: 0;
    z-index: 9999;
    overflow: hidden;
    pointer-events: none;
}

/* Each piece animates transform and opacity only â€” both compositor properties,
   so ~70 of them fall without touching layout or paint. Every value it needs
   comes in as a custom property set inline by the component. */
.coin-confetti-piece {
    position: absolute;
    top: -8vh;
    left: var(--cc-left);
    animation: coin-confetti-fall var(--cc-duration) linear var(--cc-delay) both;
    will-change: transform, opacity;
}

.coin-confetti-piece.is-confetti {
    width: var(--cc-size);
    height: calc(var(--cc-size) * 1.8);
    border-radius: 2px;
    background-color: var(--cc-color);
}

/* Coins are heavier, so they accelerate rather than drift down at a constant
   rate. The off-centre highlight is what reads as "metal" at this size. */
.coin-confetti-piece.is-coin {
    width: var(--cc-size);
    height: var(--cc-size);
    border-radius: 50%;
    background-image: radial-gradient(circle at 35% 30%, #ffe9a8, #f5b942 55%, #c98a15);
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.18);
    animation-timing-function: ease-in;
}

@keyframes coin-confetti-fall {
    0% {
        transform: translate3d(0, 0, 0) rotate(0deg);
        opacity: 0;
    }
    8% {
        opacity: 1;
    }
    85% {
        opacity: 1;
    }
    100% {
        transform: translate3d(var(--cc-drift), 115vh, 0) rotate(var(--cc-rotate));
        opacity: 0;
    }
}

/* Falling debris across the whole viewport is exactly what this setting is for.
   The click still gets acknowledged, but with a stationary fade instead of
   motion. */
@media (prefers-reduced-motion: reduce) {
    .coin-confetti-piece {
        top: 45vh;
        animation: coin-confetti-fade 0.9s ease-out var(--cc-delay) both;
    }

    @keyframes coin-confetti-fade {
        0%,
        100% {
            opacity: 0;
        }
        40% {
            opacity: 1;
        }
    }
}

/* #endregion Coin & Confetti Burst */

/*----------------------------------------------
/*  Responsive Fixes
/*----------------------------------------------*/

/* #region Responsive Fixes */

/* Every "icon + text" block on the site is a .media (or the home page's
   .content) flex row. A flex item defaults to min-width:auto, which means it
   refuses to shrink below the widest thing inside it and pushes its parent past
   the viewport instead of wrapping. That single default is what pushed the
   contact card off screen at 768px, cut the verified/partner pills off the
   server header at 320px, and clipped the Italian feature copy on the home page
   at 320px. Letting the text column shrink is the fix; the icon beside it keeps
   its size via flex-shrink below. */
.media,
.media-body,
.content-body {
    min-width: 0;
}

/* With the column now allowed to get narrow, strings that carry no break
   opportunity â€” email addresses, server names, long Italian compounds â€” would
   still set its minimum width. */
.media-body,
.content-body {
    overflow-wrap: break-word;
}

/* A heading that puts a status pill next to the title is a flex row, and flex
   rows do not wrap unless told to â€” so the pill was pushed off screen instead
   of dropping to its own line (server header at 320px). */
.media-body h4.d-flex,
.media-body h3.d-flex {
    flex-wrap: wrap;
}

/* break-word lets a long word wrap but does not lower the element's min-content
   width, so an inline-block holding an email address still sets the width of
   the whole contact column. `anywhere` is the variant that does lower it. */
.contact .contact-items .media-body span,
.contact .contact-items .media-body p,
.contact .contact-items .media-body a {
    max-width: 100%;
    overflow-wrap: anywhere;
}

/* The icon/logo beside the text must not absorb the shrinking instead. */
.media > .icon,
.media > i,
.media > img,
.media > a,
.content > .icon,
.content > span {
    flex-shrink: 0;
}

/* Pagination is a row of fixed 50px cells: five of them plus margins are wider
   than a 320px screen's content box, so the row overflowed by a couple of
   pixels and the last cell was cut off. */
ul.page-numbers {
    flex-wrap: wrap;
    max-width: 100%;
}

@media (max-width: 430px) {
    ul.page-numbers li {
        margin: 0 3px;
    }

    a.page-numbers,
    span.page-numbers {
        width: 42px;
        height: 42px;
        line-height: 42px;
        font-size: 15px;
    }
}

/* On phones the 80px logo and its 1.5rem gap take half of a 320px card's
   usable width, leaving the name a narrow column. The stacked layout already
   keeps the name readable, and trimming the logo gives it the rest. */
@media (max-width: 575px) {
    .card.project-card.prev-project-card .item-header .avatar-max-lg {
        height: 3.5rem;
        width: 3.5rem;
    }

    .card.project-card.prev-project-card .item-header .content.ms-4 {
        margin-left: 0.75rem !important;
    }
}

/* Discovery grid cards carry the same single-line ellipsis, and it bites at
   more than just phone widths â€” "BharatMC Network" was cut below 430px and
   again at 768px, where the grid switches to two columns and each card gets
   narrow again. Two lines before truncating.
   Uniform card height, which the single line was protecting, is unaffected:
   .grid-card is height:100% inside its row and the footer is pinned with
   margin-top:auto, so a second line just eats slack instead of growing the
   card past its neighbours. */
.card.project-card.grid-card .grid-card-name {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    white-space: normal;
    overflow-wrap: anywhere;
}

@media (max-width: 575px) {
    .card.project-card.grid-card .media .avatar-max-lg {
        height: 3.5rem;
        width: 3.5rem;
    }

    .card.project-card.grid-card .media-body.ms-4 {
        margin-left: 0.75rem !important;
    }

}

/* #endregion Responsive Fixes */

/*----------------------------------------------
/*  Error Pages
/*----------------------------------------------*/

/* #region Error Pages */

/* The glow below is deliberately wider than its column so it bleeds behind the
   text, which on a phone puts it past the viewport edge. Clipping it here is
   the scoped version of the blanket overflow rule this stylesheet no longer
   has: it contains one decorative element to its own section rather than
   hiding overflow for the whole document. */
.error-area {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 82vh;
    /* Weighted downward on purpose: the block sits below the middle of the
       viewport rather than centred on it, which keeps it clear of the fixed
       navbar and reads better against the page. */
    padding: 13rem 0 5rem;
    overflow: hidden;
}

.error-content {
    position: relative;
    z-index: 1;
    text-align: center;
}

/* Wide tracking is what gives the code its poster look. It is capped in vw as
   well as rem so nine tracked characters still fit a 320px screen. */
.error-code {
    margin: 0;
    font-size: clamp(2rem, 8vw, 5rem);
    font-weight: 700;
    line-height: 1.05;
    letter-spacing: 0.12em;
    color: var(--white-color);
}

.error-title {
    margin: 0.75rem 0 0;
    font-size: clamp(1.15rem, 4vw, 2rem);
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--white-color);
}

.error-text {
    max-width: 34rem;
    margin: 1rem auto 0;
    color: var(--primary-p-color);
}

.error-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.75rem;
    margin-top: 2rem;
}

.error-visual {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem 0;
}

/* The nebula the astronaut drifts in. Purely decorative, so it is a
   pseudo-element rather than a second image to download. */
.error-visual::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: min(115%, 38rem);
    aspect-ratio: 1;
    transform: translate(-50%, -50%);
    border-radius: 50%;
    background: radial-gradient(circle,
            rgba(88, 101, 242, 0.38) 0%,
            rgba(63, 94, 201, 0.16) 42%,
            transparent 70%);
    pointer-events: none;
}

.error-visual img {
    position: relative;
    z-index: 1;
    width: 100%;
    max-width: 32.5rem;
    height: auto;
}

@media (max-width: 991px) {
    /* On desktop the section is 76vh tall and vertically centred, which keeps
       the heading clear of the fixed navbar on its own. Once it collapses to
       auto height that centring is gone, so the top padding has to clear the
       navbar itself â€” otherwise the code slides underneath it, the same way the
       dashboard header did before its padding was fixed. */
    .error-area {
        min-height: auto;
        padding: 11.5rem 0 4.5rem;
    }

    .error-visual img {
        max-width: 20rem;
    }
}

/* Was reading --dash-muted, a token that only exists inside the unrelated
   .server-dashboard mockup - everywhere else it's undefined, so the icon's
   color was invalid and rendered invisible against the card. */
.dashboard-copy-id {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    padding: 0;
    border: none;
    border-radius: 6px;
    background: none;
    color: var(--primary-p-color);
    font-size: 0.85rem;
    transition: 0.3s;
}

.dashboard-copy-id:hover {
    color: var(--white-color);
    background-color: rgba(255, 255, 255, 0.08);
}

[data-theme="light"] .dashboard-copy-id:hover {
    background-color: rgba(20, 21, 43, 0.08);
}

/* ══════════════════════════════════════════════════════════════════════════
   Staff panel
   ──────────────────────────────────────────────────────────────────────────
   The panel's own pieces (see `components/staff/StaffUi.tsx`). They sit on the
   console's tokens so the two areas still read as one product, but they are
   separate classes so reshaping the panel never reshapes the console.

   The three ideas the whole block follows:
   1. Lists are columns. Every row of a list shares one grid, so a status or a
      date is read down a column instead of hunted for in a corner.
   2. A number comes with its context — a delta, an age, a trend — or it is
      not worth a tile.
   3. Charts are sized to what they hold: a quiet fortnight is a small chart,
      and an empty period is one line of text, not four empty boxes.
   ══════════════════════════════════════════════════════════════════════════ */

/* Chart series. The pair was run through the dataviz colour validator against
   both surfaces (#14162a dark, #FFFFFF light): CVD and normal-vision
   separation and contrast all pass. Change them only by re-running it. */
:root {
    --staff-series-1: #4C7DFF;
    --staff-series-2: #d95926;
    --staff-hover: rgba(255, 255, 255, 0.035);
    --staff-chip: rgba(255, 255, 255, 0.06);
}

:root[data-theme="light"] {
    --staff-series-1: #2a78d6;
    --staff-series-2: #eb6834;
    --staff-hover: rgba(20, 21, 43, 0.035);
    --staff-chip: rgba(20, 21, 43, 0.06);
}

/* ── Layout ────────────────────────────────────────────────────────────── */

.staff-grid {
    display: grid;
    gap: 1.25rem;
    margin-bottom: 1.25rem;
    align-items: stretch;
}

.staff-grid.is-2-1 {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
}

.staff-grid.is-1-2 {
    grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
}

.staff-grid.is-1-1 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.staff-stack {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    min-width: 0;
}

/* The last panel in a column takes the slack, so both columns of a row end on
   the same line instead of one trailing off above the other. */
.staff-stack > .staff-panel:last-child {
    flex: 1;
}

@media (max-width: 1199px) {
    .staff-grid.is-2-1,
    .staff-grid.is-1-2,
    .staff-grid.is-1-1 {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* ── Page header ───────────────────────────────────────────────────────── */

.staff-page-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1.5rem;
}

.staff-page-head-text {
    min-width: 0;
}

.staff-page-head h1 {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin: 0;
    font-size: 22px;
    font-weight: 700;
    line-height: 1.2;
    color: var(--white-color);
}

.staff-page-title {
    min-width: 0;
    overflow-wrap: anywhere;
}

.staff-page-icon {
    display: inline-grid;
    place-items: center;
    flex-shrink: 0;
    width: 36px;
    height: 36px;
    border-radius: 10px;
    background-color: var(--console-accent-soft);
    color: var(--console-accent);
    font-size: 15px;
}

.staff-page-head p {
    margin: 0.4rem 0 0;
    font-size: 13px;
    color: var(--primary-p-color);
}

.staff-page-back {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    margin-bottom: 0.6rem;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--primary-p-color);
    text-decoration: none;
}

.staff-page-back:hover {
    color: var(--white-color);
}

.staff-page-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

/* ── Stat tiles ────────────────────────────────────────────────────────── */

.staff-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 1rem;
    margin-bottom: 1.25rem;
}

.staff-stat {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    min-width: 0;
    padding: 1rem 1.1rem;
    border: 1px solid var(--console-line);
    border-radius: var(--console-radius);
    background-color: var(--console-surface);
    color: inherit;
    text-decoration: none;
    transition: border-color 0.15s ease, background-color 0.15s ease;
}

.staff-stat.is-link:hover {
    border-color: var(--console-line-strong);
    background-color: var(--console-surface-2);
}

.staff-stat.is-link:focus-visible {
    outline: 2px solid var(--console-accent);
    outline-offset: 2px;
}

.staff-stat-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

.staff-stat-label {
    font-size: 12.5px;
    font-weight: 500;
    color: var(--primary-p-color);
}

.staff-stat-icon {
    display: grid;
    place-items: center;
    flex-shrink: 0;
    width: 26px;
    height: 26px;
    border-radius: 8px;
    background-color: var(--staff-chip);
    color: var(--primary-p-color);
    font-size: 11px;
}

.staff-stat-icon.is-attention {
    background-color: rgba(228, 87, 76, 0.14);
    color: var(--console-danger);
}

.staff-stat-icon.is-warning {
    background-color: rgba(245, 166, 35, 0.14);
    color: var(--console-warning);
}

.staff-stat-icon.is-good {
    background-color: rgba(46, 204, 113, 0.14);
    color: var(--console-success);
}

.staff-stat-body {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 0.75rem;
    min-height: 32px;
}

/* Proportional figures on purpose: tabular digits make a big lone number
   look loosely spaced. Columns of numbers get tabular-nums instead. */
.staff-stat-value {
    font-size: 26px;
    font-weight: 700;
    line-height: 1.1;
    color: var(--white-color);
}

.staff-stat-hint {
    margin: 0;
    overflow: hidden;
    font-size: 12px;
    color: var(--primary-p-color);
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* A delta inside a hint. Colour means direction × whether that direction is
   good, and it always ships with the arrow and the signed number, never alone. */
.staff-delta {
    font-weight: 600;
}

.staff-delta.is-good {
    color: var(--console-success);
}

.staff-delta.is-bad {
    color: var(--console-danger);
}

.staff-sparkline {
    flex-shrink: 0;
    overflow: visible;
}

.staff-sparkline polyline {
    stroke: var(--primary-p-color);
    opacity: 0.55;
}

.staff-sparkline circle {
    fill: var(--staff-series-1);
    stroke: var(--console-surface);
    stroke-width: 2;
}

/* ── Panels ────────────────────────────────────────────────────────────── */

.staff-panel {
    display: flex;
    flex-direction: column;
    min-width: 0;
    border: 1px solid var(--console-line);
    border-radius: var(--console-radius);
    background-color: var(--console-surface);
    overflow: hidden;
}

.staff-grid > .staff-panel,
.staff-panel + .staff-panel {
    margin: 0;
}

.staff-page > .staff-panel {
    margin-bottom: 1.25rem;
}

.staff-panel-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-shrink: 0;
    min-height: 52px;
    padding: 0.75rem 1.1rem;
    border-bottom: 1px solid var(--console-line);
}

.staff-panel-head-text {
    min-width: 0;
}

.staff-panel-head h2 {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0;
    font-size: 14px;
    font-weight: 600;
    color: var(--white-color);
}

.staff-panel-head h2 i {
    font-size: 12px;
    color: var(--console-accent);
}

.staff-panel-head p {
    margin: 0.2rem 0 0;
    font-size: 12px;
    color: var(--primary-p-color);
}

.staff-panel-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: 0.5rem;
}

.staff-count {
    padding: 0.1rem 0.5rem;
    border-radius: 100px;
    background-color: var(--staff-chip);
    color: var(--primary-p-color);
    font-size: 11px;
    font-weight: 600;
}

.staff-panel-body {
    flex: 1;
    min-width: 0;
    padding: 1.1rem;
}

.staff-panel-body.is-flush {
    padding: 0;
}

.staff-panel-link {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--primary-p-color);
    text-decoration: none;
    white-space: nowrap;
}

.staff-panel-link i {
    font-size: 11px;
}

.staff-panel-link:hover {
    color: var(--console-accent);
}

/* A panel's footer line — "showing 20 of 192", pagination. */
.staff-panel-foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.7rem 1.1rem;
    border-top: 1px solid var(--console-line);
    font-size: 12px;
    color: var(--primary-p-color);
}

/* ── Toolbar ───────────────────────────────────────────────────────────── */

.staff-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem;
    padding: 0.75rem 1.1rem;
    border-bottom: 1px solid var(--console-line);
}

.staff-search {
    position: relative;
    display: flex;
    align-items: center;
    flex: 1 1 260px;
    min-width: 200px;
    max-width: 440px;
    margin: 0;
}

.staff-search i {
    position: absolute;
    left: 0.8rem;
    font-size: 12px;
    color: var(--primary-p-color);
    pointer-events: none;
}

.staff-search input,
.staff-select,
.staff-input {
    height: 36px;
    border: 1px solid var(--console-line-strong);
    border-radius: 9px;
    background-color: var(--console-surface-2);
    color: var(--white-color);
    font-size: 13px;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.staff-search input {
    width: 100%;
    padding: 0 0.8rem 0 2.1rem;
}

.staff-input {
    width: 100%;
    padding: 0 0.8rem;
}

.staff-search input::placeholder,
.staff-input::placeholder {
    color: var(--primary-p-color);
    opacity: 0.75;
}

.staff-search input:focus,
.staff-select:focus,
.staff-input:focus {
    outline: none;
    border-color: var(--console-accent);
    box-shadow: 0 0 0 3px rgba(109, 74, 255, 0.2);
}

.staff-toolbar-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* Sized to its options: the native arrow is replaced so the padding on the
   right is the arrow's and nothing else. */
.staff-select {
    max-width: 220px;
    padding: 0 2rem 0 0.75rem;
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%239CA0D2' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-position: right 0.75rem center;
    background-repeat: no-repeat;
    background-size: 10px 6px;
    cursor: pointer;
}

.staff-toolbar-count {
    margin-left: auto;
    font-size: 12px;
    color: var(--primary-p-color);
    white-space: nowrap;
}

/* ── Lists ─────────────────────────────────────────────────────────────── */

.staff-list {
    width: 100%;
}

.staff-list-head,
.staff-list-row {
    display: grid;
    grid-template-columns: var(--staff-cols);
    align-items: center;
    column-gap: 1rem;
    padding-right: 1.1rem;
    padding-left: 1.1rem;
}

.staff-list-head {
    min-height: 34px;
    border-bottom: 1px solid var(--console-line);
    background-color: var(--staff-hover);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--primary-p-color);
}

.staff-list-head > .is-end {
    text-align: right;
}

.staff-list-head > .is-center {
    text-align: center;
}

/* `button` rows reset the UA button look; `a` rows drop the underline. */
.staff-list-row {
    width: 100%;
    min-height: 60px;
    padding-top: 0.6rem;
    padding-bottom: 0.6rem;
    border: 0;
    border-bottom: 1px solid var(--console-line);
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    text-decoration: none;
}

.staff-list-row:last-child {
    border-bottom: 0;
}

.staff-list-row.is-link {
    cursor: pointer;
    transition: background-color 0.15s ease;
}

.staff-list-row.is-link:hover {
    background-color: var(--staff-hover);
}

.staff-list-row.is-link:focus-visible {
    outline: 2px solid var(--console-accent);
    outline-offset: -2px;
}

.staff-list-row.is-selected {
    background-color: var(--console-accent-soft);
}

.staff-list-row.is-muted .staff-cell-title {
    color: var(--primary-p-color);
    font-weight: 500;
}

.staff-cell-main {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    min-width: 0;
}

.staff-cell-main-text {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}

.staff-cell-title {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    min-width: 0;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--white-color);
}

.staff-cell-sub {
    font-size: 12px;
    color: var(--primary-p-color);
}

.staff-truncate {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.staff-cell {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem;
    min-width: 0;
    font-size: 13px;
    color: var(--secondary-p-color);
}

.staff-cell.is-end {
    justify-content: flex-end;
    text-align: right;
}

.staff-cell.is-center {
    justify-content: center;
}

.staff-cell.is-muted {
    font-size: 12.5px;
    color: var(--primary-p-color);
}

.staff-cell.is-numeric {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: var(--white-color);
}

.staff-cell .console-badge {
    white-space: nowrap;
}

.staff-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.4rem;
}

/* An unread / waiting marker beside a title. Always paired with a title
   attribute and a visually hidden word, never meaning carried by colour alone. */
.staff-dot {
    flex-shrink: 0;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background-color: var(--console-danger);
}

.staff-dot.is-accent {
    background-color: var(--staff-series-1);
}

/* On a phone the columns stop being columns: the head goes, the naming cell
   takes a line of its own and the rest follow it, each labelled. */
@media (max-width: 900px) {
    .staff-list-head {
        display: none;
    }

    .staff-list-row {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: 0.5rem 0.9rem;
        padding: 0.85rem 1rem;
    }

    .staff-list-row > .staff-cell-main {
        flex: 1 0 100%;
    }

    .staff-list-row > .staff-cell {
        flex: 0 1 auto;
        justify-content: flex-start;
    }

    .staff-list-row > .staff-cell[data-label]::before {
        content: attr(data-label);
        margin-right: 0.3rem;
        font-size: 11.5px;
        font-weight: 500;
        color: var(--primary-p-color);
    }

    .staff-list-row > .staff-actions,
    .staff-list-row > .staff-cell.is-end:last-child {
        margin-left: auto;
    }
}

/* ── Avatars & small controls ──────────────────────────────────────────── */

.staff-avatar {
    --staff-avatar-size: 32px;
    display: inline-grid;
    place-items: center;
    flex-shrink: 0;
    width: var(--staff-avatar-size);
    height: var(--staff-avatar-size);
    overflow: hidden;
    border-radius: 50%;
    background-color: var(--console-surface-2);
    color: var(--primary-p-color);
    font-size: calc(var(--staff-avatar-size) * 0.38);
    font-weight: 700;
    line-height: 1;
}

.staff-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.staff-avatar.is-icon {
    border-radius: 9px;
    background-color: var(--console-accent-soft);
    color: var(--console-accent);
    font-size: calc(var(--staff-avatar-size) * 0.4);
}

.staff-avatar.is-tint-0 { background-color: rgba(76, 125, 255, 0.18); color: #9db7ff; }
.staff-avatar.is-tint-1 { background-color: rgba(168, 85, 247, 0.18); color: #cfa9fb; }
.staff-avatar.is-tint-2 { background-color: rgba(27, 175, 122, 0.18); color: #6fd8ae; }
.staff-avatar.is-tint-3 { background-color: rgba(237, 161, 0, 0.18); color: #f2c35a; }
.staff-avatar.is-tint-4 { background-color: rgba(232, 123, 164, 0.18); color: #f2a9c5; }
.staff-avatar.is-tint-5 { background-color: rgba(156, 160, 210, 0.2); color: #c3c6ea; }

:root[data-theme="light"] .staff-avatar.is-tint-0 { color: #2a5fd0; }
:root[data-theme="light"] .staff-avatar.is-tint-1 { color: #7b3fcf; }
:root[data-theme="light"] .staff-avatar.is-tint-2 { color: #11805a; }
:root[data-theme="light"] .staff-avatar.is-tint-3 { color: #8f6200; }
:root[data-theme="light"] .staff-avatar.is-tint-4 { color: #b0406a; }
:root[data-theme="light"] .staff-avatar.is-tint-5 { color: #545886; }

.staff-icon-btn {
    display: inline-grid;
    place-items: center;
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 1px solid var(--console-line-strong);
    border-radius: 8px;
    background: transparent;
    color: var(--primary-p-color);
    font-size: 12px;
    text-decoration: none;
    transition: color 0.15s ease, background-color 0.15s ease, border-color 0.15s ease;
}

.staff-icon-btn:hover:not(:disabled) {
    background-color: var(--staff-hover);
    color: var(--white-color);
}

.staff-icon-btn.is-danger:hover:not(:disabled) {
    border-color: rgba(228, 87, 76, 0.45);
    background-color: rgba(228, 87, 76, 0.08);
    color: var(--console-danger);
}

.staff-icon-btn:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.staff-icon-btn:focus-visible {
    outline: 2px solid var(--console-accent);
    outline-offset: 2px;
}

/* ── Empty states & properties ─────────────────────────────────────────── */

.staff-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
    min-height: 180px;
    padding: 2.25rem 1.5rem;
    text-align: center;
}

.staff-empty-icon {
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    margin-bottom: 0.35rem;
    border-radius: 12px;
    background-color: var(--staff-chip);
    color: var(--primary-p-color);
}

.staff-empty-title {
    margin: 0;
    font-size: 14px;
    font-weight: 600;
    color: var(--white-color);
}

.staff-empty-hint {
    max-width: 380px;
    margin: 0;
    font-size: 12.5px;
    color: var(--primary-p-color);
}

.staff-props {
    display: flex;
    flex-direction: column;
    margin: 0;
}

.staff-prop {
    display: grid;
    grid-template-columns: minmax(110px, 38%) minmax(0, 1fr);
    align-items: center;
    gap: 1rem;
    padding: 0.6rem 0;
    border-bottom: 1px solid var(--console-line);
}

.staff-prop:first-child {
    padding-top: 0;
}

.staff-prop:last-child {
    padding-bottom: 0;
    border-bottom: 0;
}

.staff-prop dt {
    font-size: 12.5px;
    font-weight: 500;
    color: var(--primary-p-color);
}

.staff-prop dd {
    min-width: 0;
    margin: 0;
    font-size: 13px;
    color: var(--white-color);
    overflow-wrap: anywhere;
}

.staff-prop dd .staff-select,
.staff-prop dd .staff-input {
    width: 100%;
    max-width: none;
}

/* ── Trend chart ───────────────────────────────────────────────────────── */

.staff-trend {
    margin: 0;
}

.staff-trend-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    margin: 0 0 0.85rem;
    padding: 0;
    list-style: none;
    font-size: 12px;
    color: var(--primary-p-color);
}

.staff-trend-legend li {
    display: flex;
    align-items: center;
    gap: 0.45rem;
}

/* Line keys, not boxes: the legend mirrors the mark it names. */
.staff-key {
    display: inline-block;
    flex-shrink: 0;
    width: 14px;
    height: 2px;
    border-radius: 2px;
    background-color: var(--primary-p-color);
}

.staff-key.is-series-1 {
    background-color: var(--staff-series-1);
}

.staff-key.is-series-2 {
    background-color: var(--staff-series-2);
}

.staff-trend-frame {
    position: relative;
    display: grid;
    grid-template-columns: 2.25rem minmax(0, 1fr);
}

.staff-trend-yaxis {
    position: relative;
    font-size: 10.5px;
    font-variant-numeric: tabular-nums;
    color: var(--primary-p-color);
}

.staff-trend-yaxis span {
    position: absolute;
    right: 0.6rem;
    transform: translateY(-50%);
}

.staff-trend-plot {
    position: relative;
    cursor: crosshair;
    outline: none;
}

.staff-trend-plot:focus-visible {
    border-radius: 4px;
    outline: 2px solid var(--console-accent);
    outline-offset: 4px;
}

.staff-trend-plot svg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: visible;
}

.staff-trend-grid,
.staff-trend-base {
    stroke-width: 1;
    vector-effect: non-scaling-stroke;
}

.staff-trend-grid {
    stroke: var(--console-line);
}

.staff-trend-base {
    stroke: var(--console-line-strong);
}

.staff-trend-line {
    fill: none;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
}

.staff-trend-line.is-series-1 {
    stroke: var(--staff-series-1);
}

.staff-trend-line.is-series-2 {
    stroke: var(--staff-series-2);
}

.staff-trend-area.is-series-1 {
    fill: var(--staff-series-1);
    opacity: 0.1;
}

.staff-trend-cross {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 1px;
    background-color: var(--console-line-strong);
    pointer-events: none;
    transform: translateX(-0.5px);
}

.staff-trend-dot {
    position: absolute;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    box-shadow: 0 0 0 2px var(--console-surface);
    pointer-events: none;
    transform: translate(-50%, -50%);
}

.staff-trend-dot.is-series-1 {
    background-color: var(--staff-series-1);
}

.staff-trend-dot.is-series-2 {
    background-color: var(--staff-series-2);
}

.staff-trend-tip {
    position: absolute;
    top: 0;
    z-index: 3;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    min-width: 130px;
    padding: 0.55rem 0.7rem;
    border: 1px solid var(--console-line-strong);
    border-radius: 9px;
    background-color: var(--console-panel);
    box-shadow: 0 10px 24px rgba(0, 0, 0, 0.35);
    font-size: 12px;
    pointer-events: none;
    transform: translateX(12px);
}

.staff-trend-tip.is-left {
    transform: translateX(calc(-100% - 12px));
}

.staff-trend-tip-date {
    font-size: 11px;
    color: var(--primary-p-color);
}

/* Values lead, labels follow: the reader already knows the series. */
.staff-trend-tip-row {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    color: var(--primary-p-color);
}

.staff-trend-tip-row strong {
    font-size: 13px;
    font-variant-numeric: tabular-nums;
    color: var(--white-color);
}

.staff-trend-xaxis {
    position: relative;
    height: 1.5rem;
    margin-left: 2.25rem;
    font-size: 10.5px;
    color: var(--primary-p-color);
}

.staff-trend-xaxis span {
    position: absolute;
    top: 0.5rem;
    white-space: nowrap;
    transform: translateX(-50%);
}

.staff-trend-xaxis span.is-first {
    transform: none;
}

.staff-trend-xaxis span.is-last {
    transform: translateX(-100%);
}

/* ── Ranked bars ───────────────────────────────────────────────────────── */

.staff-bars {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.staff-bars-row {
    display: grid;
    grid-template-columns: minmax(90px, 36%) minmax(0, 1fr) auto;
    align-items: center;
    gap: 0.75rem;
    padding: 0.45rem 0.5rem;
    border-radius: 8px;
    color: inherit;
    font-size: 13px;
    text-decoration: none;
}

.staff-bars-row.is-link:hover {
    background-color: var(--staff-hover);
}

.staff-bars-label {
    overflow: hidden;
    color: var(--secondary-p-color);
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Square at the baseline, a 4px rounded data end — the bar grows from one
   edge, and only its value end is shaped. */
.staff-bars-track {
    height: 8px;
    background-color: var(--staff-hover);
}

.staff-bars-track span {
    display: block;
    height: 100%;
    border-radius: 0 4px 4px 0;
    background-color: var(--staff-series-1);
}

.staff-bars-value {
    min-width: 2ch;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: var(--white-color);
    text-align: right;
}

/* ── Timeline (ticket history, account activity) ───────────────────────── */

.staff-timeline {
    position: relative;
    margin: 0;
    padding: 0;
    list-style: none;
}

.staff-timeline li {
    position: relative;
    display: grid;
    grid-template-columns: 14px minmax(0, 1fr) auto;
    gap: 0.75rem;
    padding-bottom: 1rem;
}

.staff-timeline li:last-child {
    padding-bottom: 0;
}

/* The rail between dots; the last item has nothing after it to connect to. */
.staff-timeline li:not(:last-child)::before {
    content: "";
    position: absolute;
    top: 14px;
    bottom: 0;
    left: 6px;
    width: 2px;
    background-color: var(--console-line);
}

.staff-timeline-dot {
    width: 14px;
    height: 14px;
    margin-top: 2px;
    border: 3px solid var(--console-surface);
    border-radius: 50%;
    background-color: var(--primary-p-color);
    box-shadow: 0 0 0 1px var(--console-line-strong);
}

.staff-timeline-dot.is-accent {
    background-color: var(--console-accent);
}

.staff-timeline-dot.is-good {
    background-color: var(--console-success);
}

.staff-timeline-text {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
    font-size: 13px;
    color: var(--white-color);
}

.staff-timeline-text small {
    font-size: 12px;
    color: var(--primary-p-color);
}

.staff-timeline time {
    font-size: 11.5px;
    color: var(--primary-p-color);
    white-space: nowrap;
}

/* ── Small shared bits ─────────────────────────────────────────────────── */

/* "·"-separated facts on one line under a title. */
.staff-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.2rem 0.5rem;
    font-size: 12px;
    color: var(--primary-p-color);
}

.staff-meta > * + *::before {
    content: "·";
    margin-right: 0.5rem;
    opacity: 0.6;
}

.staff-mono {
    font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
    font-size: 12px;
}

/* A label over a control, for the forms inside dialogs and panels. */
.staff-field {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    margin-bottom: 0.9rem;
}

.staff-field > span {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--white-color);
}

.staff-field > small {
    font-size: 12px;
    color: var(--primary-p-color);
}

/* A block of links into other areas: the overview's "elsewhere" panel. */
.staff-links {
    display: flex;
    flex-direction: column;
    margin: 0;
    padding: 0;
    list-style: none;
}

.staff-links li + li {
    border-top: 1px solid var(--console-line);
}

.staff-links a {
    display: grid;
    grid-template-columns: 32px minmax(0, 1fr) auto;
    align-items: center;
    gap: 0.75rem;
    padding: 0.75rem 1.1rem;
    color: inherit;
    text-decoration: none;
    transition: background-color 0.15s ease;
}

.staff-links a:hover {
    background-color: var(--staff-hover);
}

.staff-links-text {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
    font-size: 13px;
    font-weight: 600;
    color: var(--white-color);
}

.staff-links-text small {
    font-size: 12px;
    font-weight: 400;
    color: var(--primary-p-color);
}

.staff-links-value {
    font-size: 15px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--white-color);
}

.staff-links-value.is-attention {
    color: var(--console-danger);
}

/* A permission matrix in miniature: one dot per verb per area. */
.staff-perm-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) repeat(3, 24px);
    align-items: center;
    gap: 0.35rem 0.5rem;
    font-size: 12px;
    color: var(--secondary-p-color);
}

.staff-perm-grid > .is-head {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-align: center;
    text-transform: uppercase;
    color: var(--primary-p-color);
}

.staff-perm-dot {
    justify-self: center;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    border: 1.5px solid var(--console-line-strong);
}

.staff-perm-dot.is-on {
    border-color: var(--console-accent);
    background-color: var(--console-accent);
}

@media (max-width: 767px) {
    .staff-page-head h1 {
        font-size: 19px;
    }

    .staff-stats {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 0.75rem;
    }

    .staff-stat {
        padding: 0.85rem;
    }

    .staff-stat-value {
        font-size: 22px;
    }

    .staff-sparkline {
        display: none;
    }

    .staff-search {
        max-width: none;
    }

    .staff-toolbar-count {
        margin-left: 0;
    }
}

/* ── Undoing the site theme inside the panel ──────────────────────────────
   Three of the public theme's element rules reach in here and were bending
   every piece above:
   - `section { padding: 130px 0 }` — a panel is a <section>, so each one had
     130px of empty band above its title and below its content;
   - `a:not(.btn) { font-size: 1rem; color: var(--primary-color) }` — every
     row, tile and "see all" that is a link turned 16px and blue, and a 0.4s
     transition on *all* made hover states lag;
   - `li { margin: .5rem 0; font-size: 1rem }` — legend and bar rows grew.
   The anchor rules below repeat the element in the selector (`a.staff-…`) to
   match the theme's specificity and win on order — the same fix
   `.dashboard-card-header a.dashboard-card-header-link` uses. */
.staff-panel {
    padding: 0;
    background-attachment: scroll;
}

a.staff-panel-link,
a.staff-page-back,
a.staff-stat,
a.staff-list-row,
a.staff-bars-row,
a.staff-icon-btn,
.staff-links a {
    line-height: inherit;
    transition-duration: 0.15s;
    transition-property: color, background-color, border-color;
}

a.staff-stat,
a.staff-list-row,
a.staff-bars-row,
.staff-links a {
    font-size: inherit;
    font-weight: inherit;
    color: inherit;
}

a.staff-panel-link,
a.staff-page-back {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--primary-p-color);
}

a.staff-panel-link:hover,
a.staff-page-back:hover {
    color: var(--white-color);
}

a.staff-bars-row {
    font-size: 13px;
}

a.staff-icon-btn {
    font-size: 12px;
    color: var(--primary-p-color);
}

.staff-bars li,
.staff-trend-legend li,
.staff-links li,
.staff-timeline li {
    margin: 0;
    line-height: 1.4;
}

.staff-trend-legend li {
    font-size: 12px;
}

.staff-bars li {
    font-size: 13px;
}

.staff-list-head > span {
    white-space: nowrap;
}

/* A chart panel beside a taller neighbour grows its plot rather than leaving
   a band of nothing under the axis: the body is a column, and the chart's
   frame takes whatever height is left over its minimum. */
.staff-panel-body {
    display: flex;
    flex-direction: column;
}

.staff-panel-body > .staff-trend {
    display: flex;
    flex: 1;
    flex-direction: column;
}

.staff-trend-frame {
    flex: 1;
}

/* The theme also has `a:link:not(.btn)` at (0,2,1), which outranks the
   `a.staff-…` rules above. Qualifying each with its container ties it, and
   these come later, so they win. */
.staff-panel a.staff-panel-link,
.staff-page-head a.staff-page-back {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--primary-p-color);
}

.staff-panel a.staff-panel-link:hover,
.staff-page-head a.staff-page-back:hover {
    color: var(--white-color);
}

.staff-bars a.staff-bars-row {
    font-size: 13px;
    color: inherit;
}

.staff-list a.staff-list-row,
.staff-stats a.staff-stat {
    font-size: inherit;
    color: inherit;
}

/* ══════════════════════════════════════════════════════════════════════════
   Staff panel — shell, navigation and data tables
   ──────────────────────────────────────────────────────────────────────────
   Modelled on a classic admin layout: a rail of icon tiles with folding
   groups, a top bar with the Support PIN lookup in the middle, a breadcrumb
   over a large page title, and data in bordered table cards. Everything is
   under `.staff-shell` (set by StaffShell) so the console, which shares the
   `console-*` shell classes, keeps its own look.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Canvas ────────────────────────────────────────────────────────────── */

/* A hairline diagonal texture, barely there: enough to give the canvas depth
   behind the cards without ever competing with them. */
.staff-shell .console-main {
    background-image: repeating-linear-gradient(
        135deg,
        rgba(255, 255, 255, 0.012) 0 1px,
        transparent 1px 24px
    );
}

:root[data-theme="light"] .staff-shell .console-main {
    background-image: repeating-linear-gradient(
        135deg,
        rgba(20, 21, 43, 0.018) 0 1px,
        transparent 1px 24px
    );
}

.staff-shell .console-content {
    padding: 1.5rem 2rem 4rem;
}

/* The page reads at a comfortable width on a big screen instead of
   stretching a table across 1,900px. */
.staff-content {
    width: 100%;
    max-width: 1280px;
    margin: 0 auto;
}

.staff-breadcrumb ol {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin: 0 0 0.5rem;
    padding: 0;
    list-style: none;
}

.staff-breadcrumb li {
    margin: 0;
    font-size: 13.5px;
    line-height: 1.4;
    color: var(--primary-p-color);
}

.staff-breadcrumb a:not(.btn),
.staff-breadcrumb a:link:not(.btn) {
    font-size: 13.5px;
    line-height: 1.4;
    color: var(--primary-p-color);
}

.staff-breadcrumb a:hover:not(.btn) {
    font-size: 13.5px;
    color: var(--white-color);
}

.staff-breadcrumb-sep i {
    font-size: 9px;
    opacity: 0.7;
}

/* The big title of the reference layout: one word, heavy, no icon plate. */
.staff-shell .staff-page-head {
    align-items: center;
    margin-bottom: 1.75rem;
}

.staff-shell .staff-page-head h1 {
    font-size: 30px;
    font-weight: 700;
    letter-spacing: -0.01em;
}

.staff-skeleton-text {
    display: inline-block;
    width: 220px;
    height: 28px;
    border-radius: 8px;
    background-color: var(--staff-chip);
}

/* ── Rail ──────────────────────────────────────────────────────────────── */

.staff-shell .console-sidebar {
    background-image: linear-gradient(180deg, rgba(76, 125, 255, 0.04), transparent 40%);
}

.staff-shell a.staff-brand,
.staff-shell a.staff-brand:link {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.65rem;
    flex-shrink: 0;
    height: 76px;
    padding: 0 1.1rem;
    font-size: inherit;
    color: inherit;
}

.staff-brand-mark {
    display: grid;
    place-items: center;
    width: 36px;
    height: 36px;
}

.staff-brand-mark img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

[data-theme="light"] .staff-brand-mark img {
    filter: invert(1);
}

.staff-brand-text {
    display: flex;
    flex-direction: column;
    line-height: 1.15;
}

.staff-brand-text strong {
    font-size: 16px;
    font-weight: 700;
    letter-spacing: 0.02em;
    color: var(--white-color);
}

.staff-brand-text small {
    font-size: 9.5px;
    font-weight: 600;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--primary-p-color);
}

/* The rules of the reference: a hairline that fades out at both ends. */
.staff-shell .staff-brand,
.staff-nav-group.has-rule {
    position: relative;
}

.staff-shell .staff-brand::after,
.staff-nav-group.has-rule::before {
    content: "";
    position: absolute;
    left: 15%;
    right: 15%;
    height: 1px;
    background-image: linear-gradient(90deg, transparent, rgba(76, 125, 255, 0.55), transparent);
}

.staff-shell .staff-brand::after {
    bottom: 0;
}

.staff-nav-group.has-rule {
    margin-top: 0.9rem;
    padding-top: 0.9rem;
}

.staff-nav-group.has-rule::before {
    top: 0;
}

.staff-nav {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: 0.25rem;
    min-height: 0;
    padding: 1rem 0.85rem;
    overflow-y: auto;
}

.staff-shell .staff-nav-item {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    width: 100%;
    padding: 0.45rem 0.55rem;
    border: 0;
    border-radius: 10px;
    background: none;
    color: var(--secondary-p-color);
    font-size: 14.5px;
    font-weight: 600;
    line-height: 1.3;
    text-align: left;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.staff-shell a.staff-nav-item,
.staff-shell a.staff-nav-item:link {
    font-size: 14.5px;
    font-weight: 600;
    line-height: 1.3;
    color: var(--secondary-p-color);
}

.staff-shell .staff-nav-item:hover,
.staff-shell a.staff-nav-item:hover {
    background-color: var(--staff-hover);
    color: var(--white-color);
}

.staff-shell .staff-nav-item.is-active,
.staff-shell a.staff-nav-item.is-active {
    background-color: var(--console-accent-soft);
    color: var(--white-color);
}

.staff-nav-icon {
    display: grid;
    place-items: center;
    flex-shrink: 0;
    width: 34px;
    height: 34px;
    border: 1px solid var(--console-line-strong);
    border-radius: 9px;
    background-color: var(--staff-hover);
    color: var(--primary-p-color);
    font-size: 13px;
    transition: color 0.15s ease, border-color 0.15s ease;
}

.staff-nav-item:hover .staff-nav-icon,
.staff-nav-item.is-active .staff-nav-icon,
.staff-nav-item.holds-active .staff-nav-icon {
    border-color: rgba(76, 125, 255, 0.5);
    color: var(--white-color);
}

.staff-nav-label {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.staff-nav-caret {
    flex-shrink: 0;
    font-size: 10px;
    color: var(--primary-p-color);
    transition: transform 0.2s ease;
}

.staff-nav-group.is-open .staff-nav-caret {
    transform: rotate(180deg);
}

.staff-nav-count {
    flex-shrink: 0;
    min-width: 20px;
    padding: 0.05rem 0.4rem;
    border-radius: 100px;
    background-color: rgba(228, 87, 76, 0.16);
    color: #ff8a80;
    font-size: 11px;
    font-weight: 700;
    text-align: center;
}

.staff-nav-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background-color: var(--console-danger);
}

/* Children line up under their group's label, not under its icon. */
.staff-nav-children {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin: 0.25rem 0 0.4rem;
    padding-left: calc(34px + 0.75rem);
}

.staff-shell a.staff-nav-sub,
.staff-shell a.staff-nav-sub:link {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.75rem;
    border-radius: 8px;
    color: var(--primary-p-color);
    font-size: 13.5px;
    font-weight: 600;
    line-height: 1.3;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.staff-shell a.staff-nav-sub:hover {
    background-color: var(--staff-hover);
    color: var(--white-color);
    font-size: 13.5px;
}

/* The active page: a filled pill, as in the reference layout. */
.staff-shell a.staff-nav-sub.is-active {
    background-color: rgba(76, 125, 255, 0.16);
    color: var(--white-color);
}

/* Rail collapsed to icons: tiles only, centred. */
.staff-shell.is-collapsed .staff-brand-text,
.staff-shell.is-collapsed .staff-nav-label,
.staff-shell.is-collapsed .staff-nav-caret,
.staff-shell.is-collapsed .staff-nav-count {
    display: none;
}

.staff-shell.is-collapsed .staff-nav-item {
    position: relative;
    justify-content: center;
    padding-right: 0;
    padding-left: 0;
}

.staff-shell.is-collapsed .staff-nav-dot {
    position: absolute;
    top: 6px;
    right: 10px;
}

.staff-shell.is-collapsed .staff-nav {
    padding-right: 0.6rem;
    padding-left: 0.6rem;
}

/* ── Top bar ───────────────────────────────────────────────────────────── */

.staff-shell .staff-topbar {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    height: 68px;
    padding: 0 2rem;
}

.staff-topbar-center {
    display: flex;
    justify-content: center;
    min-width: 0;
}

/* The Support PIN group: label, box and button in one bordered pill. */
.staff-pin {
    position: relative;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin: 0;
    padding: 0.3rem 0.3rem 0.3rem 0.85rem;
    border: 1px solid var(--console-line-strong);
    border-radius: 11px;
    background-color: var(--console-panel);
}

.staff-pin-label {
    margin: 0;
    font-size: 13px;
    font-weight: 700;
    color: var(--white-color);
    white-space: nowrap;
}

.staff-pin-input {
    width: 104px;
    height: 32px;
    padding: 0 0.6rem;
    border: 1px solid var(--console-line-strong);
    border-radius: 7px;
    background-color: var(--console-surface-2);
    color: var(--white-color);
    font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
    font-size: 13.5px;
    letter-spacing: 0.18em;
}

.staff-pin-input::placeholder {
    color: var(--primary-p-color);
    opacity: 0.6;
}

.staff-pin-input:focus {
    outline: none;
    border-color: var(--console-accent);
}

.staff-pin-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 72px;
    height: 32px;
    padding: 0 0.9rem;
    border: 0;
    border-radius: 7px;
    background-color: var(--primary-color);
    color: var(--btn-text-color);
    font-size: 13px;
    font-weight: 700;
    transition: filter 0.15s ease;
}

.staff-pin-btn:hover:not(:disabled) {
    filter: brightness(1.12);
}

.staff-pin-btn:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

.staff-pin-btn .console-spinner {
    width: 14px;
    height: 14px;
    border-width: 2px;
}

/* ── Popovers (PIN result, search, table tools) ────────────────────────── */

.staff-pop {
    position: absolute;
    top: calc(100% + 0.5rem);
    z-index: 60;
    padding: 0.5rem;
    border: 1px solid var(--console-line-strong);
    border-radius: 12px;
    background-color: var(--console-panel);
    box-shadow: 0 18px 44px rgba(0, 0, 0, 0.45);
}

:root[data-theme="light"] .staff-pop {
    box-shadow: 0 18px 44px rgba(20, 21, 43, 0.16);
}

.staff-pop-empty {
    margin: 0;
    padding: 0.85rem 0.75rem;
    font-size: 13px;
    color: var(--primary-p-color);
}

.staff-pop-warning {
    margin: 0 0 0.5rem;
    padding: 0.55rem 0.7rem;
    border-radius: 8px;
    background-color: rgba(245, 166, 35, 0.12);
    color: var(--console-warning);
    font-size: 12.5px;
    font-weight: 600;
}

.staff-pin-pop {
    left: 50%;
    width: 340px;
    transform: translateX(-50%);
}

.staff-pin-card {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding: 0.6rem;
}

.staff-pin-card + .staff-pin-card {
    border-top: 1px solid var(--console-line);
}

.staff-pin-card-head {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.staff-pin-card-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.staff-pin-card-text strong {
    font-size: 14.5px;
    color: var(--white-color);
}

.staff-pin-card-text span {
    overflow: hidden;
    font-size: 12.5px;
    color: var(--primary-p-color);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.staff-pin-facts {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.55rem 1rem;
    margin: 0;
}

.staff-pin-facts dt {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--primary-p-color);
}

.staff-pin-facts dd {
    margin: 0.1rem 0 0;
    overflow: hidden;
    font-size: 13px;
    color: var(--white-color);
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Global search. */
.staff-gsearch {
    position: relative;
}

.staff-gsearch-field {
    width: 280px;
    max-width: none;
    flex: none;
}

.staff-gsearch-pop {
    right: 0;
    width: 360px;
}

.staff-gsearch-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.staff-gsearch-list li {
    margin: 0;
    font-size: 13px;
    line-height: 1.4;
}

.staff-gsearch-heading {
    padding: 0.5rem 0.6rem 0.25rem;
    font-size: 10.5px !important;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--primary-p-color);
}

.staff-shell a.staff-gsearch-hit,
.staff-shell a.staff-gsearch-hit:link {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    padding: 0.45rem 0.6rem;
    border-radius: 8px;
    font-size: 13px;
    color: inherit;
}

.staff-shell a.staff-gsearch-hit:hover,
.staff-shell a.staff-gsearch-hit.is-active {
    background-color: var(--staff-hover);
    font-size: 13px;
}

.staff-gsearch-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.staff-gsearch-text strong,
.staff-gsearch-text small {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.staff-gsearch-text strong {
    font-size: 13px;
    color: var(--white-color);
}

.staff-gsearch-text small {
    font-size: 11.5px;
    color: var(--primary-p-color);
}

.staff-shell a.staff-gsearch-all,
.staff-shell a.staff-gsearch-all:link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: 0.35rem;
    padding: 0.6rem;
    border-top: 1px solid var(--console-line);
    font-size: 12.5px;
    font-weight: 600;
    color: var(--primary-p-color);
}

.staff-shell a.staff-gsearch-all:hover {
    font-size: 12.5px;
    color: var(--white-color);
}

@media (max-width: 1199px) {
    .staff-gsearch-field {
        width: 200px;
    }
}

@media (max-width: 991px) {
    .staff-shell .staff-topbar {
        padding: 0 1rem;
    }

    .staff-pin-label,
    .staff-gsearch {
        display: none;
    }
}

@media (max-width: 575px) {
    .staff-topbar-center {
        display: none;
    }
}

/* ── Data table ────────────────────────────────────────────────────────── */

.staff-table-card {
    overflow: hidden;
    border: 1px solid var(--console-line);
    border-radius: 14px;
    background-color: var(--console-surface);
}

.staff-table-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.75rem 1.25rem;
    border-bottom: 1px solid var(--console-line);
}

.staff-table-tools {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-left: auto;
}

.staff-table-search {
    width: 260px;
    max-width: none;
    flex: none;
}

.staff-tool {
    position: relative;
}

.staff-tool-btn {
    position: relative;
    display: grid;
    place-items: center;
    width: 36px;
    height: 36px;
    padding: 0;
    border: 0;
    border-radius: 9px;
    background: none;
    color: var(--primary-p-color);
    font-size: 15px;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.staff-tool-btn:hover,
.staff-tool-btn.is-open {
    background-color: var(--staff-hover);
    color: var(--white-color);
}

.staff-tool-badge {
    position: absolute;
    top: 2px;
    right: 1px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: 100px;
    background-color: var(--primary-color);
    color: var(--btn-text-color);
    font-size: 10px;
    font-weight: 700;
    line-height: 16px;
}

.staff-tool-pop {
    right: 0;
    width: 280px;
    padding: 0;
}

.staff-tool-pop-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--console-line);
    font-size: 13.5px;
    color: var(--white-color);
}

.staff-tool-pop-body {
    padding: 0.85rem 1rem 0.35rem;
}

.staff-tool-pop-body .staff-select {
    width: 100%;
    max-width: none;
}

.staff-check {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    margin: 0 0 0.6rem;
    font-size: 13px;
    color: var(--secondary-p-color);
    cursor: pointer;
}

.staff-check input {
    width: 15px;
    height: 15px;
    accent-color: var(--primary-color);
}

.staff-link-btn {
    padding: 0;
    border: 0;
    background: none;
    color: var(--primary-color);
    font-size: 12.5px;
    font-weight: 600;
}

.staff-link-btn:hover {
    text-decoration: underline;
}

.staff-table-scroll {
    overflow-x: auto;
}

.staff-table {
    width: 100%;
    border-collapse: collapse;
    table-layout: auto;
}

.staff-table th,
.staff-table td {
    padding: 0 1.25rem;
    text-align: left;
    vertical-align: middle;
}

.staff-table th {
    height: 50px;
    border-bottom: 1px solid var(--console-line);
    background-color: var(--staff-hover);
    font-size: 13.5px;
    font-weight: 700;
    color: var(--white-color);
    white-space: nowrap;
}

.staff-table td {
    height: 57px;
    border-bottom: 1px solid var(--console-line);
    font-size: 13.5px;
    color: var(--secondary-p-color);
    max-width: 320px;
}

.staff-table tbody tr:last-child td {
    border-bottom: 0;
}

.staff-table .is-end {
    text-align: right;
}

.staff-table .is-center {
    text-align: center;
}

.staff-table tr.is-link {
    cursor: pointer;
}

.staff-table tbody tr {
    transition: background-color 0.15s ease;
}

.staff-table tbody tr.is-link:hover,
.staff-table tbody tr:focus-within {
    background-color: var(--staff-hover);
}

.staff-table tbody tr.is-muted td {
    color: var(--primary-p-color);
}

.staff-table-card.is-loading tbody {
    opacity: 0.5;
    transition: opacity 0.15s ease;
}

.staff-sort {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    font-weight: 700;
}

.staff-sort i {
    font-size: 10px;
    color: var(--primary-p-color);
}

.staff-sort.is-sorted i {
    color: var(--staff-series-1);
}

.staff-sort:focus-visible {
    border-radius: 4px;
    outline: 2px solid var(--console-accent);
    outline-offset: 3px;
}

/* The first cell's link fills its cell and inherits the row's look. */
.staff-shell a.staff-table-link,
.staff-shell a.staff-table-link:link,
.staff-shell a.staff-table-link:hover {
    display: block;
    font-size: inherit;
    line-height: inherit;
    color: inherit;
}

.staff-table-link:focus-visible {
    border-radius: 4px;
    outline: 2px solid var(--console-accent);
    outline-offset: 4px;
}

.staff-table-person {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    min-width: 0;
    color: var(--white-color);
    font-weight: 600;
}

.staff-table-foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.85rem 1.25rem;
    border-top: 1px solid var(--console-line);
}

.staff-table-range {
    font-size: 13.5px;
    font-weight: 600;
    color: var(--white-color);
}

.staff-table-pager {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem;
}

.staff-perpage {
    display: inline-flex;
    align-items: stretch;
    margin: 0;
    overflow: hidden;
    border: 1px solid var(--console-line-strong);
    border-radius: 9px;
    font-size: 13px;
}

.staff-perpage span {
    display: flex;
    align-items: center;
    padding: 0 0.75rem;
    border-right: 1px solid var(--console-line-strong);
    color: var(--primary-p-color);
}

.staff-perpage select {
    height: 34px;
    padding: 0 1.9rem 0 0.75rem;
    border: 0;
    appearance: none;
    background: transparent url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%239CA0D2' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat right 0.7rem center / 10px 6px;
    color: var(--white-color);
    font-weight: 700;
    cursor: pointer;
}

.staff-perpage select:focus {
    outline: none;
}

.staff-perpage select option {
    background-color: var(--console-panel);
}

.staff-pages {
    display: flex;
    align-items: center;
    gap: 0.25rem;
}

.staff-page-btn {
    display: grid;
    place-items: center;
    min-width: 34px;
    height: 34px;
    padding: 0 0.5rem;
    border: 1px solid transparent;
    border-radius: 8px;
    background: none;
    color: var(--secondary-p-color);
    font-size: 13px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.staff-page-btn:hover:not(:disabled) {
    background-color: var(--staff-hover);
    color: var(--white-color);
}

.staff-page-btn.is-current {
    border-color: rgba(76, 125, 255, 0.5);
    background-color: rgba(76, 125, 255, 0.14);
    color: var(--white-color);
}

.staff-page-btn:disabled {
    opacity: 0.35;
    cursor: not-allowed;
}

.staff-page-gap {
    padding: 0 0.25rem;
    color: var(--primary-p-color);
}

/* The small tables inside a record's panels. */
.staff-table.is-mini th {
    height: 40px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--primary-p-color);
}

.staff-table.is-mini td {
    height: 50px;
    font-size: 13px;
}

.staff-mini-main {
    display: flex;
    flex-direction: column;
    min-width: 0;
    color: var(--white-color);
}

.staff-mini-main small {
    font-size: 12px;
    color: var(--primary-p-color);
}

.staff-mini-tags {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem;
}

.staff-mini-tags.is-end {
    justify-content: flex-end;
}

.staff-shell a.staff-mini-link,
.staff-shell a.staff-mini-link:link {
    font-size: 13px;
    line-height: 1.4;
    color: var(--white-color);
}

.staff-shell a.staff-mini-link:hover {
    font-size: 13px;
    color: var(--staff-series-1);
}

@media (max-width: 767px) {
    .staff-table-toolbar {
        padding: 0.75rem 1rem;
    }

    .staff-table-tools {
        width: 100%;
    }

    .staff-table-search {
        flex: 1;
        width: auto;
    }

    .staff-table th,
    .staff-table td {
        padding: 0 0.85rem;
        white-space: nowrap;
    }
}

/* ── Status pills, tags and small bits ─────────────────────────────────── */

/* "Active" / "Inactive": the reference layout's small outlined label. */
.staff-status {
    display: inline-flex;
    align-items: center;
    padding: 0.12rem 0.45rem;
    border: 1px solid var(--console-line-strong);
    border-radius: 5px;
    background-color: var(--staff-hover);
    color: var(--primary-p-color);
    font-size: 12px;
    font-weight: 600;
    line-height: 1.35;
    white-space: nowrap;
}

.staff-status.is-active {
    border-color: rgba(46, 204, 113, 0.5);
    background-color: rgba(46, 204, 113, 0.08);
    color: #3ddc84;
}

.staff-status.is-inactive {
    border-color: rgba(245, 166, 35, 0.5);
    background-color: rgba(245, 166, 35, 0.08);
    color: #f5a623;
}

:root[data-theme="light"] .staff-status.is-active {
    color: #13803f;
}

:root[data-theme="light"] .staff-status.is-inactive {
    color: #a86a00;
}

.staff-tag {
    display: inline-flex;
    align-items: center;
    padding: 0.1rem 0.45rem;
    border-radius: 5px;
    background-color: var(--console-accent-soft);
    color: #b9a8ff;
    font-size: 11px;
    font-weight: 700;
    line-height: 1.4;
    white-space: nowrap;
}

:root[data-theme="light"] .staff-tag {
    color: #5a3de0;
}

.staff-tag.is-verified {
    background-color: rgba(52, 152, 219, 0.14);
    color: #5fb4ec;
}

.staff-muted {
    color: var(--primary-p-color);
}

.staff-num {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: var(--white-color);
}

.staff-yes {
    color: var(--console-success);
}

.staff-links-icons {
    display: inline-flex;
    gap: 0.6rem;
    font-size: 14px;
    color: var(--secondary-p-color);
}

/* ── A record page (a user, later a server) ────────────────────────────── */

.staff-identity .staff-panel-body {
    gap: 1.25rem;
}

.staff-identity-head {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.staff-identity-text {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    min-width: 0;
}

.staff-identity-text strong {
    overflow: hidden;
    font-size: 17px;
    color: var(--white-color);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.staff-identity-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}

.staff-pin-value {
    display: inline-flex;
    align-items: center;
    gap: 0.75rem;
}

.staff-stack > .staff-stats {
    margin-bottom: 0;
}

.staff-settings {
    margin: 0;
    padding: 0;
    list-style: none;
}

.staff-setting {
    display: grid;
    grid-template-columns: 34px minmax(0, 1fr) auto;
    align-items: center;
    gap: 0.85rem;
    margin: 0;
    padding: 0.8rem 1.1rem;
    border-bottom: 1px solid var(--console-line);
    font-size: 13px;
    line-height: 1.4;
}

.staff-setting:last-child {
    border-bottom: 0;
}

.staff-setting .staff-avatar {
    --staff-avatar-size: 34px;
}

.staff-setting-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.staff-setting-text strong {
    font-size: 13.5px;
    color: var(--white-color);
}

.staff-setting-text small {
    overflow: hidden;
    font-size: 12px;
    color: var(--primary-p-color);
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* More of the theme reaching in: `dt` carries 15px of margin above and
   below, which made every property row half again as tall as its text; and
   a `form` is full width, which stretched the Support PIN group across the
   whole top bar. */
.staff-prop dt,
.staff-pin-facts dt {
    margin: 0;
}

.staff-shell .staff-pin {
    width: auto;
    flex: 0 0 auto;
}

.staff-perpage span {
    white-space: nowrap;
}

/* Four tiles in a two-thirds column fit on one row at 180px each. */
.staff-stack > .staff-stats {
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
}

/* ── Views over a list (the queue's tabs) ─────────────────────────────── */

.staff-tabs {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.35rem;
    margin: 0.25rem 0 1.25rem;
}

.staff-tab {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.85rem;
    border: 0;
    border-radius: 9px;
    background: none;
    color: var(--secondary-p-color);
    font-size: 14px;
    font-weight: 500;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.staff-tab i {
    font-size: 13px;
    color: var(--primary-p-color);
}

.staff-tab:hover {
    background-color: var(--staff-hover);
    color: var(--white-color);
}

.staff-tab.is-active {
    background-color: rgba(76, 125, 255, 0.12);
    color: var(--staff-series-1);
    font-weight: 600;
}

.staff-tab.is-active i {
    color: var(--staff-series-1);
}

.staff-tab:focus-visible {
    outline: 2px solid var(--console-accent);
    outline-offset: 2px;
}

.staff-tab-count {
    min-width: 20px;
    padding: 0.05rem 0.4rem;
    border-radius: 100px;
    background-color: var(--staff-chip);
    color: var(--secondary-p-color);
    font-size: 11px;
    font-weight: 700;
    text-align: center;
}

.staff-tab.is-active .staff-tab-count {
    background-color: rgba(76, 125, 255, 0.2);
    color: var(--staff-series-1);
}

/* More pill tones, for ticket status and priority. */
.staff-status.is-info {
    border-color: rgba(76, 125, 255, 0.5);
    background-color: rgba(76, 125, 255, 0.08);
    color: #7fa2ff;
}

.staff-status.is-accent {
    border-color: rgba(168, 85, 247, 0.5);
    background-color: rgba(168, 85, 247, 0.08);
    color: #c79bfb;
}

.staff-status.is-danger {
    border-color: rgba(228, 87, 76, 0.55);
    background-color: rgba(228, 87, 76, 0.08);
    color: #ff7a70;
}

:root[data-theme="light"] .staff-status.is-info { color: #2a5fd0; }
:root[data-theme="light"] .staff-status.is-accent { color: #7b3fcf; }
:root[data-theme="light"] .staff-status.is-danger { color: #c0392b; }

.staff-table-subject {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
    color: var(--white-color);
    font-weight: 600;
}

.staff-table-person.is-quiet {
    color: var(--secondary-p-color);
    font-weight: 500;
}

.staff-cell-stack {
    display: flex;
    flex-direction: column;
    min-width: 0;
    line-height: 1.3;
}

.staff-cell-stack small {
    font-size: 11.5px;
    color: var(--primary-p-color);
}

.staff-shell a.staff-row-action,
.staff-shell a.staff-row-action:link {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 13px;
    font-weight: 600;
    line-height: 1.3;
    color: var(--staff-series-1);
}

.staff-shell a.staff-row-action:hover {
    font-size: 13px;
    text-decoration: underline;
}

/* A table cell holding a truncating value needs a floor to truncate against. */
.staff-table td .staff-truncate {
    display: block;
    max-width: 100%;
}

/* ── Row actions, dialogs and small bits for the list pages ───────────── */

/* The actions at the end of a row: quiet text buttons with an icon, as in the
   reference layout, rather than a cluster of bordered buttons. */
.staff-row-actions {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: 0.35rem 1rem;
}

button.staff-row-action,
.staff-shell a.staff-row-action.is-muted,
.staff-shell a.staff-row-action.is-muted:link {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0;
    border: 0;
    background: none;
    font-size: 13px;
    font-weight: 600;
    line-height: 1.3;
    white-space: nowrap;
}

button.staff-row-action {
    color: var(--staff-series-1);
}

button.staff-row-action:hover:not(:disabled) {
    text-decoration: underline;
}

button.staff-row-action:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

button.staff-row-action:focus-visible {
    border-radius: 4px;
    outline: 2px solid var(--console-accent);
    outline-offset: 3px;
}

button.staff-row-action.is-muted,
.staff-shell a.staff-row-action.is-muted,
.staff-shell a.staff-row-action.is-muted:link {
    color: var(--secondary-p-color);
}

.staff-shell a.staff-row-action.is-muted:hover {
    font-size: 13px;
    color: var(--white-color);
}

button.staff-row-action.is-danger {
    color: #ff7a70;
}

:root[data-theme="light"] button.staff-row-action.is-danger {
    color: #c0392b;
}

.staff-strong {
    color: var(--white-color);
    font-weight: 600;
}

.staff-cell-stack.is-end {
    align-items: flex-end;
}

.staff-tag.is-plain {
    background-color: var(--staff-chip);
    color: var(--secondary-p-color);
}

/* The facts at the top of a review or reading dialog, before its controls. */
.staff-dialog-summary {
    margin-bottom: 1.1rem;
    padding: 0.9rem 1rem;
    border: 1px solid var(--console-line);
    border-radius: 10px;
    background-color: var(--staff-hover);
}

.staff-shell a.staff-inline-link,
.staff-shell a.staff-inline-link:link,
.console-modal a.staff-inline-link,
.console-modal a.staff-inline-link:link {
    font-size: 13px;
    font-weight: 600;
    line-height: 1.4;
    color: var(--staff-series-1);
}

/* A contact message in full: kept as written, line breaks and all. */
.staff-message {
    margin: 0;
    padding: 1rem;
    border-radius: 10px;
    background-color: var(--console-surface-2);
    color: var(--white-color);
    font-size: 14px;
    line-height: 1.6;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

/* Figures being replaced by a new period's: still there, visibly stale. */
.staff-refreshing {
    opacity: 0.55;
    transition: opacity 0.15s ease;
}

.staff-stats-placeholder {
    height: 112px;
    margin-bottom: 1.25rem;
}

.staff-table-caption {
    font-size: 12.5px;
    color: var(--primary-p-color);
}

.staff-page-actions .staff-select {
    height: 38px;
}

/* Inside a table a cell's pills and a row's actions stay on one line: a row
   that wraps doubles in height and breaks the rhythm the eye reads down. The
   table widens instead, and scrolls inside its card if it has to. */
.staff-table .staff-mini-tags,
.staff-table .staff-row-actions {
    flex-wrap: nowrap;
}

/* Dates and short muted values never break mid-value in a table cell. */
.staff-table td > .staff-muted {
    white-space: nowrap;
}

/* ── Home: the showcase strip under Discovery ─────────────────────────── */

.home-showcase-area {
    padding-top: 0 !important;
}

.home-showcase-intro {
    max-width: 640px;
    margin: 0.75rem 0 0;
    color: var(--primary-p-color);
}

/* The price is the pill that matters — "from 2,872" is what the card is
   selling — so it never gives up width; the tagline beside it truncates
   instead. It used to be the other way round on a narrow card. */
.showcase-card .tags > .showcase-card-price {
    flex-shrink: 0;
    max-width: none;
}

.showcase-card .tags > .status-pill:not(.showcase-card-price) {
    min-width: 0;
}

/* ── Home: the showcase carousel ──────────────────────────────────────── */

.showcase-carousel {
    position: relative;
    margin-top: 1.5rem;
}

/* A native scrolling row, snapped per card. Three cards to a desktop row —
   the size they are on /showcase — two on a tablet, and one with the next
   peeking in on a phone, which is what tells a finger there is more. */
.showcase-carousel-track {
    display: flex;
    gap: 1rem;
    padding: 0.25rem 0.125rem 0.5rem;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    scrollbar-width: none;
    overscroll-behavior-x: contain;
}

.showcase-carousel-track::-webkit-scrollbar {
    display: none;
}

.showcase-carousel-track:focus-visible {
    border-radius: 1.25rem;
    outline: 2px solid var(--primary-color);
    outline-offset: 4px;
}

.showcase-carousel-track > .showcase-cell {
    flex: 0 0 calc((100% - 2rem) / 3);
    min-width: 0;
    scroll-snap-align: start;
}

@media (max-width: 991px) {
    .showcase-carousel-track > .showcase-cell {
        flex-basis: calc((100% - 1rem) / 2);
    }
}

@media (max-width: 575px) {
    .showcase-carousel-track > .showcase-cell {
        flex-basis: 85%;
    }
}

/* Round arrows riding the row's edges. Always live: the row loops, so there
   is no end for either of them to reach. */
.showcase-carousel-btn {
    position: absolute;
    top: 50%;
    z-index: 3;
    display: grid;
    place-items: center;
    width: 46px;
    height: 46px;
    padding: 0;
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 50%;
    background-color: var(--card-bg-color);
    box-shadow: 0 10px 26px rgba(0, 0, 0, 0.45);
    color: var(--white-color);
    font-size: 15px;
    transform: translateY(-50%);
    transition: opacity 0.2s ease, background-color 0.2s ease;
}

.showcase-carousel-btn:hover {
    background-image: linear-gradient(135deg, var(--primary-color) 10%, var(--secondary-color));
    color: var(--btn-text-color);
}

.showcase-carousel-btn:focus-visible {
    outline: 2px solid var(--primary-color);
    outline-offset: 3px;
}

.showcase-carousel-btn.is-prev {
    left: -23px;
}

.showcase-carousel-btn.is-next {
    right: -23px;
}

[data-theme="light"] .showcase-carousel-btn {
    border-color: rgba(20, 21, 43, 0.12);
    box-shadow: 0 10px 26px rgba(20, 21, 43, 0.14);
}

/* On touch screens the row is swiped; arrows over the cards only cover them. */
@media (max-width: 767px) {
    .showcase-carousel-btn {
        display: none;
    }
}

/* Where the page has room beside the container, the arrows sit outside the
   cards instead of over their edges. */
@media (min-width: 1400px) {
    .showcase-carousel-btn.is-prev {
        left: -64px;
    }

    .showcase-carousel-btn.is-next {
        right: -64px;
    }
}

/* ── The showcase header: one box, one list ────────────────────────────── */

.showcase-hero .showcase-intro {
    max-width: 36rem;
    margin: 0 auto;
}

/* Find a server by name, or paste a store's address to read it — the same
   plain, bordered field style as /earn's search box (see the base
   `input, textarea, select` rules above), with a leading icon. The "Read"
   button that appears once the query looks like a store link sits outside
   this box, as a sibling in `.showcase-search` — see `.showcase-search-btn`. */
.showcase-finder {
    position: relative;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    height: 50px;
    padding: 0 1rem;
    border: 2px solid var(--primary-p-color);
    border-radius: 2px;
    background: transparent;
    transition: border-color 0.2s ease;
}

.showcase-finder:focus-within {
    border-color: var(--primary-t-color);
}

.showcase-finder > i {
    flex-shrink: 0;
    color: var(--primary-p-color);
    font-size: 14px;
}

.showcase-finder:focus-within > i {
    color: var(--primary-t-color);
}

.showcase-finder.is-link > i {
    color: var(--primary-color);
}

/* The theme's form styles give every input a border, a background and a
   height; inside the field it's the box that carries those, so the input
   itself stays bare. */
.showcase-finder input {
    flex: 1 1 auto;
    min-width: 0;
    height: 100%;
    padding: 0 0.25rem;
    border: 0 !important;
    background: transparent !important;
    box-shadow: none !important;
    color: var(--primary-p-color);
    font-size: 15px;
    outline: none;
}

.showcase-finder:focus-within input {
    color: var(--primary-t-color);
}

.showcase-finder input::placeholder {
    color: var(--primary-p-color);
    opacity: 0.8;
}

/* Locked while the store is being read, so the address can't change out from
   under the request already in flight — dimmed to read as "busy", not broken. */
.showcase-finder input:disabled {
    opacity: 0.6;
    cursor: wait;
}

/* Standing alone in the results area now (see DiscoveryBrowser.tsx), not
   squeezed into the toolbar row — sized up from the theme's default `.btn`
   to read as the one thing to do here, and its spinner sized up to match so
   the loading state is as hard to miss as the button itself. */
.showcase-search-btn {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    margin: 0;
    padding: 1.1rem 2.75rem;
    font-size: 1.05rem;
    white-space: nowrap;
}

.showcase-search-btn .fa-spinner {
    font-size: 1.2em;
}

.showcase-search-btn:disabled {
    cursor: wait;
    opacity: 0.85;
}

/* Under the button while it loads — a bare spinner past a few seconds reads
   as frozen, not busy, so this says outright that it is still working. */
.showcase-search-hint {
    margin: 0.85rem 0 0;
    color: var(--primary-p-color);
    font-size: 13px;
}

/* "Most popular · 26 servers" over the grid: a heading, not a second box. */
.showcase-list-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    margin: 3rem 0 0;
    padding-bottom: 0.9rem;
    border-bottom: 1px solid var(--card-border-color);
}

.showcase-list-head h4 {
    margin: 0;
    font-size: 18px;
}

.showcase-list-head span {
    font-size: 13px;
    color: var(--primary-p-color);
}

@media (max-width: 575px) {
    .showcase-search-btn {
        width: 100%;
        padding: 1rem 1.5rem;
    }
}

/* The purchase dialogs end on a note (or an error) and then the buttons; with
   no margin on either the buttons sat on the note's border. */
.request-buy-note + .details-form-actions,
.request-buy-note + .store-status,
.store-status + .details-form-actions {
    margin-top: 1rem;
}

/* Pill tabs that are links (the filters on /account/requests/all): the
   theme's rules for `a` would otherwise make them 16px and blue. */
.store-category-tabs a.details-tab,
.store-category-tabs a.details-tab:link,
.store-category-tabs a.details-tab:visited {
    font-size: 12px;
    font-weight: 600;
    line-height: 1;
    color: var(--primary-p-color);
    text-decoration: none;
}

.store-category-tabs a.details-tab:hover {
    font-size: 12px;
    color: var(--white-color);
}

.store-category-tabs a.details-tab.active,
.store-category-tabs a.details-tab.active:hover {
    color: var(--btn-text-color);
}

/* The filters over /account/requests/all: the account area's pill bar,
   centred above the list's card. Links, so the theme's `a` rules are undone. */
.details-tabs.request-filter-tabs {
    width: fit-content;
    max-width: 100%;
    margin: 0 auto 1.5rem;
}

.request-filter-tabs a.details-tab,
.request-filter-tabs a.details-tab:link,
.request-filter-tabs a.details-tab:visited {
    font-size: 14px;
    font-weight: 600;
    line-height: 1;
    color: var(--primary-p-color);
    text-decoration: none;
}

.request-filter-tabs a.details-tab:hover {
    font-size: 14px;
    color: var(--white-color);
}

.request-filter-tabs a.details-tab.active,
.request-filter-tabs a.details-tab.active:hover {
    color: var(--btn-text-color);
}

.request-filter-count {
    min-width: 20px;
    padding: 0.15rem 0.45rem;
    border-radius: 100px;
    background-color: rgba(255, 255, 255, 0.08);
    font-size: 11px;
    text-align: center;
}

.request-filter-tabs a.details-tab.active .request-filter-count {
    background-color: rgba(255, 255, 255, 0.22);
}

[data-theme="light"] .request-filter-count {
    background-color: rgba(20, 21, 43, 0.07);
}

/* The bin on a pending request's card: tucked into the top corner and quiet
   until pointed at, so it is findable without competing with "Buy". */
.request-card {
    position: relative;
}

.request-withdraw-btn {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: 1px solid transparent;
    border-radius: 8px;
    background: none;
    color: var(--primary-p-color);
    font-size: 12px;
    opacity: 0.55;
    transition: opacity 0.15s ease, color 0.15s ease, background-color 0.15s ease, border-color 0.15s ease;
}

.request-card:hover .request-withdraw-btn,
.request-withdraw-btn:focus-visible {
    opacity: 1;
}

.request-withdraw-btn:hover {
    border-color: rgba(228, 79, 79, 0.45);
    background-color: rgba(228, 79, 79, 0.1);
    color: #ff7a70;
    opacity: 1;
}

.request-withdraw-btn:focus-visible {
    outline: 2px solid var(--primary-color);
    outline-offset: 2px;
}

/* On a touch screen there is no hover to reveal it. */
@media (hover: none) {
    .request-withdraw-btn {
        opacity: 1;
    }
}

/* ── Partner notice: "not our partners, and here is what we do about it" ──
   Blue on purpose, never the amber of a warning: the message is a
   promise about who answers for the purchase, not a risk for the player. */
:root {
    --partner-tint: rgba(0, 71, 255, 0.08);
    --partner-line: rgba(0, 71, 255, 0.3);
    --partner-icon: #7c9bff;
}

[data-theme="light"] {
    --partner-tint: rgba(0, 71, 255, 0.06);
    --partner-line: rgba(0, 71, 255, 0.22);
    --partner-icon: #0047ff;
}

/* One line: on the showcase and requests pages, and in a server's rewards
   window. */
p.partner-strip {
    display: flex;
    align-items: flex-start;
    gap: 0.55rem;
    margin: 0;
    padding: 0.65rem 0.8rem;
    border: 1px solid var(--partner-line);
    border-radius: 10px;
    background-color: var(--partner-tint);
    color: var(--primary-p-color);
    font-size: 12px;
    line-height: 1.5;
    text-align: left;
}

p.partner-strip i {
    margin-top: 0.15rem;
    color: var(--partner-icon);
}

/* In a dialog it is a band across the window, flush under the title bar,
   rather than a box floating inside it. */
.dashboard-dialog > p.partner-strip {
    flex: 0 0 auto;
    padding: 0.6rem 1.35rem;
    border-width: 0 0 1px;
    border-radius: 0;
}

/* A label ahead of a sentence (the home page's showcase intro). */
.partner-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    margin-right: 0.6rem;
    padding: 0.2rem 0.6rem;
    border: 1px solid var(--partner-line);
    border-radius: 999px;
    background-color: var(--partner-tint);
    color: var(--partner-icon);
    font-size: 11px;
    font-weight: 700;
    line-height: 1.4;
    vertical-align: 0.1em;
    white-space: nowrap;
}

/* On the showcase page: between the list's title and its cards. */
p.partner-strip.showcase-partner-notice {
    margin-top: 1.25rem;
}

.showcase-partner-notice + .showcase-grid {
    margin-top: 1rem;
}

/* ── Referrals: the account card, the referrals page, the sign-up line ───── */
/* The link and its copy button, one row. `input[type="text"]` in the
   selector to outrank the theme's own rules for text inputs. */
.referral-link {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.referral-link input[type="text"] {
    flex: 1 1 auto;
    min-width: 0;
    height: 2.4rem;
    margin: 0;
    padding: 0 0.75rem;
    border: 1px solid var(--card-border-color);
    border-radius: 10px;
    background-color: rgba(255, 255, 255, 0.04);
    color: var(--white-color);
    font-size: 12.5px;
    text-overflow: ellipsis;
}

[data-theme="light"] .referral-link input[type="text"] {
    background-color: rgba(0, 0, 0, 0.03);
}

.referral-link input[type="text"]:focus {
    outline: none;
    border-color: var(--primary-color);
}

.referral-link .support-pin-btn {
    flex-shrink: 0;
}

/* "You were invited": green, because it is money on its way to the reader. */
p.register-invite {
    display: flex;
    align-items: flex-start;
    gap: 0.55rem;
    padding: 0.6rem 0.75rem;
    border: 1px solid rgba(62, 207, 142, 0.32);
    border-radius: 10px;
    background-color: rgba(62, 207, 142, 0.08);
    color: var(--primary-p-color);
    font-size: 12px;
    line-height: 1.5;
    text-align: left;
}

p.register-invite {
    margin: 0 0 1.5rem;
    font-size: 13px;
}

p.register-invite i {
    margin-top: 0.15rem;
    color: #3ecf8e;
}

[data-theme="light"] p.register-invite i {
    color: #14a36b;
}

/* The friends list on /account/referrals. */
ul.referral-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

ul.referral-list li.referral-row {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    margin: 0;
    padding: 0.85rem 0;
    border-bottom: 1px solid var(--card-border-color);
    font-size: 14px;
}

ul.referral-list li.referral-row:first-child {
    padding-top: 0;
}

ul.referral-list li.referral-row:last-child {
    padding-bottom: 0;
    border-bottom: 0;
}

.referral-avatar {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 50%;
    background-color: rgba(0, 71, 255, 0.15);
    color: #7c9bff;
    font-size: 14px;
    font-weight: 700;
}

[data-theme="light"] .referral-avatar {
    color: #0047ff;
}

.referral-row-main {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}

.referral-row-main strong {
    overflow: hidden;
    color: var(--white-color);
    font-size: 14px;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.referral-row-main > span {
    color: var(--primary-p-color);
    font-size: 12px;
}

/* The pill chrome is scoped per container in this theme (see the note on
   .request-card .status-pill), so it is declared again here. */
.referral-row > .status-pill {
    display: inline-block;
    flex-shrink: 0;
    padding: 0.3rem 0.8rem;
    border: 1px solid currentColor;
    border-radius: 100px;
    background: transparent;
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
}

p.referral-code-line {
    margin: 0.6rem 0 0;
    color: var(--primary-p-color);
    font-size: 12px;
}

p.referral-code-line strong {
    color: var(--white-color);
    letter-spacing: 0.08em;
}

h5.referral-how-title {
    margin: 1.5rem 0 0.9rem;
    font-size: 14px;
}

/* ── "Invite friends" in the navbar: the icon and its occasional bubble ──── */
.referral-nav {
    position: relative;
}

/* Centred under the icon, so on a phone — where the icon sits mid-bar — it
   has room on both sides instead of running off one edge. */
.referral-nudge {
    position: absolute;
    top: calc(100% + 12px);
    left: 50%;
    z-index: 31;
    display: flex;
    align-items: flex-start;
    gap: 0.25rem;
    width: max-content;
    max-width: min(260px, calc(100vw - 32px));
    padding: 0.75rem 0.45rem 0.8rem 0.95rem;
    border: 1px solid rgba(0, 71, 255, 0.45);
    border-radius: 12px;
    background-color: #13152e;
    box-shadow: 0 16px 32px -12px rgba(0, 0, 0, 0.6);
    transform: translateX(-50%);
    animation: referral-nudge-in 0.35s ease-out;
}

/* The little arrow pointing up at the icon. */
.referral-nudge::before {
    content: "";
    position: absolute;
    top: -6px;
    left: 50%;
    width: 10px;
    height: 10px;
    border-top: 1px solid rgba(0, 71, 255, 0.45);
    border-left: 1px solid rgba(0, 71, 255, 0.45);
    background-color: inherit;
    transform: translateX(-50%) rotate(45deg);
}

[data-theme="light"] .referral-nudge {
    background-color: #FFFFFF;
    box-shadow: 0 16px 32px -12px rgba(20, 21, 43, 0.25);
}

/* Solid icons need weight 900; the theme sets every navbar icon to 400,
   which turns solid-only glyphs into empty boxes. The bell has the same fix. */
#header .navbar-expand .icons .referral-nav i {
    font-weight: 900;
}

/* Outranks the theme's navbar link rule
   (header .navbar-expand .navbar-nav .nav-item a:not(.btn)), which would
   otherwise make this a padded, centred, bold white row. */
#header .navbar-nav .nav-item .referral-nudge a.referral-nudge-body:not(.btn) {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.2rem;
    min-width: 0;
    padding: 0;
    color: var(--primary-p-color);
    font-weight: 400;
    font-size: 12px;
    line-height: 1.45;
    text-align: left;
    white-space: normal;
}

#header .referral-nudge a.referral-nudge-body strong {
    color: var(--white-color);
    font-size: 13.5px;
}

#header .referral-nudge a.referral-nudge-body:hover strong {
    text-decoration: underline;
}

.referral-nudge-close {
    flex-shrink: 0;
    padding: 0.1rem 0.35rem;
    border: 0;
    background: none;
    color: var(--primary-p-color);
    font-size: 12px;
    line-height: 1;
}

.referral-nudge-close:hover {
    color: var(--white-color);
}

/* While the bubble is out, the icon it came from nods twice. */
.referral-nav .nav-link.is-nudging i {
    color: var(--primary-color);
    animation: referral-nod 0.9s ease-in-out 2;
}

@keyframes referral-nudge-in {
    from {
        opacity: 0;
        transform: translate(-50%, -6px);
    }
    to {
        opacity: 1;
        transform: translate(-50%, 0);
    }
}

@keyframes referral-nod {
    0%, 100% { transform: rotate(0); }
    25% { transform: rotate(-12deg); }
    75% { transform: rotate(12deg); }
}

@media (prefers-reduced-motion: reduce) {
    .referral-nudge,
    .referral-nav .nav-link.is-nudging i {
        animation: none;
    }
}
