
:root {
  --prim-color: rgb(3, 165, 253); 
  --prim-bg: black;                     /* page background (and text on primary buttons) */
  --disabled-color: rgb(28, 74, 102);   /* darker prim-color for inputs that are locked */
  --danger-color: #fa3838;              /* deleting: outline + text of the delete buttons */
  --hibernating-color: rgb(3, 165, 253);    /* off, a join starts it */
  --running-color: #13ec13;                 /* online */
  --partial-color: #f2800d;                 /* in between: starting, stopping */
  --stopped-color: var(--danger-color);     /* stopped from the site, or failed to start */
  --max-width: 1200px;                  /* widest the content column gets */

  --font-scale: 0.85;                 /* every font size below is multiplied by this */
  --font-xl: calc(clamp(40px, 6vw, 96px) * var(--font-scale));    /* hero / headings */
  --font-lg: calc(clamp(24px, 3.4vw, 54px) * var(--font-scale));  /* server name + label */
  --font-md: calc(clamp(16px, 2vw, 30px) * var(--font-scale));    /* inputs */
  --font-sm: calc(clamp(12px, 1.5vw, 22.5px) * var(--font-scale));  /* small text (verify banner): always 0.75x --font-md */
}

html {
    scrollbar-width: none;
}

html::-webkit-scrollbar {
    display: none;
}

body {
    background-color:var(--prim-bg);
    margin: 0;
}

div#frame {
    margin: 0 30px;
    min-height: 100vh;
    border: solid 8px var(--prim-color);
    border-top-width: 0px;
    border-bottom-width: 0px;
}

div#frame { display: flex; }
div#content {
    flex: 1 1 0;
    min-width: 0;
    padding: 0 5%;              /* gap on both sides of the server list */
    margin-left: auto;
    margin-right: auto;
    min-height: 1600px;
    max-width: var(--max-width);
}

nav#menu {
    flex: none;
    position: sticky;           /* stays put while the server list scrolls */
    top: 0;
    align-self: flex-start;
    height: 100vh;
    box-sizing: border-box;
    padding: 60px 24px 0 16px;  /* lines up with the greeting */
    border-right: 1px solid var(--prim-color);
    display: flex;
    flex-direction: column;
    gap: 16px;
}
nav#menu a {
    color: grey;
    font-family: "Silkscreen";
    font-size: var(--font-md);
    text-decoration: none;
    transition: color 0.2s;
}
nav#menu a:hover, nav#menu a.active { color: var(--prim-color); }

@media (max-width: 700px) {
    div#frame { flex-direction: column; }
    nav#menu {
        position: static;
        height: auto;
        flex-direction: row;
        flex-wrap: wrap;
        padding: 16px;
        border-right: none;
        border-bottom: 1px solid var(--prim-color);
    }
}

p#heading {
    color: var(--prim-color);
      font-family: "Pixelify Sans", sans-serif;
    font-optical-sizing: auto;
    font-weight: 400;
    font-style: normal;
    text-align: center;
    font-size: var(--font-xl);

}

div#z {
    display: flex;
    flex-wrap: wrap;
}

div#left {
    flex: 1 1 320px;
    min-width: 0;
    display: block;
}

div#distances {
    display: flex;
    flex-wrap: wrap;
    column-gap: 60px;
}

/* side by side while each gets ~200px (labels wrap inside), stacked below that */
div#distances > div.option {
    flex: 1 1 200px;
}

div.option {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    margin-top: 20px;
}

div.option label {
    color: grey;
    font-family: "Silkscreen";
    font-size: var(--font-md);
}

select {
    appearance: none;
    background-color: #000A;
    background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                      linear-gradient(135deg, currentColor 50%, transparent 50%);
    background-position: calc(100% - 0.65em) 55%, calc(100% - 0.35em) 55%;
    background-size: 0.3em 0.3em;
    background-repeat: no-repeat;
    border: 0 solid var(--prim-color);
    border-bottom-width: 4px;
    border-radius: 2px;
    padding: 0 1.4em 0 4px;
    color: var(--prim-color);
    font-family: "Silkscreen";
    font-size: var(--font-md);
    cursor: pointer;
}

select option {
    background: var(--prim-bg);
}

div#motds {
    margin-top: 30px;
}

