@font-face {
  font-family: "Sora";
  src: url("fonts/sora-latin-wght-normal.woff2") format("woff2");
  font-weight: 100 800;
  font-display: swap;
}

/* Nova's world: night navy, cool ink, periwinkle accent. Light mirrors it on cool paper. */
:root {
  --bg: #05060d;
  --surface: #0b0d1a;
  --raise: #121530;
  --hover: #171b3a;
  --line: rgb(242 244 255 / 0.1);
  --line-strong: rgb(242 244 255 / 0.2);
  --ink: #f2f4ff;
  --ink-2: #b4bbdd;
  --ink-3: #8a93b9;
  --accent: hsl(222 80% 64%);
  --accent-hover: hsl(222 85% 70%);
  --accent-ink: #05060d;
  --accent-soft: hsl(222 80% 64% / 0.16);
  --online: #5aa0ff;
  --ingame: #b38cff;
  --on-ingame: #0a0c1c;
  --danger: #ff7a88;
  --danger-soft: rgb(255 122 136 / 0.14);
  --shadow: 0 18px 48px -12px rgb(1 2 12 / 0.7), 0 2px 6px rgb(1 2 12 / 0.4);
  --radius: 10px;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --mono: "Cascadia Mono", "SF Mono", Consolas, ui-monospace, monospace;
  color-scheme: dark;
}

@media (prefers-color-scheme: light) {
  :root {
    --bg: #eef1fa;
    --surface: #f8f9fe;
    --raise: #e4e8f6;
    --hover: #dde2f3;
    --line: rgb(11 14 31 / 0.1);
    --line-strong: rgb(11 14 31 / 0.2);
    --ink: #0b0e1f;
    --ink-2: #353d60;
    --ink-3: #555e83;
    --accent: hsl(222 72% 48%);
    --accent-hover: hsl(222 76% 42%);
    --accent-ink: #f8f9fe;
    --accent-soft: hsl(222 72% 48% / 0.12);
    --online: #1f63d6;
    --ingame: #7044d6;
    --on-ingame: #f8f9fe;
    --danger: #c42840;
    --danger-soft: rgb(196 40 64 / 0.1);
    --shadow: 0 18px 48px -14px rgb(22 30 70 / 0.28), 0 2px 6px rgb(22 30 70 / 0.12);
    color-scheme: light;
  }
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  min-height: 100dvh;
  background: var(--bg);
  color: var(--ink);
  font: 400 0.9375rem/1.5 "Sora", "Segoe UI", system-ui, sans-serif;
  font-feature-settings: "tnum" 1;
  caret-color: var(--accent);
  scrollbar-color: var(--line-strong) transparent;
}
::selection { background: var(--accent); color: var(--accent-ink); }
[hidden] { display: none !important; }
h1, h2, h3, p { margin: 0; }
button, input { font: inherit; color: inherit; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 6px; }

.skip { position: absolute; left: -999px; top: 0.5rem; padding: 0.5rem 0.75rem; background: var(--accent); color: var(--accent-ink); border-radius: var(--radius); z-index: 30; }
.skip:focus { left: 0.5rem; }

.icon { width: 1.125rem; height: 1.125rem; flex: none; fill: currentColor; }

.wordmark { display: inline-flex; align-items: center; gap: 0.625rem; font-weight: 700; font-size: 1.0625rem; letter-spacing: -0.01em; }

/* The launcher's Nova mark: ring plus N, drawn as one stroke. */
.mark { fill: none; stroke: currentColor; stroke-width: 7; stroke-linecap: round; stroke-linejoin: round; overflow: visible; }
.mark-small { width: 1.5rem; height: 1.5rem; stroke-width: 9; }
.mark-draw { width: 3.5rem; height: 3.5rem; stroke-width: 5; }
@media (prefers-reduced-motion: no-preference) {
  .mark-draw .mark-ring { stroke-dasharray: 330; stroke-dashoffset: 330; animation: draw 1.1s 0.15s var(--ease) forwards; }
  .mark-draw .mark-n { stroke-dasharray: 190; stroke-dashoffset: 190; animation: draw 0.9s 0.7s var(--ease) forwards; }
}
@keyframes draw { to { stroke-dashoffset: 0; } }

