/* ------------------------------------------------------------------
   Typefaces, served from this account.
   Archivo carries the interface, Space Mono handles hostnames, keys
   and counts. Both are self hosted so no third party sees a request
   every time you open your launchpad, and so the app still looks
   right when the device is offline in standalone mode.
   ------------------------------------------------------------------ */
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/archivo-latin-400-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/archivo-latin-500-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/archivo-latin-600-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/archivo-latin-700-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url('fonts/archivo-latin-800-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Space Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/space-mono-latin-400-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Space Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/space-mono-latin-700-normal.woff2') format('woff2');
}

/* ==========================================================================
   Launchpad
   A private tile grid for self-hosted apps. Visual direction: anodized rack
   panel. Graphite surfaces, hairline seams, amber status accent, and a
   monospace label strip on every tile the way a patch panel port is labelled.
   ========================================================================== */

/* ---- tokens -------------------------------------------------------- */

:root {
  --ui:   'Archivo', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono: 'Space Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  --r-sm: 6px;
  --r-md: 10px;
  --r-lg: 14px;
  --r-xl: 20px;

  --pad: clamp(16px, 3vw, 32px);
  --tile: 192px;

  --shadow-1: 0 1px 2px rgba(8, 11, 16, .18);
  --shadow-2: 0 10px 30px -12px rgba(8, 11, 16, .45);
  --shadow-3: 0 24px 60px -20px rgba(8, 11, 16, .6);

  --ease: cubic-bezier(.2, .7, .3, 1);
}

html[data-resolved='dark'] {
  --bg:         #0F1319;
  --bg-2:       #131923;
  --surface:    #171D26;
  --surface-2:  #1E2531;
  --surface-3:  #252E3C;
  --edge:       #262E3A;
  --edge-2:     #354052;
  --text:       #E6EAF0;
  --text-dim:   #98A2B2;
  --text-faint: #69748596;
  --accent:     #F5A524;
  --accent-2:   #FFC15E;
  --accent-ink: #1A1206;
  --accent-wash:#F5A5241f;
  --live:       #3FD07F;
  --danger:     #FF6B5E;
  --danger-wash:#FF6B5E1f;
  color-scheme: dark;
}

html[data-resolved='light'] {
  --bg:         #ECEEF2;
  --bg-2:       #E4E7ED;
  --surface:    #FFFFFF;
  --surface-2:  #F5F7FA;
  --surface-3:  #EBEEF3;
  --edge:       #DBDFE7;
  --edge-2:     #C4CAD5;
  --text:       #141920;
  --text-dim:   #58616F;
  --text-faint: #8993A2;
  --accent:     #B87309;
  --accent-2:   #965D06;
  --accent-ink: #FFFFFF;
  --accent-wash:#B8730914;
  --live:       #128B4E;
  --danger:     #C13A2C;
  --danger-wash:#C13A2C14;
  color-scheme: light;
}

/* ---- base ---------------------------------------------------------- */

* { box-sizing: border-box; }

/* The hidden attribute only carries "display: none" from the browser's own
   stylesheet, which loses to any author rule that sets display. A component
   like .modal { display: grid } therefore stays on screen even while marked
   hidden, and toggling the attribute from JS does nothing visible. Everything
   in this app hides through the attribute, so it wins here, once, globally.
   Any element that needs to be visible while hidden does not exist. */
[hidden] { display: none !important; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--ui);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}

svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

h1, h2, h3 { margin: 0; font-weight: 700; letter-spacing: -.015em; }

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

::selection { background: var(--accent); color: var(--accent-ink); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

.skip {
  position: absolute; left: -999px; top: 0; z-index: 100;
  background: var(--accent); color: var(--accent-ink);
  padding: 10px 16px; border-radius: 0 0 var(--r-md) 0; font-weight: 600;
}
.skip:focus { left: 0; }

.eyebrow {
  margin: 0 0 4px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-faint);
}

/* ---- brand mark ---------------------------------------------------- */
/* Four ports on a panel. The top-left one is lit. */

