/* GvGPilot console assets - the shared base layout CSS, extracted from
   web/templates/base.html so the browser caches it (the same
   /static/console/<file>?v=STATIC_VERSION mechanism as event.css) instead of
   re-shipping ~21 KB of it inside every HTML response. The ONE palette home
   (web/templates/_tokens.html) deliberately stays inline in base.html, so this
   file declares NO custom properties of its own - a :root block here would be
   a second palette, and the drift guard now scans this directory for one.
   Content is the former inline <style> block (everything that followed the
   tokens include), dedented by the 4 spaces the template layer added; CSS
   whitespace carries no meaning, so the rendered result is unchanged. */
* { box-sizing: border-box; }
/* No image may exceed its box, and an image with no usable source must not
   render at all: an empty/failed src paints the engine's placeholder glyph,
   which Safari scales to the element's box (a viewport-sized white icon on a
   cache miss). Structure beats condition - the element is invisible until it
   has pixels. */
img { max-width: 100%; height: auto; }
img:not([src]), img[src=""] { display: none; }
/* [hidden] must always win over a component's own display rule. The UA's
   [hidden] rule is a plain `display: none` and loses to any later
   `display:` declaration of equal specificity - so a component that sets
   its own display (the attendance legend, the class picker) stayed visible
   while its JS believed it was hidden. The contract belongs to the sheet
   every console page loads, not to one page's sheet. */
[hidden] { display: none !important; }
html { color-scheme: dark; }
html { background: var(--bg); }
/* The page is the deepest plane: a long vertical fall-off, darker at the
   foot than under the board, so panels have something to float above. */
