﻿* { box-sizing: border-box; }

/* The hidden attribute has to win over any display rule we set on an element.
   Without this, anything like `.menu-drawer { display: flex }` beats the user
   agent's `[hidden] { display: none }`, so a "closed" panel stays laid out and
   invisible-but-clickable off the side of the page. */
[hidden] { display: none !important; }

:root {
  --bg: #080a11;
  --bg-soft: #11151f;
  --panel: #141926;
  --panel-2: #1a2030;
  --border: #232b3e;
  --text: #e6e9f0;
  /* --muted is body text on glass, so it has to clear 4.5:1 against the
     brightest thing behind it. Measured worst case is ~rgb(45,48,56). */
  --muted: #9aa3b8;
  --accent: #6c8cff;
  --accent-2: #8fb0ff;
  --danger: #ff5c6c;
  --ok: #37d67a;
  --radius: 16px;
  --radius-sm: 10px;
  --mono: "Cascadia Code", Consolas, "Courier New", monospace;
  --code-fs: 13.5px;
  --zoom: 100%;
  --input-bg: #0a0d13;
  --toast-bg: rgba(20, 25, 38, 0.92);

  /* ---------- glass system ----------
     Every elevated surface is a translucent tint plus a blur, so the aurora
     and the animated background bleed through instead of being painted over.
     A hairline "top light" and a soft ambient shadow do the rest of the work
     that a flat fill used to do. Kept as tokens so light mode only has to
     override this block. */
  --glass: rgba(255, 255, 255, 0.045);
  --glass-2: rgba(255, 255, 255, 0.075);
  --glass-blur: 20px;
  --glass-sat: 150%;
  --glass-line: rgba(255, 255, 255, 0.09);
  --glass-line-2: rgba(255, 255, 255, 0.16);
  /* The opaque-ish floor under the tint. Glass needs something to be *glassy
     over* — a 4% white tint on its own is just see-through, and drawer text
     over a bright background like `warp` would lose contrast. These derive from
     --bg-soft so they re-tint themselves in light mode with no extra rule. */
  --glass-base: color-mix(in srgb, var(--bg-soft) 58%, transparent);
  --glass-base-strong: color-mix(in srgb, var(--bg-soft) 84%, transparent);
  /* the 1px highlight along a surface's top edge — this is what actually
     sells the "pane of glass" read at a glance */
  --glass-light: rgba(255, 255, 255, 0.16);
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3), 0 4px 12px rgba(0, 0, 0, 0.22);
  --shadow: 0 2px 4px rgba(0, 0, 0, 0.28), 0 10px 30px rgba(0, 0, 0, 0.3);
  --shadow-lg: 0 8px 20px rgba(0, 0, 0, 0.34), 0 30px 70px rgba(0, 0, 0, 0.44);
  --glow: 0 0 0 1px rgba(108, 140, 255, 0.28), 0 6px 22px rgba(108, 140, 255, 0.24);
  --glow-strong: 0 0 0 1px rgba(108, 140, 255, 0.5), 0 10px 34px rgba(108, 140, 255, 0.42);

  /* aurora palette. a1/a2 track the account's own accent choice (set inline
     per user by _bg.ejs) so personalization still reaches gradients and glow;
     a3 is a fixed mint that stays distinct from the blues/violets. */
  --a1: var(--accent);
  --a2: var(--accent-2);
  --a3: #2ee6c5;
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);

  /* lets the browser paint native widgets (scrollbars, date pickers, range
     thumbs) in the theme you picked instead of flashing the OS default */
  color-scheme: dark;
}

html[data-theme="light"] { color-scheme: light; }

::selection {
  background: color-mix(in srgb, var(--a2) 38%, transparent);
  color: var(--text);
}

/* Only show focus rings for keyboard users: mouse clicks stay clean, but tabbing
   through the drawer, tabs and forms now has a clear trail. The ring is an
   accent glow rather than a flat outline so it reads on top of glass panels. */
:focus-visible {
  outline: 2px solid var(--accent-2);
  outline-offset: 2px;
  border-radius: 6px;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 26%, transparent);
}

html { zoom: var(--zoom); }