/* Buttons: one 10px radius for every control; chips and switches are the only full rounds. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  min-height: 2.5rem; padding: 0 1rem; border-radius: var(--radius); border: 1px solid transparent;
  background: none; cursor: pointer; font-weight: 600; font-size: 0.875rem; white-space: nowrap;
  transition: background-color 180ms var(--ease), border-color 180ms var(--ease), color 180ms var(--ease), transform 120ms var(--ease);
}
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }
.btn-primary { background: var(--accent); color: var(--accent-ink); }
.btn-primary:hover:not(:disabled) { background: var(--accent-hover); }
.btn-secondary { border-color: var(--line-strong); background: var(--surface); }
.btn-secondary:hover:not(:disabled) { background: var(--hover); }
.btn-quiet { color: var(--ink-2); }
.btn-quiet:hover:not(:disabled) { background: var(--hover); color: var(--ink); }
.btn-danger { background: var(--danger); color: var(--accent-ink); }
.btn-danger:hover:not(:disabled) { filter: brightness(1.08); }
.btn-icon { width: 2.5rem; padding: 0; }
.btn-block { width: 100%; }
.btn[aria-busy="true"] { cursor: progress; }

/* Fields */
.field { display: grid; gap: 0.375rem; }
.field-grow { flex: 1 1 16rem; }
.field-label { font-size: 0.8125rem; font-weight: 600; color: var(--ink-2); }
.field-help { font-size: 0.8125rem; color: var(--ink-3); }
.field-error { font-size: 0.8125rem; color: var(--danger); font-weight: 500; }
input[type="text"], input[type="password"] {
  min-height: 2.75rem; padding: 0 0.875rem; border-radius: var(--radius);
  border: 1px solid var(--line-strong); background: var(--bg);
  transition: border-color 180ms var(--ease), box-shadow 180ms var(--ease);
}
input:hover { border-color: var(--ink-3); }
input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
input[aria-invalid="true"] { border-color: var(--danger); }

/* Sign in */
.login { min-height: 100dvh; display: grid; place-items: center; padding: 1.5rem 1rem; }
.login-form { width: min(100%, 24rem); display: grid; gap: 1.25rem; }
.login-form .wordmark { font-size: 1.75rem; letter-spacing: -0.02em; }
.login-lede { color: var(--ink-2); margin-top: -0.75rem; }

/* App frame */
.app { max-width: 72rem; margin: 0 auto; padding: 0 clamp(1rem, 3vw, 2rem) 4rem; }
.topbar { display: flex; align-items: center; gap: 1rem; min-height: 4rem; border-bottom: 1px solid var(--line); }
.topbar-meta { margin-right: auto; color: var(--ink-3); font-size: 0.8125rem; }

.banner {
  display: flex; align-items: center; gap: 0.625rem; margin-top: 1rem; padding: 0.75rem 1rem;
  border-radius: var(--radius); background: var(--danger-soft); color: var(--danger); font-weight: 500; font-size: 0.875rem;
}

/* Status strip: the live count is the headline */
.status {
  display: grid; grid-template-columns: 1fr auto auto; align-items: end; gap: 1.5rem 2.5rem;
  padding: 2.5rem 0 2rem;
}
.status-count { display: flex; align-items: baseline; gap: 0.5rem; font-size: clamp(2.75rem, 7vw, 4.5rem); font-weight: 700; letter-spacing: -0.035em; line-height: 1; }
#online-word { font-size: clamp(1.25rem, 2.6vw, 1.625rem); font-weight: 500; color: var(--ink-2); letter-spacing: -0.01em; }
.pulse { width: 0.75rem; height: 0.75rem; border-radius: 50%; background: var(--ink-3); align-self: center; flex: none; }
.pulse.is-live { background: var(--online); box-shadow: 0 0 0 0 color-mix(in srgb, var(--online) 60%, transparent); }
@media (prefers-reduced-motion: no-preference) {
  .pulse.is-live { animation: pulse 2.4s var(--ease) infinite; }
}
@keyframes pulse { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--online) 55%, transparent); } 70%, 100% { box-shadow: 0 0 0 0.6rem transparent; } }

.online-names { list-style: none; margin: 1rem 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.5rem; min-height: 2rem; }
/* Launcher badge language: solid hue pill, dark ink. Violet = in the game, outline = Nova connected only. */
.online-names li { display: inline-flex; align-items: center; gap: 0.375rem; padding: 0.3rem 0.85rem; border-radius: 999px; border: 1px solid var(--online); color: var(--ink); font-size: 0.8125rem; font-weight: 700; letter-spacing: 0.02em; }
.online-names li.is-ingame { background: var(--ingame); border-color: var(--ingame); color: var(--on-ingame); }
.online-names .none { border: 0; padding-left: 0; color: var(--ink-3); font-weight: 400; letter-spacing: 0; }

.status-facts { display: flex; gap: 2rem; margin: 0; }
.status-facts dt { font-size: 0.75rem; color: var(--ink-3); font-weight: 500; }
.status-facts dd { margin: 0.125rem 0 0; font-size: 1.25rem; font-weight: 600; }