body {
  margin: 0;
  background:
    var(--lamp),
    linear-gradient(180deg, #10151f 0%, var(--bg) 40%, #080a0f 100%);
  color: var(--text);
  min-height: 100vh;
  font-family: var(--font);
  font-size: 15px; line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  /* No child may ever grow the document sideways: a horizontal scroll would
     visually de-center every centered column (main, .dash) mid-scroll. */
  overflow-x: clip;
}
a { color: var(--accent-hover); text-decoration: none; }
a:hover { text-decoration: underline; }
::selection { background: var(--accent-line); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0;
  clip: rect(0 0 0 0); clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}
/* ---- Skip link: first tab stop, off-screen until focused ---- */
.skip-link {
  position: absolute; left: 8px; top: -52px;
  z-index: var(--z-toast);
  background: var(--panel-2); color: var(--text);
  padding: 8px 14px; border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  font-size: .85rem; font-weight: 600; text-decoration: none !important;
  transition: top .12s ease-out;
}
.skip-link:focus-visible { top: 8px; }
@media (prefers-reduced-motion: reduce) {
  .skip-link { transition: none; }
}

/* ---- App shell ---- */
.topnav {
  display: flex; align-items: center; gap: 4px;
  padding: 0 20px; height: 58px;
  background: linear-gradient(180deg, #1a2137 0%, #121829 100%);
  border-bottom: 0;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.06), 0 2px 4px rgba(0,0,0,.45), 0 14px 30px -10px rgba(0,0,0,.7);
  position: sticky; top: 0; z-index: var(--z-sticky);
}
.topnav .nav-link.nav-premium { color: var(--accent-hover) !important; font-weight: 700; }
.topnav .nav-link.nav-premium:hover { color: var(--text) !important; }
.wordmark { font-weight: 900; letter-spacing: .02em; font-size: 1.2rem; line-height: 1; }
.wordmark .a { color: var(--text); }
.wordmark .b { color: var(--muted); font-weight: 600; letter-spacing: .14em; margin-left: 1px; }
.brand {
  display: flex; align-items: center; gap: 9px;
  font-weight: 800; font-size: 1rem; color: var(--text) !important;
  margin-right: 20px; text-decoration: none !important;
}
/* The brand mark: the winged chevron from the hero art, as a stroke glyph. */
.brand::before {
  content: ""; width: 22px; height: 22px; flex-shrink: 0;
  background-color: var(--accent-hover);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M1.5 4.5L12 10.8 22.5 4.5 19.2 10 12 14.6 4.8 10z'/%3E%3Cpath d='M7.6 13.2L12 21.5l4.4-8.3L12 15.9z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M1.5 4.5L12 10.8 22.5 4.5 19.2 10 12 14.6 4.8 10z'/%3E%3Cpath d='M7.6 13.2L12 21.5l4.4-8.3L12 15.9z'/%3E%3C/svg%3E") center / contain no-repeat;
  filter: drop-shadow(0 0 6px rgba(79,94,240,.55));
}
.topnav .nav-link {
  color: var(--muted) !important; text-decoration: none !important;
  padding: 6px 12px; border-radius: var(--radius-sm);
  font-size: .86rem; font-weight: 600;
  transition: color .12s, background .12s;
  min-height: 34px; display: inline-flex; align-items: center;
}
.topnav .nav-link:hover { color: var(--text) !important; background: var(--panel-2); }
.topnav .nav-link.active {
  color: var(--text) !important; background: var(--panel-2);
  box-shadow: inset 0 0 0 1px var(--line);
}
.topnav .spacer { flex: 1; }
.topnav .clock {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  color: var(--muted); font-size: .8rem; margin-right: 12px;
  letter-spacing: .02em;
}
.topnav .user-chip {
  color: var(--muted) !important; font-size: .84rem;
  padding: 5px 12px; border: 1px solid var(--line);
  border-radius: 99px; text-decoration: none !important;
  transition: color .12s, border-color .12s;
  min-height: 30px; display: inline-flex; align-items: center;
}
.topnav .user-chip:hover { color: var(--text) !important; border-color: var(--line-strong); }
main { max-width: 1120px; margin: 0 auto; padding: 28px 24px 48px; }

/* ---- Seamless navigation. Cross-document view transitions make every
   navigation cross-fade instead of flashing white, and the guild bar is
   NAMED so it morphs instead of re-animating (the pages change, the
   frame does not). The top nav is deliberately NOT named: it is
   `position: sticky`, so on a scrolled page the outgoing snapshot sits at
   its stuck offset while the new page renders at scroll 0 - a named group
   animates that difference and the whole bar visibly DRIFTS on every
   navigation. Unnamed, it rides the root cross-fade, where identical
   pixels cannot move. ---- */
@view-transition { navigation: auto; }
.guild-bar { view-transition-name: console-guild; }

/* Docs <-> Reference share one tab strip. Naming it keeps the frame
   STILL across the switch and cross-fades only the current-tab
   highlight; unnamed, the whole page (strip included) faded, so the
   highlight appeared to snap and the swap read as a jump. Safe to name,
   unlike the sticky top nav: the strip sits at the same offset in both
   documents, so a group animation has no drift to travel. */
.docs-tabs { view-transition-name: docs-tabs; }
::view-transition-group(docs-tabs) {
  animation-duration: .3s;
  animation-timing-function: ease-out;
}
::view-transition-old(docs-tabs),
::view-transition-new(docs-tabs) {
  animation-duration: .22s;
  animation-timing-function: ease-out;
  mix-blend-mode: normal;
}
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(docs-tabs),
  ::view-transition-old(docs-tabs),
  ::view-transition-new(docs-tabs) { animation: none !important; }
}

/* Entering a console: the dashboard row that was clicked carries the same
   name as the hub's bar, so the row IS the bar on the other side. That is
   a large geometry change (a pill becomes the console's spine), and two
   behaviours both read badly at length: stretched contents (snapshots
   squash to the animated box) and a long .4s travel (full-viewport fades
   with a lone tail feel floaty). The contents are object-fit: cover so
   they fill the landing box proportionally instead of distorting, and
   every clock here sits on one short .3s family so old, new and box land
   together. */
::view-transition-group(console-guild) {
  animation-duration: .3s;
  animation-timing-function: cubic-bezier(.22, .61, .36, 1);
}
::view-transition-old(console-guild),
::view-transition-new(console-guild) {
  animation-duration: .24s;
  animation-timing-function: ease-out;
  mix-blend-mode: normal;
  height: 100%;
  width: 100%;
  object-fit: cover;
  overflow: clip;
}
/* The page itself rides the SAME clock as the named bar: one duration
   family, so the outgoing page cannot finish fading before the bar has
   landed (which read as a jump) and the incoming page cannot arrive
   early. Short family: a lone-fade tail on a full-viewport cross-fade
   reads as drag, so old, new and box land inside .3s. */
