/* ==========================================================================
   NoteScout — theme tokens
   ========================================================================== */
:root,
html[data-theme="light"] {
  --bg-app: #f6f5f3;
  --bg-nav: #efece7;
  --bg-editor: #ffffff;
  --bg-raised: #ffffff;
  --bg-hover: rgba(20, 20, 20, 0.06);
  --bg-active: rgba(20, 20, 20, 0.10);
  --bg-input: #ffffff;
  --border: rgba(20, 20, 20, 0.12);
  --border-soft: rgba(20, 20, 20, 0.08);
  --text: #1f1d1a;
  --text-muted: #6b6862;
  --text-faint: #9a968e;
  --accent: #8a6d3b;
  --accent-contrast: #ffffff;
  --accent-soft: rgba(138, 109, 59, 0.14);
  --scrollbar-thumb: rgba(20, 20, 20, 0.22);
  --scrollbar-thumb-hover: rgba(20, 20, 20, 0.36);
  --shadow: 0 10px 30px rgba(20, 20, 20, 0.12), 0 2px 8px rgba(20, 20, 20, 0.06);
  --danger: #b3432b;
  --link: #3563c9;
}

html[data-theme="pink"] {
  --bg-app: #fdf1f4;
  --bg-nav: #fbe4ea;
  --bg-editor: #fffbfc;
  --bg-raised: #ffffff;
  --bg-hover: rgba(191, 47, 106, 0.08);
  --bg-active: rgba(191, 47, 106, 0.14);
  --bg-input: #ffffff;
  --border: rgba(191, 47, 106, 0.18);
  --border-soft: rgba(191, 47, 106, 0.12);
  --text: #3d2530;
  --text-muted: #8a5c6d;
  --text-faint: #b98a9a;
  --accent: #c9447a;
  --accent-contrast: #ffffff;
  --accent-soft: rgba(201, 68, 122, 0.16);
  --scrollbar-thumb: rgba(191, 47, 106, 0.28);
  --scrollbar-thumb-hover: rgba(191, 47, 106, 0.42);
  --shadow: 0 10px 30px rgba(150, 40, 80, 0.16), 0 2px 8px rgba(150, 40, 80, 0.08);
  --danger: #c0392b;
  --link: #b23366;
}

html[data-theme="dark"] {
  --bg-app: #16171a;
  --bg-nav: #1c1d21;
  --bg-editor: #202126;
  --bg-raised: #26272d;
  --bg-hover: rgba(255, 255, 255, 0.06);
  --bg-active: rgba(255, 255, 255, 0.10);
  --bg-input: #2a2b31;
  --border: rgba(255, 255, 255, 0.10);
  --border-soft: rgba(255, 255, 255, 0.07);
  --text: #ecebe9;
  --text-muted: #a8a7ad;
  --text-faint: #75757c;
  --accent: #d3a55a;
  --accent-contrast: #1c1d21;
  --accent-soft: rgba(211, 165, 90, 0.18);
  --scrollbar-thumb: rgba(255, 255, 255, 0.18);
  --scrollbar-thumb-hover: rgba(255, 255, 255, 0.30);
  --shadow: 0 10px 30px rgba(0, 0, 0, 0.45), 0 2px 8px rgba(0, 0, 0, 0.3);
  --danger: #e0705a;
  --link: #7aa2ff;
}

/* ---- Animated themes: panels are intentionally translucent (semi-opaque
   dark overlay) so the #theme-fx animated backdrop reads through faintly
   behind the UI, without ever compromising text contrast. ---- */