/* Add friend + one-time token reveal */
.add, .reveal { border: 1px solid var(--line); background: var(--surface); border-radius: var(--radius); padding: 1.25rem; margin-bottom: 1.5rem; }
.add-form { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0.75rem 1rem; }
.add-actions { display: flex; gap: 0.5rem; padding-top: 1.625rem; }
.add-form .field-error { flex-basis: 100%; }

.reveal { display: flex; align-items: flex-start; gap: 1.5rem; border-color: color-mix(in srgb, var(--accent) 55%, transparent); }
.reveal-mark { flex: none; color: var(--accent); }
.reveal-body { flex: 1; display: grid; gap: 0.5rem; min-width: 0; }
.reveal-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.75rem; }
.reveal-title { font-size: 1.125rem; font-weight: 650; letter-spacing: -0.01em; }
.reveal-note { color: var(--ink-2); font-size: 0.875rem; max-width: 60ch; }
.token {
  margin-top: 0.5rem; min-width: 0; max-width: 40rem; padding: 0.75rem 1rem; border-radius: var(--radius); background: var(--bg);
  border: 1px dashed var(--line-strong); font: 500 0.9375rem/1.4 var(--mono); letter-spacing: 0.02em; overflow-wrap: anywhere; user-select: all;
}
@media (prefers-reduced-motion: no-preference) {
  .reveal.is-new { animation: reveal 520ms var(--ease) both; }
  .reveal.is-new .token { animation: token 700ms 120ms var(--ease) both; }
}
@keyframes reveal { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
@keyframes token { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }

/* Tabs */
.tabs { display: flex; gap: 0.25rem; border-bottom: 1px solid var(--line); overflow-x: auto; scrollbar-width: none; }
.tab {
  position: relative; display: inline-flex; align-items: center; gap: 0.5rem; min-height: 3rem; padding: 0 1rem;
  border: 0; background: none; cursor: pointer; color: var(--ink-3); font-weight: 600; font-size: 0.875rem; white-space: nowrap;
  transition: color 180ms var(--ease);
}
.tab:hover { color: var(--ink); }
.tab[aria-selected="true"] { color: var(--ink); }
.tab::after { content: ""; position: absolute; left: 0.75rem; right: 0.75rem; bottom: -1px; height: 2px; border-radius: 2px; background: var(--accent); transform: scaleX(0); transition: transform 220ms var(--ease); }
.tab[aria-selected="true"]::after { transform: scaleX(1); }
.tab-count { color: var(--ink-3); font-weight: 500; }

.panels:focus { outline: none; }
.panel { padding-top: 0.5rem; }
.panel-title { font-size: 1rem; font-weight: 650; }
.panel-note { color: var(--ink-2); font-size: 0.875rem; max-width: 62ch; margin-top: 0.25rem; }

/* Rows: one hairline between rows, no boxes */
.rows { list-style: none; margin: 0; padding: 0; }
/* One column template for every tab, so the status column never jumps when switching tabs. */
.row {
  display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1.5fr) 9rem 10rem; align-items: center; gap: 1rem;
  min-height: 4rem; padding: 0.625rem 0.5rem; border-bottom: 1px solid var(--line);
  transition: background-color 180ms var(--ease);
}
.row:hover { background: color-mix(in srgb, var(--hover) 55%, transparent); }
.row-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row-sub { color: var(--ink-3); font-size: 0.8125rem; }
.row-id { font: 500 0.8125rem var(--mono); color: var(--ink-3); }
.row-extra { justify-self: end; }
.row-actions { display: flex; gap: 0.25rem; justify-content: flex-end; }
.row.is-revoked .row-name { color: var(--ink-3); text-decoration: line-through; text-decoration-thickness: 1px; }

.state { display: inline-flex; align-items: center; gap: 0.5rem; font-size: 0.875rem; color: var(--ink-2); }
.state::before { content: ""; width: 0.5rem; height: 0.5rem; border-radius: 50%; background: var(--ink-3); opacity: 0.6; }
.state.is-online { color: var(--ink); }
.state.is-online::before { background: var(--online); opacity: 1; }
.state.is-ingame::before { background: var(--ingame); opacity: 1; }
.state.is-revoked { color: var(--danger); }
.state.is-revoked::before { background: var(--danger); opacity: 1; }

.chips { display: flex; flex-wrap: wrap; gap: 0.375rem; }
.chip { padding: 0.125rem 0.5rem; border-radius: 999px; border: 1px solid var(--line-strong); font-size: 0.75rem; color: var(--ink-2); }

.row-edit { display: flex; gap: 0.5rem; align-items: center; grid-column: 1 / -1; flex-wrap: wrap; }
.row-edit input { flex: 1 1 12rem; min-height: 2.5rem; }
.row-confirm { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem; padding: 0.75rem 1rem; border-radius: var(--radius); background: var(--danger-soft); }
.row-confirm p { flex: 1 1 18rem; font-size: 0.875rem; }