div#motds input {
    flex: 1;
    min-width: 0;
}

div#left input[type="number"] {
    width: 5ch;
    text-align: right;
    appearance: textfield;
    -moz-appearance: textfield;
}

/* the world border takes up to 8 digits, so twice as wide */
div#left input#sborderdiameter, div#left input#sborderdamage {
    width: 10ch;
}

div#left input[type="number"]::-webkit-inner-spin-button,
div#left input[type="number"]::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

input.toggle {
    appearance: none;
    position: relative;
    width: 2.4em;
    height: 1.2em;
    margin: 0;
    border: 3px solid grey;     /* blue when on; fades with the knob (input transition below) */
    border-radius: 2px;
    background: transparent;
    cursor: pointer;
}

input.toggle:checked {
    border-color: var(--prim-color);
}

input.toggle::before {
    content: "";
    position: absolute;
    top: 2px;
    left: 2px;
    width: calc(1.2em - 10px);
    height: calc(1.2em - 10px);
    background: grey;
    transition: transform 0.15s, background 0.15s;
}

input.toggle:checked::before {
    background: var(--prim-color);
    transform: translateX(1.2em);
}


div#right {
    flex: none;
    width: 40%;
    min-width: max-content;     /* never narrower than the map + its margin */
    position:relative;
}

div#right canvas {
    display: block;
    flex: none;                 /* keep its real size; #mapframe crops it */
}

div#mapframe {
    height: 350px;
    /*overflow: hidden;*/
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    align-items: center;
    min-width: 371px;
}

div#mapbox {
    display: inline-block;
    margin-left: 30px;          /* 30px right from the left edge of the parent */
    margin-top: 20px;           /* 20px down from the top edge of the parent */
}

div#seedbox {
    position: relative;
    z-index: 2;                 /* in front of the canvas */
    width: 0;                   /* don't widen #mapbox... */
    min-width: 100%;            /* ...but fill it, i.e. match the canvas */
}

div#seedbox input {
    width: 100%;
    box-sizing: border-box;
    padding-right: 48px;
}

button.reroll {
    position: absolute;
    right: 10px;
    top: 50%;
    transform: translateY(-50%);
    width: 30px;
    height: 30px;
    padding: 0;
    background: none;
    border: none;
    color: var(--prim-color);
    cursor: pointer;
}

button.reroll svg {
    display: block;
    width: 100%;
    height: 100%;
    transition: transform 0.2s;
}

button.reroll:not(:disabled):hover svg {
    transform: rotate(90deg);
}

section#hero {
    position: relative;         /* anchors the scroll hint to its bottom */
    height: 100vh;
    height: 100dvh;
    display: flex;
    align-items: center;
    justify-content: center;
}

p#subheading {
    margin: 0;
    color: var(--prim-color);
    font-family: "Nunito", sans-serif;
    font-optical-sizing: auto;
    font-weight: 700;
    font-style: normal;
    text-align: center;
    font-size: var(--font-xl);

}
input {
    background-color: #000A;
    border: 0px solid var(--prim-color);
    color: var(--prim-color); 
    font-weight: 400;
    font-size: var(--font-md);
    border-radius: 2px;
    font-family: "Silkscreen";
    border-bottom-width:4px;
    
}

canvas {
    position: relative;
    z-index: 1;             /* above #content so it can be dragged */
    image-rendering: pixelated;
}
input {
    transition: box-shadow 0.15s, border-color 0.15s;
}

input:focus, select:focus {
    outline: none;
}

select:focus-visible, input.toggle:focus-visible {
    border-color: white;
    box-shadow: 0 12px 12px -8px var(--prim-color);
}

input:focus-visible {
    border-color: white;
    /* pushed down with a negative spread so the glow only shows under the input */
    box-shadow: 0 12px 12px -8px var(--prim-color);
}

button.reroll:focus {
    outline: none;
}

button.reroll:focus-visible svg {
    filter: drop-shadow(0 0 4px var(--prim-color));
    color: white;
}

label#snamelabel {
    display: block;
    width: 100%;                /* same box as input#sname so their left edges match */
    max-width: var(--max-width);
    margin: 0 auto 6px;
    padding: 0 4px;
    box-sizing: border-box;
    color: grey;
    font-family: "Silkscreen";
    font-size: var(--font-lg);
}