html[data-theme="static"] {
  --bg-app: #4b4b4d;
  --bg-nav: rgba(58, 58, 61, 0.93);
  --bg-editor: rgba(64, 64, 67, 0.93);
  --bg-raised: rgba(72, 72, 76, 0.96);
  --bg-hover: rgba(255, 255, 255, 0.08);
  --bg-active: rgba(255, 255, 255, 0.13);
  --bg-input: rgba(74, 74, 78, 0.96);
  --border: rgba(255, 255, 255, 0.12);
  --border-soft: rgba(255, 255, 255, 0.08);
  --text: #f0efec;
  --text-muted: #c2c0bc;
  --text-faint: #93918d;
  --accent: #cfcac0;
  --accent-contrast: #262625;
  --accent-soft: rgba(207, 202, 192, 0.20);
  --scrollbar-thumb: rgba(255, 255, 255, 0.20);
  --scrollbar-thumb-hover: rgba(255, 255, 255, 0.32);
  --shadow: 0 10px 30px rgba(0, 0, 0, 0.5), 0 2px 8px rgba(0, 0, 0, 0.32);
  --danger: #e0705a;
  --link: #bcd6e6;
}

html[data-theme="glitter"] {
  --bg-app: #180f22;
  --bg-nav: rgba(30, 17, 42, 0.92);
  --bg-editor: rgba(36, 20, 49, 0.92);
  --bg-raised: rgba(45, 26, 60, 0.96);
  --bg-hover: rgba(255, 255, 255, 0.07);
  --bg-active: rgba(255, 255, 255, 0.12);
  --bg-input: rgba(48, 28, 63, 0.96);
  --border: rgba(218, 24, 132, 0.35);
  --border-soft: rgba(218, 24, 132, 0.20);
  --text: #f6e6f1;
  --text-muted: #d199c0;
  --text-faint: #9c6e8d;
  --accent: #da1884;
  --accent-contrast: #ffffff;
  --accent-soft: rgba(218, 24, 132, 0.22);
  --scrollbar-thumb: rgba(218, 24, 132, 0.35);
  --scrollbar-thumb-hover: rgba(218, 24, 132, 0.55);
  --shadow: 0 10px 34px rgba(80, 10, 70, 0.4), 0 2px 8px rgba(80, 10, 70, 0.25);
  --danger: #ff5f9e;
  --link: #ff6fc0;
  --neon-glow: 0 0 6px rgba(218, 24, 132, 0.85), 0 0 16px rgba(218, 24, 132, 0.5), 0 0 34px rgba(218, 24, 132, 0.25);
  --neon-border: rgba(218, 24, 132, 0.9);
}

html[data-theme="space"] {
  --bg-app: #16211f;
  --bg-nav: rgba(18, 28, 27, 0.90);
  --bg-editor: rgba(14, 22, 21, 0.90);
  --bg-raised: rgba(28, 42, 41, 0.95);
  --bg-hover: rgba(255, 255, 255, 0.06);
  --bg-active: rgba(255, 255, 255, 0.10);
  --bg-input: rgba(30, 45, 44, 0.96);
  --border: rgba(255, 255, 255, 0.10);
  --border-soft: rgba(255, 255, 255, 0.07);
  /* Keep the dark theme's white/near-white text tokens, per spec. */
  --text: #ecebe9;
  --text-muted: #a8a7ad;
  --text-faint: #75757c;
  --accent: #d3a55a;
  --accent-contrast: #1c1d21;
  --accent-soft: rgba(211, 165, 90, 0.18);
  --scrollbar-thumb: rgba(255, 255, 255, 0.18);
  --scrollbar-thumb-hover: rgba(255, 255, 255, 0.30);
  --shadow: 0 10px 34px rgba(0, 0, 0, 0.5), 0 2px 8px rgba(0, 0, 0, 0.3);
  --danger: #e0705a;
  --link: #7aa2ff;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, "Helvetica Neue", Arial, sans-serif;
  background: var(--bg-app);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
}
button { font: inherit; color: inherit; }
.hidden { display: none !important; }

/* ==========================================================================
   Scrollbars
   ========================================================================== */
* { scrollbar-width: thin; scrollbar-color: var(--scrollbar-thumb) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background-color: var(--scrollbar-thumb);
  border-radius: 999px;
  border: 2px solid transparent;
  background-clip: padding-box;
}
*::-webkit-scrollbar-thumb:hover { background-color: var(--scrollbar-thumb-hover); }

/* ==========================================================================
   App shell / layout
   ========================================================================== */
