/* ════════════════════════════════════════════════════════════════════════════
   Tome — Admin console, skinned as an illuminated high-fantasy manuscript.

   Architecture
   ────────────
   1. Material-3 token layer  — color roles, elevation, shape, state, motion,
      typography. Everything below consumes these tokens.
   2. Legacy-alias layer      — the original token names (--primary, --surface,
      --shadow-sm …) are re-pointed at the M3 roles so existing page/component
      markup keeps working with ZERO JS changes.
   3. Skin                     — parchment surfaces, walnut/stone chrome, gilt
      accents, illuminated serif headings, candlelit focus glows.
   4. Components               — restyled against the tokens.

   Motion principle: every interactive change is a single transform/opacity/
   color tween on a shared easing curve. No layout-shifting hovers, no bounce —
   smooth and quiet so the data stays the focus.
   ════════════════════════════════════════════════════════════════════════════ */

/* ─── 1. Material-3 token layer ─────────────────────────────────────────────── */
:root {
  /* Color roles — seeded from the reference art: aged parchment, walnut wood,
     antique gilt, verdigris arcana, wax-seal red, mossy green. Warm + neutral. */
  --md-primary:            #9A7637;   /* antique gilt */
  --md-primary-hover:      #876328;
  --md-on-primary:         #FBF4E4;
  --md-primary-container:  #EFE2C6;
  --md-on-primary-container:#5A4216;

  --md-secondary:          #3E6E63;   /* verdigris / arcane teal (used sparingly) */
  --md-on-secondary:       #F2F6F2;
  --md-secondary-container:#DCE7E0;
  --md-on-secondary-container:#234A42;

  /* Surfaces — M3 tonal container ladder, here a parchment ramp */
  --md-background:         #ECE0C8;   /* desk / open page */
  --md-surface:            #FBF4E4;   /* card face */
  --md-surface-1:          #F7EEDB;
  --md-surface-2:          #F2E7CF;
  --md-surface-3:          #ECDFC3;
  --md-surface-4:          #E7D8B8;

  /* Chrome — dark walnut/stone framing the warm interior */
  --md-chrome:             #2A2018;
  --md-chrome-2:           #352819;
  --md-on-chrome:          #F3E7CE;
  --md-on-chrome-dim:      #C9B591;

  --md-outline:            #D9C8A6;   /* hairline rules */
  --md-outline-strong:     #C2AC82;
  --md-gilt:               #C8A24A;   /* bright gold edge for illumination */

  --md-on-surface:         #2B2114;   /* ink */
  --md-on-surface-var:     #6B5A3E;   /* faded ink */
  --md-on-surface-dim:     #A6906A;

  --md-error:              #A33B2C;   /* wax-seal red */
  --md-warning:            #B97E2E;   /* candle amber */
  --md-success:            #5E7242;   /* moss */

  /* Elevation — warm umber shadows (light comes from a single candle, soft) */
  --md-elev-1: 0 1px 2px rgba(58,40,16,.16), 0 1px 1px rgba(58,40,16,.10);
  --md-elev-2: 0 2px 6px rgba(58,40,16,.16), 0 1px 2px rgba(58,40,16,.10);
  --md-elev-3: 0 6px 16px rgba(58,40,16,.18), 0 2px 5px rgba(58,40,16,.10);
  --md-elev-4: 0 12px 30px rgba(46,32,12,.22), 0 4px 10px rgba(46,32,12,.12);

  /* Shape scale */
  --md-shape-xs: 6px;
  --md-shape-sm: 10px;
  --md-shape-md: 14px;
  --md-shape-lg: 20px;
  --md-shape-full: 999px;

  /* State-layer opacities (M3 spec) */
  --state-hover: .08;
  --state-focus: .12;
  --state-press: .12;

  /* Motion — M3 emphasized/standard easing + durations */
  --ease-standard:   cubic-bezier(.2, 0, 0, 1);
  --ease-emphasized: cubic-bezier(.2, 0, 0, 1);
  --ease-decel:      cubic-bezier(.05, .7, .1, 1);
  --dur-1: 90ms;    /* state layers */
  --dur-2: 160ms;   /* most controls */
  --dur-3: 240ms;   /* enters */
  --dur-4: 360ms;   /* overlays */

  /* Type */
  --font-display: 'Cinzel', Georgia, serif;
  --font-serif:   'EB Garamond', Georgia, serif;
  --font-body:    'Inter', system-ui, sans-serif;
}

/* ─── 2. Legacy aliases (keep all original var names working) ────────────────── */
:root {
  --primary:        var(--md-primary);
  --primary-light:  #B8954E;
  --primary-dark:   var(--md-primary-hover);
  --accent:         #B07D4B;
  --danger:         var(--md-error);
  --warning:        var(--md-warning);
  --success:        var(--md-success);

  --bg:             var(--md-background);
  --surface:        var(--md-surface);
  --surface-2:      var(--md-surface-2);
  --border:         var(--md-outline);
  --hover:          var(--md-surface-2);

  --shadow-sm:      var(--md-elev-1);
  --shadow-md:      var(--md-elev-2);
  --shadow-lg:      var(--md-elev-4);

  --text-primary:   var(--md-on-surface);
  --text-secondary: var(--md-on-surface-var);
  --text-disabled:  var(--md-on-surface-dim);

  --nav-width:      248px;
  --topbar-height:  60px;
  --radius:         var(--md-shape-sm);
  --radius-lg:      var(--md-shape-md);
  --transition:     var(--dur-2) var(--ease-standard);
  --font:           var(--font-body);
}

/* Admin-authored site notice — normal document flow, pushes content down,
   never overlays. Color is admin-customizable via inline style. */
.system-notice {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  font-size: 13px;
  color: #1a1200;
}
.system-notice-text { flex: 1; }
.system-notice-dismiss {
  background: none; border: none; color: inherit;
  font-size: 18px; line-height: 1; cursor: pointer; opacity: .7;
}
.system-notice-dismiss:hover { opacity: 1; }

/* Manual-close button for dismissible toasts (critical/warning alerts use
   this; existing short-lived toasts elsewhere are unaffected — they don't
   pass { dismissible: true }, so they render exactly as before). */
.toast-dismiss {
  background: none; border: none; color: inherit;
  font-size: 16px; line-height: 1; cursor: pointer; opacity: .6; margin-left: 4px;
  flex-shrink: 0;
}
.toast-dismiss:hover { opacity: 1; }

/* ─── Reset ──────────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; font-family: var(--font-body); background: var(--bg); color: var(--text-primary); }
/* Mobile-safe globals (no-ops on desktop: env() resolves to 0, dvh == vh) */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body { -webkit-tap-highlight-color: transparent; overscroll-behavior-y: none; }
a { color: var(--primary); text-decoration: none; }
button { font-family: inherit; cursor: pointer; border: none; background: none; color: inherit; }
input, select, textarea { font-family: inherit; }
ul { list-style: none; }
::selection { background: var(--md-primary-container); color: var(--md-on-primary-container); }

/* Material Symbols Rounded, aliased onto the legacy `.material-icons` class so
   existing markup renders the rounded set without touching any JS. */
.material-icons,
.material-symbols-rounded {
  font-family: 'Material Symbols Rounded', 'Material Icons';
  font-weight: normal; font-style: normal;
  line-height: 1; letter-spacing: normal; text-transform: none;
  display: inline-block; white-space: nowrap; word-wrap: normal;
  direction: ltr; -webkit-font-feature-settings: 'liga'; font-feature-settings: 'liga';
  -webkit-font-smoothing: antialiased;
  font-variation-settings: 'opsz' 24;
}

