/* Rexomat: the shared look of the website and the dashboard.
   A well-made machine: a graphite (or, on a light device, light grey) housing, clearly labelled controls, and
   the brand colour (Settings → Branding) only where something is primary, current or switched on. Green, amber
   and red only ever mean "fine", "needs a look" and "wrong". One typeface, Archivo, in two widths: expanded for
   titles and the name, normal for everything else. Surfaces are flat; only what floats (menus, dialogs, toasts)
   has a shadow. Motion only answers what you do, and stops with the device's "reduce motion" setting. */

/* ---------------------------------------------------------------- tokens */
:root {
  /* dark (the default: most people use Discord dark) */
  --bg: #1c1c1f;          /* the page */
  --side: #18181b;        /* the dashboard's menu */
  --surface: #232327;     /* boxes: lists, previews, menus */
  --surface-2: #2a2a2f;   /* hover, a raised part */
  --field: #18181b;       /* inputs sit a little lower than the page */
  --line: #2f2f35;        /* hairlines */
  --line-2: #3e3e46;      /* borders of controls */
  --text: #ececef;
  --text-2: #a8a8b2;      /* explanations */
  --text-3: #8b8b95;      /* the least important text (still 4.5:1 on every surface) */
  --ok: #5cc08a;
  --warn: #e2ad55;
  --bad: #ef7480;
  --info: #8f9cf5;
  --shadow: 0 12px 32px rgb(0 0 0 / .4), 0 0 0 1px var(--line-2);
  --scrim: rgb(0 0 0 / .5);

  /* the brand colour; Settings → Branding can change --accent (and --accent-ink, the text on it) */
  --accent: #ff69b4;
  --accent-ink: #2b0a1d;
  --accent-text: color-mix(in oklab, var(--accent) 72%, white);   /* the colour as text on the page */
  --accent-soft: color-mix(in srgb, var(--accent) 13%, transparent);
  --accent-line: color-mix(in srgb, var(--accent) 50%, transparent);
  --ok-soft: color-mix(in srgb, var(--ok) 12%, transparent);
  --warn-soft: color-mix(in srgb, var(--warn) 12%, transparent);
  --bad-soft: color-mix(in srgb, var(--bad) 12%, transparent);
  --blurple: #5865f2;     /* Discord's own button colour */

  --font: "Archivo", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: ui-monospace, "Cascadia Mono", Consolas, "SF Mono", monospace;
  --wide: 116%;           /* font-stretch of titles */
  --r: 7px;               /* controls */
  --r-lg: 10px;           /* boxes, dialogs */
  --fast: .12s;
  --mid: .2s;
  --ease: cubic-bezier(.2, .7, .3, 1);
  color-scheme: dark;
}
@media (prefers-color-scheme: light) {
  :root {
    --bg: #f2f2f4;
    --side: #e9e9ec;
    --surface: #ffffff;
    --surface-2: #f5f5f7;
    --field: #ffffff;
    --line: #dfdfe4;
    --line-2: #c9c9d1;
    --text: #1b1b1f;
    --text-2: #55555f;
    --text-3: #63636d;
    --ok: #1d8a50;
    --warn: #9c5d06;
    --bad: #c3374a;
    --info: #4652c7;
    --shadow: 0 10px 28px rgb(20 20 35 / .13), 0 0 0 1px var(--line-2);
    --scrim: rgb(20 20 30 / .35);
    --accent-text: color-mix(in oklab, var(--accent) 58%, black);
    --accent-soft: color-mix(in srgb, var(--accent) 12%, transparent);
    color-scheme: light;
  }
}