.markmark {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 3px;
  width: 34px; height: 34px;
  padding: 4px;
  border: 1px solid var(--edge-2);
  border-radius: var(--r-sm);
  background: var(--surface-2);
}
.markmark span { background: var(--edge-2); border-radius: 1.5px; }
.markmark span:first-child { background: var(--accent); }
.markmark--sm { width: 26px; height: 26px; gap: 2px; padding: 3px; }

/* ==========================================================================
   Sign in
   ========================================================================== */

.is-auth { background: var(--bg); }

.auth {
  min-height: 100dvh;
  display: grid;
  grid-template-columns: 1fr;
  align-content: center;
  gap: 28px;
  padding: 8vh var(--pad) 6vh;
  max-width: 1040px;
  margin: 0 auto;
}

@media (min-width: 860px) {
  .auth {
    grid-template-columns: 1fr 1fr;
    align-items: center;
    gap: 64px;
    padding-block: 4vh;
  }
}

.auth__brand { display: grid; gap: 14px; justify-items: start; }
.auth__title { font-size: clamp(30px, 5vw, 44px); letter-spacing: -.03em; }
.auth__tag { margin: 0; color: var(--text-dim); font-size: 17px; max-width: 30ch; }

.auth__strip {
  list-style: none;
  margin: 22px 0 0;
  padding: 0;
  border-top: 1px solid var(--edge);
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--text-faint);
  width: 100%;
  max-width: 360px;
}
.auth__strip li {
  display: flex; justify-content: space-between; gap: 16px;
  padding: 9px 0;
  border-bottom: 1px solid var(--edge);
}
.auth__strip b { color: var(--text-dim); letter-spacing: .1em; font-weight: 400; }

.card {
  background: var(--surface);
  border: 1px solid var(--edge);
  border-radius: var(--r-xl);
  padding: clamp(22px, 4vw, 32px);
  box-shadow: var(--shadow-2);
}
.card--auth { display: grid; gap: 16px; max-width: 440px; }
.card__title { font-size: 22px; }
.card__sub { margin: -8px 0 4px; color: var(--text-dim); font-size: 14px; }

/* ---- forms --------------------------------------------------------- */

.field { display: grid; gap: 6px; }
.field__label {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.field__wrap { position: relative; display: block; }

.input, .select, .textarea {
  width: 100%;
  font: inherit;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--edge-2);
  border-radius: var(--r-md);
  padding: 11px 13px;
  transition: border-color .15s var(--ease), background .15s var(--ease);
}
.input:focus, .select:focus, .textarea:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--surface);
}
.textarea { min-height: 76px; resize: vertical; }
.select { appearance: none; padding-right: 34px;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 17px) 55%, calc(100% - 12px) 55%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

.reveal {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  background: none; border: 0; cursor: pointer;
  font: 600 11px/1 var(--mono); letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-dim); padding: 8px;
}
.reveal:hover { color: var(--accent); }

.check { display: flex; align-items: center; gap: 9px; font-size: 14px; color: var(--text-dim); cursor: pointer; }
.check input { width: 16px; height: 16px; accent-color: var(--accent); }

.hint { margin: 4px 0 0; font-size: 12.5px; color: var(--text-faint); }

.formnote {
  margin: 0;
  font-size: 13.5px;
  padding: 10px 12px;
  border-radius: var(--r-md);
  background: var(--danger-wash);
  color: var(--danger);
  border: 1px solid color-mix(in srgb, var(--danger) 32%, transparent);
}
.formnote--warn { background: var(--accent-wash); color: var(--accent); border-color: color-mix(in srgb, var(--accent) 32%, transparent); }
.formnote--ok { background: color-mix(in srgb, var(--live) 12%, transparent); color: var(--live); border-color: color-mix(in srgb, var(--live) 32%, transparent); }

/* ---- buttons ------------------------------------------------------- */