#app {
  display: flex;
  height: 100vh;
  width: 100vw;
  overflow: hidden;
  position: relative;
  z-index: 1;
}

/* Desktop launch-time loading cover — see the comment on the element in
   index.html and boot()/revealDesktopApp() in app.js. Sits above
   everything (including the animated theme backdrops) since nothing
   underneath it is meant to be visible or interactive yet; matches the
   already-applied theme's app background so there's no color flash either. */
#desktop-boot-overlay {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-app);
  color: var(--text-muted);
  font-size: 14px;
  letter-spacing: 0.02em;
}
#desktop-boot-overlay.hidden {
  display: none;
}

/* ==========================================================================
   Animated theme backdrops (Static / Glitter / Space)
   A single fixed, full-viewport, click-through layer painted *behind* #app.
   Inert (no background/animation) unless one of the three themes is active,
   so Light/Pink/Dark pay zero cost for it.
   ========================================================================== */
#theme-fx {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}
#theme-fx::before,
#theme-fx::after {
  content: "";
  position: absolute;
  inset: -10%;
}

/* Static: TV-noise effect, built the standard way —
     1. Container: #theme-fx is already `overflow: hidden` (see above), so
        the oversized noise layers below never poke past the viewport.
     2. Texture: a tileable white-noise texture (SVG feTurbulence),
        repeated, and sized well past the container (`inset: -60%`) so
        jumping its position never reveals an edge. A contrast/brightness
        filter punches the raw (fairly soft/grey) turbulence output into
        actual near-white/near-black specks — without it the "noise" is
        too low-contrast to read as static at any reasonable opacity.
     3. Opacity: kept CONSTANT per layer — unlike Glitter/Space, the
        "pixels flickering to white/beige and back" look here comes
        entirely from jumping the texture's *position* (step 6), not from
        animating opacity.
     4. z-index/layering: unlike Glitter/Space (whose #theme-fx sits behind
        #app, at z-index 0, only ever faintly bleeding through the nav/
        editor panels' translucency), Static promotes #theme-fx itself
        above #app here — unobstructed static grain is the entire point of
        this theme, and leaving it behind the ~93%+ opaque panels made it
        essentially invisible (max single-frame pixel delta of 1/255).
        It still sits well below every interactive layer (format toolbar,
        context menus, toasts, modals all use z-index 40+), so it never
        covers anything clickable.
     5. pointer-events: none is inherited from #theme-fx, so the animated
        layers are always click/type-through, even sitting on top.
     6. Position animation: a stepped (not eased) keyframe animation jumps
        background-position to a new spot on every frame. Two layers with
        different timing/step counts and a sepia tint on the second one
        give the "white or beige" color variation from the spec. */
html[data-theme="static"] #theme-fx {
  z-index: 2;
}
html[data-theme="static"] #theme-fx::before,
html[data-theme="static"] #theme-fx::after {
  inset: -60%;
  background-repeat: repeat;
  z-index: 0;
}
html[data-theme="static"] #theme-fx::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='60' height='60'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='turbulence' 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");
  background-size: 60px 60px;
  filter: contrast(2.6) brightness(1.5);
  opacity: 0.22;
  mix-blend-mode: screen;
  animation: fxStaticPositionWhite 0.7s steps(10) infinite;
}
html[data-theme="static"] #theme-fx::after {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='44' height='44'%3E%3Cfilter id='n2'%3E%3CfeTurbulence type='turbulence' baseFrequency='1.4' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n2)'/%3E%3C/svg%3E");
  background-size: 44px 44px;
  filter: sepia(0.85) saturate(1.8) brightness(1.35) contrast(2.2);
  opacity: 0.16;
  mix-blend-mode: overlay;
  animation: fxStaticPositionBeige 0.55s steps(9) infinite reverse;
}

/* Glitter: hot-magenta backdrop; the sparkle trail/typing/click-burst
   particles themselves are rendered by glitter-fx.js, not CSS. */
