/* 1999os theme: tokens, base elements and controls. Every size is a multiple of --px (one art pixel, set by js/boot.js). */

/* "Everyday Standard" by VEXED, CC BY 4.0 (credited on /about). One font pixel is 1/6 em: only use sizes in multiples of 6 art pixels. */
@font-face {
    font-family: "Everyday Standard";
    src: url("../fonts/Everyday_Standard.ttf") format("truetype");
    font-display: swap;
}

/* Themes: one palette each, picked by data-theme on <html> (js/boot.js). Settings previews carry data-theme too, so every palette sets every colour. */
:root, [data-theme="standard"] {
    color-scheme: light;
    --desk: #2f5f6f;
    --face: #c9c3b6;
    --face-light: #e4dfd3;
    --face-hilite: #fffdf6;
    --face-shadow: #857f73;
    --face-dark: #26231f;
    --field: #fffdf6;
    --text: #1d1a17;
    --text-muted: #5d574e;
    --text-disabled: #8f897d;
    --text-accent: #43265f;
    --text-accent-2: #b24f7c;
    --title-a: #43265f;
    --title-b: #b24f7c;
    --title-inactive-a: #6f6a62;
    --title-inactive-b: #aaa498;
    --title-text: #fffdf6;
    --title-inactive-text: #fffdf6;
    --select: #43265f;
    --select-text: #fffdf6;
    --link: #3c2a9c;
    --tooltip: #fff3c4;
    --tooltip-error: #f6d8d3;

    --status-active: #1f6b3a;
    --status-probation: #5c6b14;
    --status-suspended: #a35a00;
    --status-banned: #a3242e;
    --status-deleted: #6f6a62;
}

/* The same desk after dark: charcoal-violet chrome, the title colours left glowing */
[data-theme="midnight"] {
    color-scheme: dark;
    --desk: #1b3540;
    --face: #3b3843;
    --face-light: #4d4957;
    --face-hilite: #6c6778;
    --face-shadow: #24212a;
    --face-dark: #0c0b0f;
    --field: #19171d;
    --text: #e8e2d5;
    --text-muted: #a8a194;
    --text-disabled: #77717f;
    --text-accent: #c7a6f2;
    --text-accent-2: #f08fbb;
    --title-a: #4f2c78;
    --title-b: #b24f7c;
    --title-inactive-a: #2b2930;
    --title-inactive-b: #4a4652;
    --title-text: #fffdf6;
    --title-inactive-text: #a8a194;
    --select: #6a42a3;
    --select-text: #fffdf6;
    --link: #a99cff;
    --tooltip: #403724;
    --tooltip-error: #50262c;

    --status-active: #6fca8d;
    --status-probation: #bccb5e;
    --status-suspended: #eba54c;
    --status-banned: #ff7d86;
    --status-deleted: #8d877b;
}

:root {
    --px: 1px;

    /* Type: the font is drawn on a 6 px em, shown at 2x (each font pixel is 2x2 art pixels).
       An 18 px line puts the baseline on a whole pixel and centres the 12 px capitals. */
    --font-ui: "Everyday Standard", system-ui, sans-serif;
    --font-title: var(--font-ui);
    --font-size: calc(var(--px) * 12);
    --line: calc(var(--px) * 18);
    --font-size-large: calc(var(--px) * 24);
    --line-large: calc(var(--px) * 30);

    /* Spacing */
    --s1: calc(var(--px) * 2);
    --s2: calc(var(--px) * 4);
    --s3: calc(var(--px) * 6);
    --s4: calc(var(--px) * 8);
    --s5: calc(var(--px) * 12);
    --s6: calc(var(--px) * 16);
}

/* Bevels: light top-left, dark bottom-right, two pixels deep. Built from the palette, so redeclared wherever a theme is picked */
:root, [data-theme] {
    --bevel-out: inset calc(var(--px) * -1) calc(var(--px) * -1) var(--face-dark), inset var(--px) var(--px) var(--face-hilite), inset calc(var(--px) * -2) calc(var(--px) * -2) var(--face-shadow), inset calc(var(--px) * 2) calc(var(--px) * 2) var(--face-light);
    --bevel-in: inset calc(var(--px) * -1) calc(var(--px) * -1) var(--face-hilite), inset var(--px) var(--px) var(--face-shadow), inset calc(var(--px) * -2) calc(var(--px) * -2) var(--face-light), inset calc(var(--px) * 2) calc(var(--px) * 2) var(--face-dark);
    --bevel-thin-in: inset calc(var(--px) * -1) calc(var(--px) * -1) var(--face-hilite), inset var(--px) var(--px) var(--face-shadow);
    --bevel-thin-out: inset calc(var(--px) * -1) calc(var(--px) * -1) var(--face-shadow), inset var(--px) var(--px) var(--face-hilite);
}