.btn {
  font: 600 14px/1 var(--ui);
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 11px 16px;
  border-radius: var(--r-md);
  border: 1px solid transparent;
  background: var(--surface-2);
  color: var(--text);
  cursor: pointer;
  white-space: nowrap;
  transition: transform .12s var(--ease), background .15s var(--ease), border-color .15s var(--ease);
}
.btn:hover { background: var(--surface-3); }
.btn:active { transform: translateY(1px); }
.btn[disabled] { opacity: .55; cursor: not-allowed; transform: none; }
.btn svg { width: 16px; height: 16px; }

.btn--primary { background: var(--accent); color: var(--accent-ink); }
.btn--primary:hover { background: var(--accent-2); }
.btn--ghost { background: transparent; border-color: var(--edge-2); }
.btn--ghost:hover { background: var(--surface-2); }
.btn--danger { background: transparent; border-color: color-mix(in srgb, var(--danger) 45%, transparent); color: var(--danger); }
.btn--danger:hover { background: var(--danger-wash); }
.btn--block { width: 100%; padding-block: 13px; }
.btn--sm { padding: 7px 11px; font-size: 13px; }

.iconbtn {
  display: inline-grid; place-items: center;
  width: 38px; height: 38px;
  border: 1px solid transparent;
  border-radius: var(--r-md);
  background: transparent;
  color: var(--text-dim);
  cursor: pointer;
  transition: background .15s var(--ease), color .15s var(--ease);
}
.iconbtn:hover { background: var(--surface-2); color: var(--text); }

/* ==========================================================================
   App shell
   ========================================================================== */

.topbar {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: 12px;
  height: 62px;
  padding: 0 clamp(12px, 2vw, 20px);
  padding-top: env(safe-area-inset-top);
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--edge);
}

.topbar__menu { display: inline-grid; }
.topbar__brand { display: flex; align-items: center; gap: 10px; min-width: 0; }
.topbar__name { font-weight: 700; letter-spacing: -.01em; white-space: nowrap; }
.topbar__right { display: flex; align-items: center; gap: 4px; margin-left: auto; }

@media (min-width: 900px) {
  .topbar__menu { display: none; }
}
@media (max-width: 620px) {
  .topbar__name { display: none; }
}

/* command bar */
.cmd {
  position: relative;
  flex: 1 1 auto;
  max-width: 520px;
  margin-inline: auto;
  display: flex; align-items: center;
}
.cmd__icon {
  position: absolute; left: 12px; width: 17px; height: 17px;
  color: var(--text-faint); pointer-events: none;
}
.cmd__input {
  width: 100%;
  font: 500 14px/1 var(--ui);
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--edge-2);
  border-radius: 999px;
  padding: 11px 42px 11px 37px;
  transition: border-color .15s var(--ease), box-shadow .15s var(--ease);
}
.cmd__input::-webkit-search-cancel-button { display: none; }
.cmd__input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-wash);
}
.cmd__kbd {
  position: absolute; right: 10px;
  font: 400 11px/1 var(--mono);
  color: var(--text-faint);
  border: 1px solid var(--edge-2);
  border-radius: 4px;
  padding: 4px 6px;
  pointer-events: none;
}
.cmd__input:focus ~ .cmd__kbd { opacity: 0; }

.avatar {
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border-radius: 50%;
  border: 1px solid var(--edge-2);
  background: var(--surface-2);
  color: var(--text);
  font: 700 12px/1 var(--ui);
  letter-spacing: .02em;
  cursor: pointer;
}
.avatar:hover { border-color: var(--accent); }

/* theme toggle icon swap */
html[data-resolved='dark'] .ico-sun { display: block; }
html[data-resolved='dark'] .ico-moon { display: none; }
html[data-resolved='light'] .ico-sun { display: none; }
html[data-resolved='light'] .ico-moon { display: block; }

/* layout */

/* ---- top menu strip -------------------------------------------------
   Replaces the old left rail. It sits under the topbar, holds the same
   destinations, and folds away behind the toggle in the topbar. The
   collapsed state is remembered per device in localStorage. */