span#optionsheading{

    display: block;
    width: 100%;                /* same box as input#sname so their left edges match */
    max-width: var(--max-width);
    margin: 0 auto 6px;
    margin-top:100px;
    padding: 0 4px;
    box-sizing: border-box;
    color: grey;
    font-family: "Silkscreen";
    font-size: var(--font-lg);
}

div#namebox {
    position: relative;
    width: 100%;
    max-width: var(--max-width);
    margin: 0 auto;
}

input#sname {
    display: block;
    width: 100%;
    box-sizing: border-box;
    margin: 0;
    padding: 0 calc(0.9em + 20px) 0 4px;   /* right padding keeps text clear of the reroll icon */
    font-size: var(--font-lg);
}

button#rname {
    font-size: var(--font-lg);  /* icon scales with the name text */
    width: 0.9em;
    height: 0.9em;
}

label#seedlabel {
    display: block;
    margin-top: 6px;
    padding: 0 2px;             /* same as the input's text inset, so they line up */
    color: grey;
    font-family: "Silkscreen";
    font-size: var(--font-md);  /* same size as the seed text */
}

span.optlabel {
    display: flex;
    align-items: center;
    gap: 8px;
}

span.info {
    position: relative;
    display: inline-flex;
    width: calc(var(--font-md) * 0.9);
    height: calc(var(--font-md) * 0.9);
    color: grey;
    cursor: help;
}

span.info svg {
    width: 100%;
    height: 100%;
    position:relative;
    display:flex;
}

span.info:hover, span.info:focus-visible {
    color: var(--prim-color);
    outline: none;
}

span.tip {
    visibility: hidden;
    opacity: 0;
    position: absolute;
    top: calc(100% + 10px);
    left: 50%;
    transform: translateX(-50%);
    z-index: 10;                /* above the map canvas */
    width: max-content;
    max-width: min(400px, calc(100vw - 32px - 34px));     /* 34px: padding + border */
    padding: 10px 14px;
    background: var(--prim-bg);
    border: 3px solid var(--prim-color);
    border-radius: 2px;
    color: white;
    font-family: "Nunito", sans-serif;
    font-size: calc(var(--font-md) * 0.8);
    line-height: 1.35;
    pointer-events: none;
    transition: opacity 0.15s, visibility 0.15s;
}

span.tip.wide {
    max-width: min(800px, calc(100vw - 32px - 34px));      /* long text: twice as wide */
}

span.tip ol {
    margin: 6px 0;
    padding-left: 2em;
}

span.info:hover span.tip, span.info:focus-visible span.tip {
    visibility: visible;
    opacity: 1;
}

select#sworldtype {
    display: block;
    width: 0;                   /* don't widen #mapbox... */
    min-width: 100%;            /* ...but fill it, i.e. match the canvas */
    box-sizing: border-box;
    margin-top: 16px;
}

label#worldtypelabel {
    display: block;
    margin-top: 6px;
    padding: 0 4px;             /* same as the select's text inset, so they line up */
    color: grey;
    font-family: "Silkscreen";
    font-size: var(--font-md);
}

input:disabled, select:disabled {
    color: var(--disabled-color);
    border-color: var(--disabled-color);
    cursor: not-allowed;
}

button.reroll:disabled {
    color: var(--disabled-color);
    cursor: not-allowed;
}

div.submitrow {
    position: fixed;
    left: 38px;                 /* the frame's 30px margin + 8px border */
    right: 38px;
    bottom: 0;
    z-index: 20;                /* above the options and their tooltips */
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    padding: 50px 0 30px;
    background: linear-gradient(transparent, var(--prim-bg) 45%);   /* options fade out behind it */
    pointer-events: none;       /* the see-through top doesn't block clicks on the options under it */
    transform: translateY(100%);
    visibility: hidden;         /* out of the tab order while hidden */
    transition: transform 0.2s ease-out, visibility 0.2s;
}
div.submitrow.shown {
    transform: none;
    visibility: visible;
}
div.submitrow > * {
    pointer-events: auto;
}

div#optionspage, div#pluginspage {
    padding-bottom: 200px;
}

p.savemsg {
    margin: 0;
    color: grey;
    font-family: "Silkscreen";
    font-size: var(--font-md);
    text-align: center;
}