/* Activity */
.day { margin: 1.5rem 0 0.25rem; font-size: 0.8125rem; font-weight: 600; color: var(--ink-3); }
.event { display: grid; grid-template-columns: 4.5rem 1fr; gap: 1rem; padding: 0.625rem 0.5rem; border-bottom: 1px solid var(--line); font-size: 0.875rem; }
.event time { color: var(--ink-3); font-family: var(--mono); font-size: 0.8125rem; }

/* Captures */
.capture-control { display: flex; align-items: flex-start; justify-content: space-between; gap: 1.5rem; padding: 1rem 0.5rem 1.5rem; border-bottom: 1px solid var(--line); }
.switch { position: relative; flex: none; width: 3.25rem; height: 1.875rem; border-radius: 999px; border: 1px solid var(--line-strong); background: var(--raise); cursor: pointer; transition: background-color 200ms var(--ease); }
.switch-knob { position: absolute; top: 3px; left: 3px; width: 1.375rem; height: 1.375rem; border-radius: 50%; background: var(--ink-2); transition: transform 220ms var(--ease), background-color 200ms var(--ease); }
.switch[aria-checked="true"] { background: var(--accent); border-color: var(--accent); }
.switch[aria-checked="true"] .switch-knob { transform: translateX(1.375rem); background: var(--accent-ink); }
.switch:disabled { opacity: 0.5; cursor: not-allowed; }
.row-sub-id { display: none; }

/* Empty and loading */
.empty { padding: 3rem 0.5rem; max-width: 46ch; }
.empty h3 { font-size: 1rem; font-weight: 650; }
.empty p { color: var(--ink-2); font-size: 0.875rem; margin-top: 0.375rem; }
.empty .btn { margin-top: 1rem; }
.skeleton { height: 4rem; border-bottom: 1px solid var(--line); background: linear-gradient(90deg, transparent, var(--raise), transparent) 0 0 / 200% 100%; }
@media (prefers-reduced-motion: no-preference) {
  .skeleton { animation: shimmer 1.4s linear infinite; }
}
@keyframes shimmer { to { background-position: -200% 0; } }

/* Row menu (fixed so no container clips it) */
.menu {
  position: fixed; z-index: 20; min-width: 12rem; padding: 0.375rem; border-radius: var(--radius);
  background: var(--surface); border: 1px solid var(--line-strong); box-shadow: var(--shadow);
}
.menu button {
  display: flex; align-items: center; gap: 0.625rem; width: 100%; min-height: 2.5rem; padding: 0 0.75rem; border: 0; border-radius: 6px;
  background: none; cursor: pointer; font-size: 0.875rem; text-align: left;
}
.menu button:hover, .menu button:focus-visible { background: var(--hover); outline: none; }
.menu .is-danger { color: var(--danger); }
.menu hr { border: 0; border-top: 1px solid var(--line); margin: 0.375rem 0; }

.toast {
  position: fixed; left: 50%; bottom: 1.5rem; z-index: 25; transform: translate(-50%, 1rem); opacity: 0; pointer-events: none;
  padding: 0.75rem 1.125rem; border-radius: var(--radius); background: var(--ink); color: var(--bg); font-weight: 600; font-size: 0.875rem; box-shadow: var(--shadow);
  transition: opacity 200ms var(--ease), transform 260ms var(--ease);
}
.toast.is-on { opacity: 1; transform: translate(-50%, 0); }

/* Phone */
@media (max-width: 720px) {
  .status { grid-template-columns: 1fr; padding-top: 1.75rem; gap: 1.25rem; }
  .status-facts { gap: 1.5rem; }
  #add-open { width: 100%; }
  .row { grid-template-columns: minmax(0, 1fr) auto; gap: 0.25rem 0.75rem; }
  .row > .row-main { grid-column: 1; }
  .row > .row-meta { grid-column: 1; grid-row: 2; }
  .row > .row-extra { display: none; }
  .row > .row-actions { grid-column: 2; grid-row: 1 / span 2; }
  .row-sub-id { display: inline; font-family: var(--mono); }
  .reveal { flex-direction: column; gap: 1rem; }
  .reveal-mark { width: 2.5rem; height: 2.5rem; }
  .reveal-actions .btn-primary { flex: 1; }
  .add-actions { padding-top: 0; }
  .event { grid-template-columns: 3.75rem 1fr; gap: 0.75rem; }
}

/* Small phones: all four tabs fit without hidden scrolling. */
@media (max-width: 480px) {
  .tabs { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0; }
  .tab { justify-content: center; padding: 0 0.25rem; gap: 0.25rem; font-size: 0.8125rem; }
  .tab .icon { display: none; }
  .tab::after { left: 0.375rem; right: 0.375rem; }
}