.navstrip {
  position: sticky;
  top: calc(62px + env(safe-area-inset-top));
  z-index: 39;
  border-bottom: 1px solid var(--edge);
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(12px);
  overflow: hidden;
  max-height: 60px;
  transition: max-height .22s var(--ease), border-color .22s var(--ease);
}
body.nav-hidden .navstrip { max-height: 0; border-bottom-color: transparent; }

.navstrip__inner {
  display: flex; align-items: center; gap: 4px;
  max-width: 1240px;
  margin: 0 auto;
  padding: 8px clamp(12px, 2vw, 20px);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.navstrip__inner::-webkit-scrollbar { display: none; }
.navstrip__spacer { flex: 1 1 auto; min-width: 12px; }

.nav__item {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 9px 14px;
  border: 0; border-radius: var(--r-md);
  background: transparent;
  color: var(--text-dim);
  font: 600 14px/1 var(--ui);
  white-space: nowrap;
  cursor: pointer;
  transition: background .15s var(--ease), color .15s var(--ease);
}
.nav__item svg { width: 17px; height: 17px; flex: none; }
.nav__item:hover { background: var(--surface-2); color: var(--text); }
.nav__item.is-active { background: var(--accent-wash); color: var(--accent); }
.nav__item--quiet { color: var(--text-faint); font-weight: 500; }

.navstrip__ver {
  flex: none;
  font: 400 10.5px/1 var(--mono);
  letter-spacing: .08em;
  color: var(--text-faint);
  border: 1px solid var(--edge);
  border-radius: 999px;
  padding: 5px 9px;
  margin-left: 6px;
}

.topbar__navtoggle svg { transition: transform .2s var(--ease); }
body.nav-hidden .topbar__navtoggle svg { transform: rotate(90deg); }

@media (max-width: 620px) {
  .nav__item span { font-size: 13px; }
}

.main {
  max-width: 1240px;
  margin: 0 auto;
  padding: clamp(20px, 3vw, 34px) var(--pad) 96px;
}

.view__head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  margin-bottom: 26px;
}
.view__title { font-size: clamp(22px, 3vw, 28px); }
.view__actions { display: flex; gap: 8px; }

/* ==========================================================================
   Tile grid
   ========================================================================== */

.section { margin-bottom: 34px; }

.section__head {
  display: flex; align-items: center; gap: 12px;
  margin-bottom: 14px;
}
.section__label {
  font: 700 11px/1 var(--mono);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-dim);
  white-space: nowrap;
}
.section__rule { flex: 1 1 auto; height: 1px; background: var(--edge); }
.section__count {
  font: 400 11px/1 var(--mono);
  color: var(--text-faint);
}
.section__tools { display: flex; gap: 2px; }
.section__tools .iconbtn { width: 30px; height: 30px; }
.section__tools svg { width: 15px; height: 15px; }

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, var(--tile));
  justify-content: center;
  gap: 16px;
}
@media (max-width: 560px) {
  :root { --tile: 158px; }
  .grid { gap: 12px; }
}

/* --- the tile ---
   Signature element: the monospace label strip along the bottom edge,
   printing the host the tile points at. */

.tile {
  position: relative;
  display: flex; flex-direction: column;
  min-height: 164px;
  padding: 18px 16px 0;
  border: 1px solid var(--edge);
  border-radius: var(--r-lg);
  background: var(--surface);
  color: inherit;
  text-decoration: none;
  cursor: pointer;
  overflow: hidden;
  transition: transform .16s var(--ease), border-color .16s var(--ease), box-shadow .16s var(--ease);
}
.tile:hover,
.tile:has(.tile__hit:focus-visible) {
  transform: translateY(-3px);
  border-color: var(--edge-2);
  box-shadow: var(--shadow-2);
}
.tile:active { transform: translateY(-1px) scale(.99); }

/* The whole card is the link. Keeping the anchor as an overlay means the star
   and menu buttons are real siblings rather than illegal nested controls. */
.tile__hit {
  position: absolute; inset: 0; z-index: 1;
  border-radius: inherit;
  text-decoration: none;
}
.tile__hit:focus-visible { outline: 2px solid var(--accent); outline-offset: -3px; }