*, *::before, *::after {
    box-sizing: border-box;
}

html, body {
    margin: 0;
    height: 100%;
}

body {
    background: var(--desk);
    color: var(--text);
    font-family: var(--font-ui);
    font-size: var(--font-size);
    line-height: var(--line);
    -webkit-font-smoothing: none;
    font-smooth: never;
    text-rendering: optimizeSpeed;
    /* The font has no bold; a faked one would smear the pixels */
    font-synthesis: none;
}

img, .icon, .glyph {
    image-rendering: pixelated;
}

h1, h2, h3, h4 {
    font-family: var(--font-title);
    font-size: var(--font-size);
    line-height: var(--line);
    margin: 0 0 var(--s3);
}

h1 {
    font-size: var(--font-size-large);
    line-height: var(--line-large);
}

h2 {
    font-weight: bold;
}

p {
    margin: 0 0 var(--s4);
}

a {
    color: var(--link);
}

a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible, [tabindex]:focus-visible {
    outline: var(--px) dotted var(--text);
    outline-offset: calc(var(--px) * -4);
}

hr {
    border: 0;
    height: calc(var(--px) * 2);
    box-shadow: inset 0 var(--px) var(--face-shadow), inset 0 calc(var(--px) * -1) var(--face-hilite);
    margin: var(--s4) 0;
}

code, .mono {
    font-family: ui-monospace, monospace;
    font-size: var(--font-size);
}

/* The time loop's cycle after 1999: the font has no superscript digits, so it's the font at its native size, raised to the top of the year */
sup.cycle {
    margin-left: var(--px);
    font-size: calc(var(--px) * 6);
    line-height: 0;
    vertical-align: calc(var(--px) * 5);
}

/* Icons: sprite sheets of 32 cells in a row; pick a cell with --i */
.icon {
    display: inline-block;
    flex: none;
    width: calc(var(--px) * 32);
    height: calc(var(--px) * 32);
    background: url("../img/icons-32.png") no-repeat;
    background-size: calc(var(--px) * 1024) calc(var(--px) * 32);
    background-position: calc(var(--px) * -32 * var(--i, 0)) 0;
}

.icon.small {
    width: calc(var(--px) * 16);
    height: calc(var(--px) * 16);
    background-image: url("../img/icons-16.png");
    background-size: calc(var(--px) * 512) calc(var(--px) * 16);
    background-position: calc(var(--px) * -16 * var(--i, 0)) 0;
}

.i-logo { --i: 0; }
.i-logout { --i: 1; }
.i-admin { --i: 2; }
.i-settings { --i: 3; }
.i-user { --i: 4; }
.i-invite { --i: 5; }
.i-incident { --i: 6; }
.i-growth { --i: 7; }
.i-audit { --i: 8; }
.i-info { --i: 9; }
.i-warning { --i: 10; }
.i-error { --i: 11; }
.i-question { --i: 12; }
.i-system { --i: 13; }
.i-key { --i: 14; }
.i-clock { --i: 15; }
.i-mail { --i: 16; }
.i-chat { --i: 17; }
.i-forum { --i: 18; }
.i-news { --i: 19; }

/* Placeholder until slot 18 is drawn: delete this rule once the sheets have the forum icon */
.icon.i-forum {
    background-color: var(--title-a);
    box-shadow: inset calc(var(--px) * -2) calc(var(--px) * -2) 0 var(--face-shadow);
}

/* Placeholder until slot 19 is drawn: delete this rule once the sheets have the news icon */
.icon.i-news {
    background-color: var(--title-b);
    box-shadow: inset calc(var(--px) * -2) calc(var(--px) * -2) 0 var(--face-shadow);
}

.glyph {
    display: inline-block;
    width: calc(var(--px) * 8);
    height: calc(var(--px) * 8);
    /* A stencil: the art gives the shape and the text colour fills it, so glyphs follow the theme and grey out on disabled buttons */
    background: currentColor;
    mask: url("../img/glyphs.png") no-repeat;
    mask-size: calc(var(--px) * 128) calc(var(--px) * 8);
    mask-position: calc(var(--px) * -8 * var(--g, 0)) 0;
}