/* ---------------------------------------------------------------- base */
* { box-sizing: border-box; }
html, body { margin: 0; }
html { -webkit-text-size-adjust: 100%; }
body { background: var(--bg); color: var(--text); font: 400 15px/1.55 var(--font); font-stretch: 100%;
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; font-feature-settings: "kern"; }
a { color: var(--accent-text); text-decoration: none; text-underline-offset: 3px; text-decoration-thickness: 1px; }
a:hover { text-decoration: underline; }
:focus-visible { outline: 2px solid var(--accent-text); outline-offset: 2px; border-radius: 3px; }
::selection { background: color-mix(in srgb, var(--accent) 35%, transparent); }
code, kbd, pre { font-family: var(--mono); }
code { font-size: .87em; background: var(--surface-2); border: 1px solid var(--line); padding: 1px 5px; border-radius: 4px; color: var(--text); }
h1, h2, h3 { margin: 0; line-height: 1.2; font-weight: 650; }
/* titles: the expanded width carries the voice; weight and size stay modest */
.display, h1 { font-stretch: var(--wide); letter-spacing: -.012em; }
.display { font-weight: 650; }
.muted { color: var(--text-2); }
.right { text-align: right; }
.num, time { font-variant-numeric: tabular-nums; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
[hidden] { display: none !important; }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
.skip { position: fixed; z-index: 100; left: 12px; top: -60px; padding: 8px 14px; border-radius: var(--r); background: var(--text);
  color: var(--bg); font-weight: 600; }
.skip:focus { top: 12px; text-decoration: none; }

/* ---------------------------------------------------------------- icons (static/icons.svg, Lucide) */
.ic { width: 17px; height: 17px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round; vertical-align: -3px; }
.ic.sm { width: 15px; height: 15px; vertical-align: -2px; }
.ic.lg { width: 20px; height: 20px; }

/* ---------------------------------------------------------------- buttons */
/* A button says what it does; the primary one of a place is the only filled one. While its form is being
   sent it shows a spinner in place of the label (.is-loading, ui.js), so nothing moves. */
.btn { --spin: var(--text); position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  min-height: 36px; padding: 0 14px; border-radius: var(--r); border: 1px solid var(--line-2);
  font: 600 14px/1.2 var(--font); white-space: nowrap; cursor: pointer; color: var(--text); background: var(--surface);
  transition: background var(--fast), border-color var(--fast), color var(--fast); }
.btn:hover { text-decoration: none; background: var(--surface-2); border-color: var(--text-3); }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; transform: none; }
.btn.primary { --spin: var(--accent-ink); background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.btn.primary:hover:not(:disabled) { background: color-mix(in oklab, var(--accent) 88%, var(--text)); border-color: transparent; }
.btn.ghost { background: transparent; }
.btn.ghost:hover { background: var(--surface-2); }
.btn.quiet { --spin: var(--text-2); background: transparent; border-color: transparent; color: var(--text-2); padding: 0 10px; }
.btn.quiet:hover { color: var(--text); background: var(--surface-2); }
.btn.danger { --spin: var(--bad); background: transparent; border-color: color-mix(in srgb, var(--bad) 50%, transparent); color: var(--bad); }
.btn.danger:hover:not(:disabled) { --spin: #fff; background: var(--bad); border-color: var(--bad); color: #fff; }
.btn.quiet.danger { border-color: transparent; }
.btn.discord { --spin: #fff; background: var(--blurple); border-color: var(--blurple); color: #fff; }
.btn.discord:hover { background: #4752c4; border-color: #4752c4; }
.btn.small { min-height: 30px; padding: 0 10px; font-size: 13px; border-radius: 6px; gap: 6px; }
.btn.big { min-height: 44px; padding: 0 20px; font-size: 15px; }
.btn.full { width: 100%; }
.btn.is-loading { color: transparent !important; pointer-events: none; }
.btn.is-loading > * { visibility: hidden; }
.btn.is-loading::after { content: ""; position: absolute; left: 50%; top: 50%; width: 15px; height: 15px; margin: -7.5px 0 0 -7.5px;
  border-radius: 50%; border: 2px solid var(--spin); border-right-color: transparent; animation: spin .7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.linklike { background: none; border: 0; padding: 0; font: inherit; color: var(--text-2); cursor: pointer; }
.linklike:hover { color: var(--text); text-decoration: underline; text-underline-offset: 3px; }

/* ---------------------------------------------------------------- messages ("Saved", "Couldn't …") */
/* a coloured edge and a mark in front; the text stays in the normal text colour so it's easy to read */
.flash { position: relative; display: block; padding: 11px 14px 11px 40px; border-radius: var(--r); margin: 0 0 16px;
  border: 1px solid var(--line); border-left: 3px solid var(--text-3); background: var(--surface);
  font-size: 14px; line-height: 1.5; color: var(--text); transition: opacity var(--mid); }
.flash::before { content: ""; position: absolute; left: 13px; top: 12px; width: 17px; height: 17px; background: var(--text-3);
  -webkit-mask: var(--flash-ic) center / contain no-repeat; mask: var(--flash-ic) center / contain no-repeat; }
.flash.closable { padding-right: 42px; }
.flash { --flash-ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 11v5M12 8h.01'/%3E%3C/svg%3E"); }
.flash.ok { --flash-ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='m8.5 12.5 2.5 2.5 4.5-5'/%3E%3C/svg%3E");
  border-left-color: var(--ok); background: color-mix(in srgb, var(--ok) 7%, var(--surface)); }
.flash.ok::before { background: var(--ok); }
.flash.error { --flash-ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 7.5v5.5M12 16.5h.01'/%3E%3C/svg%3E");
  border-left-color: var(--bad); background: color-mix(in srgb, var(--bad) 7%, var(--surface)); }
.flash.error::before { background: var(--bad); }
.flash.warn { --flash-ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10.3 4.3 2.6 18a2 2 0 0 0 1.7 3h15.4a2 2 0 0 0 1.7-3L13.7 4.3a2 2 0 0 0-3.4 0Z'/%3E%3Cpath d='M12 9.5v4M12 17h.01'/%3E%3C/svg%3E");
  border-left-color: var(--warn); background: color-mix(in srgb, var(--warn) 7%, var(--surface)); }
.flash.warn::before { background: var(--warn); }
.flash.info { border-left-color: var(--info); }
.flash.info::before { background: var(--info); }
.flash a { color: inherit; text-decoration: underline; text-underline-offset: 3px; }
.flash > .flash-x { position: absolute; right: 6px; top: 6px; width: 28px; height: 28px; display: grid; place-items: center;
  border: 0; border-radius: 6px; background: none; color: var(--text-2); cursor: pointer; font: 500 18px/1 var(--font); }
.flash > .flash-x:hover { color: var(--text); background: var(--surface-2); }
.flash.leaving { opacity: 0; }

/* ---------------------------------------------------------------- avatars / server icons */
.ava { width: 32px; height: 32px; border-radius: 50%; object-fit: cover; flex: none; background: var(--surface-2); }
.letter { display: inline-grid; place-items: center; flex: none; border-radius: 50%; background: var(--surface-2);
  color: var(--text); font: 650 14px/1 var(--font); text-transform: uppercase; }
.server-ico { width: 40px; height: 40px; border-radius: 10px; overflow: hidden; flex: none; display: grid; place-items: center;
  background: var(--surface-2); color: var(--text); font: 650 16px/1 var(--font); }
.server-ico img { width: 100%; height: 100%; object-fit: cover; }

/* online dot: still (a status light, not an animation) */
.dot-status { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--text-3); flex: none; }
.dot-status.on { background: var(--ok); }
.dot-status.off { background: var(--bad); }

/* ---------------------------------------------------------------- tooltip (ui.js, [data-tip]) */
.tip { position: fixed; z-index: 120; top: 0; left: 0; max-width: 260px; padding: 5px 9px; border-radius: 6px;
  background: var(--text); color: var(--bg); font: 500 12.5px/1.4 var(--font); pointer-events: none; opacity: 0;
  transition: opacity var(--fast); }
.tip.show { opacity: 1; }

/* ---------------------------------------------------------------- copy button next to commands (ui.js) */
.copy-wrap { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; vertical-align: middle; }
.copy-wrap > code { overflow-wrap: anywhere; }
.copy-btn { flex: none; display: inline-grid; place-items: center; width: 26px; height: 26px; padding: 0; border-radius: 6px;
  border: 1px solid var(--line-2); background: var(--surface); color: var(--text-2); cursor: pointer;
  transition: color var(--fast), border-color var(--fast), background var(--fast); }
.copy-btn:hover { color: var(--text); border-color: var(--text-3); }
.copy-btn .ic { width: 14px; height: 14px; }
.copy-btn.done { color: var(--ok); border-color: var(--ok); }
.copy-btn.fail { color: var(--warn); border-color: var(--warn); }

/* ---------------------------------------------------------------- toast */
.toast { position: fixed; z-index: 90; left: 50%; bottom: 20px; display: flex; align-items: center; gap: 10px;
  max-width: min(560px, calc(100% - 32px)); padding: 10px 16px 10px 12px; border-radius: var(--r-lg); font-size: 14px;
  background: var(--surface); color: var(--text); box-shadow: var(--shadow);
  transform: translate(-50%, 8px); opacity: 0; pointer-events: none; transition: opacity var(--mid), transform var(--mid) var(--ease); }
.toast.show { opacity: 1; transform: translate(-50%, 0); }
.toast::before { content: ""; flex: none; width: 18px; height: 18px; border-radius: 50%; background: var(--text-3); }
.toast.ok::before { background: var(--ok) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6.5 12.5 3.5 3.5 7.5-8'/%3E%3C/svg%3E") center / 12px no-repeat; }
.toast.error::before { background: var(--bad) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.2' stroke-linecap='round'%3E%3Cpath d='M12 6.5v7M12 17.5h.01'/%3E%3C/svg%3E") center / 12px no-repeat; }

/* ---------------------------------------------------------------- "Are you sure?" dialog (ui.js) */
.confirm { width: min(440px, calc(100% - 32px)); padding: 0; border: 0; border-radius: var(--r-lg);
  background: var(--surface); color: var(--text); box-shadow: var(--shadow); }
.confirm::backdrop { background: var(--scrim); }
.confirm-body { display: flex; gap: 14px; padding: 20px 20px 4px; }
.confirm-ico { flex: none; width: 36px; height: 36px; border-radius: 50%; display: grid; place-items: center;
  background: var(--accent-soft); color: var(--accent-text); }
.confirm.danger .confirm-ico { background: var(--bad-soft); color: var(--bad); }
.confirm h2 { font-size: 16px; font-stretch: 100%; margin: 0 0 4px; }
.confirm p { margin: 0; color: var(--text-2); font-size: 14.5px; line-height: 1.5; overflow-wrap: anywhere; }
.confirm-foot { display: flex; justify-content: flex-end; gap: 8px; padding: 18px 20px 18px; }
.confirm.danger .confirm-ok { --spin: #fff; background: var(--bad); border-color: var(--bad); color: #fff; }
.confirm.danger .confirm-ok:hover { background: color-mix(in oklab, var(--bad) 85%, black); }
.confirm[open] { animation: fade-in var(--mid) ease-out; }
.confirm[open]::backdrop { animation: fade-in var(--mid) ease-out; }
.confirm.closing, .confirm.closing::backdrop { animation: fade-in .12s ease-in reverse forwards; }
@keyframes fade-in { from { opacity: 0; } }

/* ---------------------------------------------------------------- reduced motion */
/* everything that moves is a reaction and already short; with "reduce motion" it happens at once */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0s !important; transition-delay: 0s !important; animation-duration: .01ms !important;
    animation-iteration-count: 1 !important; }
  .btn.is-loading::after, .spinning .spin-ico { animation-duration: .8s !important; animation-iteration-count: infinite !important; }
  .btn:active:not(:disabled) { transform: none; }
}