/* lit corner on hover, like a port coming online */
.tile::after {
  content: '';
  position: absolute; top: 0; left: 0;
  width: 3px; height: 0;
  background: var(--accent);
  transition: height .2s var(--ease);
}
.tile:hover::after,
.tile:has(.tile__hit:focus-visible)::after,
.tile.is-fav::after { height: 34px; }

.tile__icon {
  width: 50px; height: 50px;
  display: grid; place-items: center;
  border-radius: var(--r-md);
  background: var(--surface-2);
  border: 1px solid var(--edge);
  overflow: hidden;
  flex: none;
}
.tile__icon img { width: 33px; height: 33px; object-fit: contain; }
.tile__mono {
  width: 100%; height: 100%;
  display: grid; place-items: center;
  font: 800 16px/1 var(--ui);
  letter-spacing: -.02em;
  color: #fff;
}

.tile__name {
  margin: 13px 0 2px;
  font-size: 14.5px;
  font-weight: 600;
  letter-spacing: -.01em;
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.tile__desc {
  font-size: 12.5px;
  color: var(--text-dim);
  line-height: 1.35;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
}

.tile__strip {
  margin: auto -16px 0;
  padding: 8px 16px;
  border-top: 1px solid var(--edge);
  background: var(--surface-2);
  font: 400 10px/1.2 var(--mono);
  letter-spacing: .04em;
  color: var(--text-faint);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  display: flex; align-items: center; gap: 6px;
}
.tile__dot { width: 5px; height: 5px; border-radius: 50%; background: var(--edge-2); flex: none; }
.tile.is-shared .tile__dot { background: var(--live); }

.tile__more {
  position: absolute; top: 8px; right: 8px; z-index: 2;
  width: 28px; height: 28px;
  display: grid; place-items: center;
  border: 0; border-radius: var(--r-sm);
  background: transparent;
  color: var(--text-faint);
  cursor: pointer;
  opacity: 0;
  transition: opacity .15s var(--ease), background .15s var(--ease);
}
.tile__more svg { width: 16px; height: 16px; }
.tile:hover .tile__more, .tile__more:focus-visible { opacity: 1; }
.tile__more:hover { background: var(--surface-3); color: var(--text); }
@media (hover: none) { .tile__more { opacity: 1; } }

.tile__star {
  position: absolute; top: 8px; right: 40px; z-index: 2;
  width: 28px; height: 28px;
  display: grid; place-items: center;
  border: 0; border-radius: var(--r-sm);
  background: transparent; color: var(--text-faint);
  cursor: pointer; opacity: 0;
  transition: opacity .15s var(--ease), color .15s var(--ease);
}
.tile__star svg { width: 15px; height: 15px; }
.tile:hover .tile__star, .tile__star:focus-visible { opacity: 1; }
.tile.is-fav .tile__star { opacity: 1; color: var(--accent); }
.tile.is-fav .tile__star svg { fill: var(--accent); }
@media (hover: none) { .tile__star { opacity: 1; } }

/* arrange mode */
.is-arranging .tile { cursor: grab; touch-action: none; }
.is-arranging .tile__hit { pointer-events: none; }
.is-arranging .tile__more, .is-arranging .tile__star { display: none; }
.is-arranging .tile { border-style: dashed; }
.tile.is-dragging {
  opacity: .35;
  border-style: solid;
  border-color: var(--accent);
}
.tile.is-ghost {
  position: fixed; z-index: 90;
  pointer-events: none;
  opacity: .95;
  box-shadow: var(--shadow-3);
  border-color: var(--accent);
  border-style: solid;
  transform: rotate(-1.5deg) scale(1.03);
}

/* empty and hint states */
.empty {
  border: 1px dashed var(--edge-2);
  border-radius: var(--r-lg);
  padding: 40px 24px;
  text-align: center;
  color: var(--text-dim);
  background: var(--surface);
}
.empty h3 { font-size: 17px; margin-bottom: 6px; color: var(--text); }
.empty p { margin: 0 auto 16px; max-width: 44ch; font-size: 14px; }

.dropzone {
  border: 1px dashed var(--edge-2);
  border-radius: var(--r-lg);
  min-height: 96px;
  display: grid; place-items: center;
  font: 400 11px/1 var(--mono);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-faint);
}