.g-close { --g: 0; }
.g-minimize { --g: 1; }
.g-maximize { --g: 2; }
.g-restore { --g: 3; }
.g-check { --g: 4; }
.g-dot { --g: 5; }
.g-down { --g: 6; }
.g-right { --g: 7; }
.g-up { --g: 8; }
.g-left { --g: 9; }
.g-plus { --g: 10; }
.g-minus { --g: 11; }

/* Buttons */
button, .button {
    font: inherit;
    color: var(--text);
    background: var(--face);
    border: 0;
    border-radius: 0;
    box-shadow: var(--bevel-out);
    min-width: calc(var(--px) * 75);
    min-height: calc(var(--px) * 24);
    padding: var(--s1) var(--s4);
    cursor: pointer;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--s2);
}

button:active:not(:disabled), .button:active, button.pressed {
    box-shadow: var(--bevel-in);
    padding: calc(var(--px) * 3) calc(var(--px) * 7) var(--px) calc(var(--px) * 9);
}

button:disabled {
    color: var(--text-disabled);
    text-shadow: var(--px) var(--px) var(--face-hilite);
    cursor: default;
}

button.default {
    outline: var(--px) solid var(--face-dark);
    outline-offset: 0;
}

button.link {
    background: none;
    box-shadow: none;
    min-width: 0;
    min-height: 0;
    padding: 0;
    color: var(--link);
    text-decoration: underline;
}

/* Fields */
input:not([type]), input[type=text], input[type=email], input[type=password], input[type=search], input[type=number], input[type=tel], input[type=datetime-local], select, textarea {
    font: inherit;
    color: var(--text);
    background: var(--field);
    border: 0;
    border-radius: 0;
    box-shadow: var(--bevel-in);
    padding: calc(var(--px) * 3) var(--s2);
    min-height: calc(var(--px) * 24);
    width: 100%;
}

input:disabled, input[readonly], select:disabled, textarea:disabled {
    background: var(--face);
    color: var(--text-muted);
}

textarea {
    resize: vertical;
    min-height: calc(var(--px) * 64);
}

/* The arrow is four one-pixel rows (7, 5, 3, 1 wide) so it stays crisp without another sprite */
select {
    appearance: none;
    padding-right: calc(var(--px) * 20);
    background-image:
        linear-gradient(var(--text), var(--text)),
        linear-gradient(var(--text), var(--text)),
        linear-gradient(var(--text), var(--text)),
        linear-gradient(var(--text), var(--text));
    background-repeat: no-repeat;
    background-size: calc(var(--px) * 7) var(--px), calc(var(--px) * 5) var(--px), calc(var(--px) * 3) var(--px), var(--px) var(--px);
    background-position:
        right calc(var(--px) * 6) top calc(50% - var(--px) * 2),
        right calc(var(--px) * 7) top calc(50% - var(--px) * 1),
        right calc(var(--px) * 8) top 50%,
        right calc(var(--px) * 9) top calc(50% + var(--px) * 1);
}

input[type=checkbox], input[type=radio] {
    appearance: none;
    width: calc(var(--px) * 13);
    height: calc(var(--px) * 13);
    margin: 0 var(--s2) 0 0;
    background: var(--field);
    box-shadow: var(--bevel-in);
    vertical-align: middle;
    display: inline-grid;
    place-content: center;
    flex: none;
}

input[type=radio] {
    border-radius: 50%;
}

input[type=checkbox]:checked::after, input[type=radio]:checked::after {
    content: "";
    width: calc(var(--px) * 8);
    height: calc(var(--px) * 8);
    background: var(--text);
    mask: url("../img/glyphs.png") no-repeat;
    mask-size: calc(var(--px) * 128) calc(var(--px) * 8);
    mask-position: calc(var(--px) * -32) 0;
}

input[type=radio]:checked::after {
    mask-position: calc(var(--px) * -40) 0;
}

label {
    display: block;
    margin-bottom: var(--s1);
}

/* Box sits on the first line when the text wraps */
label.inline {
    display: flex;
    align-items: flex-start;
}

label.inline > input[type=checkbox], label.inline > input[type=radio] {
    margin-top: calc((var(--line) - var(--px) * 13) / 2);
}