p.savemsg.error {
    color: rgb(230, 40, 40);
}

p.savemsg:empty {
    display: none;
}

button.savebtn {
    padding: 0.4em 1.6em;
    border: none;
    border-radius: 2px;
    background: var(--prim-color);
    color: var(--prim-bg);
    font-family: "Silkscreen";
    font-size: calc(var(--font-lg) * 0.75);
    cursor: pointer;
    transition: background 0.15s, box-shadow 0.15s;
}

button.savebtn:hover {
    background: rgb(80, 195, 255);
}

button.savebtn:focus {
    outline: none;
}

button.savebtn:focus-visible {
    box-shadow: 0 0 0 3px white, 0 12px 16px -6px var(--prim-color);
}

button.savebtn.failed {
    animation: wiggle 0.5s ease-in-out, fail-fade 1.5s ease-in;
}

@keyframes wiggle {
    0%, 100% { transform: translateX(0) rotate(0); }
    15%      { transform: translateX(-8px) rotate(-2deg); }
    30%      { transform: translateX(7px) rotate(2deg); }
    45%      { transform: translateX(-5px) rotate(-1.5deg); }
    60%      { transform: translateX(4px) rotate(1deg); }
    75%      { transform: translateX(-2px) rotate(-0.5deg); }
}

@keyframes fail-fade {
    0%, 30% { background: rgb(230, 40, 40); }
    100%    { background: var(--prim-color); }
}

button.savebtn:disabled {
    background: var(--disabled-color);
    cursor: not-allowed;
}

button.savebtn.notice, button.savebtn.notice:hover, button.savebtn.notice:disabled {
    background: none;
    color: var(--prim-color);
    box-shadow: none;
    cursor: default;
}

div#deleterow {
    display: flex;
    justify-content: flex-start;
    padding-top: 60px;
}

button.danger {
    padding: 0.4em 1.6em;
    border: solid 4px var(--danger-color);
    border-radius: 2px;
    background: var(--prim-bg);
    color: var(--danger-color);
    font-family: "Silkscreen";
    font-size: calc(var(--font-lg) * 0.75);
    cursor: pointer;
    transition: background 0.15s, box-shadow 0.15s, opacity 0.15s;
}
button.danger:hover:not(:disabled) {
    background: color-mix(in srgb, var(--danger-color) 15%, var(--prim-bg));
}
button.danger:focus {
    outline: none;
}
button.danger:focus-visible {
    box-shadow: 0 0 0 3px white, 0 12px 16px -6px var(--danger-color);
}
button.danger:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

dialog#deletedialog {
    width: min(820px, calc(100vw - 32px));
    box-sizing: border-box;
    padding: 36px;
    border: solid 4px var(--danger-color);
    border-radius: 2px;
    background: var(--prim-bg);
    color: white;
    font-family: "Silkscreen";
    font-size: var(--font-md);
}
dialog#deletedialog::backdrop {
    background: color-mix(in srgb, var(--prim-bg) 70%, transparent);
}
dialog#deletedialog form {
    display: flex;
    flex-direction: column;
    gap: 16px;
}
p#deletetitle {
    margin: 0 0 6px;
    font-size: calc(var(--font-lg) * 0.6);
    text-align: center;
}
label[for="deleteconfirm"] {
    text-align: center;
}
span#deletename {
    color: var(--danger-color);
    user-select: all;
}
input#deleteconfirm {
    padding: 8px 10px;
    border: solid 4px grey;
    border-radius: 2px;
    background: var(--prim-bg);
    color: white;
    font: inherit;
    transition: color 1s, border-color 0.15s;
}
input#deleteconfirm.match {
    color: var(--danger-color);
}
input#deleteconfirm:focus {
    outline: none;
    border-color: var(--danger-color);
    box-shadow: none;           /* no blue glow from the general input rules */
}
p#deletemsg {
    margin: 0;
    color: var(--danger-color);
    text-align: center;
}
p#deletemsg:empty {
    display: none;
}
dialog#deletedialog button {
    width: 100%;
    font-size: calc(var(--font-lg) * 0.5);
    white-space: nowrap;
}
button#deletecancel {
    margin-top: 24px;           /* space between the input box and the buttons */
}
button#deleteforever {
    transition: color 1s, border-color 1s, opacity 1s, background 0.15s;
}
button#deleteforever:disabled {
    color: white;
    border-color: white;
}
button#deletecancel {
    padding: 0.4em 1.6em;
    border: solid 4px grey;
    border-radius: 2px;
    background: var(--prim-bg);
    color: white;
    font-family: "Silkscreen";
    cursor: pointer;
}
button#deletecancel:hover {
    border-color: white;
}