/* ==========================================================================
   Menus, modal, toasts
   ========================================================================== */

.menu {
  position: fixed; z-index: 70;
  min-width: 210px;
  padding: 6px;
  background: var(--surface);
  border: 1px solid var(--edge-2);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-3);
}
.menu__head {
  display: grid; gap: 2px;
  padding: 10px 12px 12px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--edge);
}
.menu__head strong { font-size: 14px; }
.menu__ver { color: var(--text-faint) !important; }
.menu__head span { font: 400 11px/1.3 var(--mono); color: var(--text-faint); overflow-wrap: anywhere; }
.menu__item {
  display: flex; align-items: center; gap: 9px;
  width: 100%;
  padding: 9px 12px;
  border: 0; border-radius: var(--r-sm);
  background: transparent;
  color: var(--text);
  font: 500 14px/1 var(--ui);
  text-align: left;
  cursor: pointer;
}
.menu__item:hover { background: var(--surface-2); }
.menu__item--danger { color: var(--danger); }
.menu__item--danger:hover { background: var(--danger-wash); }
.menu__sep { height: 1px; margin: 5px 8px; background: var(--edge); }

.modal { position: fixed; inset: 0; z-index: 80; display: grid; place-items: center; padding: 16px; }
.modal__scrim { position: absolute; inset: 0; background: rgba(6, 9, 13, .6); backdrop-filter: blur(3px); }
.modal__box {
  position: relative;
  width: min(560px, 100%);
  max-height: min(88dvh, 900px);
  display: flex; flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--edge-2);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-3);
  animation: pop .18s var(--ease);
}
.modal--wide .modal__box { width: min(880px, 100%); }
@keyframes pop { from { opacity: 0; transform: translateY(10px) scale(.985); } }

.modal__head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 18px 18px 14px 22px;
  border-bottom: 1px solid var(--edge);
}
.modal__head h2 { font-size: 18px; }
.modal__body { padding: 20px 22px; overflow: auto; display: grid; gap: 15px; }
.modal__foot {
  display: flex; justify-content: flex-end; gap: 8px;
  padding: 14px 22px 18px;
  border-top: 1px solid var(--edge);
}
.modal__foot .spacer { margin-right: auto; }