html[data-theme="glitter"] #theme-fx {
  background:
    radial-gradient(ellipse at 30% 18%, #3d1030 0%, #240a24 55%, #170a1f 100%);
}
html[data-theme="glitter"] #theme-fx::before {
  background-image: radial-gradient(circle, rgba(255, 200, 235, 0.95) 1px, transparent 1.6px);
  background-size: 90px 90px;
  opacity: 0.2;
  animation: fxTwinkleA 4.5s ease-in-out infinite;
}
html[data-theme="glitter"] #theme-fx::after {
  background-image: radial-gradient(circle, rgba(218, 24, 132, 0.9) 1px, transparent 1.5px);
  background-size: 140px 140px;
  background-position: 45px 65px;
  opacity: 0.16;
  animation: fxTwinkleB 6.5s ease-in-out infinite;
  animation-delay: -2s;
}

/* Space: a pulsing fade between slate (#2F4F4F) and near-black (#040406).
   Built as an opacity crossfade between two solid-color layers rather than
   animating background-color directly: background-color interpolation
   isn't GPU-composited, so on a full-viewport fixed element it visibly
   steps/judders frame to frame ("visually jarring") instead of reading as
   a smooth pulse. Opacity animations ARE compositor-driven, so the same
   two colors crossfade smoothly at any speed. The base element paints the
   first color; ::before is the second color, alone animated from
   transparent to opaque and back. */
html[data-theme="space"] #theme-fx {
  background-color: #2f4f4f;
}
html[data-theme="space"] #theme-fx::before {
  inset: 0;
  background-color: #040406;
  opacity: 0;
  will-change: opacity;
  animation: fxSpacePulse 1.9s ease-in-out infinite alternate;
}

/* Pure position jumps -- opacity stays constant (set on the element
   itself, above). At each step, a different, uncorrelated patch of the
   tiled noise texture lands under any given pixel, which is what actually
   produces the "flickering to white and back" look: each on-screen pixel
   sees a new random noise value every step rather than smoothly panning. */
@keyframes fxStaticPositionWhite {
  0% { background-position: 0% 0%; }
  10% { background-position: 61% 22%; }
  20% { background-position: 18% 77%; }
  30% { background-position: 84% 8%; }
  40% { background-position: 37% 91%; }
  50% { background-position: 93% 54%; }
  60% { background-position: 7% 33%; }
  70% { background-position: 55% 5%; }
  80% { background-position: 26% 66%; }
  90% { background-position: 71% 88%; }
  100% { background-position: 0% 0%; }
}

@keyframes fxStaticPositionBeige {
  0% { background-position: 12% 47%; }
  11% { background-position: 88% 15%; }
  22% { background-position: 40% 5%; }
  33% { background-position: 5% 90%; }
  44% { background-position: 67% 62%; }
  55% { background-position: 30% 20%; }
  66% { background-position: 95% 40%; }
  77% { background-position: 20% 70%; }
  88% { background-position: 60% 95%; }
  100% { background-position: 12% 47%; }
}

@keyframes fxTwinkleA {
  0%, 100% { opacity: 0.10; }
  50% { opacity: 0.42; }
}

@keyframes fxTwinkleB {
  0%, 100% { opacity: 0.08; }
  50% { opacity: 0.30; }
}

@keyframes fxSpacePulse {
  0% { opacity: 0; }
  100% { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  #theme-fx, #theme-fx::before, #theme-fx::after { animation: none !important; }
}

.icon { width: 18px; height: 18px; stroke: currentColor; fill: none; flex-shrink: 0; }
.icon-lg { width: 40px; height: 40px; }
.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 8px;
  border: 1px solid transparent;
  background: transparent;
  cursor: pointer;
  color: var(--text-muted);
}
.icon-btn:hover { background: var(--bg-hover); color: var(--text); }
.icon-btn[aria-pressed="true"] { background: var(--accent-soft); color: var(--accent); border-color: var(--accent-soft); }