.field {
    margin-bottom: var(--s4);
}

.field-hint {
    color: var(--text-muted);
    margin-top: var(--s1);
}

.validation-message, .validation-errors, .error-text {
    color: var(--status-banned);
    margin: var(--s1) 0 0;
    padding: 0;
    list-style: none;
}

.status-message {
    padding: var(--s3) var(--s4);
    margin-bottom: var(--s4);
    box-shadow: var(--bevel-thin-in);
    background: var(--tooltip);
}

.status-message.error {
    background: var(--tooltip-error);
}

/* Group boxes */
fieldset, .group {
    border: 0;
    margin: var(--s5) 0 var(--s4);
    padding: var(--s5) var(--s4) var(--s4);
    box-shadow: inset 0 0 0 var(--px) var(--face-shadow), inset var(--px) var(--px) 0 var(--px) var(--face-hilite);
    position: relative;
    min-width: 0;
}

legend, .group > .group-title {
    position: absolute;
    top: calc(var(--px) * -9);
    left: var(--s3);
    background: var(--face);
    padding: 0 var(--s1);
}

.button-row {
    display: flex;
    gap: var(--s3);
    justify-content: flex-end;
    flex-wrap: wrap;
    margin-top: var(--s4);
}

.button-row.left {
    justify-content: flex-start;
}

.muted {
    color: var(--text-muted);
}

.sunken {
    background: var(--field);
    box-shadow: var(--bevel-in);
    padding: var(--s1);
}