div#scrollhint {
    position: absolute;
    left: 50%;
    bottom: 50px;
    transform: translateX(-50%);
    pointer-events: none;
    transition: opacity 0.3s;
}

div#scrollhint.gone {
    opacity: 0;
}

div#scrollhint .appear {
    position: relative;
    animation: hint-appear 0.8s ease-out 1s both, hint-bob 3s infinite 1s;
}

/* soft glow behind the arrows */
div#scrollhint .appear::before {
    content: "";
    position: absolute;
    inset: -60%;
    background: radial-gradient(closest-side, rgb(3 165 253 / 0.45), transparent);
    filter: blur(8px);
    z-index: -1;
}

div#scrollhint svg {
    display: block;
    width: 44px;
    height: auto;
    color: var(--prim-color);
}

@keyframes hint-appear {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* slow rise, back down, then a fast drop past the rest point that eases back up to stop */
@keyframes hint-bob {
    0%   { transform: translateY(0); animation-timing-function: ease-in-out; }
    40%  { transform: translateY(-12px); animation-timing-function: ease-in; }
    55%  { transform: translateY(0); animation-timing-function: ease-in; }
    62%  { transform: translateY(14px); animation-timing-function: ease-out; }
    90%, 100% { transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
    div#scrollhint .appear { animation: hint-appear 0.8s ease-out 1s both; }
}

h1#greeting {
    margin: 0;
    padding: 60px 4px 0;
    color: grey;
    font-family: "Silkscreen";
    font-size: var(--font-lg);
    font-weight: 400;
    overflow-wrap: anywhere;    /* long names wrap instead of overflowing */
}

p#loggedout {
    margin: 0;
    padding: 80px 4px 0;
    color: grey;
    font-family: "Silkscreen";
    font-size: var(--font-md);
}
h1#greeting + p#loggedout { padding-top: 24px; }
p#loggedout[hidden] { display: none; }
p#loggedout a { color: var(--prim-color); }

div.serverpickrow { padding: 80px 4px 0; }
select.serverpick {
    max-width: 100%;
    font-size: var(--font-lg);
    text-overflow: ellipsis;
}

span#pageinfo {
    position: fixed;
    right: calc(30px + 8px + 16px);
    bottom: 24px;
    z-index: 20;                /* above the server widgets scrolling under it */
}
span#pageinfo span.tip {
    top: auto;
    bottom: calc(100% + 10px);
    left: auto;
    right: 0;
    transform: none;
    max-width: min(800px, calc(100vw - 120px));
}

/* + (new server), quietly tucked into the content column's top right corner */
div#content { position: relative; }
a#newserver {
    position: absolute;
    top: 24px;
    right: 24px;
    width: calc(var(--font-lg) * 0.9);
    height: calc(var(--font-lg) * 0.9);
    color: grey;
    opacity: 0.6;
    transition: color 0.2s, opacity 0.2s, filter 0.2s;
}
a#newserver svg { display: block; width: 100%; height: 100%; fill: currentColor; }
a#newserver:hover, a#newserver:focus-visible {
    color: var(--prim-color);
    opacity: 1;
    filter: drop-shadow(0 0 6px var(--prim-color));
    outline: none;
}

@property --server-color {
    syntax: "<color>";
    inherits: true;
    initial-value: rgb(3, 165, 253);
}

div.server {
    --server-color: var(--hibernating-color);   /* dashboard.js adds .running / .partial / .stopped */
    --server-faint: color-mix(in srgb, var(--server-color) 60%, transparent);   /* 40% see-through */
    margin-top: 40px;
    transition: --server-color 0.4s;
}
div.server + div.server { margin-top: 24px; }
div.server.running { --server-color: var(--running-color); }
div.server.partial { --server-color: var(--partial-color); }
div.server.stopped { --server-color: var(--stopped-color); }