::view-transition-group(root) {
  animation-duration: .3s;
  animation-timing-function: cubic-bezier(.22, .61, .36, 1);
}
::view-transition-old(root) {
  animation-duration: .2s;
  animation-timing-function: ease-out;
}
::view-transition-new(root) {
  animation-duration: .28s;
  animation-timing-function: ease-out;
}
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(console-guild),
  ::view-transition-old(console-guild),
  ::view-transition-new(console-guild),
  ::view-transition-group(root),
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation: none !important;
  }
}
/* ---- Guild section bar: THE one persistent where-am-I on guild
   surfaces. Back arrow always top-left (one level up), the page's name
   centred, the guild on the right. Replaces per-page breadcrumbs and
   back chips; public pages never render it. ---- */
/* The guild bar is the console's spine: a raised surface with the accent
   bleeding in from a lit rail on the left, the back button riding that
   rail, the guild's monogram mark, its identity (name + state badges -
   stated HERE and nowhere else), and the page name as a quiet locator. */
/* THE BOARD. Every console page opens with it: a full-bleed band under the
   nav, lit by the lamp at its top centre, carrying the guild line and then
   the page name in the display register. The band spans the viewport and
   its contents sit on the 1120 column. */
.guild-bar {
  position: relative;
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr);
  grid-template-areas: "back mark id" "title title title";
  align-items: center; column-gap: 12px; row-gap: 10px;
  margin: -28px calc(50% - 50vw) 32px; width: 100vw;
  padding: 20px var(--board-pad-x) 26px;
  border: 0;
  border-radius: 0;
  background: var(--board);
  box-shadow: var(--board-rail);
  overflow: visible;
}
.gb-back { grid-area: back; }
.gb-mark { grid-area: mark; }
.gb-identity { grid-area: id; }
.gb-title { grid-area: title; justify-self: start; min-width: 0; max-width: 100%; }
.gb-mark {
  width: 40px; height: 40px; margin-left: 2px;
  display: grid; place-items: center;
  font-family: var(--font-display);
  font-weight: var(--w-display-face); font-size: 1.3rem; letter-spacing: 0;
  color: #fff;
  background: var(--crest);
  border-radius: 9px;
  box-shadow: var(--crest-edge);
}
.gb-back {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent; color: var(--muted);
  transition: color .12s, border-color .12s, background .12s;
}
.gb-back:hover { color: var(--text); background: rgba(255,255,255,.06); box-shadow: 0 2px 8px rgba(0,0,0,.4); }
.gb-back svg { width: 15px; height: 15px; display: block; }
.gb-identity {
  display: flex; align-items: center; gap: 9px;
  min-width: 0; justify-self: start;
}
.gb-name {
  font-weight: 700; font-size: 1rem; letter-spacing: -.01em;
  color: var(--text-dim); max-width: 34ch;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gb-title h1 {
  margin: 0; padding: 0;
  font-family: var(--font-display); font-weight: var(--w-display-face);
  font-size: clamp(2rem, 1.3rem + 2.4vw, 3rem); line-height: 1;
  letter-spacing: .01em; text-transform: uppercase; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 100%;
  text-shadow: 0 2px 0 rgba(0,0,0,.3), 0 10px 30px rgba(0,0,0,.4);
}
@media (max-width: 640px) {
  .guild-bar { padding: 14px 16px 16px; margin-bottom: 24px; row-gap: 8px; }
  .gb-identity { flex-wrap: wrap; row-gap: 4px; }
  .gb-name { max-width: 18ch; }
  .gb-title h1 { font-size: 1.8rem; white-space: normal; }
}
@media (prefers-reduced-motion: reduce) {
  .gb-back { transition: none; }
}
.page-head { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 20px; gap: 12px; flex-wrap: wrap; }
/* Weight rule: one display moment per screen region. The board owns the
   page name; every head under a board returns to the body face. */
.page-head h1 {
  margin: 0; font-weight: 800; font-size: 1.35rem; line-height: 1.2;
  letter-spacing: -.02em; text-wrap: balance;
}
.page-head .sub { color: var(--muted); font-size: .9rem; margin-top: 6px; }
/* A page with no guild bar opens with its own board: the page head IS the
   band (dashboard, admin, licence, tickets). Under a guild bar the head
   stays a quiet sub-title, the board already carries the page name. */
main > .page-head, .dash > .page-head {
  margin: -28px calc(50% - 50vw) 32px; width: 100vw;
  padding: 26px var(--board-pad-x) 30px;
  border-bottom: 0;
  background: var(--board); box-shadow: var(--board-rail);
  align-items: flex-end;
}
main > .page-head h1, .dash > .page-head h1 {
  font-family: var(--font-display); font-weight: var(--w-display-face);
  font-size: clamp(2rem, 1.3rem + 2.4vw, 3rem); line-height: 1; letter-spacing: .01em; text-transform: uppercase;
  text-shadow: 0 2px 0 rgba(0,0,0,.3), 0 10px 30px rgba(0,0,0,.4);
}
main > .page-head .sub, .dash > .page-head .sub { font-size: 1rem; color: var(--text-dim); margin-top: 10px; }
main > .breadcrumbs + .page-head { margin-top: 0; }
main > .guild-bar ~ .page-head {
  margin: 0 0 20px; width: auto; padding: 0; border: 0; background: none; box-shadow: none;
  align-items: flex-start;
}
main > .guild-bar ~ .page-head h1 {
  font-family: var(--font); font-weight: 800; font-size: 1.35rem; line-height: 1.2;
  letter-spacing: -.02em; text-transform: none; text-shadow: none;
}
main > .guild-bar ~ .page-head .sub { font-size: .9rem; color: var(--muted); margin-top: 6px; }
@media (max-width: 640px) {
  main > .page-head, .dash > .page-head { padding: 18px 16px 20px; margin-bottom: 24px; }
  main > .page-head h1, .dash > .page-head h1 { font-size: 1.8rem; }
}
/* ---- Breadcrumb component: one back-trail pattern on every console
   page. Segments separated by markup spans (not literal text nodes) so
   screen readers don't announce punctuation; the current page is a
   plain span with aria-current, never a link. Legacy literal-"/"
   separators in older pages still render fine under these rules. */
.breadcrumbs {
  display: flex; align-items: center; flex-wrap: wrap; gap: 7px;
  color: var(--muted); font-size: .76rem; margin-bottom: 16px;
  font-family: var(--font-mono); letter-spacing: .01em;
}
.breadcrumbs a { color: var(--muted); text-decoration: none; }
.breadcrumbs a:hover { color: var(--text); text-decoration: underline; }
.breadcrumbs .bc-sep { opacity: .45; user-select: none; }
.breadcrumbs .bc-cur { color: var(--text-dim); }

/* ---- Docs section tabs: the shared switcher between the getting-started
   guide (/docs) and the generated reference (/documentation). Same
   grammar as the docs rail's current item (accent-lo fill, inset accent
   hairline), promoted to page level; first child of both pages' content
   so switching tabs feels like staying in one place. */
.docs-tabs {
  display: flex; gap: 6px; margin: 0 0 24px;
  padding-bottom: 14px;
  background: radial-gradient(50% 1px at 30% 100%, var(--line-strong), transparent) bottom / 100% 1px no-repeat;
}
.docs-tab {
  display: inline-flex; align-items: center; min-height: 34px;
  padding: 5px 13px; border-radius: var(--radius-sm);
  color: var(--muted); font-size: .85rem; font-weight: 600;
  text-decoration: none !important;
  transition: color .12s, background .12s, box-shadow .12s;
}
.docs-tab:hover { color: var(--text); background: var(--panel-2); }
.docs-tab.current {
  color: var(--text); background: var(--accent-lo);
  box-shadow: inset 0 0 0 1px var(--accent-line);
}
@media (prefers-reduced-motion: reduce) {
  .docs-tab { transition: none; }
}

/* ---- Surfaces ---- */
/* Elevation convention, sampled: the guild bar (below) and the premium
   card were the only surfaces on the site carrying the inset top
   highlight + under-shadow; every other card was flat --panel + a 1px
   --line. Per docs/DESIGN_SURFACE_LADDER.md §7 this adds the SAME
   convention to the shared console card - ONE component, as a controlled
   sample, so the owner can look and decide about the rest. Not mass-added
   to every card. */
/* Panels float: no outline, a lit face, a contact shadow and a wide ambient
   one. The faint 1px is light on the top edge, not a border. */
.card {
  background: var(--surface); border: 1px solid rgba(255,255,255,.04);
  border-radius: var(--radius); padding: 22px;
  box-shadow: var(--edge);
  transition: box-shadow .18s var(--ease), transform .18s var(--ease);
}
.card:hover { box-shadow: var(--edge-hi); }
/* Rows inside a panel separate by a soft seam, not a ruled line. */
.card > .table-wrap { margin: 0 -22px -22px; padding: 0 22px 22px; }
.grid { display: grid; grid-template-columns: 1fr; gap: 12px; }
section { margin-bottom: 36px; }
/* Section labels speak in the readout register: mono, tracked, with the
   accent tick. */
section > h2 {
  font-family: var(--font-mono);
  font-size: .68rem; margin: 0 0 12px; color: var(--muted-strong);
  text-transform: uppercase; letter-spacing: .13em; font-weight: 700;
  display: flex; align-items: center; gap: 9px;
}
section > h2::before {
  content: ""; width: 6px; height: 6px; border-radius: 1px;
  background: var(--accent-hover); flex-shrink: 0;
  box-shadow: 0 0 8px var(--accent-line);
}

/* ---- Badges ---- */
.badge {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 4px 11px; border-radius: 99px;
  font-family: var(--font-mono);
  font-size: .68rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  border: 1px solid transparent;
}
.badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
/* Live is the one state that moves: the dot breathes and the chip glows. */
.badge.live {
  background: var(--live-lo); color: var(--live); border-color: var(--live-line);
  box-shadow: 0 0 0 0 var(--live-lo), 0 0 16px var(--live-lo);
}
.badge.live::before { animation: livepulse 2s ease-in-out infinite; box-shadow: 0 0 8px var(--live); }
@keyframes livepulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }
.badge.idle { background: rgba(118,131,154,.12); color: var(--muted-strong); border-color: rgba(118,131,154,.2); }
.badge.info { background: var(--accent-lo); color: var(--accent-hover); border-color: var(--accent-line); }
.badge.warn { background: var(--amber-dim); color: var(--amber); border-color: rgba(232,179,57,.32); }
.badge.err { background: var(--red-dim); color: var(--red); border-color: rgba(242,86,79,.32); }
.badge.custom { background: var(--accent-lo); color: var(--accent-hover); border-color: var(--accent-line); padding: 1px 8px; font-size: .62rem; }
.badge.custom::before { display: none; }