/* ─── Parchment desk: faint vignette + paper grain behind everything ─────────── */
/* CSS/SVG only — no raster downloads, no distraction, survives innerHTML swaps. */
body.tome-theme::before {
  content: ''; position: fixed; inset: 0; z-index: -2; pointer-events: none;
  background:
    radial-gradient(120% 90% at 50% -10%, #F3E8CE 0%, var(--md-background) 55%, #E3D4B6 100%);
}
body.tome-theme::after {
  content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  opacity: .05; mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ─── Loading screen ─────────────────────────────────────────────────────────── */
.loading-screen {
  position: fixed; inset: 0;
  display: flex; align-items: center; justify-content: center;
  background:
    radial-gradient(120% 90% at 50% 0%, #F3E8CE 0%, var(--md-background) 60%, #E0D0AF 100%);
  z-index: 9999;
}
.spinner {
  width: 40px; height: 40px;
  border: 3px solid var(--md-outline);
  border-top-color: var(--md-gilt);
  border-radius: 50%;
  animation: spin .8s var(--ease-standard) infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Tome (flipping book) loader — gilt cover, candle-lit pages */
.tome-loader { width: 50px; height: 36px; position: relative; perspective: 260px; }
.tome-loader .cover {
  position: absolute; inset: 0;
  background: linear-gradient(135deg, #4A3722 0%, var(--md-chrome) 100%);
  border-radius: 3px 6px 6px 3px;
  box-shadow: var(--md-elev-2), inset 0 0 0 1.5px var(--md-gilt);
}
.tome-loader .page {
  position: absolute; top: 3px; right: 3px; width: 22px; height: 30px;
  background: linear-gradient(180deg, #FFFDF6, #F1E6CD);
  border-radius: 1px 3px 3px 1px;
  transform-origin: left center;
  animation: tome-flip 1.6s var(--ease-standard) infinite;
  box-shadow: 0 1px 2px rgba(58,40,16,.18);
}
.tome-loader .page:nth-child(3) { animation-delay: .27s; }
.tome-loader .page:nth-child(4) { animation-delay: .54s; }
@keyframes tome-flip {
  0%        { transform: rotateY(0deg);    opacity: 1; }
  50%, 100% { transform: rotateY(-162deg); opacity: .3; }
}
.loader-center {
  display: flex; flex-direction: column; align-items: center; gap: 14px;
  color: var(--text-secondary); font-family: var(--font-serif); font-size: 1.02rem;
  letter-spacing: .3px; padding: 40px;
  animation: fadeIn var(--dur-3) var(--ease-decel);
}

/* ─── App shell ──────────────────────────────────────────────────────────────── */
#app { height: 100vh; height: 100dvh; display: flex; flex-direction: column; }
/* app-shell takes whatever height is left under the topbar row — no fixed
   offsets, so page content can never slide underneath the bar. */
.app-shell { display: flex; flex: 1; min-height: 0; overflow: hidden; }

/* ─── Top bar (walnut + gilt rail) ───────────────────────────────────────────── */
.topbar {
  height: var(--topbar-height);
  background: linear-gradient(180deg, var(--md-chrome-2) 0%, var(--md-chrome) 100%);
  color: var(--md-on-chrome);
  display: flex; align-items: center; padding: 0 20px; gap: 14px;
  box-shadow: var(--md-elev-3);
  flex-shrink: 0;
  position: relative; z-index: 100;
  border-bottom: 1px solid rgba(0,0,0,.4);
}
/* The gilt rule under the bar — the "gold leaf" edge of the binding */
.topbar::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--md-gilt) 18%, #E8CE7C 50%, var(--md-gilt) 82%, transparent);
  opacity: .85;
}
.topbar-brand {
  font-family: var(--font-display); font-size: 1.28rem; font-weight: 600;
  letter-spacing: 1.5px; text-transform: uppercase;
  display: flex; align-items: center; gap: 10px;
  color: #F4E4BE; text-shadow: 0 1px 0 rgba(0,0,0,.4);
}
.topbar-brand span.version {
  font-family: var(--font-body); font-size: .68rem; opacity: .6;
  font-weight: 400; letter-spacing: .5px; text-transform: none;
}
.topbar-brand .material-icons { color: var(--md-gilt); font-size: 26px; }
.topbar-spacer { flex: 1; }
.topbar-user { display: flex; align-items: center; gap: 10px; font-size: .875rem; color: var(--md-on-chrome-dim); }
.topbar-user .avatar {
  width: 34px; height: 34px; border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #C8A24A, #8A6320);
  color: #2A2018;
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: .85rem; text-transform: uppercase;
  box-shadow: inset 0 0 0 1.5px rgba(244,228,190,.6), var(--md-elev-1);
}
.topbar-btn {
  background: rgba(244,228,190,.08);
  border: 1px solid rgba(200,162,74,.35);
  color: var(--md-on-chrome); border-radius: var(--md-shape-full);
  padding: 7px 14px; font-size: .8125rem; font-weight: 500;
  transition: background var(--dur-2) var(--ease-standard), border-color var(--dur-2) var(--ease-standard);
  display: flex; align-items: center; gap: 6px;
}
.topbar-btn:hover { background: rgba(200,162,74,.18); border-color: var(--md-gilt); }
.topbar-btn:active { background: rgba(200,162,74,.28); }

/* Hamburger + drawer scrim — created in markup but only revealed at ≤768px.
   On desktop they are removed from flow, so the desktop shell is untouched. */
.topbar-menu-btn {
  display: none;
  align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: var(--md-shape-full);
  color: var(--md-on-chrome); flex-shrink: 0;
  transition: background var(--dur-2) var(--ease-standard);
}
.topbar-menu-btn:hover { background: rgba(200,162,74,.18); }
.topbar-menu-btn .material-icons { font-size: 26px; }
.sidenav-scrim { display: none; }

/* ─── Side nav ───────────────────────────────────────────────────────────────── */
.sidenav {
  width: var(--nav-width);
  background:
    linear-gradient(180deg, var(--md-surface-1), var(--md-surface-2));
  border-right: 1px solid var(--md-outline-strong);
  display: flex; flex-direction: column;
  padding-top: 12px;
  flex-shrink: 0; overflow-y: auto;
  box-shadow: inset -1px 0 0 rgba(255,255,255,.4);
}
.sidenav-section {
  padding: 16px 18px 6px; font-family: var(--font-serif);
  font-size: .72rem; font-weight: 600;
  color: var(--md-on-surface-dim); text-transform: uppercase; letter-spacing: 1.2px;
}
.nav-item {
  position: relative; z-index: 0;
  display: flex; align-items: center; gap: 12px;
  padding: 11px 16px; border-radius: var(--md-shape-full); margin: 2px 10px;
  color: var(--text-secondary); font-size: .9rem; font-weight: 500;
  cursor: pointer; user-select: none;
  transition: color var(--dur-2) var(--ease-standard);
}
.nav-item .material-icons { font-size: 21px; transition: color var(--dur-2) var(--ease-standard); }
/* M3 state layer — a tinted ::before behind transparent content (z-index:-1) */
.nav-item::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  border-radius: inherit; background: var(--md-primary);
  opacity: 0; transition: opacity var(--dur-1) var(--ease-standard);
}
.nav-item:hover { color: var(--md-on-primary-container); }
.nav-item:hover::before { opacity: var(--state-hover); }
.nav-item.active {
  color: var(--md-on-primary-container); font-weight: 600;
  background: var(--md-primary-container);
  box-shadow: inset 0 0 0 1px rgba(154,118,55,.35);
}
.nav-item.active .material-icons { color: var(--md-primary); }
.nav-item.hidden { display: none; }

/* ─── Page content ───────────────────────────────────────────────────────────── */
.page-content {
  flex: 1; overflow-y: auto;
  padding: 28px;
}
/* Gentle, single entrance — no per-item stagger, so nothing jumps */
.page-content > * { animation: pageRise var(--dur-3) var(--ease-decel) both; }

/* ─── Page header ────────────────────────────────────────────────────────────── */
.page-header {
  display: flex; align-items: flex-end; justify-content: space-between;
  margin-bottom: 26px; padding-bottom: 14px;
  border-bottom: 1px solid var(--md-outline);
  position: relative;
}
.page-header::after {
  content: ''; position: absolute; left: 0; bottom: -1px; width: 64px; height: 2px;
  background: linear-gradient(90deg, var(--md-gilt), transparent);
}
.page-title {
  font-family: var(--font-display); font-size: 1.6rem; font-weight: 600;
  letter-spacing: .5px; color: var(--md-on-surface);
}
.page-subtitle { font-family: var(--font-serif); font-size: .95rem; color: var(--text-secondary); margin-top: 3px; }

/* ─── Cards (illuminated panels with a gilt hairline) ────────────────────────── */
.card {
  background: var(--md-surface);
  border: 1px solid var(--md-outline);
  border-radius: var(--radius-lg);
  box-shadow: var(--md-elev-1);
  padding: 22px;
  transition: box-shadow var(--dur-2) var(--ease-standard);
}
.card:hover { box-shadow: var(--md-elev-2); }
.card-title {
  font-family: var(--font-serif); font-size: 1.12rem; font-weight: 600;
  margin-bottom: 16px; color: var(--md-on-surface);
  display: flex; align-items: center; gap: 9px;
}
.card-title .material-icons { color: var(--md-primary); }
.card-grid { display: grid; gap: 18px; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }

.stat-card {
  position: relative; overflow: hidden;
  background: linear-gradient(180deg, var(--md-surface), var(--md-surface-1));
  border: 1px solid var(--md-outline);
  border-radius: var(--radius-lg); padding: 22px;
  box-shadow: var(--md-elev-1);
  transition: transform var(--dur-2) var(--ease-standard), box-shadow var(--dur-2) var(--ease-standard);
}
.stat-card::before {
  content: ''; position: absolute; top: 0; left: 0; width: 4px; height: 100%;
  background: linear-gradient(180deg, var(--md-gilt), var(--md-primary-hover));
}
.stat-card:hover { transform: translateY(-2px); box-shadow: var(--md-elev-3); }
.stat-value {
  font-family: var(--font-display); font-size: 2.1rem; font-weight: 700;
  color: var(--md-primary-hover); line-height: 1.1;
}
.stat-label {
  font-family: var(--font-serif); font-size: .9rem; color: var(--text-secondary);
  margin-top: 4px; font-weight: 500; letter-spacing: .3px;
}

/* ─── Buttons ────────────────────────────────────────────────────────────────── */
.btn {
  position: relative; flex-shrink: 0;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 20px; border-radius: var(--md-shape-full);
  font-size: .875rem; font-weight: 600; letter-spacing: .2px;
  transition: background var(--dur-2) var(--ease-standard),
              box-shadow var(--dur-2) var(--ease-standard),
              transform var(--dur-1) var(--ease-standard);
  white-space: nowrap;
}
.btn:active { transform: translateY(1px); }      /* tactile press, no layout shift */
.btn .material-icons { font-size: 18px; }

.btn-primary {
  background: linear-gradient(180deg, var(--md-primary), var(--md-primary-hover));
  color: var(--md-on-primary);
  box-shadow: var(--md-elev-1), inset 0 1px 0 rgba(255,255,255,.18);
}
.btn-primary:hover { background: linear-gradient(180deg, #A8823F, var(--md-primary-hover)); box-shadow: var(--md-elev-2); }

.btn-secondary {
  background: var(--md-surface-2); color: var(--md-on-surface);
  border: 1px solid var(--md-outline-strong);
}
.btn-secondary:hover { background: var(--md-surface-3); border-color: var(--md-primary); }

.btn-danger { background: var(--md-error); color: #FBEDE9; box-shadow: var(--md-elev-1); }
.btn-danger:hover { background: #8F3325; box-shadow: var(--md-elev-2); }

.btn-accent { background: var(--md-secondary); color: var(--md-on-secondary); box-shadow: var(--md-elev-1); }
.btn-accent:hover { background: #345B52; box-shadow: var(--md-elev-2); }

.btn-ghost { color: var(--md-primary-hover); padding: 7px 12px; background: transparent; }
.btn-ghost:hover { background: var(--md-primary-container); }

.btn-sm { padding: 6px 14px; font-size: .8125rem; }
.btn-icon { padding: 9px; border-radius: var(--md-shape-full); }
.btn[disabled] { opacity: .45; pointer-events: none; box-shadow: none; }

/* ─── Tables ─────────────────────────────────────────────────────────────────── */
.table-wrap {
  overflow-x: auto; -webkit-overflow-scrolling: touch; border-radius: var(--radius-lg);
  border: 1px solid var(--md-outline); box-shadow: var(--md-elev-1);
}
table { width: 100%; border-collapse: collapse; background: var(--md-surface); }
thead th {
  padding: 13px 16px; text-align: left;
  font-family: var(--font-serif); font-size: .78rem; font-weight: 600;
  color: var(--md-on-surface-var); text-transform: uppercase; letter-spacing: .6px;
  background: var(--md-surface-3); border-bottom: 1.5px solid var(--md-outline-strong);
}
tbody td { padding: 13px 16px; border-bottom: 1px solid var(--md-outline); font-size: .9rem; }
tbody tr:last-child td { border-bottom: none; }
tbody tr { transition: background var(--dur-1) var(--ease-standard); }
tbody tr:hover td { background: var(--md-surface-1); }
.td-actions { display: flex; gap: 6px; align-items: center; }

/* ─── Forms ──────────────────────────────────────────────────────────────────── */
.form-group { margin-bottom: 18px; }
.form-label {
  display: block; font-family: var(--font-serif); font-size: .9rem; font-weight: 600;
  margin-bottom: 6px; color: var(--md-on-surface-var); letter-spacing: .2px;
}
.form-control {
  width: 100%; padding: 10px 13px;
  border: 1.5px solid var(--md-outline-strong); border-radius: var(--md-shape-sm);
  font-size: .9rem; background: var(--md-surface); color: var(--md-on-surface);
  transition: border-color var(--dur-2) var(--ease-standard), box-shadow var(--dur-2) var(--ease-standard);
}
.form-control:hover { border-color: var(--md-primary); }
.form-control:focus { outline: none; border-color: var(--md-primary); box-shadow: 0 0 0 3px rgba(154,118,55,.20); }
.form-control::placeholder { color: var(--md-on-surface-dim); }
.form-error { color: var(--md-error); font-size: .82rem; margin-top: 4px; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }

/* ─── Badges ─────────────────────────────────────────────────────────────────── */
.badge {
  display: inline-block; padding: 3px 10px; border-radius: var(--md-shape-full);
  font-size: .72rem; font-weight: 600; letter-spacing: .3px;
  border: 1px solid transparent;
}
.badge-blue   { background: var(--md-primary-container);   color: var(--md-on-primary-container);   border-color: rgba(154,118,55,.30); }
.badge-green  { background: #DCE6CC; color: #46591F; border-color: rgba(94,114,66,.30); }
.badge-orange { background: #F4E2C4; color: #8A5A18; border-color: rgba(185,126,46,.30); }
.badge-red    { background: #F0D8D1; color: #8C2E20; border-color: rgba(163,59,44,.30); }
.badge-gray   { background: var(--md-surface-3); color: var(--md-on-surface-var); border-color: var(--md-outline); }
.badge-cyan   { background: var(--md-secondary-container); color: var(--md-on-secondary-container); border-color: rgba(62,110,99,.30); }

/* low-emphasis active surfaces, retoned to gilt */
.tool-btn.active { border-color: var(--md-primary); background: var(--md-primary-container); color: var(--md-on-primary-container); }
.qb-in-item:has(input:checked) { background: var(--md-primary-container); border-color: var(--md-primary); color: var(--md-on-primary-container); }

/* ─── Chips ──────────────────────────────────────────────────────────────────── */
.chip-list { display: flex; flex-wrap: wrap; gap: 7px; }
.chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 12px; border-radius: var(--md-shape-full); font-size: .78rem; font-weight: 500;
  background: var(--md-surface-2); border: 1px solid var(--md-outline-strong); color: var(--text-secondary);
  transition: background var(--dur-2) var(--ease-standard);
}
.chip:hover { background: var(--md-surface-3); }
.chip-remove { cursor: pointer; font-size: 15px; opacity: .6; transition: color var(--dur-1), opacity var(--dur-1); }
.chip-remove:hover { opacity: 1; color: var(--md-error); }

/* ─── Search bar ─────────────────────────────────────────────────────────────── */
.search-bar {
  display: flex; align-items: center; gap: 8px;
  background: var(--md-surface); border: 1.5px solid var(--md-outline-strong); border-radius: var(--md-shape-full);
  padding: 8px 14px; min-width: 250px;
  transition: border-color var(--dur-2) var(--ease-standard), box-shadow var(--dur-2) var(--ease-standard);
}
.search-bar:focus-within { border-color: var(--md-primary); box-shadow: 0 0 0 3px rgba(154,118,55,.18); }
.search-bar .material-icons { color: var(--md-on-surface-dim); font-size: 20px; }
.search-bar input { border: none; outline: none; font-size: .9rem; background: transparent; flex: 1; color: var(--md-on-surface); }

/* ─── Toolbar row ────────────────────────────────────────────────────────────── */
.toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 18px; flex-wrap: wrap; }
.toolbar-end { margin-left: auto; display: flex; gap: 10px; }

/* ─── Empty state ────────────────────────────────────────────────────────────── */
.empty-state { text-align: center; padding: 52px 24px; color: var(--text-secondary); font-family: var(--font-serif); }
.empty-state .material-icons { font-size: 60px; opacity: .22; display: block; margin-bottom: 12px; color: var(--md-primary); }
.empty-state p { font-size: 1rem; }

/* ─── Viz containers (kept dark — they're the "scrying" surfaces) ────────────── */
.viz-container {
  background: radial-gradient(120% 120% at 50% 0%, #141821 0%, #0d0f14 100%);
  border-radius: var(--radius-lg); overflow: hidden; position: relative;
  min-height: 480px; border: 1px solid #2a3344; box-shadow: var(--md-elev-2), inset 0 0 0 1px rgba(200,162,74,.10);
}
.viz-toolbar { position: absolute; top: 12px; left: 12px; z-index: 10; display: flex; gap: 6px; flex-wrap: wrap; }
.viz-btn {
  background: rgba(244,228,190,.08); border: 1px solid rgba(200,162,74,.22);
  color: #F3E7CE; border-radius: var(--md-shape-full); padding: 6px 12px;
  font-size: .75rem; font-weight: 500; cursor: pointer;
  transition: background var(--dur-2) var(--ease-standard);
  display: flex; align-items: center; gap: 4px;
}
.viz-btn:hover { background: rgba(200,162,74,.20); }
.viz-btn.active { background: var(--md-primary); border-color: var(--md-gilt); color: #1a140c; }
.viz-legend { position: absolute; bottom: 12px; right: 12px; background: rgba(20,16,10,.7); border: 1px solid rgba(200,162,74,.2); border-radius: var(--md-shape-sm); padding: 10px 14px; color: #F3E7CE; font-size: .75rem; }
.viz-legend-item { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.viz-legend-dot { width: 10px; height: 10px; border-radius: 50%; }

/* ─── D3 predicate editor ────────────────────────────────────────────────────── */
.pred-editor { background: var(--md-surface-2); border-radius: var(--radius-lg); border: 1px solid var(--md-outline); overflow: hidden; position: relative; }
.pred-editor svg { display: block; }
.pred-editor .editor-toolbar { background: var(--md-surface); border-bottom: 1px solid var(--md-outline); padding: 9px 12px; display: flex; gap: 8px; align-items: center; }
.tool-btn {
  padding: 6px 12px; border-radius: var(--md-shape-full); font-size: .82rem; font-weight: 500;
  border: 1.5px solid var(--md-outline-strong); background: var(--md-surface); color: var(--text-secondary);
  cursor: pointer; display: flex; align-items: center; gap: 4px;
  transition: border-color var(--dur-2) var(--ease-standard), background var(--dur-2) var(--ease-standard), color var(--dur-2) var(--ease-standard);
}
.tool-btn:hover:not(.active) { border-color: var(--md-primary); }

.geo3d { display: flex; flex-direction: column; gap: 14px; }
.geo3d-stage {
  position: relative; width: 100%; height: 340px;
  background: radial-gradient(120% 120% at 50% 0%, #141821 0%, #0d0f14 100%);
  border: 1px solid #2a3344; border-radius: var(--radius-lg); overflow: hidden;
  box-shadow: var(--md-elev-2), inset 0 0 0 1px rgba(200,162,74,.10);
}
.geo3d-canvas { display: block; width: 100%; height: 100%; touch-action: none; outline: none; }
/* Focusable for keyboard "drive" nav; show a soft gilt ring when it has focus. */
.geo3d-canvas:focus-visible { box-shadow: inset 0 0 0 2px rgba(200,162,74,.45); }
.geo3d-toolbar { position: absolute; top: 10px; left: 10px; right: 10px; z-index: 5; display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.geo3d-toolbar .viz-btn { padding: 5px 10px; font-size: .72rem; line-height: 1; }
.geo3d-toolbar .viz-btn .material-icons { font-size: 15px; }
/* Orbit / Fly segmented pair, set slightly apart from the view buttons. */
.geo3d-modes { display: inline-flex; gap: 4px; margin-right: 4px; padding-right: 8px; border-right: 1px solid rgba(200,162,74,.22); }
.geo3d-hint {
  position: absolute; bottom: 9px; left: 50%; transform: translateX(-50%); z-index: 5;
  font-size: .68rem; letter-spacing: .02em; color: #C9B591; opacity: .8;
  background: rgba(20,16,10,.55); border: 1px solid rgba(200,162,74,.18);
  padding: 3px 10px; border-radius: var(--md-shape-full); pointer-events: none; white-space: nowrap;
}

/* Display-option toggles (dot size, show segment/length, extents …). */
.geo3d-toggle-row { margin: 0; }
.geo3d-toggle { display: flex; align-items: center; gap: 9px; cursor: pointer; font-family: var(--font-serif); font-size: .9rem; color: var(--text-secondary); }
.geo3d-toggle input { width: 16px; height: 16px; accent-color: var(--md-primary); cursor: pointer; }

/* Floating 3-D text labels — HTML projected over the canvas each frame. */
.geo3d-labels { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 4; }
.geo3d-label {
  position: absolute; left: 0; top: 0; will-change: transform; white-space: nowrap;
  font: 600 11px/1.3 var(--font-body); color: #1a140c;
  background: rgba(200,162,74,.92); border: 1px solid var(--md-gilt); border-radius: var(--md-shape-xs);
  padding: 2px 7px; box-shadow: 0 2px 6px rgba(0,0,0,.35); font-variant-numeric: tabular-nums;
}

/* "Coming soon" placeholder shown in place of the stage for non-editable types. */
.geo3d-coming {
  display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center;
  min-height: 240px; gap: 10px; padding: 32px 24px;
  background: radial-gradient(120% 120% at 50% 0%, #141821 0%, #0d0f14 100%);
  border: 1px solid #2a3344; border-radius: var(--radius-lg); color: #C9B591;
}
.geo3d-coming .material-icons { font-size: 46px; color: var(--md-gilt); opacity: .85; }
.geo3d-coming-title { font-family: var(--font-serif); font-size: 1.05rem; font-weight: 600; color: #F3E7CE; }
.geo3d-coming p { font-size: .85rem; max-width: 360px; opacity: .8; }

/* Numeric controls — share the standard .form-control look, packed tighter. */
.geo3d-form { display: flex; flex-direction: column; gap: 12px; }
.geo3d-field { margin: 0; }
.geo3d-vec { display: flex; gap: 8px; }
.geo3d-axis { flex: 1; display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.geo3d-axis > span {
  font-family: var(--font-serif); font-size: .7rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: .04em; color: var(--text-secondary);
}
.geo3d-input { padding: 7px 9px; font-size: .85rem; }
.geo3d-slider { display: flex; align-items: center; gap: 10px; }
.geo3d-slider .geo3d-num { width: 84px; flex: 0 0 auto; }
.geo3d-range { flex: 1; accent-color: var(--md-primary); height: 4px; cursor: pointer; }
.geo3d-angles { display: flex; gap: 12px; }
.geo3d-angle { flex: 1; }
.geo3d-angle .geo3d-range { width: 100%; margin: 4px 0; }
.geo3d-readout-row {
  display: flex; justify-content: space-between; align-items: center;
  padding: 6px 10px; border: 1px dashed var(--md-outline); border-radius: var(--md-shape-xs);
  background: var(--md-surface-1);
}
.geo3d-readout-label { font-family: var(--font-serif); font-size: .82rem; color: var(--text-secondary); }
.geo3d-readout-val { font-size: .85rem; font-weight: 600; color: var(--text-primary); font-variant-numeric: tabular-nums; }

/* ─── Detail panel ───────────────────────────────────────────────────────────── */
.detail-panel { background: var(--md-surface); border: 1px solid var(--md-outline); border-radius: var(--radius-lg); padding: 22px; box-shadow: var(--md-elev-1); }
.detail-panel h3 { font-family: var(--font-serif); font-size: 1.12rem; font-weight: 600; margin-bottom: 14px; }
.detail-row { display: flex; justify-content: space-between; align-items: center; padding: 9px 0; border-bottom: 1px solid var(--md-outline); font-size: .9rem; }
.detail-row:last-child { border-bottom: none; }
.detail-key { color: var(--text-secondary); font-weight: 500; font-family: var(--font-serif); }
/* ─── Dashboard "mine" cards (count lives in the header, no stat cards) ───────── */
.mine-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 16px; margin-top: 16px; }
.mine-card { display: flex; flex-direction: column; }
.mine-head { padding: 14px 18px; margin: 0; display: flex; align-items: center; justify-content: space-between; }
.mine-title { display: flex; align-items: center; gap: 8px; }
.mine-count {
  font: 600 .78rem/1 var(--font-body); color: var(--md-on-primary-container);
  background: var(--md-primary-container); border: 1px solid var(--md-outline-strong);
  border-radius: var(--md-shape-full); padding: 3px 9px; min-width: 22px; text-align: center;
  font-variant-numeric: tabular-nums;
}
.mine-body { border: none; border-top: 1px solid var(--border); border-radius: 0; flex: 1; }

/* ─── Modal ──────────────────────────────────────────────────────────────────── */
.modal-backdrop {
  position: fixed; inset: 0;
  background: rgba(28,20,10,.5); backdrop-filter: blur(2px);
  display: flex; align-items: center; justify-content: center;
  z-index: 1000; padding: 24px;
  animation: fadeIn var(--dur-3) var(--ease-decel);
}
.modal {
  background: var(--md-surface); border-radius: var(--radius-lg);
  box-shadow: var(--md-elev-4); width: 100%; max-width: 520px;
  max-height: 90vh; overflow-y: auto;
  border: 1px solid var(--md-outline-strong);
  animation: modalRise var(--dur-3) var(--ease-decel);
}
.modal-header { padding: 22px 24px 0; display: flex; align-items: center; justify-content: space-between; }
.modal-title { font-family: var(--font-serif); font-size: 1.25rem; font-weight: 600; }
.modal-close { color: var(--text-secondary); font-size: 22px; cursor: pointer; border-radius: 50%; transition: color var(--dur-1), background var(--dur-1); padding: 2px; }
.modal-close:hover { color: var(--md-on-surface); background: var(--md-surface-2); }
.modal-body { padding: 20px 24px; }
.modal-footer { padding: 0 24px 22px; display: flex; justify-content: flex-end; gap: 10px; }
.modal-wide { max-width: 720px; }

/* ─── Toast ──────────────────────────────────────────────────────────────────── */
.toast-container { position: fixed; bottom: 24px; right: 24px; z-index: 2000; display: flex; flex-direction: column; gap: 10px; align-items: flex-end; }
.toast {
  background: linear-gradient(180deg, var(--md-chrome-2), var(--md-chrome));
  color: var(--md-on-chrome); border-radius: var(--md-shape-sm);
  padding: 13px 18px; font-size: .9rem; box-shadow: var(--md-elev-4);
  display: flex; align-items: center; gap: 10px; min-width: 250px; max-width: 380px;
  border: 1px solid rgba(200,162,74,.25);
  animation: toastIn var(--dur-3) var(--ease-decel);
}
.toast.success { border-left: 4px solid var(--md-success); }
.toast.error   { border-left: 4px solid var(--md-error); }
.toast.warning { border-left: 4px solid var(--md-warning); }
.toast.info    { border-left: 4px solid var(--md-gilt); }
.toast .material-icons { font-size: 19px; flex-shrink: 0; }
.toast.success .material-icons { color: #9DBE6B; }
.toast.error   .material-icons { color: #E0897B; }
.toast.warning .material-icons { color: #E0B061; }
.toast.info    .material-icons { color: var(--md-gilt); }

/* ─── Login page (the "gatehouse") ───────────────────────────────────────────── */
.login-page {
  min-height: 100vh; min-height: 100dvh; padding: 24px;
  display: flex; align-items: center; justify-content: center;
  background:
    radial-gradient(90% 70% at 50% 0%, rgba(200,162,74,.18), transparent 60%),
    linear-gradient(160deg, #1F1810 0%, var(--md-chrome) 45%, #3A2C1B 100%);
}
.login-card {
  background: linear-gradient(180deg, var(--md-surface), var(--md-surface-1));
  border-radius: var(--radius-lg);
  box-shadow: var(--md-elev-4), inset 0 0 0 1px rgba(200,162,74,.25);
  width: 100%; max-width: 410px; padding: 44px 40px;
  border: 1px solid rgba(200,162,74,.4);
  animation: modalRise var(--dur-4) var(--ease-decel);
}
.login-logo { text-align: center; margin-bottom: 28px; }
.login-logo .material-icons { font-size: 52px; color: var(--md-primary); }
.login-logo h1 { font-family: var(--font-display); font-size: 1.7rem; font-weight: 700; margin-top: 10px; letter-spacing: 1px; }
.login-logo p { color: var(--text-secondary); font-family: var(--font-serif); font-size: .98rem; margin-top: 4px; }

/* ─── Tabs ───────────────────────────────────────────────────────────────────── */
.tabs { display: flex; border-bottom: 1.5px solid var(--md-outline-strong); margin-bottom: 22px; gap: 4px; }
.tab {
  padding: 11px 18px; font-family: var(--font-serif); font-size: .95rem; font-weight: 500; cursor: pointer;
  color: var(--text-secondary); border-bottom: 2.5px solid transparent; margin-bottom: -1.5px;
  transition: color var(--dur-2) var(--ease-standard), border-color var(--dur-2) var(--ease-standard);
}
.tab.active { color: var(--md-primary-hover); border-bottom-color: var(--md-gilt); font-weight: 600; }
.tab:hover:not(.active) { color: var(--md-on-surface); }

/* ─── Misc ───────────────────────────────────────────────────────────────────── */
.section-divider { border: none; border-top: 1px solid var(--md-outline); margin: 26px 0; }

.access-denied { text-align: center; padding: 68px 24px; color: var(--text-secondary); font-family: var(--font-serif); }
.access-denied .material-icons { font-size: 66px; color: var(--md-on-surface-dim); display: block; margin-bottom: 12px; }
.access-denied h2 { font-family: var(--font-display); font-size: 1.3rem; font-weight: 600; color: var(--md-on-surface); }

/* ─── Query Builder ──────────────────────────────────────────────────────────── */
.qb { display: flex; flex-direction: column; gap: 10px; }
.qb-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.qb-empty { padding: 22px 16px; background: var(--md-surface-2); border: 1.5px dashed var(--md-outline-strong); border-radius: var(--md-shape-sm); color: var(--md-on-surface-dim); font-size: .9rem; text-align: center; font-family: var(--font-serif); }
.qb-group { background: var(--md-surface); border: 1.5px solid var(--md-outline); border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--md-elev-1); }
.qb-group-header { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 11px 14px; background: var(--md-surface-3); border-bottom: 1px solid var(--md-outline); }
.qb-group-label { font-family: var(--font-serif); font-size: .76rem; font-weight: 600; color: var(--md-on-surface-dim); text-transform: uppercase; letter-spacing: .6px; }
.qb-logic-toggle { display: flex; border: 1.5px solid var(--md-outline-strong); border-radius: var(--md-shape-full); overflow: hidden; flex-shrink: 0; }
.qb-logic-btn { padding: 5px 14px; font-size: .8rem; font-weight: 600; background: var(--md-surface); color: var(--md-on-surface-dim); border: none; cursor: pointer; transition: background var(--dur-2) var(--ease-standard), color var(--dur-2) var(--ease-standard); }
.qb-logic-btn.active { background: var(--md-primary); color: var(--md-on-primary); }
.qb-logic-btn:not(.active):hover { background: var(--md-surface-3); }
.qb-conditions { padding: 11px 14px; display: flex; flex-direction: column; gap: 8px; }
.qb-cond-hint { padding: 8px 0; color: var(--md-on-surface-dim); font-size: .82rem; }
.qb-cond-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 9px 10px; background: var(--md-surface-2); border-radius: var(--md-shape-sm); border: 1px solid var(--md-outline); }
.qb-cond-row .form-control { height: 36px; padding: 6px 10px; font-size: .82rem; }
.qb-value-wrap .form-control { width: 100%; }
.qb-in-list { display: flex; flex-wrap: wrap; gap: 6px; padding: 4px 0; }
.qb-in-item { display: inline-flex; align-items: center; gap: 5px; padding: 4px 11px; border-radius: var(--md-shape-full); font-size: .82rem; cursor: pointer; background: var(--md-surface); border: 1px solid var(--md-outline-strong); user-select: none; transition: background var(--dur-2), border-color var(--dur-2); }
.qb-in-item input[type=checkbox] { accent-color: var(--md-primary); }

/* ─── Scrollbar ──────────────────────────────────────────────────────────────── */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--md-outline-strong); border-radius: var(--md-shape-full); border: 2px solid var(--md-background); }
::-webkit-scrollbar-thumb:hover { background: var(--md-primary); }
* { scrollbar-color: var(--md-outline-strong) transparent; scrollbar-width: thin; }

/* ─── Pagination ─────────────────────────────────────────────────────────────── */
.pagination-wrap { margin-top: 8px; }
.pagination { display: flex; align-items: center; justify-content: space-between; padding: 8px 4px; font-size: .82rem; color: var(--text-secondary); font-family: var(--font-serif); }
.pagination-controls { display: flex; align-items: center; gap: 4px; }
.pg-btn { background: none; border: 1px solid var(--md-outline-strong); border-radius: var(--md-shape-xs); padding: 4px 6px; cursor: pointer; color: var(--md-on-surface); display: flex; align-items: center; transition: background var(--dur-2) var(--ease-standard), border-color var(--dur-2) var(--ease-standard); }
.pg-btn:hover:not([disabled]) { background: var(--md-primary-container); border-color: var(--md-primary); }
.pg-btn[disabled] { opacity: .35; cursor: default; }
.pagination-page { padding: 0 8px; white-space: nowrap; }
.pagination-info { white-space: nowrap; }

/* ─── Action menu ────────────────────────────────────────────────────────────── */
.action-menu { position: fixed; z-index: 3000; min-width: 184px; padding: 6px; background: var(--md-surface); border: 1px solid var(--md-outline-strong); border-radius: var(--md-shape-sm); box-shadow: var(--md-elev-3); animation: menuPop var(--dur-2) var(--ease-decel); transform-origin: top right; }
.action-menu-item { display: flex; align-items: center; gap: 10px; width: 100%; padding: 9px 10px; border-radius: var(--md-shape-xs); font-size: .88rem; color: var(--md-on-surface); text-align: left; transition: background var(--dur-1) var(--ease-standard); }
.action-menu-item:hover { background: var(--md-surface-2); }
.action-menu-item.danger { color: var(--md-error); }
.action-menu-item .material-icons { font-size: 19px; opacity: .8; }
.btn-kebab { padding: 5px; border-radius: 50%; color: var(--text-secondary); transition: background var(--dur-2) var(--ease-standard); }
.btn-kebab:hover { background: var(--md-surface-2); }

/* ─── Sortable headers / status dots ─────────────────────────────────────────── */
.th-sort { cursor: pointer; user-select: none; white-space: nowrap; transition: color var(--dur-1); }
.th-sort:hover { color: var(--md-primary); }
.sort-ind { font-size: 14px !important; vertical-align: -2px; margin-left: 4px; color: var(--md-primary); }
tbody tr.row-clickable { cursor: pointer; }
/* Selected row — shared by the mesh, predicate and device tables. */
tbody tr.row-clickable.active td { background: var(--md-primary-container); }
tbody tr.row-clickable.active:hover td { background: var(--md-primary-container); }
tbody tr.row-clickable.active td:first-child { box-shadow: inset 3px 0 0 var(--md-primary); }

/* ─── Join-device searchable picker ──────────────────────────────────────────── */
.jd-search { margin-bottom: 10px; }
.jd-list {
  max-height: 280px; overflow-y: auto;
  border: 1px solid var(--md-outline); border-radius: var(--md-shape-sm);
  background: var(--md-surface);
}
.jd-option {
  display: flex; align-items: center; gap: 10px; padding: 9px 12px;
  border-bottom: 1px solid var(--md-outline); cursor: pointer;
  transition: background var(--dur-1) var(--ease-standard);
}
.jd-option:last-child { border-bottom: none; }
.jd-option:hover { background: var(--md-surface-1); }
.jd-option.selected { background: var(--md-primary-container); box-shadow: inset 3px 0 0 var(--md-primary); }
.jd-option.selected .jd-name { color: var(--md-on-primary-container); }
.jd-ico { font-size: 18px; color: var(--text-secondary); }
.jd-name { font-weight: 600; margin-right: auto; }
.jd-id { font-family: ui-monospace, monospace; font-size: .72rem; color: var(--text-disabled); }
.jd-empty { padding: 18px 14px; color: var(--text-disabled); font-size: .85rem; text-align: center; }

.status-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; vertical-align: middle; cursor: default; box-shadow: 0 0 0 2px var(--md-surface), 0 0 0 3px var(--md-outline); }
.status-dot:focus { outline: 2px solid var(--md-primary); outline-offset: 2px; }
.status-dot.dot-green { background: var(--md-success); box-shadow: 0 0 0 2px var(--md-surface), 0 0 6px rgba(94,114,66,.8); }
.status-dot.dot-amber { background: var(--md-warning); box-shadow: 0 0 0 2px var(--md-surface), 0 0 6px rgba(185,126,46,.8); }
.status-dot.dot-blue  { background: var(--md-secondary); }
.status-dot.dot-gray  { background: var(--md-on-surface-dim); }

/* ─── Keyframes ──────────────────────────────────────────────────────────────── */
@keyframes fadeIn   { from { opacity: 0; } to { opacity: 1; } }
@keyframes pageRise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes modalRise{ from { opacity: 0; transform: translateY(16px) scale(.98); } to { opacity: 1; transform: none; } }
@keyframes toastIn  { from { opacity: 0; transform: translateX(16px); } to { opacity: 1; transform: none; } }
@keyframes menuPop  { from { opacity: 0; transform: scale(.96); } to { opacity: 1; transform: none; } }

/* ─── Responsive: tablet ─────────────────────────────────────────────────────── */
/* Below 1100px the split list+panel already stacks (see .split-layout). */

/* ─── Responsive: mobile (≤768px) ────────────────────────────────────────────── */
@media (max-width: 768px) {
  /* Reveal hamburger; condense the bar so the brand always fits */
  .topbar-menu-btn { display: inline-flex; }
  .topbar {
    gap: 8px;
    padding-left: max(8px, env(safe-area-inset-left));
    padding-right: max(12px, env(safe-area-inset-right));
  }
  .topbar > .material-icons { display: none; }   /* drop decorative book glyph; hamburger anchors the bar */
  .topbar-brand {
    font-size: 1.05rem; letter-spacing: 1px;
    display: block; min-width: 0; flex: 0 1 auto;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .topbar-brand span.version { display: none; }
  .topbar-username { display: none; }            /* avatar still conveys identity */
  .topbar-btn-label { display: none; }           /* Logout becomes icon-only */
  .topbar-btn { padding: 9px; }

  /* Off-canvas navigation drawer — slides in beneath the topbar */
  .sidenav {
    position: fixed; top: var(--topbar-height); left: 0;
    height: calc(100dvh - var(--topbar-height));
    width: min(82vw, 300px); z-index: 200;
    transform: translateX(-100%);
    transition: transform var(--dur-3) var(--ease-emphasized);
    box-shadow: var(--md-elev-4);
    padding-bottom: env(safe-area-inset-bottom);
  }
  .sidenav.open { transform: translateX(0); }
  .sidenav-scrim {
    display: block; position: fixed; inset: var(--topbar-height) 0 0; z-index: 150;
    background: rgba(28,20,10,.5);
    opacity: 0; pointer-events: none;
    transition: opacity var(--dur-3) var(--ease-standard);
  }
  .sidenav-scrim.show { opacity: 1; pointer-events: auto; }

  /* Content + layout reflow to a single column */
  .page-content { padding: 18px 16px calc(18px + env(safe-area-inset-bottom)); }
  .page-header { flex-wrap: wrap; gap: 12px; }
  .page-title { font-size: 1.35rem; }
  .form-row { grid-template-columns: 1fr; }
  .card-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 12px; }
  /* Collapse the inline 1fr-1fr grids (dashboard summary, admin associations) */
  #summary-grid,
  [style*="grid-template-columns:1fr 1fr"] { grid-template-columns: 1fr !important; }

  /* Toolbars: fluid search, wrapped controls, no horizontal overflow */
  .toolbar { gap: 8px; }
  .search-bar { min-width: 0; flex: 1 1 100%; }
  .toolbar-end { margin-left: 0; width: 100%; }

  /* Inputs ≥16px so iOS Safari doesn't auto-zoom on focus */
  .form-control, .search-bar input { font-size: 16px; }

  /* Comfortable ≥44px touch targets (Apple HIG / Material) */
  .nav-item { padding: 13px 16px; }
  .btn { padding: 11px 18px; min-height: 44px; }
  .btn-sm { padding: 9px 14px; min-height: 44px; }
  .btn-icon, .btn-kebab, .pg-btn, .modal-close {
    min-width: 44px; min-height: 44px;
    display: inline-flex; align-items: center; justify-content: center;
  }

  /* Tighter table cells; horizontal scroll preserved for wide tables */
  thead th, tbody td { padding: 11px 12px; }

  /* Tabs scroll horizontally rather than wrapping */
  .tabs { overflow-x: auto; flex-wrap: nowrap; -webkit-overflow-scrolling: touch; }
  .tab { white-space: nowrap; }

  /* Dialogs become bottom sheets (thumb-reachable, full width) */
  .modal-backdrop { padding: 0; align-items: flex-end; }
  .modal {
    max-width: none; width: 100%; max-height: 92dvh;
    border-radius: var(--md-shape-lg) var(--md-shape-lg) 0 0;
    padding-bottom: env(safe-area-inset-bottom);
  }
  .modal-wide { max-width: none; }

  /* Visualisations shrink so they don't swallow the viewport */
  .viz-container { min-height: 300px; }

  /* Toasts span the width and clear the home-indicator safe area */
  .toast-container { left: 12px; right: 12px; bottom: calc(16px + env(safe-area-inset-bottom)); align-items: stretch; }
  .toast { max-width: none; }

  .pagination { flex-wrap: wrap; gap: 8px; }
}

/* ─── Responsive: small phones (≤380px) ──────────────────────────────────────── */
@media (max-width: 380px) {
  .topbar-brand { font-size: .95rem; letter-spacing: .5px; }
  .page-content { padding: 14px 12px calc(14px + env(safe-area-inset-bottom)); }
  .page-title { font-size: 1.25rem; }
}

/* ─── Accessibility: honour reduced-motion (kills every animation/transition) ── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
}
/* ════════════════════════════════════════════════════════════════════════════
   Console v2 — breadcrumbs, command panel, entity pages, header filters,
   admin hub, visualizer (stage + node table), telemetry embeds.
   Additive section: only new selectors below this line; everything above is
   the original stylesheet untouched.
   ════════════════════════════════════════════════════════════════════════════ */

/* ─── Breadcrumbs ────────────────────────────────────────────────────────────── */
.breadcrumbs {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-bottom: 14px; font-size: .85rem; font-family: var(--font-serif);
}
.breadcrumbs .crumb { color: var(--md-primary-hover); cursor: pointer; text-decoration: none; }
.breadcrumbs .crumb:hover { text-decoration: underline; }
.breadcrumbs .crumb.current { color: var(--text-secondary); cursor: default; font-weight: 600; }
.breadcrumbs .crumb-sep { color: var(--text-disabled); user-select: none; }

/* ─── Primary command panel (search bar promoted to the page's action bar) ───── */
.command-panel {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  background: var(--md-surface-2); border: 1px solid var(--md-outline);
  border-radius: var(--radius-lg); box-shadow: var(--md-elev-1);
  padding: 12px 14px; margin-bottom: 18px;
}
.command-panel .search-bar { flex: 1 1 260px; min-width: 200px; }
.command-panel .toolbar-end { margin-left: auto; display: flex; gap: 10px; align-items: center; }

/* ─── Entity pages (mesh / predicate) — Jira-style anatomy ───────────────────── */
.entity-header { margin-bottom: 18px; }
.entity-title-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.entity-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.entity-layout { display: grid; grid-template-columns: 1fr 340px; gap: 18px; align-items: start; }
@media (max-width: 1100px) { .entity-layout { grid-template-columns: 1fr; } }
.entity-side .card { position: sticky; top: 12px; }

/* ─── Filterable table headers (combined filter + sort, e.g. predicate Type) ─── */
.th-flex { display: inline-flex; align-items: center; gap: 4px; }
.th-filter {
  background: transparent; border: none; cursor: pointer; padding: 2px;
  color: var(--md-on-surface-dim); display: inline-flex; align-items: center;
  border-radius: 4px;
}
.th-filter:hover { color: var(--md-primary); background: var(--md-surface-3); }
.th-filter.active { color: var(--md-primary); }
.th-filter-count {
  font-size: .62rem; background: var(--md-primary); color: var(--md-on-primary);
  border-radius: 8px; padding: 0 4px; margin-left: 2px;
}
.th-filter-menu {
  position: fixed; z-index: 1000; min-width: 190px; max-width: 240px;
  background: var(--md-surface); border: 1px solid var(--md-outline-strong);
  border-radius: var(--md-shape-sm); box-shadow: var(--md-elev-3);
  padding: 8px; display: flex; flex-direction: column; gap: 2px;
  animation: menuPop var(--dur-2) var(--ease-decel);
}
.th-filter-item {
  display: flex; align-items: center; gap: 8px; padding: 6px 8px;
  font-size: .82rem; border-radius: var(--md-shape-xs); cursor: pointer;
}
.th-filter-item:hover { background: var(--md-surface-2); }
.th-filter-item input { accent-color: var(--md-primary); }
.th-filter-clear { margin-top: 4px; align-self: stretch; }

/* ─── Admin hub cards ────────────────────────────────────────────────────────── */
.admin-hub { display: grid; gap: 18px; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
.admin-hub-card { cursor: pointer; transition: transform var(--dur-2) var(--ease-standard), box-shadow var(--dur-2) var(--ease-standard); }
.admin-hub-card:hover { transform: translateY(-2px); box-shadow: var(--md-elev-3); border-color: var(--md-primary); }

/* ─── Live indicator (visualizer "Go live", mesh page link state) ────────────── */
.live-dot {
  display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  background: var(--text-disabled); margin-right: 4px; vertical-align: middle;
}
.live-dot.on { background: #EF5350; animation: livePulse 1.4s ease-in-out infinite; }
@keyframes livePulse { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

/* ─── Visualizer: stage dominates, node table pinned to its right ────────────── */
.viz-layout {
  display: grid;
  /* Stage takes everything the table doesn't. minmax(0,1fr) lets the canvas
     shrink instead of forcing the aside to wrap; the table gets enough width
     to read node info but never more than ~1/5 of the viewport. */
  grid-template-columns: minmax(0, 1fr) clamp(260px, 20vw, 360px);
  gap: 16px;
  align-items: stretch;
  height: calc(100vh - 190px);          /* topbar + breadcrumbs; tune to chrome */
  min-height: 420px;
}

.viz-stage {
  position: relative;
  width: 100%; height: 100%;            /* fill the grid cell — no max-width cap */
  min-width: 0;                          /* allow shrinking inside the grid */
  background: #9ec9e8;
  border: 1px solid var(--md-outline);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--md-elev-2);
}
.viz-stage canvas { display: block; width: 100%; height: 100%; }

.viz-side {
  display: flex; flex-direction: column;
  min-height: 0; min-width: 0;
  padding: 12px;
}
.viz-side .card-title { margin-bottom: 8px; }
.viz-side .viz-node-table { flex: 1; overflow-y: auto; min-height: 0; }

/* Compact table so four columns stay readable at ~300px */
.viz-node-table table { font-size: .78rem; }
.viz-node-table th, .viz-node-table td { padding: 6px 8px; white-space: nowrap; }
.viz-node-table td .badge { font-size: .65rem; padding: 1px 7px; }

/* Narrow viewports: keep the table beside the stage (never below) — shrink it
   and let its cells ellipsize instead of stacking. */
@media (max-width: 900px) {
  .viz-layout { grid-template-columns: minmax(0, 1fr) 220px; gap: 10px; }
  .viz-node-table td { max-width: 90px; overflow: hidden; text-overflow: ellipsis; }
}

/* FPS crosshair — shown while fly-mode pointer lock is held */
.viz-crosshair {
  position: absolute; top: 50%; left: 50%; width: 14px; height: 14px;
  margin: -7px 0 0 -7px; pointer-events: none; display: none; z-index: 9;
}
.viz-crosshair.on { display: block; }
.viz-crosshair::before, .viz-crosshair::after {
  content: ''; position: absolute; background: rgba(232,206,143,.9);
}
.viz-crosshair::before { left: 6px; top: 0; width: 2px; height: 14px; }
.viz-crosshair::after  { top: 6px; left: 0; width: 14px; height: 2px; }

/* Layers / visibility panel (grouped toggles) */
.viz-panel {
  position: absolute; top: 52px; right: 12px; z-index: 10; display: none;
  background: rgba(20,16,10,.9); border: 1px solid rgba(200,162,74,.3);
  border-radius: var(--md-shape-sm); padding: 12px 14px;
  color: #F3E7CE; font-size: .8rem; min-width: 220px; max-height: 70%;
  overflow-y: auto;
}
.viz-panel.open { display: block; }
.viz-panel-group { padding: 6px 0; border-bottom: 1px solid rgba(200,162,74,.15); }
.viz-panel-group:last-child { border-bottom: none; }
.viz-opt { display: flex; align-items: center; gap: 8px; padding: 3px 0; cursor: pointer; }
.viz-opt.sub { padding-left: 20px; color: #CBBFA8; }
.viz-opt input[type=checkbox] { accent-color: var(--md-primary); }
.viz-opt input[type=range] { flex: 1; accent-color: var(--md-primary); }
.viz-opt input[type=color] { width: 34px; height: 22px; border: none; background: transparent; padding: 0; cursor: pointer; }
.viz-opt:has(input:disabled) { opacity: .45; }
.viz-mini {
  background: transparent; border: 1px solid rgba(200,162,74,.4); color: #E8CE8F;
  border-radius: 6px; font-size: .68rem; padding: 1px 8px; cursor: pointer;
}
.viz-mini:hover { background: rgba(200,162,74,.2); }

/* Controls / navigation helper overlay */
.viz-help {
  position: absolute; top: 52px; left: 12px; z-index: 10; display: none;
  background: rgba(20,16,10,.85); border: 1px solid rgba(200,162,74,.25);
  border-radius: var(--md-shape-sm); padding: 12px 14px; color: #F3E7CE;
  font-size: .78rem; max-width: 260px;
}
.viz-help.open { display: block; }
.viz-help-title { font-weight: 700; margin-bottom: 6px; color: var(--md-gilt); }
.viz-help-row { margin-bottom: 4px; }
.viz-help kbd {
  background: rgba(255,255,255,.12); border-radius: 4px; padding: 1px 6px;
  font-size: .72rem; margin-right: 6px;
}

.viz-select {
  flex: 1; background: rgba(255,255,255,.08); color: #F3E7CE;
  border: 1px solid rgba(200,162,74,.4); border-radius: 6px;
  font-size: .75rem; padding: 2px 6px;
}
.viz-select option { color: var(--md-on-surface); background: var(--md-surface); }

/* Status line (static / live / following …) */
.viz-status {
  position: absolute; bottom: 12px; left: 12px; z-index: 10;
  background: rgba(20,16,10,.7); border: 1px solid rgba(200,162,74,.2);
  border-radius: var(--md-shape-sm); padding: 6px 10px;
  color: #F3E7CE; font-size: .72rem;
}

/* ─── Telemetry (embedded Grafana): one full-page board, groups as chips ─────── */
.telemetry-shell {
  display: flex; flex-direction: column;
  height: calc(100vh - 220px);          /* topbar + header + breadcrumbs */
  min-height: 480px; padding: 14px 16px 16px;
}
.telemetry-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap; margin-bottom: 12px;
}
.telemetry-links { display: flex; align-items: center; gap: 6px 10px; flex-wrap: wrap; }
.telemetry-group { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.telemetry-group + .telemetry-group { margin-left: 10px; padding-left: 12px; border-left: 1px solid var(--md-outline); }
.telemetry-group-label {
  font-size: .72rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--text-secondary);
}
.telemetry-chip {
  background: var(--md-surface-2); border: 1px solid var(--md-outline);
  border-radius: var(--md-shape-full); padding: 4px 12px;
  font-size: .78rem; color: var(--md-on-surface-var); cursor: pointer;
  transition: background var(--dur-1), border-color var(--dur-1);
}
.telemetry-chip:hover { border-color: var(--md-primary); background: var(--md-surface-3); }
.telemetry-chip.active {
  background: var(--md-primary-container); border-color: var(--md-primary);
  color: var(--md-on-primary-container); font-weight: 600;
}
.grafana-frame-full {
  flex: 1; width: 100%; min-height: 0;
  border: 1px solid var(--md-outline);
  border-radius: var(--md-shape-sm); background: #0d0f14;
}

/* ─── Console v2 mobile adjustments ──────────────────────────────────────────── */
@media (max-width: 768px) {
  .command-panel { padding: 10px 12px; gap: 8px; }
  .command-panel .search-bar { flex: 1 1 100%; }
  .command-panel .toolbar-end { margin-left: 0; width: 100%; }
  .entity-side .card { position: static; }
  .viz-layout { height: calc(100dvh - 190px); }
  .telemetry-shell { height: calc(100dvh - 230px); min-height: 380px; }
}

/* ─── Predicate editor: stage dominates, properties dock right ─────────────────
   Same anatomy as .viz-layout — the proven full-height editor frame. */
.editor-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(280px, 24vw, 360px);
  gap: 16px;
  align-items: stretch;
  height: calc(100vh - 230px);          /* topbar + breadcrumbs + entity header */
  min-height: 420px;
}
.editor-stage { padding: 0; overflow: hidden; display: flex; min-width: 0; }
.editor-stage > div { flex: 1; display: flex; min-width: 0; min-height: 0; }
.editor-stage .geo3d { flex: 1; gap: 0; min-height: 0; }
.editor-stage .geo3d-stage { height: 100%; border: none; border-radius: 0; box-shadow: none; }
.editor-stage .geo3d-coming { flex: 1; min-height: 0; border: none; border-radius: 0; }

.editor-side { display: flex; flex-direction: column; gap: 12px; overflow-y: auto; min-height: 0; }
.editor-side .card-title { margin-bottom: 2px; }
.editor-side-footer {
  margin-top: auto;                      /* pin actions to the dock's foot */
  display: flex; gap: 8px;
  padding-top: 14px; border-top: 1px solid var(--md-outline);
}
.editor-side-footer .btn { flex: 1; justify-content: center; }

@media (max-width: 1100px) {
  /* Small screens: properties lead (name what you're drawing), stage follows. */
  .editor-layout { display: flex; flex-direction: column; height: auto; }
  .editor-side { order: -1; overflow: visible; }
  .editor-stage { min-height: 340px; height: 55vh; }
}

/* ─── Topbar: notifications inbox + account menu ───────────────────────────── */
.inbox-slot { position: relative; display: inline-flex; }
.inbox-bell { position: relative; }
.inbox-count {
  position: absolute; top: -4px; right: -6px;
  font: 700 .62rem/1 var(--font-body); color: #fff; background: var(--danger, #D32F2F);
  border-radius: var(--md-shape-full); padding: 2px 5px; min-width: 16px; text-align: center;
}
.inbox-panel {
  position: absolute; top: calc(100% + 10px); right: 0; z-index: 300;
  width: min(360px, 92vw); max-height: 60vh; overflow-y: auto;
  background: var(--md-surface); border: 1px solid var(--md-outline);
  border-radius: var(--radius-lg); box-shadow: var(--md-elev-3);
}
.inbox-head {
  font-family: var(--font-serif); font-weight: 600; font-size: .9rem;
  padding: 12px 14px; border-bottom: 1px solid var(--md-outline);
}
.inbox-empty { padding: 18px 14px; color: var(--text-secondary); font-size: .85rem; }
.inbox-item {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px; border-bottom: 1px solid var(--md-outline); font-size: .85rem;
}
.inbox-item:last-child { border-bottom: none; }
.inbox-item > .material-icons { font-size: 20px; color: var(--md-primary); flex-shrink: 0; }
.inbox-item-body { flex: 1; min-width: 0; }
.inbox-item-sub { color: var(--text-secondary); font-size: .75rem; margin-top: 2px; }

.avatar-btn { cursor: pointer; border: none; }
.topbar-user { position: relative; }
.account-menu {
  position: absolute; top: calc(100% + 10px); right: 0; z-index: 300;
  width: 240px; background: var(--md-surface); border: 1px solid var(--md-outline);
  border-radius: var(--radius-lg); box-shadow: var(--md-elev-3); overflow: hidden;
}
.account-menu-head { padding: 12px 14px; border-bottom: 1px solid var(--md-outline); }
.account-menu-name { font-weight: 600; font-size: .9rem; margin-bottom: 6px; }
.account-menu-roles { display: flex; flex-wrap: wrap; gap: 3px; }
.account-menu-item {
  display: flex; align-items: center; gap: 8px; width: 100%;
  background: none; border: none; cursor: pointer; text-align: left;
  padding: 11px 14px; font-size: .85rem; color: var(--text-primary);
}
.account-menu-item:hover { background: var(--md-surface-2); }

:root{
  --pc-pose:#C6892F; --pc-scalar:#3E7C7B; --pc-vector:#4E7A4B;
  --pc-boolean:#7A5B8E; --pc-event:#B4472F; --pc-geometry:#2E6BA8;
}
.composer-layout{display:grid;grid-template-columns:250px 1fr 270px;gap:14px;height:calc(100vh - 150px)}
.composer-palette,.composer-inspector{overflow:auto;padding:12px}

/* shelves */
.shelf{border-radius:12px;background:var(--md-surface-1);border:1px solid var(--md-outline);overflow:hidden;margin-bottom:12px}
.shelf-head{display:flex;align-items:center;gap:9px;padding:9px 11px 7px;border-left:5px solid var(--shelf)}
.shelf-sigil{width:24px;height:24px;flex:none;display:grid;place-items:center;color:var(--md-on-primary);
  background:var(--shelf);border-radius:7px;font-size:.75rem}
.shelf-name{font-size:.85rem;font-weight:650;color:var(--text-primary);letter-spacing:.02em}
.shelf-why{display:block;font-size:.7rem;color:var(--text-secondary);font-style:italic;font-family:var(--font-serif)}
.shelf-items{padding:4px 9px 9px;display:flex;flex-direction:column;gap:6px}
.palette-item{position:relative;display:flex;align-items:center;gap:9px;width:100%;text-align:left;padding:8px 10px;
  border:1px solid var(--border);border-radius:9px;background:var(--surface);cursor:grab;font-size:.82rem;color:var(--text);
  transition:border-color .18s,box-shadow .18s,transform .18s}
.palette-item:hover,.palette-item:focus-visible{border-color:var(--shelf,var(--accent));transform:translateX(2px);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--shelf,var(--accent)) 20%,transparent)}
.pi-glyph{font-size:1.05rem;flex:none}
.pi-body{min-width:0}
.pi-name{font-weight:600;display:block}
.pi-desc{display:block;font-size:.7rem;color:var(--text-secondary);font-family:var(--font-serif);font-style:italic;
  max-height:0;overflow:hidden;transition:max-height .22s ease}
.palette-item:hover .pi-desc,.palette-item:focus-visible .pi-desc{max-height:3.4em}
.pi-grab{margin-left:auto;font-size:.64rem;color:var(--text-secondary);opacity:0;transition:opacity .18s;white-space:nowrap;flex:none}
.palette-item:hover .pi-grab,.palette-item:focus-visible .pi-grab{opacity:1}
.shelf-docs-link{display:flex;align-items:center;gap:6px;font-size:.76rem;color:var(--accent);padding:4px 2px}

/* primer flyout (body-appended, beside the hovered shelf item) */
.shelf-flyout{position:fixed;z-index:70;width:210px;background:var(--surface);border:1px solid var(--md-outline-strong);
  border-radius:10px;box-shadow:var(--md-elev-4);overflow:hidden;pointer-events:none}
.shelf-flyout .fly-line,.fly-line{padding:7px 10px 9px;font-size:.7rem;color:var(--text-secondary);
  font-family:var(--font-serif);font-style:italic}

/* board */
.composer-board-wrap{position:relative;padding:0;overflow:hidden}
.board-host{position:absolute;inset:0;overflow:hidden;
  background:radial-gradient(circle, color-mix(in srgb,var(--text-secondary) 18%,transparent) 1px, transparent 1px) 0 0/16px 16px}
.board-links{position:absolute;inset:0;pointer-events:none;overflow:visible}
.board-guide{position:absolute;background:var(--md-gilt);opacity:0;transition:opacity .12s;pointer-events:none;z-index:4}
.board-guide.v{width:1.5px;top:0;bottom:0}
.board-guide.h{height:1.5px;left:0;right:0}
.board-guide.show{opacity:.9}

/* cards — three families, three silhouettes */
.block{position:absolute;width:190px;background:var(--surface);border:1.5px solid var(--md-outline-strong);
  border-radius:12px;box-shadow:var(--md-elev-2);cursor:grab;user-select:none;touch-action:none;--fam:var(--pc-scalar)}
.block.f-action{--fam:var(--pc-pose);border-radius:22px 10px 10px 22px;border-left-width:3px}
.block.f-eval{--fam:var(--pc-scalar);border-radius:8px;border-top-width:3px}
.block.f-trigger{--fam:var(--pc-event);border-radius:10px}
.block.f-trigger:after{content:'';position:absolute;right:-13px;top:50%;margin-top:-9px;
  border:9px solid transparent;border-left:11px solid var(--pc-event)}
.block.f-event{--fam:var(--pc-geometry);border-radius:10px 10px 16px 16px;border-bottom-width:3px}
.block.sel{border-color:var(--md-gilt);box-shadow:0 0 0 3px color-mix(in srgb,var(--md-gilt) 32%,transparent),var(--md-elev-2)}
.block.dragging{box-shadow:var(--md-elev-4);cursor:grabbing}
.block-head{display:flex;align-items:center;gap:7px;padding:8px 11px;font-size:.84rem;color:var(--text);
  background:color-mix(in srgb,var(--fam) 13%,var(--surface));
  border-bottom:1px solid color-mix(in srgb,var(--fam) 30%,var(--surface));border-radius:inherit;
  border-bottom-left-radius:0;border-bottom-right-radius:0}
.block-glyph{font-size:1rem}
.block-title{font-weight:650;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.block-fam{margin-left:auto;font-size:.58rem;letter-spacing:.1em;text-transform:uppercase;flex:none;
  border-radius:999px;padding:1px 7px;background:var(--fam);color:var(--md-on-primary)}
.block-wm{position:absolute;right:6px;bottom:-8px;font-size:46px;line-height:1;color:var(--fam);
  opacity:.08;pointer-events:none;font-family:var(--font-serif)}
.block.f-action .block-wm{right:auto;left:6px}
.block-more{position:absolute;top:5px;right:6px;width:20px;height:20px;border-radius:6px;display:none;
  place-items:center;font-size:.85rem;color:var(--text-secondary);background:var(--md-surface-2);
  border:1px solid var(--md-outline);cursor:pointer;z-index:3}
.block.sel .block-more{display:grid}
.block-squelch{display:none;position:absolute;top:-9px;right:-9px;width:20px;height:20px;border-radius:50%;
  background:var(--md-error);color:var(--md-on-primary);font-size:12px;line-height:20px;text-align:center;z-index:3}

/* sockets — named rows; hollow takes (left), filled gives (right) */
.block-socks{padding:6px 0 10px}
.sock{position:relative;display:flex;align-items:center;gap:7px;font-size:.72rem;color:var(--text-secondary);
  padding:4px 14px;margin:1px 0;min-height:22px}
.sock-out{justify-content:flex-end;color:var(--text)}
.sock-label{pointer-events:none}
.port{position:absolute;width:15px;height:15px;border-radius:50%;border:2.5px solid var(--pt,#888);
  background:var(--surface);cursor:crosshair;touch-action:none;transition:transform .12s,background .12s;z-index:2}
.sock-in .port{left:-8px}
.sock-out .port{right:-8px;background:var(--pt,#888)}
.port.pt-pose{--pt:var(--pc-pose)}       .port.pt-scalar{--pt:var(--pc-scalar);border-radius:4px}
.port.pt-vector{--pt:var(--pc-vector)}   .port.pt-boolean{--pt:var(--pc-boolean);border-radius:4px;rotate:45deg}
.port.pt-event{--pt:var(--pc-event)}     .port.pt-geometry{--pt:var(--pc-geometry);border-radius:4px}
.port:hover,.port.magnet{transform:scale(1.35);box-shadow:0 0 0 4px color-mix(in srgb,var(--pt) 26%,transparent)}
.port.magnet{background:var(--pt)}
.sock.needs .port{border-style:dashed;animation:sock-breathe 1.8s ease-in-out infinite}
.sock.needs .sock-label{color:var(--md-error);font-style:italic;font-family:var(--font-serif)}
.sock.needs .sock-label:after{content:' — needs a wire'}
@keyframes sock-breathe{0%,100%{box-shadow:0 0 0 0 color-mix(in srgb,var(--pt) 45%,transparent)}50%{box-shadow:0 0 0 6px transparent}}

/* wiring emphasis: pulse legal, squelch illegal, refuse on wrong drop */
.board-host.wiring .block.can-take .sock-in .port{animation:port-ring 1.1s ease-out infinite}
@keyframes port-ring{0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--pt) 55%,transparent)}
  70%{box-shadow:0 0 0 9px transparent}100%{box-shadow:0 0 0 0 transparent}}
.board-host.wiring .block.no-take{opacity:.38;filter:saturate(.35);transform:scale(.97)}
.board-host.wiring .block.no-take .block-squelch{display:block}
.block.deny{animation:block-deny .4s ease 2}
@keyframes block-deny{0%,100%{translate:0 0}25%{translate:-5px 0}75%{translate:5px 0}}

/* wires + chips + try-it current */
.link{fill:none;stroke-width:3}
.link.tmp{stroke-dasharray:5 4;opacity:.85}
.board-host.flowing .link:not(.tmp){stroke-dasharray:5 9;animation:link-flow .7s linear infinite}
@keyframes link-flow{to{stroke-dashoffset:-28}}
.wire-chip{position:absolute;z-index:3;transform:translate(-50%,-50%);font-size:.64rem;pointer-events:auto;
  background:var(--surface);border:1.5px solid var(--pt,var(--border));color:var(--text);
  border-radius:999px;padding:1px 8px;box-shadow:var(--md-elev-1);cursor:context-menu}
.wire-chip.pt-scalar{--pt:var(--pc-scalar)} .wire-chip.pt-vector{--pt:var(--pc-vector)}
.wire-chip.pt-boolean{--pt:var(--pc-boolean)} .wire-chip.pt-event{--pt:var(--pc-event)}
.wire-chip.pt-pose{--pt:var(--pc-pose)} .wire-chip.pt-geometry{--pt:var(--pc-geometry)}
.board-host.flowing .wire-chip{background:var(--pt);color:var(--md-on-primary)}

/* transport + hint bar + help button */
.composer-transport{position:absolute;left:12px;bottom:40px;display:flex;gap:10px;align-items:center;z-index:5;
  background:color-mix(in srgb,var(--surface) 88%,transparent);padding:8px 12px;border-radius:10px;border:1px solid var(--border)}
.composer-lamp{font-size:.82rem;color:var(--text-secondary);padding:4px 10px;border-radius:999px;border:1px solid var(--border);font-variant-numeric:tabular-nums;white-space:nowrap}
.composer-lamp.lit{background:#4E7A4B;color:#fff;border-color:#4E7A4B}
.composer-lamp.err{border-color:#B4472F;color:#B4472F}
.btn-help{width:28px;height:28px;border-radius:50%;border:1.5px solid var(--md-outline-strong);
  background:var(--md-surface-2);color:var(--text-secondary);font-weight:700;cursor:pointer;flex:none}
.btn-help:hover{border-color:var(--accent);color:var(--accent)}
.btn-help.sm{width:22px;height:22px;font-size:.7rem;margin-left:auto}
.board-hintbar{position:absolute;left:0;right:0;bottom:0;z-index:5;background:color-mix(in srgb,var(--md-chrome) 92%,transparent);
  color:var(--md-on-chrome);font-size:.75rem;padding:7px 14px;letter-spacing:.02em}
.board-hintbar.deny{background:color-mix(in srgb,var(--md-error) 92%,transparent)}
.board-hintbar.ok{background:color-mix(in srgb,var(--md-success) 92%,transparent)}

/* context menus (reduced options; body-appended) */
.board-menu{position:fixed;z-index:80;min-width:190px;background:var(--surface);border:1px solid var(--md-outline-strong);
  border-radius:10px;box-shadow:var(--md-elev-4);font-size:.8rem;padding:5px;color:var(--text)}
.bm-head{font-size:.62rem;letter-spacing:.1em;text-transform:uppercase;color:var(--text-secondary);padding:5px 10px 3px}
.bm-item{display:flex;align-items:center;flex-wrap:wrap;gap:4px 8px;width:100%;text-align:left;
  border:none;background:none;border-radius:7px;padding:6px 10px;cursor:pointer;color:inherit;font:inherit}
.bm-item:hover:not(.off){background:var(--md-surface-2)}
.bm-item.danger{color:var(--md-error)}
.bm-item.off{color:var(--text-secondary);opacity:.65;cursor:default}
.bm-why{flex-basis:100%;font-size:.66rem;font-style:italic;font-family:var(--font-serif)}

/* inspector */
.inspector-head{display:flex;align-items:center;gap:8px;font-weight:600;margin-bottom:8px;color:var(--text)}
.ins-glyph{font-size:1.2rem}
.inspector-primer{border:1px solid var(--md-outline);border-radius:10px;overflow:hidden;margin-bottom:8px}
.ins-line{font-size:.74rem;color:var(--text-secondary);font-family:var(--font-serif);font-style:italic;margin-bottom:10px}
.ins-field{display:flex;flex-direction:column;gap:4px;margin:8px 0;font-size:.85rem;color:var(--text-secondary)}
.ins-field input{padding:7px 9px;border:1px solid var(--border);border-radius:8px;background:var(--surface);color:var(--text)}
.ins-note{font-size:.72rem;color:var(--accent)}
.ins-delete{margin-top:14px;width:100%;justify-content:center}
.inspector-empty{color:var(--text-secondary);font-size:.85rem;padding:8px 0}

/* help overlay — workflow walkthroughs */
.help-overlay{position:fixed;inset:0;z-index:90;background:color-mix(in srgb,var(--md-chrome) 45%,transparent);
  display:grid;place-items:center;padding:20px}
.help-panel{width:min(560px,94vw);max-height:88vh;overflow:auto;background:var(--surface);
  border:1px solid var(--md-outline-strong);border-radius:14px;box-shadow:var(--md-elev-4);padding:14px 16px 16px}
.help-top{display:flex;align-items:center;gap:10px;margin-bottom:10px}
.help-title{font-weight:650;font-size:1rem;color:var(--text)}
.help-guide-link{display:flex;align-items:center;gap:4px;font-size:.74rem;color:var(--accent);margin-left:auto}
.help-close{border:none;background:none;font-size:1rem;color:var(--text-secondary);cursor:pointer;padding:4px}
.help-tabs{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:12px}
.help-tab{font-size:.74rem;border:1px solid var(--md-outline-strong);background:var(--surface);color:var(--text-secondary);
  border-radius:999px;padding:5px 12px;cursor:pointer}
.help-tab.on{background:var(--md-primary);border-color:var(--md-primary);color:var(--md-on-primary)}
.help-primer{border:1px solid var(--md-outline);border-radius:10px;overflow:hidden;margin-bottom:10px}
.help-steps{margin:0 0 10px;padding-left:20px;font-size:.84rem;color:var(--text);display:grid;gap:7px}
.help-deep{font-size:.76rem;color:var(--accent)}

/* primer scenes — shared by flyout, inspector, help and /docs pages */
svg.primer{display:block;width:100%;height:auto;background:
  radial-gradient(circle, color-mix(in srgb,var(--text-secondary) 14%,transparent) 1px, transparent 1.5px) 0 0/16px 16px,var(--md-surface-1)}
svg.primer text{font-family:var(--font-body)}
@keyframes pa-aimswing{0%,100%{transform:rotate(-16deg)}50%{transform:rotate(16deg)}}
.pa-aim{transform-origin:52px 70px;animation:pa-aimswing 3.2s ease-in-out infinite}
@keyframes pa-angB{0%,15%{transform:rotate(-46deg)}55%,70%{transform:rotate(-4deg)}100%{transform:rotate(-46deg)}}
.pa-angB{transform-origin:60px 112px;animation:pa-angB 4.5s ease-in-out infinite}
@keyframes pa-angArc{0%,15%{stroke-dashoffset:0}55%,70%{stroke-dashoffset:82}100%{stroke-dashoffset:0}}
.pa-angArc{stroke-dasharray:100;animation:pa-angArc 4.5s ease-in-out infinite}
@keyframes pa-angT1{0%,20%{opacity:1}45%,75%{opacity:0}95%,100%{opacity:1}}
@keyframes pa-angT2{0%,40%{opacity:0}55%,70%{opacity:1}85%,100%{opacity:0}}
.pa-angT1{animation:pa-angT1 4.5s linear infinite}
.pa-angT2{animation:pa-angT2 4.5s linear infinite}
@keyframes pa-coneswing{0%{transform:rotate(-24deg)}38%,62%{transform:rotate(0deg)}100%{transform:rotate(24deg)}}
.pa-cone{transform-origin:38px 70px;animation:pa-coneswing 5s ease-in-out infinite alternate}
@keyframes pa-conecol{0%,30%{fill:#A33B2C}42%,58%{fill:#5E7242}70%,100%{fill:#A33B2C}}
.pa-conefill{animation:pa-conecol 5s linear infinite alternate;opacity:.18}
@keyframes pa-conestroke{0%,30%{stroke:#A33B2C}42%,58%{stroke:#5E7242}70%,100%{stroke:#A33B2C}}
.pa-conestroke{animation:pa-conestroke 5s linear infinite alternate}
@keyframes pa-sphglow{0%,30%{fill:#C4B28E}42%,58%{fill:#C8A24A}70%,100%{fill:#C4B28E}}
.pa-sph{animation:pa-sphglow 5s linear infinite alternate}
@keyframes pa-yeschip{0%,34%{opacity:0}44%,56%{opacity:1}66%,100%{opacity:0}}
.pa-yes{animation:pa-yeschip 5s linear infinite alternate}
@keyframes pa-nochip{0%,26%{opacity:1}38%,62%{opacity:0}74%,100%{opacity:1}}
.pa-no{animation:pa-nochip 5s linear infinite alternate}
@keyframes pa-holdin{0%,8%{fill-opacity:0}10%,30%{fill-opacity:1}32%,44%{fill-opacity:0}46%,88%{fill-opacity:1}90%,100%{fill-opacity:0}}
.pa-hin{animation:pa-holdin 7s linear infinite}
@keyframes pa-holdring{0%,9%{stroke-dashoffset:100}31%{stroke-dashoffset:48}32%,45%{stroke-dashoffset:100}46%{stroke-dashoffset:100}80%{stroke-dashoffset:0}88%{stroke-dashoffset:0}90%,100%{stroke-dashoffset:100}}
.pa-hring{stroke-dasharray:100;animation:pa-holdring 7s linear infinite}
@keyframes pa-holdout{0%,79%{fill-opacity:0}81%,88%{fill-opacity:1}90%,100%{fill-opacity:0}}
.pa-hout{animation:pa-holdout 7s linear infinite}
@keyframes pa-holdnote{0%,30%{opacity:0}33%,42%{opacity:1}46%,100%{opacity:0}}
.pa-hnote{animation:pa-holdnote 7s linear infinite}
@keyframes pa-sparkdraw{0%{stroke-dashoffset:240}70%,100%{stroke-dashoffset:0}}
.pa-swave{stroke-dasharray:240;animation:pa-sparkdraw 5s linear infinite}
@keyframes pa-ping1{0%,30%{r:4;opacity:0}34%{r:6;opacity:.9}52%{r:26;opacity:0}100%{r:4;opacity:0}}
.pa-ping1{animation:pa-ping1 5s linear infinite}
@keyframes pa-ping2{0%,36%{r:4;opacity:0}40%{r:6;opacity:.7}58%{r:34;opacity:0}100%{r:4;opacity:0}}
.pa-ping2{animation:pa-ping2 5s linear infinite}
@keyframes pa-pingdot{0%,30%{opacity:0}34%,60%{opacity:1}70%,100%{opacity:0}}
.pa-pingdot{animation:pa-pingdot 5s linear infinite}
@keyframes pa-sparkonce{0%,36%{opacity:0}42%,72%{opacity:1}80%,100%{opacity:0}}
.pa-sonce{animation:pa-sparkonce 5s linear infinite}
@keyframes pa-gestdraw{0%,6%{stroke-dashoffset:230}64%,100%{stroke-dashoffset:0}}
.pa-gink{stroke-dasharray:230;animation:pa-gestdraw 5.5s ease-in-out infinite}
@keyframes pa-gestglow{0%,62%{opacity:0}70%,88%{opacity:1}96%,100%{opacity:0}}
.pa-gok{animation:pa-gestglow 5.5s linear infinite}
@keyframes pa-garm{0%,6%{transform:rotate(-34deg)}20%{transform:rotate(20deg)}34%{transform:rotate(-22deg)}48%{transform:rotate(26deg)}64%,100%{transform:rotate(-6deg)}}
.pa-garm{transform-origin:44px 74px;animation:pa-garm 5.5s ease-in-out infinite}
@keyframes pa-twalk{0%,100%{transform:translateY(-20px)}50%{transform:translateY(20px)}}
.pa-twalk{animation:pa-twalk 4.5s ease-in-out infinite}
@keyframes pa-taim{0%,100%{transform:rotate(9deg)}50%{transform:rotate(-9deg)}}
.pa-taim{transform-origin:44px 70px;animation:pa-taim 4.5s ease-in-out infinite}
@keyframes pa-rc1{0%,8%{opacity:.35}14%,88%{opacity:1}94%,100%{opacity:.35}}
.pa-rc1{animation:pa-rc1 6s linear infinite}
@keyframes pa-rcw1{0%,14%{opacity:.25}20%,88%{opacity:1}94%,100%{opacity:.25}}
.pa-rcw1{animation:pa-rcw1 6s linear infinite}
@keyframes pa-rcring{0%,20%{stroke-dashoffset:100}58%{stroke-dashoffset:0}88%{stroke-dashoffset:0}94%,100%{stroke-dashoffset:100}}
.pa-rcring{stroke-dasharray:100;animation:pa-rcring 6s linear infinite}
@keyframes pa-rcw2{0%,58%{opacity:.25}64%,88%{opacity:1}94%,100%{opacity:.25}}
.pa-rcw2{animation:pa-rcw2 6s linear infinite}
@keyframes pa-rcping{0%,62%{r:5;opacity:0}66%{r:7;opacity:.9}84%{r:22;opacity:0}100%{r:5;opacity:0}}
.pa-rcping{animation:pa-rcping 6s linear infinite}
@media (prefers-reduced-motion:reduce){
  [class^="pa-"],[class*=" pa-"]{animation:none!important}
  .board-host.wiring .block.can-take .sock-in .port,.sock.needs .port,.block.deny{animation:none!important}
}

/* ── Composer v3 — header, filter, marquee, wire selection, save, hints ──── */
.composer-header{display:flex;align-items:center;gap:12px;margin:2px 0 10px}
.composer-name{font-family:var(--font-display);font-size:1.15rem;color:var(--text-primary);
  max-width:40ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.composer-header-actions{margin-left:auto;display:flex;align-items:center;gap:8px}
.composer-guide-link{display:flex;align-items:center;gap:5px;font-size:.8rem;color:var(--accent);
  text-decoration:none;padding:4px 8px;border-radius:8px}
.composer-guide-link:hover{background:var(--md-surface-2)}
.btn-sm{padding:5px 12px;font-size:.82rem}

.palette-filter{display:flex;align-items:center;gap:7px;margin-bottom:10px;color:var(--text-secondary)}
.form-control-sm{padding:5px 8px;font-size:.82rem;border:1px solid var(--border);border-radius:8px;
  background:var(--surface);color:var(--text);flex:1}

/* marquee (drag-select) */
.board-marquee{position:absolute;border:1.5px dashed var(--md-gilt);
  background:color-mix(in srgb,var(--md-gilt) 12%,transparent);pointer-events:none;display:none;z-index:6}
.board-marquee.show{display:block}

/* wire selection + fat hit-line */
.link-hit{fill:none;stroke:transparent;stroke-width:14;pointer-events:stroke;cursor:pointer}
.link.sel{stroke-width:4;filter:drop-shadow(0 0 3px color-mix(in srgb,var(--md-gilt) 70%,transparent))}
.wire-chip.sel{outline:2px solid var(--md-gilt);outline-offset:1px}

/* param descriptions + multi/wire inspector */
.ins-desc{display:block;font-size:.7rem;color:var(--text-secondary);font-style:italic;
  font-family:var(--font-serif);margin-top:3px;line-height:1.4}
.ins-line kbd{border:1px solid var(--md-outline-strong);border-bottom-width:2px;border-radius:4px;
  padding:0 4px;font-size:.8em;background:var(--md-surface-2)}

/* library "where are my recipes?" hint */
.shelf-foot{padding:2px 10px 10px}
.lib-hint{font-size:.72rem;color:var(--text-secondary);line-height:1.5;
  border-top:1px dashed var(--md-outline);padding-top:8px}
.lib-hint b{color:var(--text-primary)}
.lib-hint-link{color:var(--accent);cursor:pointer;text-decoration:underline}

/* fading transient notifications */
.board-hintbar{transition:opacity .55s ease}
.board-hintbar.fading{opacity:0}
.composer-lamp{transition:opacity .4s ease}