div.server .head {
    display: flex;              /* addresses on the left, player count on the right */
    align-items: stretch;       /* .side is full height, so the power buttons sit in the corner */
    min-height: 133px;
    box-sizing: border-box;
    border: 1px solid var(--server-faint);
    border-bottom: 4px solid var(--server-color);   /* the thick bottom stays solid */
    border-radius: 2px;
    background-color: var(--prim-bg);
    background-clip: padding-box;   /* keep the lines from showing through the see-through border */
    /* 1px diagonal lines in the status color, 32px apart */
    background-image: repeating-linear-gradient(45deg, var(--server-faint) 0 1px, transparent 1px 32px);
    cursor: pointer;
}

div.server .address {
    flex: 1;
    min-width: 0;
    margin: 12px 16px;
    font-family: "Silkscreen";
    font-size: var(--font-md);
    overflow-wrap: anywhere;
}
div.server .address > div, div.server .players {
    width: fit-content;
    max-width: 100%;
    box-sizing: border-box;
    padding: 2px 6px;
    background-color: var(--prim-bg);
}
div.server .name, div.server .short, div.server .online { color: var(--server-color); }
div.server .domain, div.server .shortdomain, div.server .max { color: grey; }
/* the address changing (start.py --forward's ngrok address): ADDRESS_FADE in dashboard.js */
div.server .address span { transition: opacity 0.5s; }
div.server .address .fading span { opacity: 0; }

div.server .address { align-self: flex-start; }

div.server .side {
    flex: none;
    display: flex;
    flex-direction: column;
    align-items: flex-end;      /* both right aligned */
    justify-content: space-between;     /* players top right, power buttons bottom right */
    gap: 8px;
    margin: 12px 16px 12px 0;
}
div.server .players {
    font-family: "Silkscreen";
    font-size: var(--font-md);
}

div.server .power {
    display: flex;
    align-items: center;        /* the bigger restart button stays centered between the others */
    gap: 3.4px;
    padding: 3.4px;
    background-color: var(--prim-bg);   /* like .players: no lines through it */
    cursor: default;            /* not the head's pointer: clicks here don't open the terminal */
}
div.server .power button {
    display: flex;
    width: calc(var(--font-md) * 1.19);
    height: calc(var(--font-md) * 1.19);
    padding: calc(var(--font-md) * 0.2125);
    box-sizing: border-box;
    border: none;
    border-radius: 2px;
    background: none;
    cursor: pointer;
    transition: opacity 0.4s;
}
div.server .power svg {
    width: 100%;
    height: 100%;
    overflow: visible;          /* the outlines' outer half sits just past the icon's edge */
    transition: transform 0.2s;
}
div.server .power .stop path, div.server .power .start path {
    fill: none;
    stroke: currentColor;
    stroke-width: 4px;
    stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
}
div.server .power .stop { color: var(--stopped-color); }
div.server .power .restart {
    color: var(--partial-color);
    width: calc(var(--font-md) * 1.19 * 1.15 * 1.03);  /* ~18% bigger than stop and start */
    height: calc(var(--font-md) * 1.19 * 1.15 * 1.03);
    padding: calc(var(--font-md) * 0.2125 * 1.15 * 1.03);
}
div.server .power .start { color: var(--running-color); }
div.server .power .restart:not(:disabled):hover svg { transform: rotate(45deg); }
div.server .power .stop:not(:disabled):hover svg,
div.server .power .start:not(:disabled):hover svg { transform: rotate(-45deg); }
div.server .power button:focus-visible { outline: 2px solid currentColor; outline-offset: 1px; }
div.server .power button:disabled {
    opacity: 0.6;
    cursor: default;
    pointer-events: none;       /* a click lands on .power, which doesn't open the terminal */
}