/* ---- Nav panel ---- */
.nav-panel {
  width: 340px;
  min-width: 220px;
  max-width: 55vw;
  flex-shrink: 0;
  background: var(--bg-nav);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  transition: margin-left 0.24s ease, opacity 0.2s ease;
}
#app.fullscreen .nav-panel {
  margin-left: -340px;
  opacity: 0;
  pointer-events: none;
}
/* Fullscreen also hides the formatting toolbar (if it was open) for a
   maximally distraction-free surface — purely visual, so it comes right
   back in whatever state it was in (open or closed) when fullscreen is
   turned off, with no extra state to track. The topbar's icon row (with
   the fullscreen button itself) is untouched, so exiting fullscreen is
   always reachable. */
#app.fullscreen .format-toolbar {
  display: none;
}

.filename-bar {
  position: relative;
  padding: 10px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.filename-btn {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 10px;
  border-radius: 8px;
  border: 1px solid transparent;
  background: transparent;
  cursor: pointer;
  text-align: left;
}
.filename-btn:hover { background: var(--bg-hover); }
.filename-btn .icon-caret { width: 14px; height: 14px; color: var(--text-faint); transition: transform 0.15s ease; }
.filename-btn[aria-expanded="true"] .icon-caret { transform: rotate(-180deg); }
.filename-label {
  font-weight: 600;
  font-size: 14.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.filename-input {
  font-weight: 600;
  font-size: 14.5px;
  border: 1px solid var(--accent);
  border-radius: 6px;
  padding: 2px 6px;
  background: var(--bg-input);
  color: var(--text);
  width: 100%;
  outline: none;
}

.dropdown-menu {
  position: absolute;
  top: calc(100% + 2px);
  left: 10px;
  right: 10px;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: var(--shadow);
  padding: 6px;
  z-index: 60;
}
.dropdown-menu button {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border: none;
  background: transparent;
  border-radius: 7px;
  cursor: pointer;
  font-size: 14px;
  text-align: left;
}
.dropdown-menu button:hover { background: var(--bg-hover); }
.dropdown-sep { height: 1px; background: var(--border-soft); margin: 6px 4px; }

.nav-tree {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 6px 6px 12px;
}

.add-node-controls {
  margin: 10px;
  flex-shrink: 0;
}
.add-node-row {
  display: flex;
  gap: 6px;
}
.add-node-btn {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 9px 10px;
  border-radius: 9px;
  border: 1px dashed var(--border);
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.add-node-btn .icon { flex-shrink: 0; }
.add-node-btn:hover { background: var(--bg-hover); color: var(--text); border-color: var(--accent); }
.add-node-btn.primary { border-style: solid; }

/* ---- Nav tree rows ---- */
.nav-row {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 6px;
  border-radius: 7px;
  cursor: pointer;
  user-select: none;
  font-size: 13.6px;
  line-height: 1.3;
  color: var(--text);
  position: relative;
}
.nav-row:hover { background: var(--bg-hover); }
.nav-row.selected { background: var(--accent-soft); color: var(--accent); font-weight: 600; }
.nav-row .nav-title {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
}
.nav-row .nav-chevron {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  color: var(--text-faint);
  transition: transform 0.15s ease;
  display: flex;
  align-items: center;
  justify-content: center;
}
.nav-row.expanded > .nav-chevron { transform: rotate(90deg); }
.nav-row .nav-chevron.spacer { visibility: hidden; }
.nav-row .nav-icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.nav-row .nav-icon svg { width: 15px; height: 15px; }
.nav-row .nav-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--text-faint);
  flex-shrink: 0;
  margin: 0 4px;
}
.nav-children { overflow: hidden; }
.nav-children.collapsed { display: none; }
.nav-level-book > .nav-row { padding-left: 6px; }
.nav-level-chapter > .nav-row { padding-left: 26px; }
.nav-level-page > .nav-row { padding-left: 46px; }

/* ---- Editor panel ---- */
.editor-panel {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  background: var(--bg-editor);
}

.editor-topbar {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 22px 32px 8px;
  flex-shrink: 0;
}
.page-title {
  flex: 1;
  font-size: 30px;
  font-weight: 700;
  line-height: 1.25;
  outline: none;
  min-height: 40px;
  word-break: break-word;
}
.page-title:empty::before {
  content: attr(data-placeholder);
  color: var(--text-faint);
}
.editor-actions { display: flex; gap: 4px; flex-shrink: 0; padding-top: 2px; }

.format-toolbar {
  display: flex;
  align-items: center;
  gap: 4px;
  margin: 4px 32px 4px;
  padding: 6px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg-raised);
  flex-shrink: 0;
  flex-wrap: wrap;
}
.format-toolbar button {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 7px 10px;
  border: none;
  border-radius: 7px;
  background: transparent;
  cursor: pointer;
  font-size: 13px;
  color: var(--text-muted);
}
.format-toolbar button:hover { background: var(--bg-hover); color: var(--text); }
.format-toolbar button.active { background: var(--accent-soft); color: var(--accent); }
.toolbar-sep { width: 1px; align-self: stretch; background: var(--border); margin: 4px 2px; }