/* Window chrome, shared by the desktop and by the standalone dialog pages */
.window {
    background: var(--face);
    box-shadow: var(--bevel-out);
    padding: calc(var(--px) * 3);
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.titlebar {
    display: flex;
    align-items: center;
    gap: var(--s2);
    height: calc(var(--px) * 22);
    padding: 0 var(--s1) 0 var(--s1);
    background: linear-gradient(90deg, var(--title-inactive-a), var(--title-inactive-b));
    color: var(--title-inactive-text);
    font-family: var(--font-title);
    font-weight: bold;
    flex: none;
    user-select: none;
    touch-action: none;
}

.window.active > .titlebar, .dialog-page .titlebar, .titlebar.active {
    background: linear-gradient(90deg, var(--title-a), var(--title-b));
    color: var(--title-text);
}

.titlebar .title {
    /* Tall enough that clipping for the ellipsis never cuts accents or descenders */
    line-height: calc(var(--px) * 24);
    flex: 1;
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.titlebar button {
    min-width: 0;
    min-height: 0;
    width: calc(var(--px) * 16);
    height: calc(var(--px) * 16);
    padding: 0;
}

.titlebar button:active {
    padding: calc(var(--px) * 2) 0 0 calc(var(--px) * 2);
}

.titlebar button + button.close {
    margin-left: var(--s1);
}

.window-body {
    flex: 1;
    min-height: 0;
    overflow: auto;
    padding: var(--s4);
}

/* Standalone pages (login, signup, account management) render as one dialog on an empty desktop */
.dialog-page {
    min-height: 100%;
    display: grid;
    place-items: center;
    padding: var(--s6);
}

.dialog-page > .window {
    width: min(100%, calc(var(--px) * 440));
}

.dialog-page > .window.wide {
    width: min(100%, calc(var(--px) * 640));
}

/* Native modal dialogs (the leaving-1999os warning) wear the same chrome as the desktop's message boxes */
dialog.window {
    border: 0;
    color: var(--text);
    width: min(calc(100% - var(--s6)), calc(var(--px) * 360));
    max-width: none;
}

dialog.window:not([open]) {
    display: none;
}

dialog.window::backdrop {
    background: transparent;
}

.leave-url {
    overflow-wrap: anywhere;
}

.dialog-banner {
    height: calc(var(--px) * 56);
    margin: calc(var(--px) * -8) calc(var(--px) * -8) var(--s4);
    background: var(--title-a) url("../img/logon-banner.png") no-repeat left center;
    background-size: calc(var(--px) * 320) calc(var(--px) * 56);
}

.dialog-icon-row {
    display: flex;
    gap: var(--s5);
    align-items: flex-start;
}

.dialog-icon-row > :last-child {
    flex: 1;
    min-width: 0;
}

/* Tabs */
.tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 0;
    padding-left: var(--s1);
    position: relative;
    z-index: 1;
}

.tabs button, .tabs .button {
    min-width: 0;
    min-height: 0;
    padding: var(--s1) var(--s4) var(--s2);
    margin-top: var(--s1);
    box-shadow: inset var(--px) var(--px) var(--face-hilite), inset calc(var(--px) * -1) 0 var(--face-dark), inset calc(var(--px) * -2) 0 var(--face-shadow);
}

.tabs button.selected, .tabs .button.selected {
    margin-top: 0;
    margin-bottom: calc(var(--px) * -2);
    padding-bottom: calc(var(--px) * 6);
    background: var(--face);
}

.tab-panel {
    box-shadow: var(--bevel-out);
    padding: var(--s5) var(--s4) var(--s4);
    min-height: 0;
}

/* Tables (list views) */
.table-wrap {
    background: var(--field);
    box-shadow: var(--bevel-in);
    padding: calc(var(--px) * 2);
    overflow: auto;
    max-width: 100%;
}

table.list {
    border-collapse: collapse;
    width: 100%;
}

table.list th {
    position: sticky;
    top: 0;
    text-align: left;
    font-weight: normal;
    background: var(--face);
    box-shadow: var(--bevel-thin-out);
    padding: var(--s1) var(--s3);
    white-space: nowrap;
}

table.list td {
    padding: var(--s1) var(--s3);
    vertical-align: top;
}

table.list tr.clickable {
    cursor: pointer;
}

table.list tr.clickable:hover td, table.list tr.selected td {
    background: var(--select);
    color: var(--select-text);
}

table.list tr.selected a, table.list tr.clickable:hover a {
    color: var(--select-text);
}

.status {
    white-space: nowrap;
}

.status-Active { color: var(--status-active); }
.status-Probation { color: var(--status-probation); }
.status-Suspended { color: var(--status-suspended); font-weight: bold; }
.status-Banned { color: var(--status-banned); font-weight: bold; }
.status-Deleted { color: var(--status-deleted); font-style: italic; }

.severity-Info { color: var(--text-muted); }
.severity-Warning { color: var(--status-suspended); }
.severity-Serious { color: var(--status-banned); font-weight: bold; }

.retracted {
    text-decoration: line-through;
    color: var(--text-disabled);
}

/* Embedded account pages (inside the Settings window) drop the desktop and the outer frame */
html.embedded body {
    background: var(--face);
}

html.embedded .dialog-page {
    display: block;
    place-items: normal;
    padding: 0;
}

html.embedded .dialog-page > .window {
    width: auto;
    box-shadow: none;
    padding: 0;
}

html.embedded .dialog-page > .window > .titlebar, html.embedded .dialog-banner {
    display: none;
}

/* Settings already has tabs, so the account sections become a list box on the left. It wraps above the page when too narrow. */
html.embedded .manage {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s4);
}

html.embedded .manage > .tabs {
    flex: none;
    flex-direction: column;
    flex-wrap: nowrap;
    padding: calc(var(--px) * 2);
    background: var(--field);
    box-shadow: var(--bevel-in);
}

html.embedded .manage > .tabs .button, html.embedded .manage > .tabs .button:active {
    justify-content: flex-start;
    margin: 0;
    padding: var(--s1) var(--s3);
    background: none;
    box-shadow: none;
    white-space: nowrap;
}

html.embedded .manage > .tabs .button.selected {
    background: var(--select);
    color: var(--select-text);
}

html.embedded .manage > .tab-panel {
    flex: 1 1 calc(var(--px) * 200);
    min-width: 0;
    padding: 0;
    box-shadow: none;
}

/* Classes from the stock Identity pages, mapped onto the theme */
.form-floating, .mb-3 {
    display: flex;
    flex-direction: column;
    margin-bottom: var(--s4);
}

.form-floating > label {
    order: -1;
}

.form-floating > input::placeholder {
    color: transparent;
}

.alert, .text-info {
    padding: var(--s3) var(--s4);
    margin-bottom: var(--s4);
    box-shadow: var(--bevel-thin-in);
    background: var(--tooltip);
}

.alert-danger {
    background: var(--tooltip-error);
}

.text-danger {
    color: var(--status-banned);
}

.w-100 {
    width: 100%;
}

.recovery-code {
    font-family: ui-monospace, monospace;
}

button.link + .status {
    margin-left: var(--s2);
}