div.server .drawer {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    height: 0;
    overflow: hidden;
    transition: all 0.8s cubic-bezier(0.81, -0.01, 0, 1.42);
}
div.server .terminal {
    --line: 1.4em;
    /* while the bouncy transition overshoots, stretch to fill so it stays attached to the head */
    flex: 1 0 auto;
    padding: 4px 8px;
    background-color: var(--prim-bg);
    /* flush with the head's sides; its thick bottom border is the terminal's top */
    border: 1px solid var(--server-faint);
    border-top: none;
    border-radius: 0 0 2px 2px;
    color: white;
    font-family: "Silkscreen";
    font-size: calc(clamp(13px, 1.3vw, 17px) * var(--font-scale));
    line-height: var(--line);
}
div.server .log {
    max-height: calc(var(--line) * 5);
    overflow-y: auto;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    scrollbar-width: none;
}
div.server .log::-webkit-scrollbar { display: none; }
div.server .log .error { color: var(--stopped-color); }
div.server .prompt {
    display: flex;
    gap: 1ch;
    margin: 0;
}
div.server .terminal.full .prompt {
    padding-top: 2px;           /* padding, not margin, so dashboard.js's height measurement includes it */
    border-top: 1px solid var(--server-faint);
}
div.server .terminal .upper { color: var(--prim-color); }
div.server .field {
    position: relative;
    flex: 1;
    min-width: 0;
}
div.server .mirror {
    position: absolute;
    inset: 0;
    overflow: hidden;
    white-space: pre;
    pointer-events: none;
}
div.server .command {
    position: relative;         /* above the mirror, so clicks and the caret land on the input */
    width: 100%;
    box-sizing: border-box;
    padding: 0;
    border: none;
    border-radius: 0;
    outline: none;
    box-shadow: none;           /* no focus glow from the general input rules */
    background: none;
    color: transparent;         /* the mirror underneath shows the text */
    font: inherit;
    caret-color: white;
}
div.server .command::selection { color: var(--prim-bg); background: white; }

span.greyheading {
    color: grey;
    font-family: "Silkscreen";
    font-size: var(--font-lg);
    text-align: center;
    display: block;
}

/* Verify code for servers whose owner hasn't verified yet (dashboard.js). The x hides it for 2h. */
div#verify-banner {
    position: relative;
    width: 80%;
    margin: auto;
    box-sizing: border-box;
    padding: 5px calc(var(--font-sm) + 16px);   /* room for the x on the right */
    border: 4px solid var(--partial-color);
    border-top: 0;
    border-radius: 0 0 2px 2px;
    background-color: color-mix(in srgb, var(--partial-color) 40%, transparent);
    color: var(--partial-color);
    font-family: "Silkscreen";
    font-size: var(--font-sm);
    line-height: 1.25;
    text-align: center;
}

div#verify-banner[hidden] {
    display: none;
}

div#verify-banner.done {     /* only "Successfully verified ..." lines */
    border-color: var(--running-color);
    background-color: color-mix(in srgb, var(--running-color) 25%, transparent);
    color: var(--running-color);
}

div#verify-banner .code {
    color: white;
}

button#verify-close {
    position: absolute;
    top: 50%;
    right: 8px;
    transform: translateY(-50%);
    width: var(--font-sm);
    height: var(--font-sm);
    padding: 0;
    border: none;
    background: none;
    color: var(--partial-color);
    cursor: pointer;
}

button#verify-close svg {
    display: block;
    width: 100%;
    height: 100%;
    fill: none;
    stroke: currentColor;
    stroke-width: 1px;          /* a thin x */
    vector-effect: non-scaling-stroke;
}

button#verify-close:hover, button#verify-close:focus-visible {
    color: white;
    outline: none;
}

/* Only while the banner shows: the greeting moves up by the banner's height (one line + 10px
   padding + 4px border), keeping its text in line with the menu */
div#verify-banner:not([hidden]) ~ h1#greeting {
    padding-top: calc(60px - 1.25 * var(--font-sm) - 14px);
}

/* Plugins tab: installed plugins, then the rest (dashboard.js). A row opens #plugindialog. */
div#pluginspage span.greyheading {
    margin-top: 60px;
}

div.pluginlist {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-top: 24px;
}

div#pluginspage.loaded div.pluginlist:empty::before {    /* "No plugins installed." etc. */
    content: attr(data-empty);
    color: grey;
    font-family: "Silkscreen";
    font-size: var(--font-sm);
    text-align: center;
}

div.plugin {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    padding: 12px 20px;
    border: none;
    border-left: 4px solid var(--prim-color);
    background: var(--prim-bg);
    color: var(--prim-color);
    font-family: "Silkscreen";
    font-size: var(--font-md);
    cursor: pointer;
}

div.plugin:hover, div.plugin:focus-visible {
    background: white;
    color: var(--prim-bg);
    outline: none;
}