.content-scroll {
  flex: 1;
  overflow-y: auto;
  overflow-x: auto;
  padding: 10px 32px 40px;
  position: relative;
}

.content-editable {
  min-height: 200px;
  outline: none;
  font-size: 16px;
  line-height: 1.7;
  max-width: 860px;
}
.content-editable:empty::before {
  content: attr(data-placeholder);
  color: var(--text-faint);
}
.content-editable img { max-width: 100%; border-radius: 8px; display: block; margin: 10px 0; }
.content-editable a { color: var(--link); text-decoration: underline; }
.content-editable .text-large { font-size: 1.6em; font-weight: 700; }
.content-editable .text-medium { font-size: 1.2em; font-weight: 600; }
.content-editable .text-normal { font-size: 1em; font-weight: 400; }
.content-editable p { margin: 0 0 0.8em; }
.content-editable ul, .content-editable ol { margin: 0 0 0.8em 1.3em; padding: 0; }
.content-editable li { margin: 0.25em 0; }
.content-editable input[type="checkbox"] {
  width: 16px;
  height: 16px;
  margin: 0 8px 0 0;
  vertical-align: middle;
  cursor: pointer;
  accent-color: var(--accent);
}
.content-editable img.inline-image {
  cursor: grab;
}
.content-editable img.inline-image:active { cursor: grabbing; }

.file-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px 5px 8px;
  margin: 2px 3px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--bg-raised);
  font-size: 13px;
  color: var(--text);
  cursor: pointer;
  user-select: none;
  vertical-align: middle;
}
.file-chip:hover { background: var(--bg-hover); }
.file-chip svg { width: 14px; height: 14px; color: var(--text-muted); }
.file-chip .file-chip-size { color: var(--text-faint); }

.attachments-strip {
  max-width: 860px;
  margin-top: 24px;
  padding-top: 14px;
  border-top: 1px solid var(--border-soft);
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.attachments-strip:empty { display: none; border: none; margin: 0; padding: 0; }

.empty-state {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  color: var(--text-faint);
  text-align: center;
  padding: 40px;
}

.drop-overlay {
  position: absolute;
  inset: 0;
  background: var(--accent-soft);
  border: 2px dashed var(--accent);
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 40;
  margin: 8px;
  /* Purely decorative: never intercept drag/drop hit-testing itself, or it
     becomes the drop target instead of #content-scroll, which breaks both
     the file-drop handler and native in-editor image dragging. */
  pointer-events: none;
}
.drop-overlay-inner { display: flex; flex-direction: column; align-items: center; gap: 8px; color: var(--accent); font-weight: 600; }

/* ==========================================================================
   Modals
   ========================================================================== */
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(10, 10, 10, 0.35);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
}
.modal {
  width: 400px;
  max-width: 92vw;
  max-height: 86vh;
  overflow: auto;
  background: var(--bg-raised);
  border-radius: 14px;
  box-shadow: var(--shadow);
  border: 1px solid var(--border);
}
.modal-icon-picker { width: 460px; }
.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 18px 10px;
}
.modal-header h2 { font-size: 16px; margin: 0; }
.modal-close {
  border: none;
  background: transparent;
  cursor: pointer;
  color: var(--text-muted);
  display: flex;
  padding: 4px;
  border-radius: 6px;
}
.modal-close:hover { background: var(--bg-hover); color: var(--text); }
.modal-body { padding: 6px 18px 18px; display: flex; flex-direction: column; gap: 6px; }
.modal-footer { display: flex; justify-content: flex-end; gap: 8px; padding: 0 18px 18px; }