.toaster {
  position: fixed; z-index: 95;
  left: 50%; bottom: calc(20px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  display: grid; gap: 8px; width: min(420px, calc(100vw - 32px));
}
.toast {
  padding: 12px 15px;
  border-radius: var(--r-md);
  background: var(--surface-3);
  border: 1px solid var(--edge-2);
  box-shadow: var(--shadow-3);
  font-size: 14px;
  animation: rise .2s var(--ease);
}
.toast--bad { border-color: color-mix(in srgb, var(--danger) 45%, transparent); color: var(--danger); }
.toast--good { border-color: color-mix(in srgb, var(--live) 45%, transparent); }
@keyframes rise { from { opacity: 0; transform: translateY(12px); } }

/* ==========================================================================
   Settings and admin
   ========================================================================== */

.panel {
  background: var(--surface);
  border: 1px solid var(--edge);
  border-radius: var(--r-lg);
  padding: clamp(18px, 3vw, 26px);
  margin-bottom: 18px;
}
.panel h2 { font-size: 17px; margin-bottom: 4px; }
.panel__sub { margin: 0 0 18px; color: var(--text-dim); font-size: 13.5px; }
.panel__grid { display: grid; gap: 15px; max-width: 460px; }
.panel__foot { margin-top: 18px; display: flex; gap: 8px; }

.tabs { display: flex; gap: 4px; margin-bottom: 20px; border-bottom: 1px solid var(--edge); }
.tab {
  border: 0; background: transparent; cursor: pointer;
  padding: 10px 14px;
  font: 600 13.5px/1 var(--ui);
  color: var(--text-dim);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.tab:hover { color: var(--text); }
.tab.is-active { color: var(--accent); border-bottom-color: var(--accent); }

.tablewrap { overflow-x: auto; border: 1px solid var(--edge); border-radius: var(--r-lg); background: var(--surface); }
table.data { width: 100%; border-collapse: collapse; font-size: 13.5px; min-width: 560px; }
table.data th {
  text-align: left;
  font: 700 10.5px/1 var(--mono);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-faint);
  padding: 12px 14px;
  border-bottom: 1px solid var(--edge);
  white-space: nowrap;
}
table.data td { padding: 12px 14px; border-bottom: 1px solid var(--edge); vertical-align: middle; }
table.data tr:last-child td { border-bottom: 0; }
table.data tbody tr:hover { background: var(--surface-2); }
table.data .num { font-family: var(--mono); font-size: 12px; color: var(--text-dim); }
table.data .rowacts { display: flex; gap: 6px; justify-content: flex-end; }

.pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 8px;
  border-radius: 999px;
  font: 700 10px/1.4 var(--mono);
  letter-spacing: .08em;
  text-transform: uppercase;
  border: 1px solid var(--edge-2);
  color: var(--text-dim);
}
.pill--on { color: var(--live); border-color: color-mix(in srgb, var(--live) 40%, transparent); }
.pill--admin { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
.pill--off { color: var(--text-faint); }

.who { display: flex; align-items: center; gap: 10px; }
.who__av {
  width: 30px; height: 30px; flex: none;
  border-radius: 50%;
  display: grid; place-items: center;
  background: var(--surface-3);
  border: 1px solid var(--edge-2);
  font: 700 11px/1 var(--ui);
}
.who__name { font-weight: 600; }
.who__sub { font: 400 11px/1.2 var(--mono); color: var(--text-faint); }

.miniicon {
  width: 30px; height: 30px; flex: none;
  border-radius: var(--r-sm);
  border: 1px solid var(--edge);
  background: var(--surface-2);
  display: grid; place-items: center;
  overflow: hidden;
}
.miniicon img { width: 20px; height: 20px; object-fit: contain; }
.miniicon span { font: 800 11px/1 var(--ui); color: #fff; width: 100%; height: 100%; display: grid; place-items: center; }

/* icon picker inside the app editor */
.iconpick { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.iconpick__preview {
  width: 58px; height: 58px; flex: none;
  border-radius: var(--r-md);
  border: 1px solid var(--edge-2);
  background: var(--surface-2);
  display: grid; place-items: center;
  overflow: hidden;
}
.iconpick__preview img { width: 38px; height: 38px; object-fit: contain; }
.iconpick__preview span { width: 100%; height: 100%; display: grid; place-items: center; font: 800 19px/1 var(--ui); color: #fff; }
.iconpick__acts { display: flex; gap: 8px; flex-wrap: wrap; }

.seg { display: flex; gap: 0; border: 1px solid var(--edge-2); border-radius: var(--r-md); overflow: hidden; }
.seg button {
  flex: 1 1 0; min-width: 0;
  border: 0; background: var(--surface-2); color: var(--text-dim);
  padding: 10px 8px;
  font: 600 12.5px/1.2 var(--ui);
  cursor: pointer;
  border-right: 1px solid var(--edge-2);
}
.seg button:last-child { border-right: 0; }
.seg button.is-on { background: var(--accent); color: var(--accent-ink); }

.assign {
  max-height: 190px; overflow: auto;
  border: 1px solid var(--edge-2); border-radius: var(--r-md);
  padding: 6px;
  display: grid; gap: 2px;
}
.assign label {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 9px; border-radius: var(--r-sm);
  font-size: 13.5px; cursor: pointer;
}
.assign label:hover { background: var(--surface-2); }
.assign input { accent-color: var(--accent); }

.hiddenlist { display: grid; gap: 8px; }
.hiddenrow {
  display: flex; align-items: center; gap: 11px;
  padding: 10px 12px;
  border: 1px solid var(--edge); border-radius: var(--r-md);
  background: var(--surface-2);
  font-size: 13.5px;
}
.hiddenrow .btn { margin-left: auto; }

.loading {
  padding: 40px; text-align: center;
  font: 400 11px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase;
  color: var(--text-faint);
}

/* ==========================================================================
   Widgets
   Small cards in their own group above the app tiles. Same panel material
   as a tile, wider footprint, content per type.
   ========================================================================== */

.widgetgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, 296px);
  justify-content: center;
  gap: 16px;
}
@media (max-width: 660px) {
  .widgetgrid { grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 12px; }
}

.widget {
  position: relative;
  display: flex; flex-direction: column;
  min-height: 132px;
  border: 1px solid var(--edge);
  border-radius: var(--r-lg);
  background: var(--surface);
  overflow: hidden;
  transition: border-color .16s var(--ease), box-shadow .16s var(--ease);
}
.widget:hover { border-color: var(--edge-2); box-shadow: var(--shadow-1); }

.widget__head {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 10px 10px 16px;
  border-bottom: 1px solid var(--edge);
  background: var(--surface-2);
}
.widget__type {
  font: 700 10px/1 var(--mono);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent);
  flex: none;
}
.widget__title {
  font: 600 13px/1.3 var(--ui);
  color: var(--text-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  flex: 1 1 auto; min-width: 0;
}
.widget__more {
  flex: none;
  width: 28px; height: 28px;
  display: grid; place-items: center;
  border: 0; border-radius: var(--r-sm);
  background: transparent;
  color: var(--text-faint);
  cursor: pointer;
}
.widget__more svg { width: 16px; height: 16px; }
.widget__more:hover { background: var(--surface-3); color: var(--text); }

.widget__body {
  flex: 1 1 auto;
  padding: 14px 16px 16px;
  display: grid;
  align-content: center;
  gap: 4px;
  min-width: 0;
}

/* clock */
.widget__time { font: 700 34px/1.1 var(--mono); letter-spacing: -.02em; }
.widget__date { font: 400 12px/1.3 var(--mono); color: var(--text-dim); }

/* countdown */
.widget__count { font: 700 34px/1.1 var(--mono); letter-spacing: -.02em; }
.widget__count small { font-size: 14px; font-weight: 400; color: var(--text-dim); margin-left: 6px; }
.widget__when { font: 400 12px/1.3 var(--mono); color: var(--text-dim); }
.widget__count.is-past { color: var(--live); }

/* note */
.widget__note {
  align-content: start;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--text-dim);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  max-height: 132px;
  overflow: auto;
}

/* rss */
.widget__feed { align-content: start; gap: 0; padding: 6px 8px 8px; }
.widget__feed a {
  display: block;
  padding: 7px 8px;
  border-radius: var(--r-sm);
  color: var(--text);
  font-size: 13px;
  line-height: 1.4;
  text-decoration: none;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.widget__feed a:hover { background: var(--surface-2); color: var(--accent); }
.widget__feed .widget__feednote {
  padding: 8px;
  font: 400 11px/1.4 var(--mono);
  color: var(--text-faint);
}

/* arrange mode */
.is-arranging .widget { cursor: grab; touch-action: none; border-style: dashed; }
.is-arranging .widget__more { display: none; }
.is-arranging .widget__feed a { pointer-events: none; }
.widget.is-dragging { opacity: .35; border-style: solid; border-color: var(--accent); }
.widget.is-ghost {
  position: fixed; z-index: 90;
  pointer-events: none;
  opacity: .95;
  box-shadow: var(--shadow-3);
  border-color: var(--accent);
  border-style: solid;
  transform: rotate(-1.5deg) scale(1.03);
}

/* sign in page: way back to the public site */
.auth__back { margin: 2px 0 0; text-align: center; font-size: 13px; }
.auth__back a { color: var(--text-faint); }
.auth__back a:hover { color: var(--accent); }

/* ---- motion preferences -------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .tile:hover { transform: none; }
}