/* Text selected in a highlighted row: back to the normal colours */
div.plugin:hover ::selection, div.plugin:focus-visible ::selection {
    background: var(--prim-bg);
    color: var(--prim-color);
}

span.pluginname {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

button.pluginaction {
    position: relative;
    z-index: 1;                         /* over the name */
    display: flex;
    flex: none;
    margin: -12px -20px -12px 0;        /* the whole right end of the row */
    padding: 12px 20px;
    border: none;
    background: none;
    color: inherit;
    cursor: pointer;
}

/* A bigger hitbox: clicks up to twice its width to the right of it still count */
button.pluginaction::after {
    content: "";
    position: absolute;
    inset: 0 -200% 0 0;
}

/* ...cut off at the window's edge rather than making the page scroll sideways (both: html's
   overflow goes to the window, which can still be scrolled by script; body's then clips for real) */
html:has(div#pluginspage), html:has(div#pluginspage) body {
    overflow-x: clip;
}

@media (max-width: 700px) {
    /* narrow screens: a shadow sets it off from a long name running under it */
    button.pluginaction {
        box-shadow: 0 0 24px 12px black;
    }
    button.pluginaction::after {
        right: -50%;
    }
}

svg.pluginicon {
    flex: none;
    width: calc(var(--font-md) * 0.9);
    height: calc(var(--font-md) * 0.9);
    fill: currentColor;
}

div#installedplugins svg.pluginicon {
    transform: rotate(45deg);           /* the + becomes an x */
}

/* Like the popup after creating a server (index.css): the page behind it blurred, darkened and
   pixelated into 24x24px blocks (#pixelate in dashboard.html) */
dialog#plugindialog {
    box-sizing: border-box;
    flex-direction: column;
    align-items: center;
    gap: 40px;
    width: 84%;
    max-width: 960px;
    min-height: 50%;
    max-height: none;
    margin: auto;
    padding: 30px 20px;
    border: 4px solid var(--prim-color);
    border-radius: 2px;
    background: none;
    isolation: isolate;
    color: var(--prim-color);
    font-family: "Silkscreen";
    font-size: var(--font-md);
    text-align: center;
    overflow: visible;
}

dialog#plugindialog[open] {
    display: flex;
}

dialog#plugindialog::backdrop {
    background: none;
}

dialog#plugindialog::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: rgb(0 0 0 / 0.4);
    backdrop-filter: blur(16px);
    filter: url(#pixelate);
}

span#plugindialogname {
    max-width: 100%;
    padding: 0 calc(var(--font-sm) + 16px);    /* clear of the x */
    box-sizing: border-box;
    font-size: var(--font-lg);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;                         /* one line */
}

span#plugindialogdescription a {               /* links in the options.json HTML */
    color: inherit;
    text-decoration: underline;
}

span#plugindialogdescription a:hover, span#plugindialogdescription a:focus-visible {
    color: white;
}

button#plugindialogclose {
    position: absolute;
    top: 12px;
    right: 12px;
    width: var(--font-sm);
    height: var(--font-sm);
    padding: 0;
    border: none;
    background: none;
    color: var(--prim-color);
    cursor: pointer;
}

button#plugindialogclose svg {
    display: block;
    width: 100%;
    height: 100%;
    fill: none;
    stroke: currentColor;
    stroke-width: 1px;
    vector-effect: non-scaling-stroke;
}

button#plugindialogclose:hover, button#plugindialogclose:focus-visible {
    color: white;
    outline: none;
}

/* Add or Remove: the same blue button either way */
button#plugindialogaction {
    margin-top: auto;
    padding: 0.4em 1.6em;
    border: none;
    border-radius: 2px;
    background: var(--prim-color);
    color: var(--prim-bg);
    font-family: "Silkscreen";
    font-size: calc(var(--font-lg) * 0.75);
    cursor: pointer;
    transition: background 0.15s, box-shadow 0.15s;
}

button#plugindialogaction:hover {
    background: rgb(80, 195, 255);
}

button#plugindialogaction:focus {
    outline: none;
}

button#plugindialogaction:focus-visible {
    box-shadow: 0 0 0 3px white, 0 12px 16px -6px var(--prim-color);
}

svg#filters {
    position: absolute;
    width: 0;
    height: 0;
}