.field-label { font-size: 12.5px; color: var(--text-muted); margin-top: 10px; }
.text-input {
  padding: 9px 11px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--bg-input);
  color: var(--text);
  font-size: 14px;
  outline: none;
  width: 100%;
}
.text-input:focus { border-color: var(--accent); }

.btn {
  padding: 8px 16px;
  border-radius: 8px;
  border: 1px solid transparent;
  cursor: pointer;
  font-size: 13.5px;
  font-weight: 600;
}
.btn-primary { background: var(--accent); color: var(--accent-contrast); }
.btn-primary:hover { filter: brightness(1.06); }
.btn-secondary { background: transparent; color: var(--text-muted); border-color: var(--border); }
.btn-secondary:hover { background: var(--bg-hover); }

.theme-options { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; padding: 6px 0; }
.theme-option {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 12px 8px;
  border-radius: 10px;
  border: 1.5px solid var(--border);
  background: transparent;
  cursor: pointer;
  font-size: 13px;
}
.theme-option:hover { background: var(--bg-hover); }
.theme-option.active { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); font-weight: 600; }
.theme-swatch { width: 36px; height: 36px; border-radius: 50%; border: 1px solid rgba(0,0,0,0.1); }
.theme-swatch-light { background: linear-gradient(135deg, #f6f5f3 50%, #8a6d3b 50%); }
.theme-swatch-pink { background: linear-gradient(135deg, #fdf1f4 50%, #c9447a 50%); }
.theme-swatch-dark { background: linear-gradient(135deg, #16171a 50%, #d3a55a 50%); }
.theme-swatch-static { background: linear-gradient(135deg, #4b4b4d 45%, #efe6d2 100%); }
.theme-swatch-glitter { background: radial-gradient(circle at 35% 30%, #ff6fc7 0%, #da1884 45%, #22081a 100%); box-shadow: 0 0 8px rgba(218, 24, 132, 0.6); }
.theme-swatch-space { background: linear-gradient(160deg, #2f4f4f 0%, #040406 100%); }

/* ---- Glitter theme: neon edge glow on the app's structural panels/edges.
   Scoped entirely under html[data-theme="glitter"] so every other theme is
   completely unaffected. The moving sparkle particles themselves (cursor
   trail, typing sparkle, click burst) are handled by glitter-fx.js. ---- */
html[data-theme="glitter"] .nav-panel {
  box-shadow: inset -1px 0 0 var(--neon-border), 4px 0 18px -6px rgba(218, 24, 132, 0.55);
}
html[data-theme="glitter"] .editor-topbar {
  box-shadow: 0 1px 0 var(--neon-border), 0 4px 16px -6px rgba(218, 24, 132, 0.5);
}
html[data-theme="glitter"] .modal {
  box-shadow: var(--shadow), var(--neon-glow);
  border-color: var(--neon-border);
}
html[data-theme="glitter"] .format-toolbar,
html[data-theme="glitter"] .dropdown-menu,
html[data-theme="glitter"] .context-menu,
html[data-theme="glitter"] .icon-grid,
html[data-theme="glitter"] .attachments-strip .file-chip,
html[data-theme="glitter"] .content-editable .file-chip {
  box-shadow: var(--neon-glow);
  border-color: var(--neon-border);
}
html[data-theme="glitter"] .add-node-btn {
  border-color: var(--neon-border);
}
html[data-theme="glitter"] .add-node-btn:hover,
html[data-theme="glitter"] .icon-btn:hover,
html[data-theme="glitter"] .icon-btn[aria-pressed="true"],
html[data-theme="glitter"] .format-toolbar button.active,
html[data-theme="glitter"] .nav-row.selected {
  box-shadow: var(--neon-glow);
}
html[data-theme="glitter"] .text-input:focus,
html[data-theme="glitter"] .page-title:focus,
html[data-theme="glitter"] .content-editable:focus {
  box-shadow: var(--neon-glow);
}

.modal-divider { height: 1px; background: var(--border-soft); margin: 4px 0 12px; }
.desktop-app-promo {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 4px 2px 2px;
}
.desktop-app-promo-text { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.desktop-app-promo-text strong { font-size: 13.5px; }
.desktop-app-promo-text span { font-size: 12px; color: var(--text-muted); line-height: 1.4; }
.desktop-app-promo .btn { white-space: nowrap; display: flex; align-items: center; gap: 6px; }
.desktop-app-promo .btn .icon { width: 15px; height: 15px; }

.modal-reminder { width: 380px; }
.modal-reminder .modal-body { padding-top: 20px; }
.reminder-text { font-size: 14px; line-height: 1.6; color: var(--text); margin: 0; }

.icon-grid {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 4px;
  max-height: 320px;
  overflow-y: auto;
  margin-top: 8px;
}
.icon-grid button {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid transparent;
  border-radius: 8px;
  background: transparent;
  cursor: pointer;
  color: var(--text);
}
.icon-grid button:hover { background: var(--bg-hover); border-color: var(--border); }
.icon-grid button.active { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }
.icon-grid svg { width: 18px; height: 18px; }

.color-swatch-grid {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 8px;
  margin: 8px 0 4px;
}
.color-swatch-grid button {
  width: 100%;
  aspect-ratio: 1;
  border-radius: 50%;
  border: 2px solid transparent;
  cursor: pointer;
  position: relative;
}
.color-swatch-grid button.active { border-color: var(--text); }
.color-custom-input { width: 100%; height: 38px; border-radius: 8px; border: 1px solid var(--border); background: var(--bg-input); cursor: pointer; padding: 2px; }

/* ==========================================================================
   Context menu
   ========================================================================== */
.context-menu {
  position: fixed;
  min-width: 190px;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: var(--shadow);
  padding: 6px;
  z-index: 120;
}
.context-menu button {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border: none;
  background: transparent;
  border-radius: 7px;
  cursor: pointer;
  font-size: 13.5px;
  text-align: left;
  color: var(--text);
}
.context-menu button:hover { background: var(--bg-hover); }
.context-menu button.danger { color: var(--danger); }
.context-menu .context-menu-sep { height: 1px; background: var(--border); margin: 5px 4px; }

/* ==========================================================================
   Toast
   ========================================================================== */
.toast {
  position: fixed;
  bottom: 22px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--bg-raised);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 10px 18px;
  border-radius: 999px;
  box-shadow: var(--shadow);
  font-size: 13.5px;
  z-index: 200;
}

/* ==========================================================================
   Glitter theme sparkle particles (see glitter-fx.js)
   ========================================================================== */
#glitter-particles {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 250;
  overflow: hidden;
}
.glitter-particle {
  position: absolute;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  box-shadow: 0 0 5px 1px currentColor;
  animation-name: glitterPop;
  animation-timing-function: ease-out;
  animation-fill-mode: forwards;
  will-change: transform, opacity;
}
@keyframes glitterPop {
  0% { opacity: 1; transform: translate(-50%, -50%) scale(1) rotate(0deg); }
  100% {
    opacity: 0;
    transform: translate(calc(-50% + var(--dx, 0px)), calc(-50% + var(--dy, 0px))) scale(0.25) rotate(90deg);
  }
}

@media (max-width: 760px) {
  .nav-panel { position: absolute; z-index: 50; height: 100%; box-shadow: var(--shadow); }
  .editor-topbar, .content-scroll { padding-left: 16px; padding-right: 16px; }
  .format-toolbar { margin-left: 16px; margin-right: 16px; }
}