/* ---- Banner notices (premium) ---- */
.banner {
  border-radius: var(--radius-sm); padding: 12px 16px;
  font-size: .85rem; margin-bottom: 14px;
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  border: 1px solid rgba(255,255,255,.04);
  box-shadow: var(--edge);
}
.banner.warn { background: linear-gradient(160deg, rgba(232,179,57,.2), var(--amber-dim) 60%, rgba(232,179,57,.06)); }
.banner.info { background: linear-gradient(160deg, rgba(79,94,240,.24), var(--accent-lo) 60%, rgba(79,94,240,.06)); }
.banner.ok { background: linear-gradient(160deg, rgba(47,212,155,.2), var(--green-dim) 60%, rgba(47,212,155,.05)); }
.banner a { font-weight: 700; }

/* ---- Buttons ---- */
button, .btn {
  background: var(--btn); color: #fff; border: 1px solid transparent;
  padding: 8px 16px; border-radius: var(--radius-sm);
  font-weight: 650; cursor: pointer; font-size: .85rem;
  min-height: 40px;
  box-shadow: var(--btn-edge);
  transition: background .13s, transform .06s, box-shadow .13s, border-color .13s, filter .13s;
  text-decoration: none; display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  font-family: inherit; letter-spacing: .01em;
}
button:hover, .btn:hover { background: var(--accent-hover); text-decoration: none; box-shadow: var(--btn-edge), 0 4px 14px rgba(79,94,240,.32); }
button:active, .btn:active { transform: translateY(1px); box-shadow: var(--btn-edge); }
button:focus-visible, .btn:focus-visible, a:focus-visible, [tabindex]:focus-visible,
select:focus-visible, input:focus-visible {
  outline: 2px solid var(--accent-hover); outline-offset: 2px; border-radius: 6px;
}
button.green { background: linear-gradient(180deg, #4be0ac 0%, var(--live) 100%); color: #06251a; }
button.green:hover { background: #4be0ac; box-shadow: var(--btn-edge), 0 4px 14px rgba(47,212,155,.28); }
button.danger { background: linear-gradient(180deg, var(--red) 0%, var(--red-deep) 100%); }
button.danger:hover { filter: brightness(1.08); background: var(--red); }
button.ghost, .btn.ghost {
  background: var(--surface); border: 1px solid rgba(255,255,255,.05); color: var(--text-dim);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.07), 0 1px 2px rgba(0,0,0,.5), 0 6px 16px -6px rgba(0,0,0,.6);
}
button.ghost:hover, .btn.ghost:hover { background: var(--surface-hi); color: var(--text); transform: translateY(-1px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 2px 4px rgba(0,0,0,.5), 0 10px 24px -8px rgba(0,0,0,.7); }
button.danger.ghost { color: var(--red); border-color: rgba(242,86,79,.35); background: transparent; box-shadow: none; }
button.danger.ghost:hover { background: var(--red-dim); border-color: var(--red); }
button:disabled { opacity: .45; cursor: not-allowed; box-shadow: none; }

/* ---- Quick-link chips (guild consoles, cards) ---- */
.qchip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 12px; min-height: 40px;
  border: 1px solid rgba(255,255,255,.05); border-radius: var(--radius-sm);
  background: var(--surface);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.07), 0 1px 2px rgba(0,0,0,.5), 0 6px 16px -6px rgba(0,0,0,.6);
  color: var(--text-dim); font-size: .8rem; font-weight: 600;
  text-decoration: none !important; white-space: nowrap;
  transition: background .12s, color .12s, transform .12s var(--ease), box-shadow .12s;
}
.qchip:hover { background: var(--surface-hi); color: var(--text); transform: translateY(-1px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 2px 4px rgba(0,0,0,.5), 0 10px 24px -8px rgba(0,0,0,.7); }

/* ---- Hero CTA (shared by home/invite pages) ---- */
.cta-big {
  background: var(--btn); color: #fff; font-weight: 800;
  letter-spacing: .02em; padding: 18px 40px; border-radius: var(--radius-sm);
  text-decoration: none; font-size: 1.05rem;
  display: inline-flex; align-items: center; gap: 8px; min-height: 56px;
  box-shadow: var(--btn-edge), 0 8px 24px rgba(79,94,240,.28);
  transition: background .15s, transform .06s, box-shadow .15s;
}
.cta-big:hover { background: var(--accent-hover); transform: translateY(-1px);
  text-decoration: none; box-shadow: var(--btn-edge), 0 10px 28px rgba(79,94,240,.46); }
.cta-big:active { transform: translateY(0); }

/* ---- Forms: fields are cut INTO the surface, never the same plane as it ---- */
select, textarea, input[type="text"], input[type="time"], input[type="number"],
input[type="datetime-local"], input[type="password"], input[type="search"],
input[type="date"], input[type="url"], input[type="email"], input:not([type]) {
  background: var(--well); border: 1px solid transparent;
  color: var(--text); height: 40px; padding: 0 12px; border-radius: var(--radius-sm);
  font-size: .88rem; font-family: inherit; outline: none;
  box-shadow: var(--cut);
  transition: border-color .13s, box-shadow .13s, background .13s;
}
textarea { height: auto; padding: 10px 12px; line-height: 1.5; }
select:hover, input:hover, textarea:hover { border-color: rgba(119,132,255,.25); }
select:focus, input:focus, textarea:focus {
  border-color: var(--accent); box-shadow: var(--cut), 0 0 0 4px var(--accent-lo), 0 0 24px -4px var(--accent-line);
  background: var(--well);
}
select { cursor: pointer; }
input[type="checkbox"] { accent-color: var(--accent); width: 15px; height: 15px; cursor: pointer; }
::placeholder { color: var(--muted); opacity: .8; }
label { font-size: .85rem; color: var(--text-dim); display: flex; flex-direction: column; gap: 6px; }
label.check-row, .inline-label { flex-direction: row; align-items: center; }

/* ---- Tables ---- */
table { width: 100%; border-collapse: collapse; }
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
th, td { text-align: left; padding: 13px 16px; border-bottom: 0; font-size: .88rem; box-shadow: var(--seam); }
th { color: var(--muted-strong); font-weight: 700; font-size: .68rem; text-transform: uppercase; letter-spacing: .1em; font-family: var(--font-mono); }
/* The head row is pressed into the surface; the data rows float on it and
   separate by a soft seam, not a ruled line. */
thead th { background: linear-gradient(180deg, rgba(0,0,0,.34), rgba(0,0,0,.2)); box-shadow: inset 0 2px 5px rgba(0,0,0,.4); padding-top: 11px; padding-bottom: 11px; }
thead th:first-child { border-top-left-radius: var(--radius-sm); }
thead th:last-child { border-top-right-radius: var(--radius-sm); }
tbody td:first-child, tbody th[scope="row"] { font-weight: 650; color: var(--text); }
tbody th[scope="row"] { font-family: var(--font); font-size: .88rem; text-transform: none; letter-spacing: 0; }
tbody tr { transition: background .1s; }
tbody tr:hover td, tbody tr:hover th { background: rgba(255,255,255,.03); }
tbody tr:first-child td, tbody tr:first-child th { box-shadow: none; }
.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
code { font-family: var(--font-mono); }

/* ---- Empty states: invitations, not bare text ---- */
.empty {
  color: var(--muted); padding: 44px 24px;
  text-align: center; border: 0; border-radius: var(--radius);
  background: var(--well); box-shadow: var(--cut);
  font-size: .92rem; line-height: 1.6;
}
.empty b { color: var(--text-dim); font-style: normal; }
/* A leading bold line is the empty state's title. */
.empty > b:first-child {
  display: block; margin-bottom: 4px;
  color: var(--text); font-weight: 800; font-size: 1.05rem; letter-spacing: -.01em;
}
.empty > b:first-child + br { display: none; }

.toast {
  position: fixed; bottom: 20px; right: 20px; z-index: var(--z-toast);
  background: var(--live); color: #06251a; padding: 11px 20px;
  border-radius: var(--radius-sm); font-weight: 700; display: none;
  box-shadow: var(--elev-3); font-size: .88rem;
}
.toast.err { background: var(--red-deep); color: #fff; }
.countdown-bar { height: 4px; background: var(--line); border-radius: 2px; margin: 12px 0; overflow: hidden; }
.countdown-bar .fill { height: 100%; background: var(--live); transition: width 1s linear; border-radius: 2px; }

.topnav .nav-link, .topnav .user-chip { white-space: nowrap; }
@media (max-width: 900px) {
  /* Two rows: identity (brand, then the owner chrome at the right), then
     the destinations. The spacer becomes the line break. */
  .topnav { flex-wrap: wrap; height: auto; padding: 8px 10px 8px; row-gap: 2px; gap: 2px; }
  .topnav .nav-link { padding: 6px 7px; font-size: .78rem; min-height: 36px; order: 3; }
  .topnav .user-chip { padding: 4px 10px; font-size: .78rem; }
  .topnav .spacer { flex: 0 0 100%; height: 0; order: 2; }
  .topnav #owner-chrome { order: 1; margin-left: auto; display: inline-flex; align-items: center; gap: 4px; }
  .topnav #owner-chrome .nav-link { order: 0; }
  .topnav .clock { display: none; }
  .brand { margin-right: 8px; order: 0; }
}
@media (max-width: 640px) {
  main { padding: 20px 14px 40px; }
  .grid { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
  .countdown-bar .fill { transition: none; }
  .badge.live::before { animation: none; }
  .card:hover, .qchip:hover, button.ghost:hover, .btn.ghost:hover { transform: none; }
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
/* ---- Footer: one consistent centered strip on every page (BL-194 #5),
   home-style: hairline rule above, the legal links row, then the quiet
   operator line. Sits on the same 1120 column as main so the rule
   lines up with the content edges. */
.legal-foot {
  max-width: 1120px; margin: 0 auto; padding: 22px 24px 34px;
  border-top: 0;
  background: radial-gradient(60% 1px at 50% 0, var(--line-strong), transparent) top / 100% 1px no-repeat;
  display: flex; flex-direction: column; gap: 9px;
  align-items: center; text-align: center;
  color: var(--muted); font-size: .8rem;
}
.legal-foot .foot-links { display: flex; gap: 20px; flex-wrap: wrap; justify-content: center; }
.legal-foot a { color: var(--muted); }
.legal-foot a:hover { color: var(--text); }
.legal-foot .foot-op { font-size: .74rem; color: var(--muted); opacity: .85; }
.legal-foot .foot-op a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.legal-foot .foot-op a:hover { color: var(--text-dim); }
/* Home already renders its own in-page footer (the reference look this
   strip mirrors) - don't stack a second legal block under it. */
body:has(.home-footer) .legal-foot { display: none; }
@media (prefers-reduced-motion: no-preference) {
  .legal-foot a { transition: color .12s ease-out; }
}