html[data-theme="light"] {
  --bg: #eef1f8;
  --bg-soft: #e9edf5;
  --panel: #ffffff;
  --panel-2: #f0f3f9;
  --border: #d4dbea;
  --text: #1c2436;
  /* On light glass the muted grey has to clear 4.5:1 too. #66708a measured
     ~4.3:1 and #5a6479 ~3.3:1 once the canvas bleeds through the pane, so the
     muted tone is deliberately darker than the old palette. */
  --muted: #4d5666;
  --input-bg: #ffffff;
  --toast-bg: rgba(255, 255, 255, 0.96);

  /* Light mode glass needs a much higher floor than dark mode. The canvas
     backgrounds are dark and saturated, and at 0.55 opacity over a light page
     they composite to a mid grey — translucent panes then sit on that grey and
     muted body text drops to ~3:1. So light panes are nearly opaque white and
     take their depth from the shadow scale instead. */
  --glass: rgba(255, 255, 255, 0.62);
  --glass-2: rgba(255, 255, 255, 0.8);
  --glass-blur: 16px;
  --glass-sat: 160%;
  --glass-line: rgba(16, 24, 48, 0.1);
  --glass-line-2: rgba(16, 24, 48, 0.16);
  --glass-base: color-mix(in srgb, #ffffff 90%, transparent);
  --glass-base-strong: color-mix(in srgb, #ffffff 95%, transparent);
  --glass-light: rgba(255, 255, 255, 0.9);
  --shadow-sm: 0 1px 2px rgba(20, 30, 60, 0.07), 0 3px 10px rgba(20, 30, 60, 0.06);
  --shadow: 0 1px 3px rgba(20, 30, 60, 0.08), 0 8px 24px rgba(20, 30, 60, 0.09);
  --shadow-lg: 0 6px 16px rgba(20, 30, 60, 0.1), 0 24px 56px rgba(20, 30, 60, 0.14);
  --glow: 0 0 0 1px rgba(76, 120, 255, 0.22), 0 4px 16px rgba(76, 120, 255, 0.16);
  --glow-strong: 0 0 0 1px rgba(76, 120, 255, 0.4), 0 8px 26px rgba(76, 120, 255, 0.26);
}
/* The canvas effects are painted for dark pages. On light they are dialled well
   back, both so the page does not turn muddy grey and so glass panes sitting on
   top of them keep enough contrast for body text. */
html[data-theme="light"] .bg-fx { opacity: 0.22; }
html[data-theme="light"] .access-item:hover { background: rgba(0, 0, 0, 0.05); }
html[data-theme="light"] .access-item:has(input:checked) {
  background: rgba(76, 156, 255, 0.14);
  color: #1d4fa8;
}
html[data-theme="light"] .btn-ghost:hover { background: rgba(0, 0, 0, 0.05); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

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

body {
  background:
    radial-gradient(1000px 500px at 80% -10%, rgba(108, 140, 255, 0.16), transparent 60%),
    radial-gradient(800px 400px at 10% 110%, rgba(55, 214, 122, 0.08), transparent 60%),
    var(--bg);
  color: var(--text);
  font-family: "Segoe UI", system-ui, -apple-system, Roboto, sans-serif;
  line-height: 1.55;
}

/* ---------- background layer ---------- */
.bg-fx {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  zoom: calc(100% / var(--zoom));
}

/* Aurora: slow, blurred colour masses sitting *under* the canvas background.
   Glass surfaces above it pick the glow up through their translucency, which
   is what makes the panes read as glass instead of grey plastic. It is
   deliberately subtle — the 26 canvas backgrounds are the user's explicit
   choice and must stay legible on top of it.

   Performance: everything is painted into ONE element so it is a single
   blurred layer (one rasterization per reload, no extra blur passes for the
   circles), and only `transform` animates so the drift never repaints it. */
.aurora {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  zoom: calc(100% / var(--zoom));
  background:
    radial-gradient(46% 52% at 16% 18%, color-mix(in srgb, var(--a1) 58%, transparent), transparent 68%),
    radial-gradient(44% 46% at 84% 26%, color-mix(in srgb, var(--a2) 46%, transparent), transparent 70%);
  filter: blur(72px);
  opacity: 0.42;
  animation: aurora-drift 64s var(--ease) infinite alternate;
}
.aurora::before,
.aurora::after {
  content: '';
  position: absolute;
  border-radius: 50%;
}
.aurora::before {
  width: 44%;
  height: 44%;
  left: 6%;
  top: 48%;
  background: radial-gradient(circle, color-mix(in srgb, var(--a3) 42%, transparent), transparent 66%);
}
.aurora::after {
  width: 38%;
  height: 38%;
  right: 4%;
  top: 6%;
  background: radial-gradient(circle, color-mix(in srgb, var(--a1) 40%, transparent), transparent 66%);
}

@keyframes aurora-drift {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to { transform: translate3d(2%, 1.5%, 0) scale(1.08); }
}

/* Light mode: the same masses, but far weaker. At full strength a blue/violet
   wash over white turns the page lavender, drags muted text under 4.5:1 and
   makes the light theme look like a filter over the dark one. */
html[data-theme="light"] .aurora {
  opacity: 0.16;
  filter: blur(86px);
}

/* ---------- background picker ---------- */
/* the picker itself is a section inside the menu drawer now, so only the grid
   and swatches need rules here */
.bg-picker-grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 8px;
}
/* two columns inside the drawer: the swatch names are words, not just dots */
.menu-section .bg-picker-grid { grid-template-columns: 1fr 1fr; }

.bg-swatch {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  padding: 8px 4px;
  border-radius: 10px;
  border: 1px solid var(--glass-line);
  background: var(--bg-soft);
  color: var(--muted);
  font-size: 11px;
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s, transform 0.15s;
}
.bg-swatch:hover { border-color: var(--accent); color: var(--text); }
.bg-swatch.active {
  border-color: var(--accent);
  color: var(--text);
  background: rgba(108, 140, 255, 0.12);
}
.swatch {
  width: 34px;
  height: 24px;
  border-radius: 6px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  display: block;
}
.sw-constellation { background: radial-gradient(circle at 30% 30%, #1c2540, #0b0e14 70%); }
.sw-aurora { background: linear-gradient(180deg, #4c4cff, #37d67a 45%, #ff7896); }
.sw-matrix { background: radial-gradient(circle at 50% 30%, #37d67a, #0a1a10 75%); }
.sw-stars { background: radial-gradient(circle at 30% 25%, #2a3550, #0b0e14 75%); }
.sw-waves { background: linear-gradient(180deg, #151c30, #2c4a8a 55%, #37d67a); }
.sw-ripples { background: radial-gradient(circle at 50% 50%, transparent 30%, #6c8cff 32%, transparent 46%); }
.sw-bubbles { background: radial-gradient(circle at 30% 40%, #a0b9ff, #0e1420 70%); }
.sw-plasma { background: linear-gradient(120deg, #606cff, #785aff 40%, #ff7896); }
.sw-grid { background: linear-gradient(180deg, #160b1e, #4a1030 55%, #ff5e8c); }
.sw-fireflies { background: radial-gradient(circle at 25% 40%, #ffe066 0 8%, transparent 9%), linear-gradient(180deg, #141c2c, #0b0e14); }
.sw-rain { background: linear-gradient(180deg, #17233d 0 12%, transparent 12%, #17233d 0 24%, transparent 24%, #17233d 0 36%, transparent 36%), radial-gradient(circle at 50% 30%, #2a3550, #080c14 80%); }
.sw-smoke { background: radial-gradient(ellipse at 50% 70%, rgba(160,165,180,0.5) 0 18%, transparent 30%), linear-gradient(180deg, #0d1016, #0a0d12); }
.sw-pulse { background: radial-gradient(circle at 50% 50%, #ff5e8c 0 10%, transparent 12%, #ff5e8c 0 24%, transparent 26%, #606cff 0 36%, transparent 38%), linear-gradient(180deg, #0c0f16, #0a0d14); }
.sw-meteor { background: linear-gradient(120deg, transparent 30%, #c0cfff 42% 48%, transparent 55%), radial-gradient(circle at 20% 20%, #273351, #080b12 75%); }
.sw-hexgrid { background: repeating-linear-gradient(60deg, #0d1220 0 10px, #16203a 10px 11px), repeating-linear-gradient(-60deg, transparent 0 10px, rgba(108,140,255,0.35) 10px 11px), repeating-linear-gradient(0deg, transparent 0 19px, rgba(108,140,255,0.22) 19px 20px); }
.sw-helix { background: repeating-linear-gradient(48deg, rgba(108,140,255,0.85) 0 2px, transparent 2px 9px), repeating-linear-gradient(-48deg, rgba(255,94,140,0.85) 0 2px, transparent 2px 9px), linear-gradient(180deg, #0b1020, #0a0d14); }
.sw-circuit { background: linear-gradient(#3ec6a0, #3ec6a0) 0 0/100% 1px no-repeat, linear-gradient(90deg, #2f8f77, #2f8f77) 0 0/1px 100% no-repeat, repeating-linear-gradient(0deg, transparent 0 11px, rgba(62,198,160,0.4) 11px 12px), repeating-linear-gradient(90deg, transparent 0 11px, rgba(62,198,160,0.4) 11px 12px), #081410; }
.sw-warp { background: repeating-conic-gradient(from 0deg at 50% 50%, rgba(200,216,255,0.75) 0deg 1deg, transparent 1deg 5deg), radial-gradient(circle at 50% 50%, #dbe6ff, #0a0e1a 62%); }
.sw-bokeh { background: radial-gradient(circle at 22% 32%, rgba(143,176,255,0.55) 0 12%, transparent 13%), radial-gradient(circle at 72% 26%, rgba(255,120,180,0.45) 0 9%, transparent 10%), radial-gradient(circle at 58% 74%, rgba(120,220,255,0.4) 0 14%, transparent 15%), linear-gradient(180deg, #10141f, #0a0d13); }
.sw-tunnel { background: repeating-radial-gradient(circle at 50% 50%, rgba(143,176,255,0.5) 0 2px, transparent 2px 11px), linear-gradient(160deg, #241a4a, #0a0d14 70%); }
.sw-flat { background: #080a11; }






a { color: var(--accent-2); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ---------- layout ---------- */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 24px;
  border-bottom: 1px solid var(--glass-line);
  /* Glass header: a translucent tint plus a strong blur and a touch of
     saturation so whatever is scrolling underneath reads as colour, not fog.
     `blur()` here is also what pins the aurora into the header's glow. */
  background: linear-gradient(180deg, var(--glass-2), var(--glass)), var(--glass-base);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  box-shadow: 0 1px 0 var(--glass-light) inset, 0 8px 24px rgba(0, 0, 0, 0.18);
  position: sticky;
  top: 0;
  z-index: 10;
}

.brand {
  color: var(--text);
  font-weight: 800;
  font-size: 19px;
  letter-spacing: -0.2px;
  display: inline-flex;
  align-items: center;
}
/* the mark gets the accent gradient so the logo reads as the one lit element
   in the header; the glow keeps it from looking like flat text */
.brand-mark {
  margin-right: 7px;
  font-size: 21px;
  line-height: 1;
  background: linear-gradient(135deg, var(--a1), var(--a2) 55%, var(--a3));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 0 10px color-mix(in srgb, var(--a1) 55%, transparent));
}

/* ---------- suggestions tab ---------- */
.suggest-wrap {
  display: flex;
  flex-direction: column;
  gap: 18px;
  max-width: 760px;
}
.suggest-intro { margin: 0; }
.suggest-intro .browse-sub { margin-bottom: 0; }

.suggest-form { display: flex; flex-direction: column; gap: 10px; }
.suggest-input {
  min-height: 110px;
  resize: vertical;
  line-height: 1.55;
  font-family: inherit;
}
.suggest-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.suggest-hint { margin: 0; }

.suggest-list { display: flex; flex-direction: column; gap: 12px; }
.suggest-item { padding: 15px 18px; }
.suggest-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 8px;
}
.suggest-by {
  font-weight: 700;
  font-size: 14px;
  color: var(--text);
}
/* your own suggestions stand out slightly from everyone else's */
.suggest-by-admin { color: var(--accent-2); }
.suggest-body {
  margin: 0;
  color: var(--text);
  font-size: 14.5px;
  line-height: 1.6;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* ---------- menu drawer ---------- */
/* The whole top bar collapses into one button. The drawer is a real dialog so
   it can trap focus, and it slides in on transform (cheaper than animating
   left/top and it stays off the main thread). */
.menu-btn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 8px 14px 8px 11px;
  border-radius: 12px;
  border: 1px solid var(--glass-line-2);
  background: var(--glass-2);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  box-shadow: 0 1px 0 var(--glass-light) inset, var(--shadow-sm);
  color: var(--text);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.16s ease, border-color 0.16s ease, transform 0.16s ease, box-shadow 0.16s ease;
}
.menu-btn:hover {
  background: var(--glass);
  border-color: color-mix(in srgb, var(--a1) 55%, var(--glass-line-2));
  transform: translateY(-1px);
  box-shadow: 0 1px 0 var(--glass-light) inset, var(--glow);
}

.menu-btn-icon {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  width: 16px;
}
.menu-btn-icon i {
  display: block;
  height: 2px;
  width: 100%;
  border-radius: 2px;
  background: currentColor;
  transition: transform 0.2s ease, opacity 0.2s ease;
}
.menu-btn[aria-expanded="true"] .menu-btn-icon i:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.menu-btn[aria-expanded="true"] .menu-btn-icon i:nth-child(2) { opacity: 0; }
.menu-btn[aria-expanded="true"] .menu-btn-icon i:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* stop the page behind the drawer from scrolling away under your finger */
html.menu-open, html.menu-open body { overflow: hidden; }

.menu-scrim {
  position: fixed;
  inset: 0;
  background: rgba(4, 6, 11, 0.55);
  -webkit-backdrop-filter: blur(6px) saturate(120%);
  backdrop-filter: blur(6px) saturate(120%);
  opacity: 0;
  transition: opacity 0.24s ease;
  z-index: 90;
}
.menu-scrim.show { opacity: 1; }
html[data-theme="light"] .menu-scrim { background: rgba(30, 38, 66, 0.28); }

.menu-drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(360px, 100%);
  display: flex;
  flex-direction: column;
  /* A real frosted pane: translucent tint, heavy blur, saturation boost so the
     aurora and canvas behind it show through as colour rather than grey. */
  background: linear-gradient(180deg, var(--glass-2), var(--glass) 40%), var(--glass-base-strong);
  -webkit-backdrop-filter: blur(28px) saturate(170%);
  backdrop-filter: blur(28px) saturate(170%);
  border-left: 1px solid var(--glass-line-2);
  /* the inset highlight is the detail that makes the edge look like glass */
  box-shadow: 1px 0 0 var(--glass-light) inset, -28px 0 70px rgba(0, 0, 0, 0.5);
  transform: translateX(100%);
  transition: transform 0.28s cubic-bezier(0.22, 0.8, 0.3, 1);
  z-index: 95;
}
html[data-theme="light"] .menu-drawer {
  box-shadow: 1px 0 0 var(--glass-light) inset, -20px 0 50px rgba(20, 30, 60, 0.16);
}
.menu-drawer.show { transform: translateX(0); }

.menu-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 18px;
  border-bottom: 1px solid var(--glass-line);
  box-shadow: 0 1px 0 var(--glass-light) inset;
  flex: 0 0 auto;
}
.menu-head-title {
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  /* gradient wordmark for the drawer title */
  background: linear-gradient(120deg, var(--a1), var(--a2) 60%, var(--a3));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.menu-close {
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  font-size: 22px;
  line-height: 1;
  border-radius: 10px;
  border: 1px solid var(--glass-line);
  background: var(--glass);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  /* an icon glyph, so it needs the full 4.5:1 body-text contrast — --muted
     measures ~4.3:1 on this pane */
  color: var(--text);
  cursor: pointer;
  transition: background 0.16s ease, color 0.16s ease, transform 0.16s ease, border-color 0.16s ease;
}
.menu-close:hover { background: var(--glass-2); color: var(--text); border-color: var(--glass-line-2); transform: rotate(90deg); }

.menu-body {
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 14px 14px 20px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.menu-links { display: flex; flex-direction: column; gap: 4px; }

/* rows slide in one after the other, so the drawer reads as one motion */
.menu-item {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  padding: 11px 12px;
  border-radius: 12px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--text);
  font-size: 14.5px;
  font-weight: 500;
  text-align: left;
  cursor: pointer;
  opacity: 0;
  transform: translateX(14px);
  transition: background 0.16s var(--ease), border-color 0.16s var(--ease), transform 0.16s var(--ease), box-shadow 0.16s var(--ease);
}
.menu-item:hover {
  background: var(--glass-2);
  border-color: var(--glass-line);
  text-decoration: none;
  color: var(--text);
  box-shadow: 0 1px 0 var(--glass-light) inset;
}
.menu-item:active { transform: scale(0.99); }
.menu-item-ico {
  flex: 0 0 auto;
  width: 22px;
  text-align: center;
  font-size: 15px;
  /* icons pick up the accent gradient and glow slightly on hover */
  background: linear-gradient(135deg, var(--a1), var(--a2) 70%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.menu-item:hover .menu-item-ico {
  filter: drop-shadow(0 0 8px color-mix(in srgb, var(--a1) 60%, transparent));
}
.menu-item-label { flex: 1 1 auto; }
.menu-item-chip { margin-left: auto; }
.menu-item-form { display: flex; }

.menu-btn, .menu-drawer .menu-item { animation: none; }
.menu-drawer.show .menu-item {
  animation: menuItemIn 0.34s cubic-bezier(0.22, 0.8, 0.3, 1) forwards;
  animation-delay: calc(var(--i, 0) * 45ms + 60ms);
}
@keyframes menuItemIn {
  from { opacity: 0; transform: translateX(14px); }
  to { opacity: 1; transform: translateX(0); }
}

.menu-section {
  border: 1px solid var(--glass-line);
  border-radius: 14px;
  background: linear-gradient(160deg, var(--glass-2), var(--glass) 55%), var(--glass-base);
  -webkit-backdrop-filter: blur(--glass-blur) saturate(var(--glass-sat));
  backdrop-filter: blur(--glass-blur) saturate(var(--glass-sat));

  padding: 13px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.menu-section-title {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.7px;
  text-transform: uppercase;
  color: var(--muted);
}
.menu-section-title .menu-item-ico { width: auto; font-size: 13px; }

/* pinned outside the scrolling body so logging out is always one click away,
   however long the settings and background lists get */
.menu-foot {
  flex: 0 0 auto;
  padding: 10px 14px;
  border-top: 1px solid var(--border);
  background: var(--bg-soft);
}
.menu-logout { color: var(--danger); cursor: pointer; }
.menu-item-form:hover .menu-item-ico { color: var(--danger); }
.inline-form { display: inline; margin: 0; }



.wrap {
  max-width: 900px;
  margin: 0 auto;
  padding: 32px 24px 64px;
}
.wrap.narrow { max-width: 720px; }
.center { text-align: center; }

.hero {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 28px;
}
.hero h1 { margin: 0 0 4px; font-size: clamp(22px, 3.2vw, 30px); letter-spacing: -0.4px; }
.muted { color: var(--muted); }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 9px 18px;
  border-radius: 11px;
  border: 1px solid transparent;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
  background: transparent;
  /* position: relative so .btn-primary's ::before glow can sit under the label
     without a wrapper element */
  position: relative;
  isolation: isolate;
  transition: background 0.15s var(--ease), border-color 0.15s var(--ease), color 0.15s var(--ease), box-shadow 0.2s var(--ease), transform 0.15s var(--ease);
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(1px) scale(0.99); }

/* Primary reads as a lit surface: gradient fill, inner top light, and a
   separate blurred ::before halo that lifts off the button on hover. */
.btn-primary {
  background: linear-gradient(135deg, var(--a1), var(--a2) 55%, var(--a3));
  color: #0b0e14;
  font-weight: 700;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.34) inset, 0 6px 20px rgba(108, 140, 255, 0.32);
}
.btn-primary::before {
  content: '';
  position: absolute;
  inset: -2px;
  z-index: -1;
  border-radius: inherit;
  background: linear-gradient(135deg, var(--a1), var(--a2));
  filter: blur(10px);
  opacity: 0;
  transition: opacity 0.2s var(--ease);
}
.btn-primary:hover {
  filter: brightness(1.08) saturate(1.1);
  text-decoration: none;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.42) inset, 0 10px 28px rgba(108, 140, 255, 0.45);
}
.btn-primary:hover::before { opacity: 0.75; }

/* Ghost buttons are now glass panes rather than outlined boxes. */
.btn-ghost {
  border-color: var(--glass-line-2);
  color: var(--text);
  background: var(--glass);
  box-shadow: 0 1px 0 var(--glass-light) inset;
}
.btn-ghost:hover {
  background: var(--glass-2);
  border-color: color-mix(in srgb, var(--a1) 45%, var(--glass-line-2));
  text-decoration: none;
  box-shadow: 0 1px 0 var(--glass-light) inset, var(--glow);
}

/* code mask / reveal (logging tab) — masked codes render as bullets; the
   toggle row uses a ghost button next to the cell. ● is width-stable. */
.mask-cell { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.login-log-masked { font-family: "Cascadia Code", Consolas, "Courier New", monospace; font-size: 13px; color: var(--accent-2); letter-spacing: .15em; user-select: none; }
.btn-xs { padding: 3px 9px; font-size: 12px; line-height: 1.4; border-radius: 8px; }

.btn-danger {
  border-color: color-mix(in srgb, var(--danger) 45%, transparent);
  color: var(--danger);
  background: color-mix(in srgb, var(--danger) 8%, transparent);
}
.btn-danger:hover {
  background: color-mix(in srgb, var(--danger) 16%, transparent);
  border-color: var(--danger);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--danger) 30%, transparent), 0 6px 18px color-mix(in srgb, var(--danger) 26%, transparent);
}

.btn-block { width: 100%; }
.btn-sm { padding: 5px 12px; font-size: 13px; border-radius: 8px; }

/* ---------- cards ---------- */
.card-list { display: grid; gap: 14px; }

.card {
  display: block;
  position: relative;
  isolation: isolate;
  /* translucent pane so the aurora glows through each card */
  background: linear-gradient(160deg, var(--glass-2), var(--glass) 55%), var(--glass-base);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  border: 1px solid var(--glass-line);
  border-radius: var(--radius);
  padding: 18px 20px;
  color: var(--text);
  text-decoration: none;
  box-shadow: var(--shadow);
  transition: border-color 0.18s var(--ease), transform 0.18s var(--ease), box-shadow 0.18s var(--ease), background 0.18s var(--ease);
}
/* the hairline highlight along the top edge — this is what actually sells the
   "pane of glass" read at a glance */
.card::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  border-radius: var(--radius) var(--radius) 0 0;
  background: linear-gradient(90deg, transparent, var(--glass-light), transparent);
  pointer-events: none;
}
/* a second, wider glow that only appears on hover */
.card::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: radial-gradient(120% 80% at 50% 0%, color-mix(in srgb, var(--a1) 22%, transparent), transparent 70%);
  opacity: 0;
  transition: opacity 0.22s var(--ease);
  pointer-events: none;
}
.card:hover {
  border-color: color-mix(in srgb, var(--a1) 50%, var(--glass-line));
  text-decoration: none;
  transform: translateY(-3px);
  box-shadow: var(--shadow-lg);
}
.card:hover::after { opacity: 1; }

.card-head { display: flex; align-items: center; gap: 10px; }
.card-title { font-weight: 700; font-size: 17px; }
.card-excerpt { color: var(--muted); margin: 8px 0 14px; font-size: 14px; }
.card-meta { display: flex; gap: 12px; align-items: center; font-size: 13px; color: var(--muted); }

.lock-badge {
  color: var(--accent-2);
  border: 1px solid color-mix(in srgb, var(--a1) 45%, transparent);
  background: color-mix(in srgb, var(--a1) 12%, transparent);
  border-radius: 999px;
  padding: 2px 10px;
  font-size: 12px;
  white-space: nowrap;
}

.chip {
  font-size: 12px;
  color: var(--muted);
  border: 1px solid var(--glass-line);
  background: var(--glass);
  padding: 2px 10px;
  border-radius: 999px;
  white-space: nowrap;
}
.chip-lock { color: var(--accent-2); border-color: color-mix(in srgb, var(--a1) 45%, transparent); background: color-mix(in srgb, var(--a1) 10%, transparent); }
.chip-ok { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 45%, transparent); background: color-mix(in srgb, var(--ok) 10%, transparent); }
.chip-bad { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 45%, transparent); background: color-mix(in srgb, var(--danger) 10%, transparent); }
.chip-admin {
  color: var(--accent-2);
  border-color: color-mix(in srgb, var(--a2) 45%, transparent);
  background: color-mix(in srgb, var(--a2) 12%, transparent);
}

.run-link {
  color: var(--accent);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
}
.run-link:hover { text-decoration: underline; }

.row-paused td { opacity: 0.55; }

.empty-state {
  text-align: center;
  padding: 60px 0;
  border: 1px dashed var(--glass-line-2);
  border-radius: var(--radius);
  background: var(--glass);
  color: var(--muted);
}

/* ---------- paper / code ---------- */
.paper {
  background: linear-gradient(160deg, var(--glass-2), var(--glass) 55%), var(--glass-base);
  -webkit-backdrop-filter: blur(--glass-blur) saturate(var(--glass-sat));
  backdrop-filter: blur(--glass-blur) saturate(var(--glass-sat));
  border: 1px solid var(--glass-line);
  border-radius: var(--radius);
  box-shadow: var(--shadow), 0 1px 0 var(--glass-light) inset;
  padding: 24px;
}
.paper-head h1 { margin: 0 0 6px; font-size: 24px; }
.paper-meta { display: flex; gap: 12px; align-items: center; color: var(--muted); font-size: 13px; }

.toolbar { display: flex; align-items: center; gap: 14px; margin: 20px 0 0; }
.copy-status { color: var(--ok); font-weight: 600; opacity: 0; transition: opacity 0.2s; }
.copy-status.show { opacity: 1; }

.run-output {
  background: var(--input-bg);
  border: 1px solid var(--glass-line);
  border-radius: 10px;
  padding: 18px;
  overflow-x: auto;
  font-family: var(--mono);
  font-size: var(--code-fs);
  line-height: 1.6;
  margin: 16px 0 0;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--text);
}

.loader-hint { margin: 20px 0 0; border: 1px dashed var(--border); border-radius: 10px; padding: 16px; }
.loader-hint-head { color: var(--ok); font-weight: 600; margin-bottom: 6px; }
.loader-snippet {
  background: var(--input-bg);
  border: 1px solid var(--glass-line);
  border-radius: 8px;
  padding: 12px;
  overflow-x: auto;
  font-family: var(--mono);
  font-size: 12.5px;
  line-height: 1.6;
  white-space: pre-wrap;
  word-break: break-word;
}

.code-block {
  background: var(--input-bg);
  border: 1px solid var(--glass-line);
  border-radius: 10px;
  padding: 18px;
  overflow-x: auto;
  font-family: var(--mono);
  font-size: var(--code-fs);
  line-height: 1.6;
  margin: 16px 0 0;
  white-space: pre-wrap;
  word-break: break-word;
}

/* ---------- table ---------- */
.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--glass-line);
  border-radius: var(--radius);
  background: linear-gradient(180deg, var(--glass-2), var(--glass) 55%), var(--glass-base);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  box-shadow: var(--shadow);
}
.table { width: 100%; border-collapse: collapse; background: transparent; }
.table th, .table td { text-align: left; padding: 12px 16px; border-bottom: 1px solid var(--glass-line);
  /* Auto table layout never shrinks below a cell's min-content, so one long
     unbreakable run (a space-free suggestion, a token) blew a column wide and
     pushed the table past its plate. `anywhere` is what lowers min-content -
     `break-word` does not. */
  overflow-wrap: anywhere; }
.table th {
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  /* the header cell sits on a darker slab so small uppercase --muted text keeps
     its 4.5:1 — it is not "large" text at 12px, whatever its weight */
  background: color-mix(in srgb, var(--bg-soft) 85%, transparent);
  backdrop-filter: blur(6px);
  position: sticky;
  top: 0;
}
.table tr:last-child td { border-bottom: none; }
.table tr:hover td { background: color-mix(in srgb, var(--a1) 7%, transparent); }
.cell-title { font-weight: 600; }
.ta-r { text-align: right !important; }
.table .inline-form { margin-left: 6px; }

/* ---------- forms ---------- */
.form-title { margin-top: 0; }
.form-card {
  background: linear-gradient(160deg, var(--glass-2), var(--glass) 55%), var(--glass-base);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  border: 1px solid var(--glass-line);
  border-radius: var(--radius);
  box-shadow: var(--shadow), 0 1px 0 var(--glass-light) inset;
  padding: 24px;
  display: grid;
  gap: 10px;
}
.form-card label { font-weight: 600; font-size: 13px; color: var(--muted); }

.text-input, .code-input-lg, .settings-row select, .settings-row input[type="text"] {
  width: 100%;
  /* inputs are a slightly *darker* glass than panels, so the recessed well
     reads as recessed */
  background: color-mix(in srgb, var(--input-bg) 82%, transparent);
  border: 1px solid var(--glass-line);
  border-radius: 11px;
  color: var(--text);
  padding: 12px 14px;
  font-size: 14px;
  font-family: inherit;
  transition: border-color 0.16s var(--ease), box-shadow 0.16s var(--ease), background 0.16s var(--ease);
}
.text-input::placeholder, .code-input-lg::placeholder { color: color-mix(in srgb, var(--muted) 78%, transparent); }
.text-input:hover, .code-input-lg:hover { border-color: var(--glass-line-2); }
.text-input:focus, .code-input-lg:focus, .settings-row select:focus, .settings-row input[type="text"]:focus {
  outline: none;
  border-color: color-mix(in srgb, var(--a1) 70%, transparent);
  /* focus reads as an inner glow, not just a coloured border */
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--a1) 22%, transparent), 0 0 18px color-mix(in srgb, var(--a1) 18%, transparent);
}

.code-input-lg {
  font-family: var(--mono);
  font-size: var(--code-fs);
  line-height: 1.6;
  resize: vertical;
}

/* the changelog entry field reuses the big code textarea but is prose, not code */
.textarea-prose {
  font-family: inherit;
  font-size: 15px;
  line-height: 1.6;
  resize: vertical;
}

.check-row { display: flex; align-items: center; gap: 10px; color: var(--text) !important; cursor: pointer; margin-top: 4px; }
.check-row input { width: 17px; height: 17px; accent-color: var(--accent); }

.form-actions { display: flex; gap: 10px; margin-top: 8px; }

/* ---------- login ---------- */
.auth-body {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  padding: 24px;
}
.auth-card-wrap { width: 100%; max-width: 400px; }

.auth-card {
  background: linear-gradient(165deg, var(--glass-2), var(--glass) 50%), var(--glass-base-strong);
  -webkit-backdrop-filter: blur(34px) saturate(180%);
  backdrop-filter: blur(34px) saturate(180%);
  border: 1px solid var(--glass-line-2);
  border-radius: 20px;
  padding: 40px 32px;
  text-align: center;
  box-shadow: var(--shadow-lg), 0 1px 0 var(--glass-light) inset;
  animation: rise 0.35s ease-out;
}

.auth-icon { font-size: 34px; margin-bottom: 6px; }
.auth-card h1 { font-size: 22px; margin: 8px 0 4px; }
.auth-card .muted { margin: 0 0 18px; }

.code-input {
  width: 100%;
  background: var(--input-bg);
  border: 1px solid var(--glass-line);
  border-radius: 10px;
  color: var(--text);
  text-align: center;
  font-size: 16px;
  letter-spacing: 4px;
  padding: 14px;
  margin-bottom: 14px;
}
.code-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(108, 140, 255, 0.15); }

.back-link { display: inline-block; margin-top: 16px; color: var(--muted); font-size: 14px; }

.alert {
  background: rgba(255, 92, 108, 0.12);
  border: 1px solid rgba(255, 92, 108, 0.4);
  color: var(--danger);
  border-radius: 10px;
  padding: 10px 14px;
  font-size: 14px;
  margin-bottom: 14px;
}

.shake { animation: shake 0.4s; }

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

@keyframes rise {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes shake {
  10%, 90% { transform: translateX(-2px); }
  20%, 80% { transform: translateX(4px); }
  30%, 50%, 70% { transform: translateX(-6px); }
  40%, 60% { transform: translateX(6px); }
}

/* ---------- live "viewing now" presence rail ---------- */
.viewing-rail { min-width: 0; }
.viewing-rail { background: linear-gradient(160deg, var(--glass-2), var(--glass) 55%), var(--glass-base);
  -webkit-backdrop-filter: blur(--glass-blur) saturate(var(--glass-sat));
  backdrop-filter: blur(--glass-blur) saturate(var(--glass-sat));
 border: 1px solid var(--glass-line); border-radius: 12px; padding: 14px; }
.rail-title { margin: 0 0 10px; font-size: 13px; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); }
.viewer-list { display: flex; flex-direction: column; gap: 8px; }
.viewer-chip {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--bg-soft); border: 1px solid var(--glass-line);
  border-radius: 999px; padding: 5px 11px; font-size: 13px; width: max-content;
}
.viewer-chip::before { content: '●'; color: #2fbf71; font-size: 10px; }
.viewing-empty { color: var(--muted); font-size: 13px; line-height: 1.5; }

/* pinned + read-only chips on note cards + detail pane */
.pin-badge, .ro-chip { font-size: 12px; border-radius: 999px; padding: 2px 8px; flex: none; }
.pin-badge { background: #fff4cc; color: #7a5b00; }
.ro-chip { background: #ffe9e6; color: #a13a2a; }
.card-head { display: flex; align-items: center; gap: 6px; }
.card-title { flex: 1 1 auto; min-width: 0; }

/* detail pane read-only treatment */
.detail-actions .btn-ghost[disabled] { opacity: .5; pointer-events: none; }

@media (max-width: 620px) {
  .hero { flex-direction: column; align-items: flex-start; }
  .wrap { padding-left: 16px; padding-right: 16px; }
  .paper, .form-card { padding: 18px; }
  .code-form { flex-direction: column; align-items: stretch; }
}

/* ---------- browse: left list + right detail ---------- */
.browse-title { margin: 0 0 4px; font-size: clamp(20px, 2.8vw, 26px); letter-spacing: -0.3px; }
.browse-sub { margin: 0 0 18px; }

.browse {
  display: grid;
  grid-template-columns: 300px 1fr 220px;
  gap: 18px;
  align-items: start;
}

.note-list-pane { min-width: 0; }

.search-bar { margin-bottom: 12px; }

.note-list {
  display: grid;
  gap: 12px;
  max-height: calc(100vh - 250px);
  overflow-y: auto;
  padding-right: 4px;
  padding-bottom: 8px;
}

.note-item {
  padding: 12px 14px;
  min-width: 0;
}
.note-item .card-title {
  font-size: 15px;
  overflow-wrap: anywhere;
}
.note-item .card-excerpt {
  font-size: 13px;
  line-height: 1.45;
  margin: 5px 0 9px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.note-item .card-meta {
  font-size: 12px;
  gap: 8px;
  flex-wrap: wrap;
}

.note-item.active {
  border-color: var(--accent);
  background: rgba(108, 140, 255, 0.07);
  box-shadow: 0 0 0 1px rgba(108, 140, 255, 0.45);
}

.no-results { text-align: center; padding: 16px 0; }

.note-detail-pane {
  position: sticky;
  top: 86px;
  background: linear-gradient(165deg, var(--glass-2), var(--glass) 55%), var(--glass-base);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  border: 1px solid var(--glass-line);
  border-radius: var(--radius);
  padding: 26px 28px;
  min-height: 300px;
  box-shadow: var(--shadow-lg), 0 1px 0 var(--glass-light) inset;
}

/* Collapse the browse grid to a single column on narrow screens. This has to
   come after the base .browse / .note-detail-pane rules above, otherwise the
   later declarations win at equal specificity and the phone keeps the
   three-column desktop layout, which is far wider than the screen. */
@media (max-width: 820px) {
  .browse { grid-template-columns: 1fr; }
  .note-list { max-height: 45vh; }
  .note-detail-pane { position: static; min-height: 0; }
  .viewing-rail { order: 3; }
}


.detail-empty {
  min-height: 250px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  text-align: center;
}
.detail-empty-mark { font-size: 26px; color: var(--accent-2); opacity: 0.45; }
.detail-empty p { margin: 0; }

.detail-title { margin: 0 0 12px; font-size: 24px; line-height: 1.25; }
.detail-title + .lock-badge { margin-bottom: 12px; display: inline-block; }
.detail-desc { margin: 0 0 14px; font-size: 15px; color: var(--text); max-width: 640px; }
.detail-meta { display: flex; align-items: center; gap: 12px; color: var(--muted); font-size: 13px; margin-bottom: 20px; }
.detail-actions { display: flex; gap: 10px; flex-wrap: wrap; }

.btn-copy-quick { min-width: 90px; }
.btn-copy-done { border-color: rgba(55, 214, 122, 0.5); color: var(--ok); }

/* ---------- handmade copy button ---------- */
.btn-hand {
  font-family: "Segoe Print", "Bradley Hand", "Comic Sans MS", cursive;
  font-weight: 600;
  font-size: 15px;
  letter-spacing: 0.4px;
  color: var(--text);
  background: transparent;
  border: 2px solid rgba(108, 140, 255, 0.5);
  border-radius: 14px 8px 13px 10px;
  box-shadow: 3px 4px 0 rgba(0, 0, 0, 0.45), inset 0 -3px 0 rgba(108, 140, 255, 0.12);
  transform: rotate(-1.6deg);
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.btn-hand:hover {
  transform: rotate(-1.6deg) translateY(-2px) scale(1.02);
  box-shadow: 5px 7px 0 rgba(0, 0, 0, 0.45);
  text-decoration: none;
}
.btn-hand:active {
  transform: rotate(-1deg) translateY(1px);
  box-shadow: 1px 2px 0 rgba(0, 0, 0, 0.45);
}
.hand-label {
  padding: 0 6px;
  border-radius: 4px;
  background-image: linear-gradient(
    100deg,
    rgba(255, 214, 80, 0) 2%,
    rgba(255, 214, 80, 0.32) 10%,
    rgba(255, 214, 80, 0.32) 90%,
    rgba(255, 214, 80, 0) 98%
  );
}

.paper-desc {
  color: var(--text);
  margin: 2px 0 10px;
  font-size: 15px;
  max-width: 640px;
}

/* ---------- extra buttons / badges ---------- */
.btn-lg { padding: 13px 20px; font-size: 15px; border-radius: 12px; }

.btn-admin {
  background: linear-gradient(135deg, #b57bff, #e58ff0);
  color: #130a1f;
  box-shadow: 0 6px 20px rgba(181, 123, 255, 0.3);
}
.btn-admin:hover { filter: brightness(1.08); text-decoration: none; }

.chip-admin {
  color: #d7b6ff;
  border-color: rgba(181, 123, 255, 0.4);
  background: rgba(181, 123, 255, 0.12);
}

.small { font-size: 13px; }
.auth-foot { margin-top: 18px; display: flex; justify-content: center; gap: 6px; font-size: 13px; }

/* ---------- login screen flair ---------- */
.auth-top { display: flex; flex-direction: column; align-items: center; gap: 10px; margin-bottom: 6px; }
.auth-badge {
  font-size: 11px;
  letter-spacing: 3px;
  color: var(--accent-2);
  border: 1px solid rgba(108, 140, 255, 0.35);
  background: rgba(108, 140, 255, 0.08);
  padding: 4px 12px;
  border-radius: 999px;
}
.auth-badge-admin {
  color: #e3c2ff;
  border-color: rgba(181, 123, 255, 0.4);
  background: rgba(181, 123, 255, 0.1);
}
.auth-icon-admin { color: #e0b3ff; }

.auth-orb {
  position: fixed;
  border-radius: 50%;
  filter: blur(90px);
  opacity: 0.5;
  pointer-events: none;
  z-index: 0;
}
.auth-orb-a {
  width: 420px; height: 420px;
  background: radial-gradient(circle, rgba(108, 140, 255, 0.55), transparent 70%);
  top: -120px; left: -120px;
}
.auth-orb-b {
  width: 460px; height: 460px;
  background: radial-gradient(circle, rgba(181, 123, 255, 0.4), transparent 70%);
  bottom: -160px; right: -140px;
}
.admin-body .auth-orb-a { background: radial-gradient(circle, rgba(181, 123, 255, 0.5), transparent 70%); }

.auth-body { position: relative; }
.auth-card-wrap { position: relative; z-index: 1; }

/* ---------- changelog ---------- */
/* The entries open in a centred overlay that reads like a note: a title bar, a
   scrollable body, and no separate page to navigate to. Dismissing it is the
   backdrop, Escape, or the same trigger that opened it. */

.changelog-trigger {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 12px;
  background: var(--glass-2);
  border: 1px solid var(--glass-line);
  border-radius: 999px;
  color: var(--text);
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}
.changelog-trigger:hover { background: rgba(108, 140, 255, 0.1); border-color: var(--accent); }

/* sign-in screen: no nav bar to hang off, so the trigger sits in the corner */
.changelog-trigger-auth {
  position: fixed;
  top: 18px;
  right: 18px;
  z-index: 3;
}

.changelog-overlay {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: rgba(6, 8, 13, 0.72);
  backdrop-filter: blur(3px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.changelog-overlay[hidden] { display: none; }

/* ---- safe mode (Ctrl+X brake) ----
   deliberately mirrors the changelog overlay classes so the two menus look
   like the same thing */
.safe-overlay { z-index: 1200; }
.safe-overlay[hidden] { display: none; }

.safe-card {
  width: min(460px, 100%);
  max-height: 88vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  background: linear-gradient(165deg, var(--glass-2), var(--glass) 50%), var(--glass-base-strong);
  -webkit-backdrop-filter: blur(30px) saturate(180%);
  backdrop-filter: blur(30px) saturate(180%);
  border: 1px solid var(--glass-line-2);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg), 0 1px 0 var(--glass-light) inset;
  animation: modal-in 0.18s ease-out;
}
.safe-overlay[data-active="1"] .safe-card { border-color: #f0a03c; box-shadow: var(--shadow-lg), 0 0 0 1px rgba(240,160,60,.4), 0 0 34px rgba(240,160,60,.22); }

.safe-body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px 20px 18px;
  overflow-y: auto;
}
.safe-lead { margin: 0; color: var(--text); font-size: 14px; }
.safe-code { width: 100%; }
.safe-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}
.safe-msg { margin: 0; font-size: 13px; min-height: 1em; }
.safe-msg-bad { color: #ff8080; }
.safe-hint { margin: 0; }

/* the sign-in card is visibly locked while safe mode is on, not just refusing
   the code after a submit */
.auth-card.is-locked .code-input,
.auth-card.is-locked button[type="submit"] { opacity: 0.5; }
.auth-card.is-locked { cursor: not-allowed; }

.changelog-card {
  width: min(640px, 100%);
  max-height: 82vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: linear-gradient(165deg, var(--glass-2), var(--glass) 50%), var(--glass-base-strong);
  -webkit-backdrop-filter: blur(30px) saturate(180%);
  backdrop-filter: blur(30px) saturate(180%);
  border: 1px solid var(--glass-line-2);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg), 0 1px 0 var(--glass-light) inset;
  animation: modal-in 0.18s ease-out;
}

.changelog-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
}

.changelog-title {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin: 0;
  font-size: 17px;
  font-weight: 600;
}

.changelog-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 3px rgba(108, 140, 255, 0.18);
  flex: none;
}

.changelog-count {
  margin-left: auto;
  font-size: 12px;
  color: var(--muted);
  border: 1px solid var(--glass-line);
  border-radius: 999px;
  padding: 1px 8px;
  min-width: 22px;
  text-align: center;
}
.changelog-count:empty { display: none; }

/* the note-style body: one column of entries that scrolls on its own */
.changelog-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 10px 8px 14px;
}

.changelog-list { list-style: none; margin: 0; padding: 0; }

.changelog-item {
  display: flex;
  gap: 14px;
  align-items: baseline;
  padding: 12px 12px;
  border-radius: 10px;
}
.changelog-item + .changelog-item { border-top: 1px solid var(--border); }

.changelog-when {
  flex: none;
  width: 66px;
  font-size: 12px;
  color: var(--muted);
}

.changelog-text {
  flex: 1;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--text);
  overflow-wrap: anywhere;
  /* an entry is written like a note body, so keep the author's line breaks */
  white-space: pre-wrap;
}

.changelog-empty {
  margin: 0;
  padding: 18px 12px;
  font-size: 13px;
  color: var(--muted);
}

.changelog-nav-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  flex: none;
}

@media (max-width: 620px) {
  .changelog-overlay { padding: 12px; align-items: flex-end; }
  .changelog-card { max-height: 88vh; }
  .changelog-item { flex-direction: column; gap: 4px; }
  .changelog-when { width: auto; }
  .changelog-trigger-auth { top: 12px; right: 12px; }
}

/* ---------- admin panels ---------- */
.wrap.wide { max-width: 1080px; }
.mono { font-family: "Cascadia Code", Consolas, "Courier New", monospace; font-size: 13px; }

.panel {
  background: linear-gradient(160deg, var(--glass-2), var(--glass) 55%), var(--glass-base);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  border: 1px solid var(--glass-line);
  border-radius: var(--radius);
  box-shadow: var(--shadow), 0 1px 0 var(--glass-light) inset;
  margin-top: 34px;
}
.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}
.panel-head h2 { margin: 0; font-size: 20px; }

.code-form {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.code-entry-row {
  display: flex;
  gap: 10px;
  align-items: center;
}
.code-entry-row .text-input { flex: 1; min-width: 0; }
.code-entry-row .text-input:first-child { flex: 0 1 40%; }
@media (max-width: 620px) {
  .code-entry-row { flex-direction: column; align-items: stretch; }
  .code-entry-row .text-input:first-child { flex: 1; }
}

.access-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 12px;
  margin: 6px 0 4px;
  width: 100%;
}
.access-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.access-group .small { font-weight: 600; }
.access-controls { display: flex; gap: 6px; }
.access-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.access-label { margin-bottom: 0; }
.access-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  /* Was a hard 190px, which showed about two entries no matter how tall the
     window was and hid the rest behind an inner scrollbar. Scale with the
     viewport instead, so the box is only as short as it has to be. */
  max-height: clamp(220px, 44vh, 520px);
  overflow-y: auto;
  border: 1px solid var(--glass-line);
  border-radius: 8px;
  padding: 6px;
  background: var(--glass);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
}
.access-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 13px;
}
.access-item:hover { background: rgba(255, 255, 255, 0.05); }
.access-item input {
  accent-color: var(--accent, #4c9cff);
  flex: none;
}
.access-item-label {
  /* Was nowrap + ellipsis, so any title wider than the column lost its tail
     with no way to read it. Note titles are short and the box is a list, so
     wrap instead of truncating. */
  overflow-wrap: anywhere;
  line-height: 1.35;
}
.access-empty {
  color: var(--muted);
  font-size: 13px;
  padding: 4px 6px;
}
.access-item:has(input:checked) {
  background: rgba(76, 156, 255, 0.12);
  color: #ddeaff;
}

.expiry-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 2px;
}
.expiry-row label { font-weight: 600; }
.select-inline { max-width: 220px; }
.expiry-row .text-input[hidden] { display: none; }
#customExpires { max-width: 260px; }

/* ---------- logout confirmation modal ---------- */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(5, 8, 15, 0.55);
  -webkit-backdrop-filter: blur(8px) saturate(120%);
  backdrop-filter: blur(8px) saturate(120%);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 200;
  padding: 20px;
}
.modal {
  background: linear-gradient(165deg, var(--glass-2), var(--glass) 50%), var(--glass-base-strong);
  -webkit-backdrop-filter: blur(30px) saturate(180%);
  backdrop-filter: blur(30px) saturate(180%);
  border: 1px solid var(--glass-line-2);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg), 0 1px 0 var(--glass-light) inset;
  padding: 24px 26px;
  max-width: 420px;
  width: 100%;
  animation: toast-in 0.25s ease-out;
}
.modal-title { margin: 0 0 10px; font-size: 20px; }
.modal-text { margin: 0 0 20px; color: var(--muted); line-height: 1.5; }
.modal-actions { display: flex; gap: 10px; justify-content: flex-end; }

/* ---------- realtime toasts ---------- */
.toast {
  display: flex;
  align-items: center;
  gap: 12px;
  background: linear-gradient(180deg, var(--glass-2), var(--glass)), var(--glass-base-strong);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
  backdrop-filter: blur(16px) saturate(160%);
  border: 1px solid var(--glass-line-2);
  box-shadow: var(--shadow), 0 1px 0 var(--glass-light) inset;
  border-radius: 12px;
  padding: 12px 14px;
  color: var(--text);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
  animation: toast-in 0.3s ease-out;
  text-decoration: none;
}
.toast-link:hover { text-decoration: none; border-color: var(--accent-2); }
.toast-err {
  border-color: color-mix(in srgb, var(--danger) 55%, transparent);
  background: linear-gradient(180deg, color-mix(in srgb, var(--danger) 14%, transparent), color-mix(in srgb, var(--danger) 7%, transparent)), var(--glass-base-strong);
  box-shadow: var(--shadow), 0 0 0 1px color-mix(in srgb, var(--danger) 22%, transparent), 0 8px 24px color-mix(in srgb, var(--danger) 22%, transparent);
}
.toast-err .toast-title { color: var(--danger); }
.toast-ok {
  border-color: color-mix(in srgb, var(--ok) 45%, transparent);
  box-shadow: var(--shadow), 0 0 0 1px color-mix(in srgb, var(--ok) 20%, transparent), 0 8px 24px color-mix(in srgb, var(--ok) 20%, transparent);
}
.toast-ann {
  border: 2px solid var(--accent-2);
  box-shadow: 0 0 0 1px var(--accent-2), 0 12px 40px rgba(0, 0, 0, 0.6);
}
.toast-ann .toast-title { color: var(--accent-2); font-size: 15px; }
.toast-ann .toast-text { color: var(--text); font-size: 14px; }
.announce { display: flex; gap: 10px; margin-bottom: 18px; }
.announce .text-input { flex: 1; }

/* announcements overlay the top of the screen instead of pushing content down */
.announce-host {
  position: fixed;
  top: 16px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: min(560px, calc(100vw - 32px));
  z-index: 9999;
  pointer-events: none;
}
.announce-host .toast {
  pointer-events: auto;
  cursor: pointer;
  justify-content: space-between;
  animation: toast-in-top 0.3s ease-out;
}
.announce-host .toast-out {
  animation: toast-out-top 0.35s ease-in forwards;
}
.announce-host .toast-body { display: flex; flex-direction: column; }
.toast-dismiss {
  align-self: center;
  flex-shrink: 0;
  color: var(--accent-2);
  font-size: 12px;
  font-weight: 600;
  border: 1px solid var(--accent-2);
  border-radius: 999px;
  padding: 3px 10px;
  opacity: 0.9;
}
.toast-dismiss:hover { opacity: 1; background: rgba(255, 255, 255, 0.08); }
.toast-title { font-weight: 700; font-size: 14px; }
.toast-text { color: var(--muted); font-size: 13px; margin-top: 2px; }
.toast-go { display: block; color: var(--accent-2); font-size: 13px; font-weight: 600; margin-top: 6px; }
.toast-out { animation: toast-out 0.35s ease-in forwards; }

@keyframes toast-in {
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes toast-in-top {
  from { opacity: 0; transform: translateY(-14px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes toast-out-top {
  to { opacity: 0; transform: translateY(-14px); }
}
@keyframes toast-out {
  to { opacity: 0; transform: translateY(8px); }
}

@keyframes card-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes pop-in {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes star-pop {
  0% { transform: scale(1); }
  50% { transform: scale(1.35); }
  100% { transform: scale(1); }
}

@keyframes modal-in {
  from { opacity: 0; transform: scale(0.98) translateY(6px); }
  to { opacity: 1; transform: scale(1) translateY(0); }
}

/* ---------- tabs (styled like the site's buttons) ---------- */
.tabs {
  display: flex;
  gap: 8px;
  margin-bottom: 18px;
  /* Was nowrap + overflow-x:auto with the scrollbar hidden, so past ~1024 the
     last tabs were clipped with nothing on screen hinting there was more.
     Let them wrap instead - every tab stays readable at every width. */
  flex-wrap: wrap;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding-bottom: 2px;
}
.tabs::-webkit-scrollbar { display: none; }
.tab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 14px;
  border-radius: 11px;
  border: 1px solid var(--glass-line);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
  background: var(--glass);
  box-shadow: 0 1px 0 var(--glass-light) inset;
  color: var(--muted);
  transition: background 0.15s var(--ease), border-color 0.15s var(--ease), transform 0.05s, box-shadow 0.18s var(--ease), color 0.15s;
  flex: 0 0 auto;
  white-space: nowrap;
}
.tab:hover {
  color: var(--text);
  border-color: color-mix(in srgb, var(--a1) 55%, var(--glass-line-2));
  background: var(--glass-2);
}
.tab:active { transform: translateY(1px); }
.tab.active {
  background: linear-gradient(135deg, var(--a1), var(--a2));
  border-color: transparent;
  color: #0b0e14;
  font-weight: 700;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.3) inset, 0 6px 20px color-mix(in srgb, var(--a1) 40%, transparent);
}
.tab.active:hover { filter: brightness(1.08); color: #0b0e14; box-shadow: 0 1px 0 rgba(255, 255, 255, 0.3) inset, 0 10px 28px color-mix(in srgb, var(--a1) 52%, transparent); }

.tab-pane { min-width: 0; }

/* ---------- downloads / games ---------- */
.downloads-view { display: block; }
.dl-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
  gap: 14px;
}
.download-item { display: block; }
.download-item .card-excerpt { margin-bottom: 12px; }
.download-item .mono { color: var(--accent-2); }
.dl-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.download-item .btn { align-self: flex-start; }

/* ---------- community (user-published scripts) ---------- */
.community-view { display: block; }
.community-layout {
  display: grid;
  grid-template-columns: minmax(260px, 380px) 1fr;
  gap: 22px;
  align-items: start;
}
.community-form { margin: 0; }
.community-form-title { font-size: 18px; margin: 0 0 14px; }
.community-form .code-input-lg { font-family: var(--mono); }
.community-list { min-width: 0; }
.community-item { position: relative; }
.community-item .card-title { font-weight: 700; }
.community-item .chip { margin-left: auto; }
.community-item .card-meta { display: flex; justify-content: space-between; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.us-err { margin: 10px 0 0; color: var(--danger); }

/* ---------- community script modal ---------- */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(6, 8, 13, 0.72);
  backdrop-filter: blur(3px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  z-index: 1000;
}
.modal-overlay[hidden] { display: none; }
.modal-card {
  background: linear-gradient(165deg, var(--glass-2), var(--glass) 50%), var(--glass-base-strong);
  -webkit-backdrop-filter: blur(30px) saturate(180%);
  backdrop-filter: blur(30px) saturate(180%);
  border: 1px solid var(--glass-line-2);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg), 0 1px 0 var(--glass-light) inset;
  width: min(860px, 100%);
  max-height: 86vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
}
.modal-title { font-size: 18px; margin: 0; overflow-wrap: anywhere; }
.modal-meta {
  padding: 10px 20px;
  font-size: 13px;
  color: var(--muted);
  border-bottom: 1px solid var(--border);
}
.modal-code {
  margin: 0;
  border: none;
  border-radius: 0;
  flex: 1;
  min-height: 180px;
  overflow: auto;
}
.modal-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 20px;
  border-top: 1px solid var(--border);
  background: rgba(0, 0, 0, 0.18);
}
.copy-status.show { visibility: visible; opacity: 1; }
.bg-dim { opacity: 0.35; }

@media (max-width: 760px) {
  .community-layout { grid-template-columns: 1fr; }
}

/* the drawer is the only nav on small screens, so give it the full width and
   drop the button's text label to keep the top bar uncluttered */
@media (max-width: 520px) {
  .menu-btn-label { display: none; }
  .menu-btn { padding: 9px 11px; }
  /* 100% not 100vw: vw includes the vertical scrollbar, which makes a
     full-width drawer wider than the page and overflow it */
  .menu-drawer { width: 100%; border-left: 0; }
  .topbar { padding: 12px 14px; }
  /* six columns of 16px-per-side padding alone force the admin tables wider
     than a phone; trim it so nothing has to be scrolled sideways to read */
  .table th, .table td { padding: 8px 8px; }
}

.or-divider {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 14px 0;
  color: var(--muted);
  font-size: 13px;
}
.or-divider::before,
.or-divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--border);
}

/* ---------- favorites + saved tab ---------- */
.fav-btn {
  appearance: none;
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--muted);
  font-size: 15px;
  line-height: 1;
  padding: 2px 4px;
  border-radius: 6px;
  flex: none;
  transition: color 0.15s, transform 0.1s;
}
.fav-btn:hover { color: var(--accent-2); transform: scale(1.12); }
.fav-btn.on { color: #ffc94d; }
.card-head { display: flex; align-items: center; gap: 8px; }
.card-head .fav-btn { margin-left: auto; }

.saved-list { display: grid; gap: 14px; }
.saved-note, .saved-script { margin: 0; }
.saved-note { display: block; }
.saved-script { display: block; }
.saved-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.saved-meta { display: flex; align-items: center; gap: 10px; color: var(--muted); font-size: 13px; }
.saved-kinds { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.saved-kinds .chip { cursor: pointer; user-select: none; transition: border-color 0.15s, background 0.15s, color 0.15s; }
.saved-kinds .chip:hover { border-color: var(--accent); color: var(--text); }
.saved-kinds .chip.active { background: rgba(108, 140, 255, 0.18); border-color: var(--accent); color: var(--text); }

/* ---------- community toolbar (search / sort / mine) ---------- */
.community-tools { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-bottom: 14px; }
.community-tools .us-search { flex: 1 1 180px; min-width: 150px; }
.community-tools .check-row { margin: 0; white-space: nowrap; }
.community-tools select.text-input { width: auto; padding: 10px 12px; cursor: pointer; }

/* ---------- settings section (inside the menu drawer) ---------- */
.settings-row {
  display: flex;
  align-items: center;
  gap: 10px;
  justify-content: space-between;
  flex-wrap: wrap;
}
/* inside the drawer the rows are separated by hairlines instead of margins */
.menu-section .settings-row {
  margin-bottom: 0;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
}
.menu-section .settings-row:last-child { padding-bottom: 0; border-bottom: 0; }
.settings-row label { font-weight: 600; font-size: 13px; color: var(--muted); }
.settings-swatches { display: flex; gap: 6px; flex-wrap: wrap; }
.theme-swatch {
  appearance: none;
  width: 26px;
  height: 26px;
  border-radius: 8px;
  border: 2px solid var(--border);
  cursor: pointer;
  padding: 0;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.theme-swatch:hover { transform: scale(1.08); }
.theme-swatch.on { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(108, 140, 255, 0.35); }
.settings-range { flex: 1 1 130px; max-width: 160px; accent-color: var(--accent); }
.theme-toggle { display: flex; gap: 6px; }
.theme-toggle button.on { background: rgba(108, 140, 255, 0.18); border-color: var(--accent); }


/* ---------- entrance animations ---------- */
.card-list > .card,
.dl-list > .download-item,
.saved-list > .saved-note,
.saved-list > .saved-script,
.community-list > .community-item {
  animation: card-in 0.35s ease-out backwards;
}
.note-list > .note-item { animation: card-in 0.3s ease-out backwards; }

.card-list > .card:nth-child(n+2),
.dl-list > .download-item:nth-child(n+2),
.saved-list > .saved-note:nth-child(n+2),
.saved-list > .saved-script:nth-child(n+2),
.community-list > .community-item:nth-child(n+2),
.note-list > .note-item:nth-child(2) { animation-delay: 0.05s; }
.note-list > .note-item:nth-child(3) { animation-delay: 0.1s; }
.note-list > .note-item:nth-child(4) { animation-delay: 0.15s; }
.note-list > .note-item:nth-child(5) { animation-delay: 0.2s; }
.note-list > .note-item:nth-child(6) { animation-delay: 0.25s; }

.tab-pane { animation: fade-in 0.3s ease-out; }
.code-block { animation: fade-in 0.35s ease-out; }
.modal { animation: modal-in 0.25s ease-out; }
.modal-card { animation: modal-in 0.25s ease-out; }

.fav-btn.pop { animation: star-pop 0.3s ease-out; }

/* ---------- AI assistant chat widget ---------- */
.ai-btn {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 6000;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: none;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  color: var(--bg);
  font-weight: 800;
  font-size: 15px;
  cursor: pointer;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
}
.ai-btn:hover { transform: translateY(-1px) scale(1.04); }

.ai-panel {
  position: fixed;
  right: 18px;
  bottom: 82px;
  z-index: 5999;
  width: min(380px, calc(100vw - 36px));
  height: min(480px, calc(100vh - 140px));
  display: flex;
  flex-direction: column;
  background: linear-gradient(160deg, var(--glass-2), var(--glass) 55%), var(--glass-base);
  -webkit-backdrop-filter: blur(--glass-blur) saturate(var(--glass-sat));
  backdrop-filter: blur(--glass-blur) saturate(var(--glass-sat));

  border: 1px solid var(--glass-line);
  border-radius: var(--radius);
  box-shadow: 0 18px 60px rgba(0, 0, 0, 0.55);
  opacity: 0;
  pointer-events: none;
  transform: translateY(8px);
  transition: opacity 0.18s ease, transform 0.18s ease;
  overflow: hidden;
}
.ai-panel.open { opacity: 1; pointer-events: auto; transform: translateY(0); }

.ai-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  font-weight: 700;
}
.ai-close {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  padding: 0 2px;
}
.ai-close:hover { color: var(--text); }

.ai-log {
  flex: 1;
  overflow-y: auto;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ai-msg {
  padding: 8px 10px;
  border-radius: 10px;
  font-size: 13px;
  line-height: 1.45;
  white-space: pre-wrap;
  word-wrap: break-word;
  max-width: 88%;
}
.ai-msg.user { align-self: flex-end; background: var(--accent); color: var(--bg); }
.ai-msg.assistant { align-self: flex-start; background: rgba(127, 140, 170, 0.14); }
/* links the assistant hands back for a note */
.ai-link {
  color: var(--accent-2);
  text-decoration: underline;
  text-underline-offset: 2px;
  overflow-wrap: anywhere;
}
.ai-link:hover { color: var(--accent); }

.ai-msg.streaming::after {
  content: '';
  display: inline-block;
  width: 6px;
  height: 13px;
  margin-left: 2px;
  vertical-align: -2px;
  background: var(--accent-2);
  animation: ai-blink 1s steps(2) infinite;
}
@keyframes ai-blink { 50% { opacity: 0; } }

.ai-form {
  display: flex;
  gap: 8px;
  padding: 10px;
  border-top: 1px solid var(--border);
}
.ai-form .text-input { flex: 1; }

/* starter questions */
.ai-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 0 10px 10px;
}
.ai-chip {
  border: 1px solid var(--glass-line);
  background: rgba(127, 140, 170, 0.1);
  color: var(--muted);
  border-radius: 999px;
  padding: 5px 10px;
  font-size: 12px;
  cursor: pointer;
}
.ai-chip:hover { color: var(--text); border-color: var(--accent); }

/* "I looked something up" line */
.ai-tool {
  align-self: flex-start;
  font-size: 11px;
  color: var(--muted);
  background: rgba(127, 140, 170, 0.08);
  border-left: 2px solid var(--accent-2);
  border-radius: 0 8px 8px 0;
  padding: 4px 8px;
  max-width: 90%;
}

/* approval card for a change the assistant wants to make */
.ai-action {
  align-self: flex-start;
  width: 92%;
  border: 1px solid var(--accent);
  border-radius: 10px;
  padding: 10px;
  background: rgba(127, 140, 170, 0.1);
}
.ai-action.danger { border-color: #e5534b; }
.ai-action.done { border-color: #3fb950; opacity: 0.85; }
.ai-action.failed { border-color: #e5534b; }
.ai-action.cancelled { opacity: 0.6; }
.ai-action-label { font-size: 13px; font-weight: 700; }
.ai-action-detail {
  font-size: 12px;
  color: var(--muted);
  margin: 4px 0 8px;
  white-space: pre-wrap;
  word-wrap: break-word;
}
.ai-action-row { display: flex; gap: 8px; }
.ai-action-row .btn { padding: 5px 12px; font-size: 12px; }
.ai-action-row .btn:disabled { opacity: 0.6; cursor: default; }

/* ---------- public chat + private whispers ---------- */
/* The chat button sits bottom-left (the assistant already owns bottom-right).
   It opens a centred overlay that reads like the changelog: a scrollable body
   and a composer. Messages are append-only; nothing here deletes them. */
.chat-toggle {
  position: fixed;
  left: 18px;
  bottom: 18px;
  z-index: 6000;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  border: 1px solid var(--glass-line-2);
  border-radius: 999px;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  color: var(--bg);
  font: inherit;
  font-weight: 700;
  font-size: 14px;
  cursor: pointer;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
}
.chat-toggle:hover { transform: translateY(-1px) scale(1.03); }
.chat-toggle-ico { font-size: 16px; line-height: 1; }
.chat-toggle-badge {
  position: absolute;
  top: -4px;
  right: -4px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: #e5534b;
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}
.chat-overlay { z-index: 1100; }
.chat-overlay[hidden] { display: none; }

.chat-card {
  width: min(720px, 100%);
  height: min(660px, 88vh);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: linear-gradient(165deg, var(--glass-2), var(--glass) 50%), var(--glass-base-strong);
  -webkit-backdrop-filter: blur(30px) saturate(180%);
  backdrop-filter: blur(30px) saturate(180%);
  border: 1px solid var(--glass-line-2);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg), 0 1px 0 var(--glass-light) inset;
  animation: modal-in 0.18s ease-out;
}
.chat-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
}
.chat-title {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin: 0;
  font-size: 17px;
  font-weight: 600;
}
.chat-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 3px rgba(108, 140, 255, 0.18);
  flex: none;
}
.whisper-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent-2);
  box-shadow: 0 0 0 3px rgba(108, 140, 255, 0.18);
  flex: none;
}
.chat-close,
.whisper-close {
  margin-left: auto;
  background: none;
  border: none;
  color: var(--muted);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
}
.chat-close:hover,
.whisper-close:hover { color: var(--text); }

.chat-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 12px 14px;
}
.whisper-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 12px 14px;
}
.chat-list,
.whisper-list { display: flex; flex-direction: column; gap: 2px; }

/* Discord-style: a name line then the message, own messages pushed right */
.chat-msg {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 4px 10px;
  border-radius: 10px;
}
.chat-msg.grouped { padding-top: 1px; }
.chat-msg .chat-name {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--accent);
}
.chat-msg .chat-name.admin { color: var(--accent-2); }
.chat-msg .chat-text {
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--text);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.chat-msg.mine { align-items: flex-end; text-align: right; }
.chat-msg.mine .chat-name { color: var(--accent-2); }
.chat-msg.mine .chat-text { color: var(--text); }
.chat-time {
  font-size: 10.5px;
  color: var(--muted);
  margin-left: 8px;
  white-space: nowrap;
}
.chat-empty,
.whisper-empty {
  margin: 0;
  padding: 18px 12px;
  font-size: 13px;
  color: var(--muted);
}

.chat-form {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  padding: 10px 12px;
  border-top: 1px solid var(--border);
}
.chat-input {
  flex: 1;
  resize: none;
  min-height: 42px;
  max-height: 140px;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid var(--glass-line);
  background: var(--bg-soft);
  color: var(--text);
  font: inherit;
  font-size: 14.5px;
  line-height: 1.4;
}
.chat-input:focus { outline: none; border-color: var(--accent); }
.chat-input::placeholder { color: var(--muted); }
.chat-send { flex: none; }
.chat-err {
  margin: 0;
  padding: 0 16px 12px;
  font-size: 13px;
  color: #ff8080;
}

/* paused banner — shown across the top when the admin freezes the room */
.chat-paused {
  margin: 0;
  padding: 8px 18px;
  font-size: 13px;
  font-weight: 600;
  color: #ffd27d;
  background: rgba(255, 170, 60, 0.12);
  border-bottom: 1px solid var(--border);
}

/* picture attach button (the <label> wraps a hidden file input) */
.chat-attach {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border-radius: 10px;
  border: 1px solid var(--glass-line);
  background: var(--bg-soft);
  color: var(--muted);
  cursor: pointer;
  flex: none;
  transition: border-color 0.15s, color 0.15s, transform 0.15s;
}
.chat-attach:hover { border-color: var(--accent); color: var(--text); }
.chat-form[data-paused="1"] .chat-attach { opacity: 0.5; cursor: not-allowed; }
.chat-attach-ico { font-size: 16px; line-height: 1; }

/* attached-picture preview sits above the input row while waiting to send */
.chat-form.has-preview { flex-wrap: wrap; }
.chat-form .chat-preview {
  flex: 1 1 100%;
  order: -1;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border: 1px solid var(--glass-line);
  border-radius: 10px;
  background: var(--bg-soft);
}
.chat-preview img {
  max-width: 120px;
  max-height: 90px;
  border-radius: 6px;
  object-fit: cover;
}
.chat-preview-x {
  margin-left: auto;
  background: none;
  border: none;
  color: var(--muted);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
}
.chat-preview-x:hover { color: var(--danger); }

/* shared pictures in the feed */
.chat-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-width: min(100%, 560px);
}
.chat-msg .chat-media {
  display: block;
  margin: 2px 0;
}
.chat-media-img {
  display: block;
  max-width: min(100%, 340px);
  max-height: 260px;
  border-radius: 10px;
  cursor: zoom-in;
  border: 1px solid var(--glass-line);
  background: rgba(0, 0, 0, 0.25);
}

/* lightbox for a clicked picture */
.chat-lightbox {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(4, 6, 10, 0.92);
  cursor: zoom-out;
  padding: 24px;
}
.chat-lightbox img {
  max-width: 96vw;
  max-height: 92vh;
  border-radius: 12px;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6);
}

/* ---- whispers: the drawer conversation list ---- */
.whisper-threads {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 2px 10px 10px;
}
.whisper-new { align-self: flex-start; }
.whisper-thread-list { display: flex; flex-direction: column; gap: 2px; }
.whisper-thread {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 1px;
  width: 100%;
  text-align: left;
  padding: 7px 10px;
  border: none;
  border-radius: 8px;
  background: none;
  color: var(--text);
  font: inherit;
  cursor: pointer;
}
.whisper-thread:hover { background: rgba(108, 140, 255, 0.1); }
.whisper-thread-name { font-size: 13.5px; font-weight: 600; padding-right: 26px; }
.whisper-thread-prev {
  font-size: 12px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding-right: 26px;
}
.whisper-thread-badge {
  position: absolute;
  right: 8px;
  top: 8px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: #e5534b;
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}
.whisper-thread-empty {
  margin: 0;
  padding: 4px 4px 2px;
  font-size: 12.5px;
  color: var(--muted);
}
.whisper-nav-badge {
  display: inline-block;
  min-width: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: #e5534b;
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}
.whisper-nav-badge[hidden] { display: none; }

.whisper-overlay { z-index: 1100; }
.whisper-overlay[hidden] { display: none; }
.whisper-card {
  width: min(560px, 100%);
  height: min(580px, 86vh);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: linear-gradient(165deg, var(--glass-2), var(--glass) 50%), var(--glass-base-strong);
  -webkit-backdrop-filter: blur(30px) saturate(180%);
  backdrop-filter: blur(30px) saturate(180%);
  border: 1px solid var(--glass-line-2);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg), 0 1px 0 var(--glass-light) inset;
  animation: modal-in 0.18s ease-out;
}
.whisper-head {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
}
.whisper-title { margin: 0; font-size: 16px; font-weight: 600; flex: 1; overflow-wrap: anywhere; }
.whisper-picker { display: flex; flex-direction: column; gap: 8px; padding: 18px 18px; }
.whisper-picker-row { display: flex; gap: 8px; }
.whisper-picker-row .text-input { flex: 1; }

@media (max-width: 620px) {
  .chat-toggle { left: 12px; bottom: 12px; padding: 10px 13px; }
  .chat-toggle-label { display: none; }
  .chat-overlay,
  .whisper-overlay { padding: 12px; align-items: flex-end; }
  .chat-card { height: 82vh; }
  .whisper-card { height: 78vh; }
}

