@jungherz-de/notionkit-elements 1.5.3 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/README.md +27 -18
  2. package/dist/components/base.js +346 -0
  3. package/dist/components/nk-ai-input-row.js +2 -1
  4. package/dist/components/nk-ai-msg.js +10 -3
  5. package/dist/components/nk-ai-thread.js +2 -1
  6. package/dist/components/nk-app.js +2 -1
  7. package/dist/components/nk-avatar-group.js +2 -1
  8. package/dist/components/nk-avatar.js +57 -0
  9. package/dist/components/nk-banner.js +2 -1
  10. package/dist/components/nk-block-host.js +2 -1
  11. package/dist/components/nk-board-view.js +4 -2
  12. package/dist/components/nk-breadcrumb.js +2 -1
  13. package/dist/components/nk-btn.js +31 -4
  14. package/dist/components/nk-callout.js +2 -1
  15. package/dist/components/nk-check.js +2 -1
  16. package/dist/components/nk-cmdk.js +3 -2
  17. package/dist/components/nk-code.js +2 -1
  18. package/dist/components/nk-comment.js +9 -6
  19. package/dist/components/nk-comments.js +2 -1
  20. package/dist/components/nk-danger-zone.js +2 -1
  21. package/dist/components/nk-database.js +16 -6
  22. package/dist/components/nk-divider.js +2 -1
  23. package/dist/components/nk-emoji-picker.js +2 -1
  24. package/dist/components/nk-empty.js +2 -1
  25. package/dist/components/nk-field.js +2 -1
  26. package/dist/components/nk-fields.js +2 -1
  27. package/dist/components/nk-filter-bar.js +59 -37
  28. package/dist/components/nk-heading.js +2 -1
  29. package/dist/components/nk-input.js +2 -1
  30. package/dist/components/nk-kbd.js +2 -1
  31. package/dist/components/nk-list-view.js +96 -0
  32. package/dist/components/nk-member-list.js +2 -1
  33. package/dist/components/nk-member-row.js +10 -6
  34. package/dist/components/nk-mention.js +2 -1
  35. package/dist/components/nk-menu-item.js +27 -3
  36. package/dist/components/nk-menu.js +88 -2
  37. package/dist/components/nk-modal.js +3 -2
  38. package/dist/components/nk-model-card.js +2 -1
  39. package/dist/components/nk-page-actions.js +2 -1
  40. package/dist/components/nk-page-cover.js +12 -11
  41. package/dist/components/nk-page-title.js +2 -1
  42. package/dist/components/nk-page.js +12 -4
  43. package/dist/components/nk-panel.js +61 -0
  44. package/dist/components/nk-panels.js +18 -0
  45. package/dist/components/nk-pop.js +2 -1
  46. package/dist/components/nk-profile-row.js +2 -1
  47. package/dist/components/nk-progress.js +5 -2
  48. package/dist/components/nk-prop.js +54 -0
  49. package/dist/components/nk-props.js +21 -0
  50. package/dist/components/nk-quote.js +2 -1
  51. package/dist/components/nk-radio.js +2 -1
  52. package/dist/components/nk-section-label.js +2 -1
  53. package/dist/components/nk-segmented.js +21 -1
  54. package/dist/components/nk-select.js +2 -1
  55. package/dist/components/nk-settings-pane.js +2 -1
  56. package/dist/components/nk-settings-user.js +2 -1
  57. package/dist/components/nk-sheet.js +97 -0
  58. package/dist/components/nk-sidebar.js +17 -37
  59. package/dist/components/nk-skeleton.js +2 -1
  60. package/dist/components/nk-slider.js +2 -1
  61. package/dist/components/nk-stat.js +2 -1
  62. package/dist/components/nk-stats.js +2 -1
  63. package/dist/components/nk-steps.js +61 -0
  64. package/dist/components/nk-switch.js +2 -1
  65. package/dist/components/nk-synced.js +2 -1
  66. package/dist/components/nk-tab-bar-item.js +2 -1
  67. package/dist/components/nk-tab-bar.js +2 -1
  68. package/dist/components/nk-tab.js +2 -1
  69. package/dist/components/nk-table-view.js +6 -2
  70. package/dist/components/nk-tabs.js +2 -1
  71. package/dist/components/nk-tag.js +2 -1
  72. package/dist/components/nk-template-btn.js +2 -1
  73. package/dist/components/nk-textarea.js +2 -1
  74. package/dist/components/nk-theme-toggle.js +2 -1
  75. package/dist/components/nk-toast.js +2 -1
  76. package/dist/components/nk-todo.js +2 -1
  77. package/dist/components/nk-toggle.js +2 -1
  78. package/dist/components/nk-topbar.js +2 -1
  79. package/dist/components/nk-tree-item.js +2 -1
  80. package/dist/components/nk-tree.js +2 -1
  81. package/dist/components/nk-workspace-switcher.js +2 -1
  82. package/dist/components/shared/avatar-BiqCaHOt.js +19 -0
  83. package/dist/components/shared/{focus-DXrK9oLe.js → focus-BNAChOXO.js} +12 -4
  84. package/dist/components/shared/{property-cell-CtXQpUjQ.js → property-cell-o7N30kAQ.js} +8 -3
  85. package/dist/notionkit-elements.esm.js +759 -120
  86. package/dist/notionkit-elements.js +767 -119
  87. package/dist/notionkit-elements.min.js +1 -1
  88. package/package.json +7 -6
  89. package/src/components/content/nk-progress.js +3 -1
  90. package/src/components/data/nk-ai-msg.js +8 -2
  91. package/src/components/data/nk-comment.js +7 -5
  92. package/src/components/data/nk-database.js +14 -5
  93. package/src/components/data/nk-filter-bar.js +57 -36
  94. package/src/components/data/nk-list-view.js +93 -0
  95. package/src/components/data/nk-table-view.js +2 -0
  96. package/src/components/forms/nk-btn.js +29 -3
  97. package/src/components/overlays/nk-menu-item.js +25 -2
  98. package/src/components/overlays/nk-menu.js +86 -1
  99. package/src/components/overlays/nk-sheet.js +95 -0
  100. package/src/components/page/nk-avatar.js +55 -0
  101. package/src/components/page/nk-member-row.js +8 -5
  102. package/src/components/page/nk-page-cover.js +10 -10
  103. package/src/components/page/nk-page.js +10 -3
  104. package/src/components/page/nk-panel.js +59 -0
  105. package/src/components/page/nk-panels.js +16 -0
  106. package/src/components/page/nk-prop.js +52 -0
  107. package/src/components/page/nk-props.js +19 -0
  108. package/src/components/page/nk-segmented.js +19 -0
  109. package/src/components/page/nk-steps.js +59 -0
  110. package/src/components/shell/nk-sidebar.js +15 -36
  111. package/src/index.js +18 -0
  112. package/src/util/avatar.js +17 -0
  113. package/src/util/focus.js +11 -3
  114. package/src/util/property-cell.js +7 -3
  115. package/dist/components/shared/base-C3eJwHKA.js +0 -366
@@ -1,15 +1,15 @@
1
1
  var NotionKitElements = (function (exports) {
2
2
  'use strict';
3
3
 
4
- // NotionKit v1.5.3 – Constructable Stylesheet
4
+ // NotionKit v1.7.1 – Constructable Stylesheet
5
5
  // Auto-generated by build-styles-js.mjs – do not edit manually.
6
6
 
7
7
  // The :root and [data-theme="dark"] blocks that declare --nk-* …
8
- const tokensCss = ":root{color-scheme:light;--nk-bg:#ffffff;--nk-bg-sidebar:#f9f8f7;--nk-bg-hover:rgba(55,53,47,0.06);--nk-bg-active:rgba(55,53,47,0.08);--nk-bg-callout:#f0efed;--nk-bg-code:#f7f6f3;--nk-bg-card:#ffffff;--nk-bg-input:rgba(242,241,238,0.6);--nk-text:#2c2c2b;--nk-text-secondary:#7d7a75;--nk-text-tertiary:#91918e;--nk-text-sidebar:#5f5e5b;--nk-border:rgba(28,19,1,0.11);--nk-border-strong:rgba(27,21,0,0.19);--nk-accent:#2383e2;--nk-on-accent:#ffffff;--nk-danger:#cd3c3a;--nk-tag-gray-bg:#e3e2e0;--nk-tag-gray-text:#32302c;--nk-tag-brown-bg:#eee0da;--nk-tag-brown-text:#442a1e;--nk-tag-orange-bg:#fadec9;--nk-tag-orange-text:#49290e;--nk-tag-yellow-bg:#fdecc8;--nk-tag-yellow-text:#402c1b;--nk-tag-green-bg:#dbeddb;--nk-tag-green-text:#1c3829;--nk-tag-blue-bg:#d3e5ef;--nk-tag-blue-text:#183347;--nk-tag-purple-bg:#e8deee;--nk-tag-purple-text:#412454;--nk-tag-pink-bg:#f5e0e9;--nk-tag-pink-text:#4c2337;--nk-tag-red-bg:#ffe2dd;--nk-tag-red-text:#5d1715;--nk-tint-gray:#f1f1ef;--nk-color-gray:#787774;--nk-tint-brown:#f4eeee;--nk-color-brown:#9f6b53;--nk-tint-orange:#fbecdd;--nk-color-orange:#d9730d;--nk-tint-yellow:#fbf3db;--nk-color-yellow:#cb912f;--nk-tint-green:#edf3ec;--nk-color-green:#448361;--nk-tint-blue:#e7f3f8;--nk-color-blue:#337ea9;--nk-tint-purple:#f8f3fc;--nk-color-purple:#9065b0;--nk-tint-pink:#fcf1f6;--nk-color-pink:#c14c8a;--nk-tint-red:#fdebec;--nk-color-red:#cd3c3a;--nk-decor-purple:#9065b0;--nk-decor-blue:#529cca;--nk-decor-orange:#d9730d;--nk-scrim:rgba(15,15,15,0.6);--nk-scrim-soft:rgba(15,15,15,0.5);--nk-sidebar-width:260px;--nk-tab-bar-height:58px;--nk-radius:6px;--nk-font:ui-sans-serif,-apple-system,\"Segoe UI\",Inter,Helvetica,Arial,sans-serif;--nk-font-mono:ui-monospace,\"SF Mono\",Menlo,Consolas,monospace;--nk-shadow-menu:rgba(15,15,15,0.05) 0px 0px 0px 1px,rgba(15,15,15,0.1) 0px 3px 6px,rgba(15,15,15,0.2) 0px 9px 24px;--nk-shadow-card:0 1px 2px rgba(0,0,0,0.04);--nk-shadow-btn:inset 0 0 0 1px rgba(15,15,15,0.1),0 1px 2px rgba(15,15,15,0.1);--nk-shadow-knob:0 1px 2px rgba(0,0,0,0.2);--nk-shadow-segment:0 1px 2px rgba(0,0,0,0.08)}[data-theme=dark]{color-scheme:dark;--nk-bg:#191919;--nk-bg-sidebar:#202020;--nk-bg-hover:rgba(255,255,255,0.055);--nk-bg-active:rgba(255,255,255,0.08);--nk-bg-callout:#252525;--nk-bg-code:#202020;--nk-bg-card:#202020;--nk-bg-input:rgba(255,255,255,0.055);--nk-text:rgba(255,255,255,0.81);--nk-text-secondary:rgba(255,255,255,0.46);--nk-text-tertiary:rgba(255,255,255,0.32);--nk-text-sidebar:rgba(255,255,255,0.62);--nk-border:rgba(255,255,255,0.094);--nk-border-strong:rgba(255,255,255,0.16);--nk-accent:#529CCA;--nk-danger:#df5452;--nk-tag-gray-bg:#373737;--nk-tag-gray-text:rgba(255,255,255,0.85);--nk-tag-brown-bg:#603b2c;--nk-tag-brown-text:rgba(255,255,255,0.85);--nk-tag-orange-bg:#854c1d;--nk-tag-orange-text:rgba(255,255,255,0.85);--nk-tag-yellow-bg:#89632a;--nk-tag-yellow-text:rgba(255,255,255,0.85);--nk-tag-green-bg:#2b593f;--nk-tag-green-text:rgba(255,255,255,0.85);--nk-tag-blue-bg:#28456c;--nk-tag-blue-text:rgba(255,255,255,0.85);--nk-tag-purple-bg:#492f64;--nk-tag-purple-text:rgba(255,255,255,0.85);--nk-tag-pink-bg:#69314c;--nk-tag-pink-text:rgba(255,255,255,0.85);--nk-tag-red-bg:#6e3630;--nk-tag-red-text:rgba(255,255,255,0.85);--nk-tint-gray:#252525;--nk-color-gray:#9b9b9b;--nk-tint-brown:#2e2724;--nk-color-brown:#ba856f;--nk-tint-orange:#36291f;--nk-color-orange:#c77d48;--nk-tint-yellow:#372e20;--nk-color-yellow:#ca8f3d;--nk-tint-green:#242b26;--nk-color-green:#529e72;--nk-tint-blue:#1f282d;--nk-color-blue:#5e87c9;--nk-tint-purple:#2a2430;--nk-color-purple:#9d68d3;--nk-tint-pink:#2e2328;--nk-color-pink:#d15796;--nk-tint-red:#332523;--nk-color-red:#df5452;--nk-shadow-menu:rgba(15,15,15,0.2) 0px 0px 0px 1px,rgba(15,15,15,0.4) 0px 3px 6px,rgba(15,15,15,0.6) 0px 9px 24px;--nk-shadow-card:none;--nk-shadow-btn:inset 0 0 0 1px rgba(255,255,255,0.1),0 1px 2px rgba(0,0,0,0.3)}";
8
+ const tokensCss = ":root{color-scheme:light;--nk-bg: #ffffff;--nk-bg-sidebar: #f9f8f7;--nk-bg-hover: rgba(55,53,47,.06);--nk-bg-active: rgba(55,53,47,.08);--nk-bg-callout: #f0efed;--nk-bg-code: #f7f6f3;--nk-bg-card: #ffffff;--nk-bg-input: rgba(242,241,238,.6);--nk-text: #2c2c2b;--nk-text-secondary: #7d7a75;--nk-text-tertiary: #91918e;--nk-text-sidebar: #5f5e5b;--nk-border: rgba(28,19,1,.11);--nk-border-strong: rgba(27,21,0,.19);--nk-accent: #2383e2;--nk-on-accent: #ffffff;--nk-danger: #cd3c3a;--nk-tag-gray-bg: #e3e2e0;--nk-tag-gray-text: #32302c;--nk-tag-brown-bg: #eee0da;--nk-tag-brown-text: #442a1e;--nk-tag-orange-bg: #fadec9;--nk-tag-orange-text: #49290e;--nk-tag-yellow-bg: #fdecc8;--nk-tag-yellow-text: #402c1b;--nk-tag-green-bg: #dbeddb;--nk-tag-green-text: #1c3829;--nk-tag-blue-bg: #d3e5ef;--nk-tag-blue-text: #183347;--nk-tag-purple-bg: #e8deee;--nk-tag-purple-text: #412454;--nk-tag-pink-bg: #f5e0e9;--nk-tag-pink-text: #4c2337;--nk-tag-red-bg: #ffe2dd;--nk-tag-red-text: #5d1715;--nk-tint-gray: #f1f1ef;--nk-color-gray: #787774;--nk-tint-brown: #f4eeee;--nk-color-brown: #9f6b53;--nk-tint-orange: #fbecdd;--nk-color-orange: #d9730d;--nk-tint-yellow: #fbf3db;--nk-color-yellow: #cb912f;--nk-tint-green: #edf3ec;--nk-color-green: #448361;--nk-tint-blue: #e7f3f8;--nk-color-blue: #337ea9;--nk-tint-purple: #f8f3fc;--nk-color-purple: #9065b0;--nk-tint-pink: #fcf1f6;--nk-color-pink: #c14c8a;--nk-tint-red: #fdebec;--nk-color-red: #cd3c3a;--nk-decor-purple: #9065b0;--nk-decor-blue: #529cca;--nk-decor-orange: #d9730d;--nk-scrim: rgba(15,15,15,.6);--nk-scrim-soft: rgba(15,15,15,.5);--nk-sidebar-width: 260px;--nk-tab-bar-height: 58px;--nk-radius: 6px;--nk-font: ui-sans-serif, -apple-system, \"Segoe UI\", Inter, Helvetica, Arial, sans-serif;--nk-font-mono: ui-monospace, \"SF Mono\", Menlo, Consolas, monospace;--nk-shadow-menu: rgba(15,15,15,.05) 0px 0px 0px 1px, rgba(15,15,15,.1) 0px 3px 6px, rgba(15,15,15,.2) 0px 9px 24px;--nk-shadow-card: 0 1px 2px rgba(0,0,0,.04);--nk-shadow-btn: inset 0 0 0 1px rgba(15,15,15,.1), 0 1px 2px rgba(15,15,15,.1);--nk-shadow-knob: 0 1px 2px rgba(0,0,0,.2);--nk-shadow-segment: 0 1px 2px rgba(0,0,0,.08)}[data-theme=dark]{color-scheme:dark;--nk-bg: #191919;--nk-bg-sidebar: #202020;--nk-bg-hover: rgba(255,255,255,.055);--nk-bg-active: rgba(255,255,255,.08);--nk-bg-callout: #252525;--nk-bg-code: #202020;--nk-bg-card: #202020;--nk-bg-input: rgba(255,255,255,.055);--nk-text: rgba(255,255,255,.81);--nk-text-secondary: rgba(255,255,255,.46);--nk-text-tertiary: rgba(255,255,255,.32);--nk-text-sidebar: rgba(255,255,255,.62);--nk-border: rgba(255,255,255,.094);--nk-border-strong: rgba(255,255,255,.16);--nk-accent: #529CCA;--nk-danger: #df5452;--nk-tag-gray-bg: #373737;--nk-tag-gray-text: rgba(255,255,255,.85);--nk-tag-brown-bg: #603b2c;--nk-tag-brown-text: rgba(255,255,255,.85);--nk-tag-orange-bg: #854c1d;--nk-tag-orange-text: rgba(255,255,255,.85);--nk-tag-yellow-bg: #89632a;--nk-tag-yellow-text: rgba(255,255,255,.85);--nk-tag-green-bg: #2b593f;--nk-tag-green-text: rgba(255,255,255,.85);--nk-tag-blue-bg: #28456c;--nk-tag-blue-text: rgba(255,255,255,.85);--nk-tag-purple-bg: #492f64;--nk-tag-purple-text: rgba(255,255,255,.85);--nk-tag-pink-bg: #69314c;--nk-tag-pink-text: rgba(255,255,255,.85);--nk-tag-red-bg: #6e3630;--nk-tag-red-text: rgba(255,255,255,.85);--nk-tint-gray: #252525;--nk-color-gray: #9b9b9b;--nk-tint-brown: #2e2724;--nk-color-brown: #ba856f;--nk-tint-orange: #36291f;--nk-color-orange: #c77d48;--nk-tint-yellow: #372e20;--nk-color-yellow: #ca8f3d;--nk-tint-green: #242b26;--nk-color-green: #529e72;--nk-tint-blue: #1f282d;--nk-color-blue: #5e87c9;--nk-tint-purple: #2a2430;--nk-color-purple: #9d68d3;--nk-tint-pink: #2e2328;--nk-color-pink: #d15796;--nk-tint-red: #332523;--nk-color-red: #df5452;--nk-shadow-menu: rgba(15,15,15,.2) 0px 0px 0px 1px, rgba(15,15,15,.4) 0px 3px 6px, rgba(15,15,15,.6) 0px 9px 24px;--nk-shadow-card: none;--nk-shadow-btn: inset 0 0 0 1px rgba(255,255,255,.1), 0 1px 2px rgba(0,0,0,.3)}";
9
9
 
10
10
  // … and everything else, in two pieces around where they were.
11
- const componentsHead = "[class*=nk-],[class*=nk-] *,[class*=nk-] ::after,[class*=nk-] ::before,[class*=nk-]::after,[class*=nk-]::before{box-sizing:border-box}[class*=nk-] :where(h1,h2,h3,h4,h5,h6,p,figure,blockquote,dl,dd,pre,ul,ol,li){margin:0;padding:0}[class*=nk-] :where(ul,ol){list-style:none}:where(button,input,select,textarea)[class*=nk-],[class*=nk-] :where(button,input,select,textarea,option,optgroup,fieldset,legend){margin:0;padding:0}[class*=nk-][hidden]:not([hidden=until-found i]){display:none!important}::slotted([hidden]:not([hidden=until-found i])){display:none!important}";
12
- const componentsTail = ".nk-body{margin:0;min-height:100vh;min-height:100dvh;font-family:var(--nk-font);font-size:14px;background:var(--nk-bg);color:var(--nk-text);-webkit-font-smoothing:auto;transition:background .25s,color .25s}.nk-app{display:flex;height:100vh;height:100dvh;overflow:hidden}.nk-sidebar{width:calc(var(--nk-sidebar-width) + env(safe-area-inset-left,0px));min-width:calc(var(--nk-sidebar-width) + env(safe-area-inset-left,0px));padding-left:env(safe-area-inset-left,0);background:var(--nk-bg-sidebar);display:flex;flex-direction:column;border-right:1px solid var(--nk-border);transition:background .25s}.nk-workspace{display:flex;align-items:center;gap:8px;padding:10px 12px;margin:6px 8px 2px;border-radius:var(--nk-radius);cursor:pointer;font-weight:500;user-select:none}.nk-workspace:hover{background:var(--nk-bg-hover)}.nk-workspace .avatar,.nk-workspace ::slotted(.avatar),.nk-workspace ::slotted([slot=avatar]){width:22px;height:22px;border-radius:4px;background:linear-gradient(135deg,var(--nk-decor-purple),var(--nk-decor-blue));color:var(--nk-on-accent);font-size:11px;font-weight:600;display:flex;align-items:center;justify-content:center}.nk-workspace .chev{margin-left:auto;color:var(--nk-text-tertiary);font-size:11px}.nk-sidebar-scroll{flex:1;overflow-y:auto;padding:4px 8px 16px}.nk-sidebar-scroll::-webkit-scrollbar{width:8px}.nk-sidebar-scroll::-webkit-scrollbar-thumb{background:var(--nk-border-strong);border-radius:4px}.nk-section-label{font-size:12px;font-weight:500;letter-spacing:.01em;color:var(--nk-text-tertiary);padding:14px 10px 4px;display:flex;justify-content:space-between;align-items:center}.nk-section-label .plus{cursor:pointer;border-radius:4px;padding:0 4px;font-size:13px;opacity:0;transition:opacity .15s}.nk-section-label:hover .plus{opacity:1}.nk-section-label .plus:hover{background:var(--nk-bg-hover)}.nk-sidebar-footer{padding:8px;border-top:1px solid var(--nk-border);color:var(--nk-text-sidebar);font-size:14px}.nk-sidebar-footer .nk-tree-item{min-height:26px}.nk-main{flex:1;display:flex;flex-direction:column;min-width:0}.nk-topbar{height:44px;display:flex;align-items:center;padding:0 max(12px,env(safe-area-inset-right,0px)) 0 max(12px,env(safe-area-inset-left,0px));gap:8px;flex-shrink:0}.nk-breadcrumb{display:flex;align-items:center;gap:4px;font-size:14px}.nk-breadcrumb .crumb,.nk-breadcrumb ::slotted(.crumb){padding:2px 6px;border-radius:4px;cursor:pointer;color:var(--nk-text-sidebar);display:flex;align-items:center;gap:5px}.nk-breadcrumb .crumb:hover{background:var(--nk-bg-hover)}a.crumb{text-decoration:none}.nk-breadcrumb .crumb.current,.nk-breadcrumb ::slotted(.crumb.current){color:var(--nk-text)}.nk-breadcrumb .sep{color:var(--nk-text-tertiary);font-size:12px}.nk-topbar-actions{margin-left:auto;display:flex;align-items:center;gap:4px}.nk-topbar-btn{padding:4px 8px;border-radius:var(--nk-radius);cursor:pointer;color:var(--nk-text-sidebar);font-size:14px;user-select:none;border:none;background:0 0;font-family:inherit}.nk-topbar-btn:hover{background:var(--nk-bg-hover)}.nk-topbar-btn ::slotted(svg),.nk-topbar-btn svg{width:16px;height:16px;flex-shrink:0;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}.nk-share-btn{font-size:14px;padding:4px 8px}.nk-topbar-actions ::slotted(.nk-topbar-meta),.nk-topbar-meta{padding:4px 8px;font-size:12px;color:var(--nk-text-tertiary);white-space:nowrap}.nk-theme-toggle{font-size:15px;width:30px;height:28px;padding:0}.nk-tab-bar{display:none;flex:none;align-items:stretch;gap:2px;position:sticky;bottom:0;z-index:30;box-sizing:border-box;height:calc(var(--nk-tab-bar-height) - 6px + max(6px,env(safe-area-inset-bottom,0px)));padding:6px max(4px,env(safe-area-inset-right,0px)) max(6px,env(safe-area-inset-bottom,0px)) max(4px,env(safe-area-inset-left,0px));background:var(--nk-bg-sidebar);border-top:1px solid var(--nk-border)}.nk-tab-bar.always{display:flex}.nk-tab-bar.fixed{position:fixed;left:0;right:0;bottom:0}.nk-tab-bar-spacer{display:none;flex:none;height:calc(var(--nk-tab-bar-height) - 6px + max(6px,env(safe-area-inset-bottom,0px)))}.nk-tab-bar.always.fixed+.nk-tab-bar-spacer{display:block}.nk-tab-bar.floating{position:fixed;left:max(12px,env(safe-area-inset-left,0px));right:max(12px,env(safe-area-inset-right,0px));bottom:calc(12px + env(safe-area-inset-bottom,0px));height:var(--nk-tab-bar-height);padding:6px;border:1px solid var(--nk-border);border-radius:16px;box-shadow:var(--nk-shadow-menu)}.nk-tab-bar-item{flex:1 1 0;min-width:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;padding:4px 2px;border:none;border-radius:var(--nk-radius);background:0 0;font-family:inherit;font-size:10.5px;line-height:1.2;color:var(--nk-text-secondary);text-decoration:none;cursor:pointer;user-select:none;-webkit-tap-highlight-color:transparent}.nk-tab-bar-item:hover{color:var(--nk-text);background:var(--nk-bg-hover)}.nk-tab-bar-item.active{color:var(--nk-accent)}.nk-tab-bar-item:disabled{opacity:.5;cursor:not-allowed}.nk-tab-bar-item .icon,.nk-tab-bar-item ::slotted([slot=icon]){font-size:20px;line-height:1}.nk-tab-bar-item .label,.nk-tab-bar-item ::slotted(.label){max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nk-tree-item{display:flex;align-items:center;gap:6px;padding:3px 8px 3px 10px;border-radius:var(--nk-radius);cursor:pointer;user-select:none;color:var(--nk-text-sidebar);position:relative;min-height:28px}.nk-tree-item:hover{background:var(--nk-bg-hover)}.nk-tree-item.active{background:var(--nk-bg-active);color:var(--nk-text);font-weight:500}.nk-tree-item.compact{min-height:26px}.nk-tree-item .icon,.nk-tree-item ::slotted(.icon),.nk-tree-item ::slotted([slot=icon]){font-size:15px;width:20px;text-align:center;flex-shrink:0}.nk-tree-item .label,.nk-tree-item ::slotted(.label){white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.nk-tree-item .actions{margin-left:auto;display:none;gap:2px;color:var(--nk-text-tertiary)}.nk-tree-item:hover .actions{display:flex}.nk-tree-item .actions span{padding:0 3px;border-radius:3px;font-size:12px}.nk-tree-item .actions span:hover{background:var(--nk-bg-active)}.nk-tree-children{margin-left:14px;border-left:1px solid var(--nk-border);padding-left:4px;overflow:hidden}.nk-tree-children.collapsed{display:none}.nk-toggle-arrow{width:16px;height:16px;flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;font-size:9px;color:var(--nk-text-tertiary);border-radius:3px;transition:transform .15s}.nk-toggle-arrow.open{transform:rotate(90deg)}.nk-kbd-hint{margin-left:auto;display:flex;gap:3px;align-items:center}.nk-kbd{font-family:inherit;font-size:10.5px;background:var(--nk-bg-callout);border:1px solid var(--nk-border-strong);border-bottom-width:2px;border-radius:4px;padding:0 4px}.nk-page-scroll{flex:1;overflow-y:auto}.nk-page-scroll::-webkit-scrollbar{width:10px}.nk-page-scroll::-webkit-scrollbar-thumb{background:var(--nk-border-strong);border-radius:5px;border:2px solid var(--nk-bg)}.nk-cover{height:200px;background:radial-gradient(ellipse at 20% 40%,color-mix(in srgb,var(--nk-decor-purple) 35%,transparent),transparent 55%),radial-gradient(ellipse at 80% 20%,color-mix(in srgb,var(--nk-decor-blue) 35%,transparent),transparent 55%),radial-gradient(ellipse at 60% 90%,color-mix(in srgb,var(--nk-decor-orange) 25%,transparent),transparent 55%),var(--nk-bg-callout)}.nk-page{max-width:760px;margin:0 auto;padding:24px max(64px,env(safe-area-inset-right,0px)) 120px max(64px,env(safe-area-inset-left,0px));font-size:16px;line-height:1.5}.nk-cover+.nk-page,.nk-page.covered{padding-top:0}.nk-page ::slotted(.nk-page-icon),.nk-page ::slotted([slot=icon]),.nk-page-icon{font-size:64px;line-height:1;margin-top:0;cursor:pointer;user-select:none;display:inline-block}.nk-cover+.nk-page .nk-page-icon,.nk-cover+.nk-page ::slotted(.nk-page-icon),.nk-cover+.nk-page ::slotted([slot=icon]),.nk-page.covered .nk-page-icon,.nk-page.covered ::slotted(.nk-page-icon),.nk-page.covered ::slotted([slot=icon]){margin-top:-42px}.nk-page-title{font-size:40px;font-weight:700;line-height:1.2;margin:8px 0 4px;outline:0;letter-spacing:0}.nk-page-meta{color:var(--nk-text-tertiary);font-size:13px;margin-bottom:24px;display:flex;gap:16px}.nk-page p.lead{font-size:16px;line-height:1.6;color:var(--nk-text-secondary);margin-bottom:20px}.nk-page ::slotted(p.lead){font-size:16px;line-height:1.6;color:var(--nk-text-secondary);margin-bottom:20px!important}.nk-heading{font-size:24px;font-weight:600;line-height:1.3;margin:32px 0 10px;display:flex;align-items:center;gap:8px}.nk-callout{display:flex;gap:10px;align-items:flex-start;background:var(--nk-bg-callout);border-radius:var(--nk-radius);padding:16px 16px 16px 12px;margin:16px 0;line-height:1.5}.nk-callout .c-icon,.nk-callout ::slotted(.c-icon),.nk-callout ::slotted([slot=icon]){font-size:17px}.nk-todo{display:flex;align-items:flex-start;gap:8px;padding:4px 0}.nk-todo input[type=checkbox]{appearance:none;width:16px;height:16px;margin-top:3px;border:1.4px solid var(--nk-border-strong);border-radius:2px;cursor:pointer;flex-shrink:0;position:relative;background:var(--nk-bg)}.nk-todo input[type=checkbox]:checked{background:var(--nk-accent);border-color:var(--nk-accent)}.nk-todo input[type=checkbox]:checked::after{content:\"✓\";color:var(--nk-on-accent);font-size:11px;position:absolute;inset:0;display:flex;align-items:center;justify-content:center}.nk-todo input:checked+span{text-decoration:line-through;color:var(--nk-text-tertiary)}.nk-todo input:disabled{opacity:.5;cursor:not-allowed}.nk-toggle{margin:6px 0}.nk-toggle summary{cursor:pointer;list-style:none;display:flex;align-items:center;gap:6px;padding:4px 6px;border-radius:var(--nk-radius);font-weight:500;user-select:none}.nk-toggle summary::-webkit-details-marker{display:none}.nk-toggle summary:hover{background:var(--nk-bg-hover)}.nk-toggle summary::before{content:\"▸\";color:var(--nk-text-tertiary);font-size:11px;transition:transform .15s;display:inline-block}.nk-toggle[open] summary::before{transform:rotate(90deg)}.nk-toggle .toggle-body,.nk-toggle ::slotted(.toggle-body){padding:4px 0 8px 26px;color:var(--nk-text-secondary);line-height:1.55}.nk-divider{border:none;border-top:1px solid var(--nk-border);margin:24px 0}.nk-quote{border-left:3px solid var(--nk-text);padding:2px 0 2px 14px;margin:16px 0;color:var(--nk-text-secondary);line-height:1.5}.nk-quote .q-cite{display:block;margin-top:6px;font-size:12.5px;color:var(--nk-text-tertiary)}.nk-mention{display:inline-flex;align-items:center;gap:4px;padding:0 4px;border-radius:4px;font-weight:500;cursor:pointer;white-space:nowrap}.nk-mention:hover{background:var(--nk-bg-hover)}.nk-mention.person{color:var(--nk-text)}.nk-mention.person .mini-avatar,.nk-mention.person ::slotted(.mini-avatar),.nk-mention.person ::slotted([slot=avatar]){width:16px;height:16px;border-radius:50%;color:var(--nk-on-accent);font-size:8.5px;font-weight:600;display:inline-flex;align-items:center;justify-content:center}.nk-mention.page{color:var(--nk-text-secondary);text-decoration:underline;text-decoration-color:var(--nk-border-strong);text-underline-offset:2px}.nk-mention.date{color:var(--nk-color-orange)}.nk-inline-code{font-family:var(--nk-font-mono);font-size:85%;color:var(--nk-danger);background:color-mix(in srgb,var(--nk-danger) 8%,transparent);border-radius:4px;padding:1px 5px}.nk-code{background:var(--nk-bg-code);border:1px solid var(--nk-border);border-radius:var(--nk-radius);padding:20px 24px;font-family:var(--nk-font-mono);font-size:13px;line-height:1.6;margin:14px 0;overflow-x:auto;color:var(--nk-text-secondary);white-space:pre;position:relative}.nk-code .lang{position:absolute;top:6px;right:10px;font-size:11px;color:var(--nk-text-tertiary);font-family:var(--nk-font)}.nk-code .tag,.nk-code ::slotted(.tag){color:var(--nk-accent)}.nk-code .attr,.nk-code ::slotted(.attr){color:var(--nk-color-orange)}.nk-database{margin:12px 0 8px}.nk-db-tabs{display:flex;gap:2px;align-items:center;padding:0 0 6px;margin-bottom:0;font-size:14px}.nk-db-tab{padding:4px 8px;cursor:pointer;color:var(--nk-text-secondary);border-radius:var(--nk-radius);user-select:none;line-height:20px;display:flex;align-items:center;gap:6px}.nk-db-tab:hover{color:var(--nk-text);background:var(--nk-bg-hover)}.nk-db-tab.active{color:var(--nk-text);background:var(--nk-bg-active);font-weight:500}.nk-db-tab .badge,.nk-db-tab ::slotted(.badge){background:var(--nk-bg-callout);border-radius:8px;font-size:11px;padding:0 6px;color:var(--nk-text-tertiary)}.nk-table-wrap{overflow-x:auto}.nk-table{width:100%;border-collapse:collapse;font-size:14px}.nk-table th{text-align:left;font-weight:400;color:var(--nk-text-secondary);height:36px;padding:0 8px;border-bottom:1px solid var(--nk-border);border-right:1px solid var(--nk-border);font-size:14px;white-space:nowrap;user-select:none;cursor:pointer}.nk-table th:hover{background:var(--nk-bg-hover)}.nk-table th .th-icon,.nk-table th ::slotted(.th-icon){margin-right:6px;font-size:13px;color:var(--nk-text-tertiary)}.nk-table td{height:36px;padding:6px 8px;line-height:1.5;border-bottom:1px solid var(--nk-border);border-right:1px solid var(--nk-border);white-space:nowrap;vertical-align:middle}.nk-table td:last-child,.nk-table th:last-child{border-right:none}.nk-table td.wrap,.nk-table.wrap td{white-space:normal;vertical-align:top}.nk-table tbody tr:hover{background:var(--nk-bg-hover)}.nk-table .row-title{display:flex;align-items:center;gap:7px;font-weight:500;cursor:pointer}.nk-table .row-title:hover{text-decoration:underline;text-decoration-color:var(--nk-text-tertiary)}.nk-table .date-cell{color:var(--nk-text-secondary)}.nk-table .person-cell{display:flex;align-items:center;gap:6px;color:var(--nk-text-secondary)}.nk-table .person-cell .mini-avatar,.nk-table .person-cell ::slotted(.mini-avatar){width:20px;height:20px;border-radius:50%;font-size:10px;color:var(--nk-on-accent);display:inline-flex;align-items:center;justify-content:center;font-weight:600}.nk-new-row,.nk-table .new-row{color:var(--nk-text-tertiary);cursor:pointer;padding:8px;display:flex;align-items:center;gap:7px;font-size:14px}.nk-new-row:hover,.nk-table .new-row:hover{background:var(--nk-bg-hover)}.nk-tag{display:inline-flex;align-items:center;max-width:100%;height:20px;padding:0 6px;border-radius:3px;font-size:14px;font-weight:400;line-height:20px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;vertical-align:middle;background:var(--nk-tag-gray-bg);color:var(--nk-tag-gray-text)}.nk-tag.gray{background:var(--nk-tag-gray-bg);color:var(--nk-tag-gray-text)}.nk-tag.brown{background:var(--nk-tag-brown-bg);color:var(--nk-tag-brown-text)}.nk-tag.orange{background:var(--nk-tag-orange-bg);color:var(--nk-tag-orange-text)}.nk-tag.yellow{background:var(--nk-tag-yellow-bg);color:var(--nk-tag-yellow-text)}.nk-tag.green{background:var(--nk-tag-green-bg);color:var(--nk-tag-green-text)}.nk-tag.blue{background:var(--nk-tag-blue-bg);color:var(--nk-tag-blue-text)}.nk-tag.purple{background:var(--nk-tag-purple-bg);color:var(--nk-tag-purple-text)}.nk-tag.pink{background:var(--nk-tag-pink-bg);color:var(--nk-tag-pink-text)}.nk-tag.red{background:var(--nk-tag-red-bg);color:var(--nk-tag-red-text)}.nk-progress{width:110px;height:6px;border-radius:3px;background:var(--nk-tint-blue);overflow:hidden;display:inline-block}.nk-progress>i{display:block;height:100%;background:var(--nk-color-blue);border-radius:3px}.nk-progress-label{font-size:12px;color:var(--nk-text-tertiary);margin-left:7px}.nk-board{display:none;gap:12px;padding:14px 2px;overflow-x:auto}.nk-board.active{display:flex}.nk-board-col{min-width:220px;width:220px;flex-shrink:0}.nk-board-col-header{display:flex;align-items:center;gap:7px;margin-bottom:8px;font-size:13.5px;font-weight:500}.nk-board-col-header .count{color:var(--nk-text-tertiary);font-weight:400}.nk-card{background:var(--nk-bg-card);border:1px solid var(--nk-border);border-radius:8px;padding:10px 12px;margin-bottom:8px;cursor:grab;box-shadow:var(--nk-shadow-card);transition:border-color .15s}.nk-card:hover{border-color:var(--nk-border-strong)}.nk-card .card-title,.nk-card ::slotted(.card-title){font-weight:500;margin-bottom:7px;display:flex;gap:6px;align-items:center}.nk-card .card-meta,.nk-card ::slotted(.card-meta){display:flex;gap:6px;flex-wrap:wrap;align-items:center;font-size:12px;color:var(--nk-text-secondary)}.nk-field{display:flex;align-items:center;justify-content:space-between;gap:24px;padding:9px 0}.nk-field .f-label,.nk-field ::slotted(.f-label),.nk-field ::slotted([slot=label]){font-size:14px}.nk-field .f-desc,.nk-field ::slotted(.f-desc),.nk-field ::slotted([slot=desc]){font-size:12px;color:var(--nk-text-secondary);margin-top:2px;line-height:1.45}.nk-field .f-control,.nk-field ::slotted(.f-control){flex-shrink:0}.nk-field.stacked,.nk-fields>.nk-field{flex-direction:column;align-items:stretch;gap:6px;min-width:0}.nk-field.stacked .f-control,.nk-field.stacked .nk-input,.nk-field.stacked .nk-select,.nk-field.stacked .nk-textarea,.nk-fields>.nk-field .f-control,.nk-fields>.nk-field .nk-input,.nk-fields>.nk-field .nk-select,.nk-fields>.nk-field .nk-textarea{width:100%;min-width:0}.nk-field.compact,.nk-fields>.nk-field{padding:0;gap:4px;min-width:0}.nk-field.compact .f-label,.nk-field.compact ::slotted([slot=label]),.nk-fields>.nk-field .f-label,.nk-fields>.nk-field ::slotted([slot=label]){font-size:12px;color:var(--nk-text-tertiary)}.nk-fields{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px 12px;padding:9px 0}.nk-fields>.nk-field{min-width:0}.nk-input,.nk-select,.nk-textarea{font-family:inherit;font-size:14px;line-height:20px;color:var(--nk-text);background:var(--nk-bg-input);border:1px solid var(--nk-border);border-radius:var(--nk-radius);padding:5px 10px;outline:0;transition:border-color .15s,box-shadow .15s;min-width:210px}.nk-input:hover,.nk-select:hover,.nk-textarea:hover{border-color:var(--nk-border-strong)}.nk-input:focus,.nk-select:focus,.nk-textarea:focus{border-color:color-mix(in srgb,var(--nk-accent) 60%,transparent);box-shadow:0 0 0 2px color-mix(in srgb,var(--nk-accent) 30%,transparent)}.nk-input::placeholder,.nk-textarea::placeholder{color:var(--nk-text-tertiary)}.nk-input.wide,.nk-select.wide,.nk-textarea.wide{width:100%;min-width:0}.nk-input[type=date],.nk-input[type=datetime-local],.nk-input[type=month],.nk-input[type=time]{appearance:none}.nk-input::-webkit-date-and-time-value{text-align:start;min-height:1lh}.nk-select.compact{min-width:120px}.nk-textarea{resize:vertical;min-height:70px;line-height:1.5}.nk-select{appearance:none;cursor:pointer;padding-right:26px;background-image:linear-gradient(45deg,transparent 50%,var(--nk-text-tertiary) 50%),linear-gradient(135deg,var(--nk-text-tertiary) 50%,transparent 50%);background-position:calc(100% - 14px) 55%,calc(100% - 10px) 55%;background-size:4px 4px;background-repeat:no-repeat}.nk-btn{font-family:inherit;font-size:14px;line-height:20px;font-weight:500;border-radius:var(--nk-radius);cursor:pointer;padding:3px 12px;border:1px solid transparent;transition:background .15s,border-color .15s,box-shadow .15s,opacity .15s;display:inline-flex;align-items:center;gap:6px;white-space:nowrap}.nk-btn ::slotted(svg),.nk-btn svg{width:15px;height:15px;flex-shrink:0;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}.nk-btn.primary{background:var(--nk-accent);color:var(--nk-on-accent)}.nk-btn.primary:hover{opacity:.88}.nk-btn.secondary{background:var(--nk-bg-card);color:var(--nk-text);box-shadow:var(--nk-shadow-btn)}.nk-btn.secondary:hover{background:color-mix(in srgb,var(--nk-bg-card),var(--nk-text) 6%)}.nk-btn.danger{background:var(--nk-bg-card);color:var(--nk-danger);box-shadow:var(--nk-shadow-btn)}.nk-btn.danger:hover{background:color-mix(in srgb,var(--nk-danger) 8%,var(--nk-bg-card))}.nk-btn.danger-solid{background:var(--nk-danger);color:var(--nk-on-accent)}.nk-btn.danger-solid:hover{opacity:.88}.nk-btn.small{padding:1px 8px;font-size:13px;line-height:20px}a.nk-btn{text-decoration:none}.nk-btn:disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.nk-switch{position:relative;width:34px;height:20px;flex-shrink:0;appearance:none;border:none;cursor:pointer;border-radius:20px;background:var(--nk-border-strong);transition:background .2s}.nk-switch::after{content:\"\";position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;background:var(--nk-on-accent);transition:transform .2s;box-shadow:var(--nk-shadow-knob)}.nk-switch:checked,.nk-switch[aria-checked=true]{background:var(--nk-accent)}.nk-switch:checked::after,.nk-switch[aria-checked=true]::after{transform:translateX(14px)}.nk-switch:disabled{opacity:.5;cursor:not-allowed}.nk-switch-label{display:inline-flex;align-items:flex-start;gap:8px;font-size:14px;cursor:pointer}.nk-switch-label>.nk-switch{font-size:inherit;line-height:inherit;margin-top:max(0px,calc((1lh - 20px)/ 2))}.nk-switch-label>span{padding-top:max(0px,calc((20px - 1lh)/ 2))}.nk-switch-label:has(.nk-switch:disabled){cursor:not-allowed;color:var(--nk-text-tertiary)}.nk-check{display:flex;align-items:flex-start;gap:8px;padding:4px 0;font-size:14px;cursor:pointer}.nk-check input{appearance:none;width:16px;height:16px;flex-shrink:0;border:1.4px solid var(--nk-border-strong);border-radius:3px;cursor:pointer;position:relative;background:var(--nk-bg);font-size:inherit;line-height:inherit;margin-top:max(0px,calc((1lh - 16px)/ 2))}.nk-check input[type=radio]{border-radius:50%}.nk-check input:checked{background:var(--nk-accent);border-color:var(--nk-accent)}.nk-check input:checked::after{content:\"✓\";color:var(--nk-on-accent);font-size:10.5px;position:absolute;inset:0;display:flex;align-items:center;justify-content:center}.nk-check input[type=radio]:checked::after{content:\"●\";font-size:7px}.nk-check input:disabled{opacity:.5;cursor:not-allowed}.nk-check input:disabled+*{opacity:.6}.nk-slider{width:210px;accent-color:var(--nk-accent);cursor:pointer}.nk-slider-value{font-size:12.5px;color:var(--nk-text-tertiary);margin-top:3px}.nk-profile-row{display:flex;align-items:center;gap:14px;padding:8px 0}.nk-profile-row .big-avatar,.nk-profile-row ::slotted(.big-avatar),.nk-profile-row ::slotted([slot=avatar]){width:56px;height:56px;border-radius:50%;background:linear-gradient(135deg,var(--nk-decor-purple),var(--nk-decor-blue));color:var(--nk-on-accent);font-size:20px;font-weight:600;display:flex;align-items:center;justify-content:center}.nk-model-card{border:1px solid var(--nk-border-strong);border-radius:8px;padding:12px 14px;margin-bottom:10px;cursor:pointer;display:flex;align-items:flex-start;gap:11px;transition:border-color .15s,background .15s}.nk-model-card:hover{background:var(--nk-bg-hover)}.nk-model-card.selected{border-color:var(--nk-accent);background:color-mix(in srgb,var(--nk-accent) 6%,transparent)}.nk-model-card .m-radio{width:15px;height:15px;border-radius:50%;flex-shrink:0;margin-top:2px;border:1.4px solid var(--nk-border-strong);position:relative}.nk-model-card.selected .m-radio{border-color:var(--nk-accent)}.nk-model-card.selected .m-radio::after{content:\"\";position:absolute;inset:3px;border-radius:50%;background:var(--nk-accent)}.nk-model-card .m-name,.nk-model-card ::slotted(.m-name),.nk-model-card ::slotted([slot=title]){font-weight:500;font-size:14px;display:flex;align-items:center;gap:7px}.nk-model-card .m-desc,.nk-model-card ::slotted(.m-desc),.nk-model-card ::slotted([slot=desc]){font-size:12px;color:var(--nk-text-secondary);margin-top:2px;line-height:1.45}.nk-danger-zone{border:1px solid color-mix(in srgb,var(--nk-danger) 40%,transparent);border-radius:8px;padding:14px 16px;margin-top:26px}.nk-danger-zone .dz-title{color:var(--nk-danger);font-weight:600;font-size:13px;margin-bottom:8px}.nk-member-row{display:flex;align-items:center;gap:10px;padding:8px 0;border-bottom:1px solid var(--nk-border)}.nk-member-list ::slotted(.nk-member-row:last-child),.nk-member-list>.nk-member-row:last-child,.nk-member-row.last{border-bottom:none}.nk-member-row .mini-avatar,.nk-member-row ::slotted(.mini-avatar),.nk-member-row ::slotted([slot=avatar]){width:28px;height:28px;border-radius:50%;color:var(--nk-on-accent);display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600;flex-shrink:0}.nk-member-row>:has(> .m-mail){min-width:0}.nk-member-row .m-mail{font-size:12px;color:var(--nk-text-secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nk-member-row .nk-select{min-width:120px;margin-left:auto}.nk-member-row ::slotted([slot=role]){margin-left:auto}.nk-modal-backdrop{position:fixed;inset:0;background:var(--nk-scrim);padding:env(safe-area-inset-top,0) env(safe-area-inset-right,0) env(safe-area-inset-bottom,0) env(safe-area-inset-left,0);display:flex;align-items:center;justify-content:center;z-index:100;opacity:0;pointer-events:none;transition:opacity .2s}.nk-modal-backdrop.open{opacity:1;pointer-events:auto}.nk-modal{width:min(1150px,92vw);height:min(715px,86vh);max-width:100%;max-height:100%;background:var(--nk-bg);border-radius:10px;box-shadow:var(--nk-shadow-menu);display:flex;overflow:hidden;transform:scale(.98) translateY(6px);transition:transform .2s}.nk-modal-backdrop.open .nk-modal{transform:scale(1) translateY(0)}.nk-settings-nav{width:240px;min-width:240px;background:var(--nk-bg-sidebar);border-right:1px solid var(--nk-border);padding:10px 8px;overflow-y:auto;flex-shrink:0}.nk-settings-user{display:flex;align-items:center;gap:9px;padding:6px 10px 12px;margin-bottom:4px}.nk-settings-user .avatar,.nk-settings-user ::slotted(.avatar),.nk-settings-user ::slotted([slot=avatar]){width:34px;height:34px;border-radius:50%;background:linear-gradient(135deg,var(--nk-decor-purple),var(--nk-decor-blue));color:var(--nk-on-accent);font-weight:600;font-size:13px;display:flex;align-items:center;justify-content:center}.nk-settings-user .name{font-weight:500;font-size:14px}.nk-settings-user .mail{font-size:12px;color:var(--nk-text-secondary)}.nk-settings-nav .nk-tree-item{min-height:28px}.nk-settings-nav .nk-tree-item.active{background:var(--nk-bg-active);color:var(--nk-text);font-weight:500}.nk-settings-content{flex:1;overflow-y:auto;padding:36px 60px 80px;min-width:0}.nk-settings-content::-webkit-scrollbar{width:10px}.nk-settings-content::-webkit-scrollbar-thumb{background:var(--nk-border-strong);border-radius:5px;border:2px solid var(--nk-bg)}.nk-settings-pane{display:none;max-width:800px}.nk-settings-pane.active{display:block}.nk-settings-pane>h2{font-size:22px;font-weight:600;line-height:1.3;margin-bottom:20px}.nk-settings-pane>h3{font-size:16px;font-weight:500;padding-bottom:8px;border-bottom:1px solid var(--nk-border);margin:30px 0 12px}.nk-settings-pane ::slotted(h2){font-size:22px;font-weight:600;line-height:1.3;padding:0!important;margin:0 0 20px!important}.nk-settings-pane ::slotted(h3){font-size:16px;font-weight:500;border:0;border-bottom:1px solid var(--nk-border);padding:0 0 8px!important;margin:30px 0 12px!important}.nk-pop{background:var(--nk-bg);border-radius:10px;box-shadow:var(--nk-shadow-menu);padding:10px;width:296px}.nk-emoji-search{width:100%;font-family:inherit;font-size:14px;color:var(--nk-text);background:var(--nk-bg-input);border:1px solid var(--nk-border);border-radius:var(--nk-radius);padding:6px 10px;outline:0;margin-bottom:8px}.nk-emoji-grid{display:grid;grid-template-columns:repeat(8,1fr);gap:2px}.nk-emoji-grid ::slotted(span),.nk-emoji-grid span{font-size:18px;text-align:center;padding:4px 0;border-radius:5px;cursor:pointer;user-select:none}.nk-emoji-grid span:hover{background:var(--nk-bg-hover)}.nk-emoji-cats{display:flex;gap:2px;margin-top:8px;padding-top:8px;border-top:1px solid var(--nk-border)}.nk-emoji-cats span{font-size:14px;padding:3px 7px;border-radius:5px;cursor:pointer;color:var(--nk-text-tertiary);filter:grayscale(1);opacity:.6}.nk-emoji-cats span.active,.nk-emoji-cats span:hover{filter:none;opacity:1;background:var(--nk-bg-hover)}.nk-menu{padding:5px;width:230px}.nk-menu-item{display:flex;align-items:center;gap:9px;padding:4px 8px;min-height:28px;border-radius:5px;cursor:pointer;font-size:14px;user-select:none}.nk-menu-item:hover{background:var(--nk-bg-hover)}.nk-menu-item .m-icon,.nk-menu-item ::slotted(.m-icon),.nk-menu-item ::slotted([slot=icon]){width:17px;text-align:center;font-size:14px}.nk-menu-item .m-shortcut,.nk-menu-item ::slotted(.m-shortcut){margin-left:auto;font-size:12px;color:var(--nk-text-tertiary)}.nk-menu-item.danger{color:var(--nk-danger)}.nk-menu-sep{border-top:1px solid var(--nk-border);margin:5px 4px}.nk-menu-label{font-size:12px;color:var(--nk-text-tertiary);padding:5px 8px 2px}.nk-cmdk-backdrop{position:fixed;inset:0;background:var(--nk-scrim-soft);display:flex;justify-content:center;align-items:flex-start;padding:max(14vh,env(safe-area-inset-top,0px)) env(safe-area-inset-right,0) env(safe-area-inset-bottom,0) env(safe-area-inset-left,0);z-index:110;opacity:0;pointer-events:none;transition:opacity .18s}.nk-cmdk-backdrop.open{opacity:1;pointer-events:auto}.nk-cmdk{max-width:100%;width:min(560px,92vw);background:var(--nk-bg);border-radius:12px;box-shadow:var(--nk-shadow-menu);overflow:hidden;transform:scale(.98);transition:transform .18s}.nk-cmdk-backdrop.open .nk-cmdk{transform:scale(1)}.nk-cmdk-input-row{display:flex;align-items:center;gap:10px;padding:14px 16px;border-bottom:1px solid var(--nk-border)}.nk-cmdk-input-row input{flex:1;border:none;outline:0;background:0 0;font-family:inherit;font-size:16px;color:var(--nk-text)}.nk-cmdk-input-row input::placeholder{color:var(--nk-text-tertiary)}.nk-cmdk-list{max-height:320px;overflow-y:auto;padding:6px}.nk-cmdk-group{font-size:12px;color:var(--nk-text-tertiary);padding:8px 10px 3px}.nk-cmdk-item{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:6px;cursor:pointer;font-size:14px;user-select:none}.nk-cmdk-item.selected{background:var(--nk-bg-active)}.nk-cmdk-item .m-icon,.nk-cmdk-item ::slotted(.m-icon),.nk-cmdk-item ::slotted([slot=icon]){width:17px;text-align:center;font-size:14px}.nk-cmdk-item .m-shortcut,.nk-cmdk-item ::slotted(.m-shortcut){margin-left:auto;font-size:12px;color:var(--nk-text-tertiary)}.nk-cmdk-empty{padding:30px;text-align:center;color:var(--nk-text-tertiary);font-size:13.5px}.nk-cmdk-footer{display:flex;gap:14px;padding:8px 16px;border-top:1px solid var(--nk-border);font-size:11.5px;color:var(--nk-text-tertiary)}.nk-toast{position:fixed;bottom:max(20px,calc(env(safe-area-inset-bottom,0px) + 12px));left:50%;transform:translateX(-50%) translateY(80px);z-index:120;width:max-content;max-width:calc(100% - 32px);background:var(--nk-text);color:var(--nk-bg);padding:8px 16px;border-radius:8px;font-size:14px;opacity:0;transition:.3s;pointer-events:none;box-shadow:var(--nk-shadow-menu);display:flex;gap:8px;align-items:center}.nk-toast.show{opacity:1;transform:translateX(-50%) translateY(0)}.nk-gallery-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(280px,100%),1fr));gap:20px 32px;margin:12px 0}.nk-g-item>h4{font-size:12px;font-weight:500;color:var(--nk-text-tertiary);text-transform:uppercase;letter-spacing:.04em;margin-bottom:8px}.nk-g-item ::slotted(h4){font-size:12px;font-weight:500;color:var(--nk-text-tertiary);text-transform:uppercase;letter-spacing:.04em;margin-bottom:8px!important}.nk-tabs{display:flex;gap:2px;border-bottom:1px solid var(--nk-border);font-size:14px}.nk-tab{padding:7px 11px;cursor:pointer;color:var(--nk-text-secondary);border-bottom:2px solid transparent;margin-bottom:-1px;user-select:none}.nk-tab:hover{color:var(--nk-text)}.nk-tab.active{color:var(--nk-text);border-bottom-color:var(--nk-text);font-weight:500}.nk-tab-panel{padding:12px 2px;color:var(--nk-text-secondary);line-height:1.55;font-size:14px}.nk-template-btn{display:flex;align-items:center;gap:8px;width:100%;font-family:inherit;font-size:14px;color:var(--nk-text-secondary);background:var(--nk-bg-callout);border:none;border-radius:var(--nk-radius);padding:8px 12px;cursor:pointer;margin-bottom:6px;text-align:left}.nk-template-btn:hover{background:var(--nk-bg-hover)}.nk-stats{display:flex;gap:10px}.nk-stat{flex:1;border:1px solid var(--nk-border);border-radius:8px;padding:12px 14px}.nk-stat .s-label,.nk-stat ::slotted(.s-label),.nk-stat ::slotted([slot=label]){font-size:12px;color:var(--nk-text-secondary);margin-bottom:4px}.nk-stat .s-value,.nk-stat ::slotted(.s-value),.nk-stat ::slotted([slot=value]){font-size:22px;font-weight:600;letter-spacing:-.01em}.nk-stat .s-delta,.nk-stat ::slotted(.s-delta),.nk-stat ::slotted([slot=delta]){font-size:12px;margin-top:3px}.nk-stat .s-delta.up,.nk-stat ::slotted(.s-delta.up),.nk-stat ::slotted([slot=delta].up){color:var(--nk-color-green)}.nk-stat .s-delta.down,.nk-stat ::slotted(.s-delta.down),.nk-stat ::slotted([slot=delta].down){color:var(--nk-danger)}.nk-synced{border:1.5px solid color-mix(in srgb,var(--nk-danger) 55%,transparent);border-radius:8px;padding:12px 14px;position:relative;margin:8px 0}.nk-synced .synced-badge{position:absolute;top:-9px;right:10px;font-size:11px;background:var(--nk-danger);color:var(--nk-on-accent);border-radius:8px;padding:1px 8px}.nk-segmented{display:inline-flex;background:var(--nk-bg-callout);border-radius:7px;padding:2px}.nk-segmented button{font-family:inherit;font-size:14px;border:none;background:0 0;color:var(--nk-text-secondary);padding:4px 12px;border-radius:5px;cursor:pointer}.nk-segmented ::slotted(button){font-family:inherit;font-size:14px;border:none;background:0 0;color:var(--nk-text-secondary);padding:4px 12px!important;border-radius:5px;cursor:pointer}.nk-segmented ::slotted(button.active),.nk-segmented button.active{background:var(--nk-bg);color:var(--nk-text);font-weight:500;box-shadow:var(--nk-shadow-segment)}.nk-segmented.wrap{flex-wrap:wrap}.nk-segmented.scroll{max-width:100%;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}.nk-segmented.scroll::-webkit-scrollbar{display:none}.nk-segmented.scroll ::slotted(button),.nk-segmented.scroll button{flex-shrink:0;white-space:nowrap}.nk-banner{display:flex;align-items:center;gap:10px;font-size:14px;border-radius:8px;padding:10px 14px;margin-bottom:8px;color:var(--nk-text)}.nk-banner.info{background:var(--nk-tint-blue)}.nk-banner.success{background:var(--nk-tint-green)}.nk-banner.warning{background:var(--nk-tint-yellow)}.nk-banner.danger{background:var(--nk-tint-red)}.nk-banner .b-action,.nk-banner ::slotted(.b-action),.nk-banner ::slotted([slot=action]){margin-left:auto;font-weight:500;cursor:pointer;text-decoration:underline;text-underline-offset:2px}.nk-avatar-group{display:flex}.nk-avatar-group .mini-avatar,.nk-avatar-group ::slotted(.mini-avatar){width:26px;height:26px;border-radius:50%;color:var(--nk-on-accent);font-size:10.5px;font-weight:600;border:2px solid var(--nk-bg);display:flex;align-items:center;justify-content:center;margin-left:-7px}.nk-avatar-group .mini-avatar:first-child,.nk-avatar-group ::slotted(.mini-avatar:first-child){margin-left:0}.nk-avatar-group .more,.nk-avatar-group ::slotted(.more){background:var(--nk-bg-callout);color:var(--nk-text-secondary)}.nk-skeleton{border-radius:5px;margin-bottom:10px;background:linear-gradient(90deg,var(--nk-bg-callout) 25%,var(--nk-bg-hover) 50%,var(--nk-bg-callout) 75%);background-size:200% 100%;animation:1.6s infinite nk-shimmer}@keyframes nk-shimmer{to{background-position:-200% 0}}.nk-empty{text-align:center;padding:36px 20px;border:1.5px dashed var(--nk-border-strong);border-radius:10px;color:var(--nk-text-tertiary)}.nk-empty .e-icon,.nk-empty ::slotted(.e-icon),.nk-empty ::slotted([slot=icon]){font-size:30px;margin-bottom:8px}.nk-empty .e-title,.nk-empty ::slotted(.e-title),.nk-empty ::slotted([slot=title]){font-weight:500;color:var(--nk-text-secondary);margin-bottom:3px;font-size:14px}.nk-empty .e-desc,.nk-empty ::slotted(.e-desc),.nk-empty ::slotted([slot=desc]){font-size:13px;margin-bottom:12px}.nk-empty .e-actions,.nk-empty ::slotted(.e-actions){display:flex;flex-wrap:wrap;justify-content:center;gap:8px}.nk-comments{border-left:1px solid var(--nk-border);padding:4px 0 4px 18px;margin:8px 0 8px 8px}.nk-comment{display:flex;gap:9px;margin-bottom:14px}.nk-comment .mini-avatar,.nk-comment ::slotted(.mini-avatar),.nk-comment ::slotted([slot=avatar]){width:24px;height:24px;border-radius:50%;color:var(--nk-on-accent);flex-shrink:0;font-size:10px;font-weight:600;display:flex;align-items:center;justify-content:center}.nk-comment .c-head,.nk-comment ::slotted(.c-head){font-size:12px;color:var(--nk-text-tertiary);margin-bottom:2px}.nk-comment .c-head b{color:var(--nk-text);font-weight:600}.nk-comment .c-body,.nk-comment ::slotted(.c-body){font-size:14px;line-height:1.5}.nk-comment-input{display:flex;gap:8px;align-items:center;margin-top:4px}.nk-comment-input input{min-width:0;flex:1}.nk-ai-thread{display:flex;flex-direction:column;gap:14px}.nk-ai-msg{display:flex;gap:9px}.nk-ai-msg .mini-avatar,.nk-ai-msg ::slotted(.mini-avatar),.nk-ai-msg ::slotted([slot=avatar]){width:24px;height:24px;border-radius:50%;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:12px;background:var(--nk-bg-callout)}.nk-ai-msg.user .mini-avatar,.nk-ai-msg.user ::slotted(.mini-avatar),.nk-ai-msg.user ::slotted([slot=avatar]){background:linear-gradient(135deg,var(--nk-decor-purple),var(--nk-decor-blue));color:var(--nk-on-accent);font-size:9.5px;font-weight:600}.nk-ai-msg .a-body,.nk-ai-msg ::slotted(.a-body){font-size:14px;line-height:1.55;padding-top:2px}.nk-ai-msg .a-name,.nk-ai-msg ::slotted(.a-name){font-size:12px;font-weight:600;margin-bottom:2px}.nk-ai-msg .a-name span{color:var(--nk-text-tertiary);font-weight:400}.nk-ai-actions{display:flex;gap:4px;margin-top:6px}.nk-ai-actions button{font-family:inherit;font-size:12px;color:var(--nk-text-secondary);background:0 0;border:1px solid var(--nk-border);border-radius:5px;padding:2px 8px;cursor:pointer}.nk-ai-actions ::slotted(button){font-family:inherit;font-size:12px;color:var(--nk-text-secondary);background:0 0;border:1px solid var(--nk-border);border-radius:5px;padding:2px 8px!important;cursor:pointer}.nk-ai-actions ::slotted(button:hover),.nk-ai-actions button:hover{background:var(--nk-bg-hover);color:var(--nk-text)}.nk-ai-input-row{display:flex;align-items:center;gap:8px;margin-top:14px;border:1px solid var(--nk-border-strong);border-radius:10px;padding:8px 12px}.nk-ai-input-row:focus-within{border-color:var(--nk-accent)}.nk-ai-input-row input{flex:1;border:none;outline:0;background:0 0;font-family:inherit;font-size:14px;color:var(--nk-text);min-width:0}.nk-ai-input-row input::placeholder{color:var(--nk-text-tertiary)}.nk-ai-send{border:none;background:var(--nk-accent);color:var(--nk-on-accent);border-radius:6px;width:26px;height:26px;cursor:pointer;font-size:13px;flex-shrink:0}.nk-block-host{position:relative;border-radius:var(--nk-radius);margin:8px 0;padding:2px 0 2px 2px;transition:background .15s,box-shadow .15s}.nk-block-host:hover{background:var(--nk-bg-hover)}.nk-block-host:focus-within{background:0 0;box-shadow:0 0 0 2px color-mix(in srgb,var(--nk-accent) 25%,transparent)}.nk-block-host.nk-drop-target{box-shadow:0 -2px 0 0 var(--nk-accent);background:0 0}.nk-block-host .nk-block-handle,.nk-block-host ::slotted(.nk-block-handle){position:absolute;left:-26px;top:4px;width:18px;height:20px;border-radius:4px;display:flex;align-items:center;justify-content:center;color:var(--nk-text-tertiary);font-size:13px;cursor:grab;opacity:0;transition:opacity .15s;user-select:none}.nk-block-host:hover .nk-block-handle{opacity:1}.nk-block-host .nk-block-actions{position:absolute;display:flex;gap:1px;z-index:2;opacity:0;transition:opacity .15s;pointer-events:none}.nk-block-host .nk-block-actions.show{opacity:1;pointer-events:auto}.nk-block-host .nk-block-actions ::slotted(button),.nk-block-host .nk-block-actions button{width:20px;height:22px;padding:0;border:none;border-radius:4px;background:0 0;color:var(--nk-text-tertiary);font-family:inherit;font-size:14px;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center}.nk-block-host .nk-block-actions button:hover{background:var(--nk-bg-hover);color:var(--nk-text)}.nk-block-host .nk-block-actions .drag{cursor:grab}.nk-block-host .nk-block-actions .drag:active{cursor:grabbing}.nk-block-host .ProseMirror{outline:0;font-family:var(--nk-font);font-size:14px;line-height:1.6;color:var(--nk-text);min-height:60px;padding:4px 2px}.nk-block-host .ProseMirror>*+*{margin-top:6px}.nk-block-host .ProseMirror h1{font-size:30px;font-weight:600;letter-spacing:-.01em;margin:24px 0 6px}.nk-block-host .ProseMirror h2{font-size:22px;font-weight:600;margin:20px 0 6px}.nk-block-host .ProseMirror h3{font-size:17px;font-weight:600;margin:16px 0 4px}.nk-block-host .ProseMirror p{margin:0}.nk-block-host .ProseMirror ol,.nk-block-host .ProseMirror ul{padding-left:24px;margin:4px 0}.nk-block-host .ProseMirror ul{list-style:disc}.nk-block-host .ProseMirror ol{list-style:decimal}.nk-block-host .ProseMirror li{margin:2px 0}.nk-block-host .ProseMirror li::marker{color:var(--nk-text-tertiary)}.nk-block-host .ProseMirror ul[data-type=taskList]{list-style:none;padding-left:2px}.nk-block-host .ProseMirror ul[data-type=taskList] li{display:flex;gap:8px;align-items:flex-start}.nk-block-host .ProseMirror ul[data-type=taskList] li>label{flex-shrink:0;margin-top:3px;user-select:none}.nk-block-host .ProseMirror ul[data-type=taskList] li>div{flex:1;min-width:0}.nk-block-host .ProseMirror ul[data-type=taskList] input[type=checkbox]{appearance:none;width:16px;height:16px;margin:0;border:1.4px solid var(--nk-border-strong);border-radius:2px;cursor:pointer;position:relative;background:var(--nk-bg);display:block}.nk-block-host .ProseMirror ul[data-type=taskList] input[type=checkbox]:checked{background:var(--nk-accent);border-color:var(--nk-accent)}.nk-block-host .ProseMirror ul[data-type=taskList] input[type=checkbox]:checked::after{content:\"✓\";color:var(--nk-on-accent);font-size:11px;position:absolute;inset:0;display:flex;align-items:center;justify-content:center}.nk-block-host .ProseMirror li[data-checked=true]>div{text-decoration:line-through;color:var(--nk-text-tertiary)}.nk-block-host .ProseMirror-gapcursor::after{border-top-color:var(--nk-text)}.nk-block-host .ProseMirror .ProseMirror-selectednode{background:color-mix(in srgb,var(--nk-accent) 8%,transparent)}.nk-block-host .ProseMirror blockquote{border-left:3px solid var(--nk-text);padding:2px 0 2px 14px;margin:12px 0;color:var(--nk-text-secondary)}.nk-block-host .ProseMirror code{font-family:var(--nk-font-mono);font-size:85%;color:var(--nk-danger);background:color-mix(in srgb,var(--nk-danger) 8%,transparent);border-radius:4px;padding:1px 5px}.nk-block-host .ProseMirror pre{background:var(--nk-bg-code);border:1px solid var(--nk-border);border-radius:var(--nk-radius);padding:16px 20px;margin:12px 0;font-family:var(--nk-font-mono);font-size:13px;line-height:1.6;color:var(--nk-text-secondary);overflow-x:auto}.nk-block-host .ProseMirror pre code{background:0 0;color:inherit;padding:0;font-size:inherit}.nk-block-host .ProseMirror hr{border:none;border-top:1px solid var(--nk-border);margin:20px 0}.nk-block-host .ProseMirror a{color:var(--nk-accent);text-decoration:underline;text-underline-offset:2px}.nk-block-host .ProseMirror-selectednode{box-shadow:0 0 0 2px color-mix(in srgb,var(--nk-accent) 35%,transparent);border-radius:3px}.nk-block-host .ProseMirror ::selection{background:color-mix(in srgb,var(--nk-accent) 25%,transparent)}.nk-block-host .ProseMirror .is-empty::before,.nk-block-host .ProseMirror p.is-editor-empty:first-child::before{content:attr(data-placeholder);color:var(--nk-text-tertiary);float:left;height:0;pointer-events:none}.nk-block-host .bn-container{font-family:var(--nk-font);color:var(--nk-text);background:0 0}.nk-block-host .bn-editor{padding:4px 2px}.nk-block-host .bn-block-content{font-size:14px;line-height:1.6}.nk-block-host .bn-side-menu{color:var(--nk-text-tertiary)}.nk-block-host .bn-drag-handle{border-radius:4px}.nk-block-host .bn-drag-handle:hover{background:var(--nk-bg-hover)}.nk-block-host .novel-editor{font-family:var(--nk-font);color:var(--nk-text)}.nk-block-host .novel-prose{max-width:none}.nk-block-host .bn-suggestion-menu,.nk-block-host .tippy-box,.nk-slash-menu{background:var(--nk-bg);border-radius:10px;box-shadow:var(--nk-shadow-menu);padding:6px;width:280px;max-height:320px;overflow-y:auto;font-family:var(--nk-font);font-size:14px;color:var(--nk-text)}.nk-slash-menu-label{font-size:12px;color:var(--nk-text-tertiary);padding:6px 9px 2px}.nk-slash-item{display:flex;align-items:center;gap:10px;padding:6px 9px;border-radius:5px;cursor:pointer;user-select:none}.nk-slash-item.selected,.nk-slash-item:hover{background:var(--nk-bg-hover)}.nk-slash-item .m-icon,.nk-slash-item ::slotted(.m-icon){width:28px;height:28px;flex-shrink:0;border-radius:4px;background:var(--nk-bg-callout);border:1px solid var(--nk-border);display:flex;align-items:center;justify-content:center;font-size:15px}.nk-slash-item .m-desc{font-size:12px;color:var(--nk-text-tertiary)}.nk-bubble-menu{display:flex;align-items:center;gap:2px;background:var(--nk-bg);border-radius:8px;box-shadow:var(--nk-shadow-menu);padding:4px}.nk-bubble-menu button{font-family:inherit;font-size:13px;border:none;background:0 0;color:var(--nk-text-secondary);padding:4px 8px;border-radius:5px;cursor:pointer}.nk-bubble-menu ::slotted(button){font-family:inherit;font-size:13px;border:none;background:0 0;color:var(--nk-text-secondary);padding:4px 8px!important;border-radius:5px;cursor:pointer}.nk-bubble-menu ::slotted(button:hover),.nk-bubble-menu button:hover{background:var(--nk-bg-hover);color:var(--nk-text)}.nk-bubble-menu ::slotted(button.active),.nk-bubble-menu button.active{color:var(--nk-accent)}@media (max-width:860px){.nk-sidebar{display:none}.nk-tab-bar{display:flex}.nk-tab-bar.fixed+.nk-tab-bar-spacer{display:block}.nk-page{padding-left:max(24px,env(safe-area-inset-left,0px));padding-right:max(24px,env(safe-area-inset-right,0px));padding-bottom:80px}.nk-settings-nav{width:60px;min-width:60px}.nk-settings-nav .label,.nk-settings-nav .nk-section-label,.nk-settings-user .u-text{display:none}.nk-settings-content{padding:24px}.nk-cmdk-backdrop{padding-top:max(6vh,env(safe-area-inset-top,0px))}.nk-cmdk{width:min(560px,96vw)}.nk-stats{flex-wrap:wrap}.nk-breadcrumb{min-width:0}.nk-breadcrumb ::slotted(.crumb:not(:last-child)),.nk-breadcrumb ::slotted(.sep),.nk-breadcrumb>.crumb:not(:last-child),.nk-breadcrumb>.sep,.nk-topbar-actions ::slotted(.nk-topbar-meta),.nk-topbar-meta{display:none}.nk-breadcrumb ::slotted(.crumb:last-child),.nk-breadcrumb>.crumb:last-child{display:block;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.nk-topbar-actions{flex-shrink:0}.nk-field{flex-wrap:wrap;row-gap:6px}.nk-field .f-control,.nk-field ::slotted(.f-control){max-width:100%;min-width:0}.nk-input,.nk-select,.nk-slider,.nk-textarea{max-width:100%}:root:has(.nk-tab-bar:not([hidden])) .nk-toast{bottom:calc(var(--nk-tab-bar-height) + max(6px,env(safe-area-inset-bottom,0px)) + 6px)}:root:has(.nk-tab-bar.floating:not([hidden])) .nk-toast{bottom:calc(var(--nk-tab-bar-height) + 24px + env(safe-area-inset-bottom,0px))}}@media (prefers-reduced-motion:reduce){.nk-skeleton{animation:none;background:var(--nk-bg-callout)}[class*=nk-],[class*=nk-]::after,[class*=nk-]::before{animation-duration:NaNs!important;animation-iteration-count:1!important;transition-duration:NaNs!important;scroll-behavior:auto!important}}\n/*# sourceMappingURL=notionkit.min.css.map */";
11
+ const componentsHead = "[class*=nk-],[class*=nk-] *,[class*=nk-]:before,[class*=nk-]:after,[class*=nk-] *:before,[class*=nk-] *:after{box-sizing:border-box}[class*=nk-] :where(h1,h2,h3,h4,h5,h6,p,figure,blockquote,dl,dd,pre,ul,ol,li){margin:0;padding:0}[class*=nk-] :where(ul,ol){list-style:none}[class*=nk-] :where(button,input,select,textarea,option,optgroup,fieldset,legend),:where(button,input,select,textarea)[class*=nk-]{margin:0;padding:0}[class*=nk-][hidden]:not([hidden=until-found i]){display:none!important}::slotted([hidden]:not([hidden=\"until-found\" i])){display:none!important}";
12
+ const componentsTail = ".nk-body{margin:0;min-height:100vh;min-height:100dvh;font-family:var(--nk-font);font-size:14px;background:var(--nk-bg);color:var(--nk-text);-webkit-font-smoothing:auto;transition:background .25s ease,color .25s ease}.nk-app{display:flex;height:100vh;height:100dvh;overflow:hidden}.nk-sidebar{width:calc(var(--nk-sidebar-width) + env(safe-area-inset-left,0px));min-width:calc(var(--nk-sidebar-width) + env(safe-area-inset-left,0px));padding-left:env(safe-area-inset-left,0px);background:var(--nk-bg-sidebar);display:flex;flex-direction:column;border-right:1px solid var(--nk-border);transition:background .25s ease}.nk-workspace{display:flex;align-items:center;gap:8px;padding:10px 12px;margin:6px 8px 2px;border-radius:var(--nk-radius);cursor:pointer;font-weight:500;user-select:none}.nk-workspace:hover{background:var(--nk-bg-hover)}.nk-workspace .avatar,.nk-workspace ::slotted(.avatar),.nk-workspace ::slotted([slot=\"avatar\"]){width:22px;height:22px;border-radius:4px;background:linear-gradient(135deg,var(--nk-decor-purple),var(--nk-decor-blue));color:var(--nk-on-accent);font-size:11px;font-weight:600;display:flex;align-items:center;justify-content:center}.nk-workspace .chev{margin-left:auto;color:var(--nk-text-tertiary);font-size:11px}.nk-sidebar-scroll{flex:1;overflow-y:auto;padding:4px 8px 16px}.nk-sidebar-scroll::-webkit-scrollbar{width:8px}.nk-sidebar-scroll::-webkit-scrollbar-thumb{background:var(--nk-border-strong);border-radius:4px}.nk-section-label{font-size:12px;font-weight:500;letter-spacing:.01em;color:var(--nk-text-tertiary);padding:14px 10px 4px;display:flex;justify-content:space-between;align-items:center}.nk-section-label .plus{cursor:pointer;border-radius:4px;padding:0 4px;font-size:13px;opacity:0;transition:opacity .15s}.nk-section-label:hover .plus{opacity:1}.nk-section-label .plus:hover{background:var(--nk-bg-hover)}.nk-sidebar-footer{padding:8px;border-top:1px solid var(--nk-border);color:var(--nk-text-sidebar);font-size:14px}.nk-sidebar-footer .nk-tree-item{min-height:26px}.nk-sidebar-backdrop{display:none;position:fixed;inset:0;z-index:59;background:var(--nk-scrim-soft)}.nk-sidebar-toggle{display:none}.nk-main{flex:1;display:flex;flex-direction:column;min-width:0}.nk-topbar{height:44px;display:flex;align-items:center;padding:0 max(12px,env(safe-area-inset-right,0px)) 0 max(12px,env(safe-area-inset-left,0px));gap:8px;flex-shrink:0}.nk-breadcrumb{display:flex;align-items:center;gap:4px;font-size:14px}.nk-breadcrumb .crumb,.nk-breadcrumb ::slotted(.crumb){padding:2px 6px;border-radius:4px;cursor:pointer;color:var(--nk-text-sidebar);display:flex;align-items:center;gap:5px}.nk-breadcrumb .crumb:hover{background:var(--nk-bg-hover)}a.crumb{text-decoration:none}.nk-breadcrumb .crumb.current,.nk-breadcrumb ::slotted(.crumb.current){color:var(--nk-text)}.nk-breadcrumb .sep{color:var(--nk-text-tertiary);font-size:12px}.nk-topbar-actions{margin-left:auto;display:flex;align-items:center;gap:4px}.nk-topbar-btn{padding:4px 8px;border-radius:var(--nk-radius);cursor:pointer;color:var(--nk-text-sidebar);font-size:14px;user-select:none;border:none;background:transparent;font-family:inherit}.nk-topbar-btn:hover{background:var(--nk-bg-hover)}.nk-topbar-btn svg,.nk-topbar-btn ::slotted(svg){width:16px;height:16px;flex-shrink:0;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}.nk-share-btn{font-size:14px;padding:4px 8px}.nk-topbar-meta,.nk-topbar-actions ::slotted(.nk-topbar-meta){padding:4px 8px;font-size:12px;color:var(--nk-text-tertiary);white-space:nowrap}.nk-theme-toggle{font-size:15px;width:30px;height:28px;padding:0}.nk-tab-bar{display:none;flex:none;align-items:stretch;gap:2px;position:sticky;bottom:0;z-index:30;box-sizing:border-box;height:calc(var(--nk-tab-bar-height) - 6px + max(6px,env(safe-area-inset-bottom,0px)));padding:6px max(4px,env(safe-area-inset-right,0px)) max(6px,env(safe-area-inset-bottom,0px)) max(4px,env(safe-area-inset-left,0px));background:var(--nk-bg-sidebar);border-top:1px solid var(--nk-border)}.nk-tab-bar.always{display:flex}.nk-tab-bar.fixed{position:fixed;left:0;right:0;bottom:0}.nk-tab-bar-spacer{display:none;flex:none;height:calc(var(--nk-tab-bar-height) - 6px + max(6px,env(safe-area-inset-bottom,0px)))}.nk-tab-bar.always.fixed+.nk-tab-bar-spacer{display:block}.nk-tab-bar.floating{position:fixed;left:max(12px,env(safe-area-inset-left,0px));right:max(12px,env(safe-area-inset-right,0px));bottom:calc(12px + env(safe-area-inset-bottom,0px));height:var(--nk-tab-bar-height);padding:6px;border:1px solid var(--nk-border);border-radius:16px;box-shadow:var(--nk-shadow-menu)}.nk-tab-bar-item{flex:1 1 0;min-width:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;padding:4px 2px;border:none;border-radius:var(--nk-radius);background:transparent;font-family:inherit;font-size:10.5px;line-height:1.2;color:var(--nk-text-secondary);text-decoration:none;cursor:pointer;user-select:none;-webkit-tap-highlight-color:transparent}.nk-tab-bar-item:hover{color:var(--nk-text);background:var(--nk-bg-hover)}.nk-tab-bar-item.active{color:var(--nk-accent)}.nk-tab-bar-item:disabled{opacity:.5;cursor:not-allowed}.nk-tab-bar-item .icon,.nk-tab-bar-item ::slotted([slot=\"icon\"]){font-size:20px;line-height:1}.nk-tab-bar-item .label,.nk-tab-bar-item ::slotted(.label){max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nk-tree-item{display:flex;align-items:center;gap:6px;padding:3px 8px 3px 10px;border-radius:var(--nk-radius);cursor:pointer;user-select:none;color:var(--nk-text-sidebar);position:relative;min-height:var(--_nk-row, 28px)}.nk-tree-item:hover{background:var(--nk-bg-hover)}.nk-tree-item.active{background:var(--nk-bg-active);color:var(--nk-text);font-weight:500}.nk-tree-item.compact{min-height:26px}.nk-tree-item .icon,.nk-tree-item ::slotted(.icon),.nk-tree-item ::slotted([slot=\"icon\"]){font-size:15px;width:20px;text-align:center;flex-shrink:0}.nk-tree-item .label,.nk-tree-item ::slotted(.label){white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.nk-tree-item .actions{margin-left:auto;display:none;gap:2px;color:var(--nk-text-tertiary)}.nk-tree-item:hover .actions{display:flex}.nk-tree-item .actions span{padding:0 3px;border-radius:3px;font-size:12px}.nk-tree-item .actions span:hover{background:var(--nk-bg-active)}.nk-tree-children{margin-left:14px;border-left:1px solid var(--nk-border);padding-left:4px;overflow:hidden}.nk-tree-children.collapsed{display:none}.nk-toggle-arrow{width:16px;height:16px;flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;font-size:9px;color:var(--nk-text-tertiary);border-radius:3px;transition:transform .15s}.nk-toggle-arrow.open{transform:rotate(90deg)}.nk-kbd-hint{margin-left:auto;display:flex;gap:3px;align-items:center}.nk-kbd{font-family:inherit;font-size:10.5px;background:var(--nk-bg-callout);border:1px solid var(--nk-border-strong);border-bottom-width:2px;border-radius:4px;padding:0 4px}.nk-page-scroll{flex:1;overflow-y:auto}.nk-page-scroll::-webkit-scrollbar{width:10px}.nk-page-scroll::-webkit-scrollbar-thumb{background:var(--nk-border-strong);border-radius:5px;border:2px solid var(--nk-bg)}.nk-cover{height:200px;background:radial-gradient(ellipse at 20% 40%,color-mix(in srgb,var(--nk-decor-purple) 35%,transparent),transparent 55%),radial-gradient(ellipse at 80% 20%,color-mix(in srgb,var(--nk-decor-blue) 35%,transparent),transparent 55%),radial-gradient(ellipse at 60% 90%,color-mix(in srgb,var(--nk-decor-orange) 25%,transparent),transparent 55%),var(--nk-bg-callout)}.nk-cover>img,.nk-cover ::slotted(img){display:block;width:100%;height:100%;object-fit:cover}.nk-page{max-width:760px;margin:0 auto;padding:24px max(64px,env(safe-area-inset-right,0px)) 120px max(64px,env(safe-area-inset-left,0px));font-size:16px;line-height:1.5}.nk-page.full{max-width:none}.nk-page.small{font-size:14px}.nk-cover+.nk-page,.nk-page.covered{padding-top:0}.nk-page-icon,.nk-page ::slotted(.nk-page-icon),.nk-page ::slotted([slot=\"icon\"]){font-size:64px;line-height:1;margin-top:0;cursor:pointer;user-select:none;display:inline-block}.nk-cover+.nk-page .nk-page-icon,.nk-cover+.nk-page ::slotted(.nk-page-icon),.nk-cover+.nk-page ::slotted([slot=\"icon\"]),.nk-page.covered .nk-page-icon,.nk-page.covered ::slotted(.nk-page-icon),.nk-page.covered ::slotted([slot=\"icon\"]){margin-top:-42px}.nk-page-title{font-size:40px;font-weight:700;line-height:1.2;margin:8px 0 4px;outline:none;letter-spacing:0}.nk-page-meta{color:var(--nk-text-tertiary);font-size:13px;margin-bottom:24px;display:flex;gap:16px}.nk-props{display:flex;flex-direction:column;margin:0 0 20px;font-size:14px;line-height:1.5}.nk-prop{display:flex;align-items:flex-start;min-width:0}.nk-prop .p-name{flex:0 0 160px;min-width:0;min-height:34px;padding:0 6px;display:flex;align-items:center;gap:6px;overflow:hidden;border-radius:var(--nk-radius);color:var(--nk-text-secondary);white-space:nowrap;user-select:none}.nk-prop .p-icon,.nk-prop ::slotted([slot=\"icon\"]){width:16px;flex-shrink:0;text-align:center;font-size:13px}.nk-prop .p-value{flex:1 1 auto;min-width:0;min-height:34px;padding:5px 8px;display:flex;align-items:center;flex-wrap:wrap;gap:4px 6px;border-radius:var(--nk-radius);overflow-wrap:anywhere}.nk-prop .p-name:hover,.nk-prop .p-value:hover{background:var(--nk-bg-hover)}.nk-page p.lead{font-size:1em;line-height:1.6;color:var(--nk-text-secondary);margin-bottom:20px}.nk-page ::slotted(p.lead){font-size:1em;line-height:1.6;color:var(--nk-text-secondary);margin-bottom:20px!important}.nk-heading{font-size:1.5em;font-weight:600;line-height:1.3;margin:32px 0 10px;display:flex;align-items:center;gap:8px}.nk-callout{display:flex;gap:10px;align-items:flex-start;background:var(--nk-bg-callout);border-radius:var(--nk-radius);padding:16px 16px 16px 12px;margin:16px 0;line-height:1.5}.nk-callout .c-icon,.nk-callout ::slotted(.c-icon),.nk-callout ::slotted([slot=\"icon\"]){font-size:17px}.nk-todo{display:flex;align-items:flex-start;gap:8px;padding:4px 0}.nk-todo input[type=checkbox]{appearance:none;width:16px;height:16px;margin-top:3px;border:1.4px solid var(--nk-border-strong);border-radius:2px;cursor:pointer;flex-shrink:0;position:relative;background:var(--nk-bg)}.nk-todo input[type=checkbox]:checked{background:var(--nk-accent);border-color:var(--nk-accent)}.nk-todo input[type=checkbox]:checked:after{content:\"\\2713\";color:var(--nk-on-accent);font-size:11px;position:absolute;inset:0;display:flex;align-items:center;justify-content:center}.nk-todo input:checked+span{text-decoration:line-through;color:var(--nk-text-tertiary)}.nk-todo input:disabled{opacity:.5;cursor:not-allowed}.nk-toggle{margin:6px 0}.nk-toggle summary{cursor:pointer;list-style:none;display:flex;align-items:center;gap:6px;padding:4px 6px;border-radius:var(--nk-radius);font-weight:500;user-select:none}.nk-toggle summary::-webkit-details-marker{display:none}.nk-toggle summary:hover{background:var(--nk-bg-hover)}.nk-toggle summary:before{content:\"\\25b8\";color:var(--nk-text-tertiary);font-size:11px;transition:transform .15s;display:inline-block}.nk-toggle[open] summary:before{transform:rotate(90deg)}.nk-toggle .toggle-body,.nk-toggle ::slotted(.toggle-body){padding:4px 0 8px 26px;color:var(--nk-text-secondary);line-height:1.55}.nk-divider{border:none;border-top:1px solid var(--nk-border);margin:24px 0}.nk-quote{border-left:3px solid var(--nk-text);padding:2px 0 2px 14px;margin:16px 0;color:var(--nk-text-secondary);line-height:1.5}.nk-quote .q-cite{display:block;margin-top:6px;font-size:12.5px;color:var(--nk-text-tertiary)}.nk-mention{display:inline-flex;align-items:center;gap:4px;padding:0 4px;border-radius:4px;font-weight:500;cursor:pointer;white-space:nowrap}.nk-mention:hover{background:var(--nk-bg-hover)}.nk-mention.person{color:var(--nk-text)}.nk-mention.person .mini-avatar,.nk-mention.person .nk-avatar,.nk-mention.person ::slotted(.mini-avatar),.nk-mention.person ::slotted([slot=\"avatar\"]){width:16px;height:16px;border-radius:50%;color:var(--nk-on-accent);font-size:8.5px;font-weight:600;display:inline-flex;align-items:center;justify-content:center}.nk-mention.page{color:var(--nk-text-secondary);text-decoration:underline;text-decoration-color:var(--nk-border-strong);text-underline-offset:2px}.nk-mention.date{color:var(--nk-color-orange)}.nk-inline-code{font-family:var(--nk-font-mono);font-size:85%;color:var(--nk-danger);background:color-mix(in srgb,var(--nk-danger) 8%,transparent);border-radius:4px;padding:1px 5px}.nk-code{background:var(--nk-bg-code);border:1px solid var(--nk-border);border-radius:var(--nk-radius);padding:20px 24px;font-family:var(--nk-font-mono);font-size:13px;line-height:1.6;margin:14px 0;overflow-x:auto;color:var(--nk-text-secondary);white-space:pre;position:relative}.nk-code .lang{position:absolute;top:6px;right:10px;font-size:11px;color:var(--nk-text-tertiary);font-family:var(--nk-font)}.nk-code .tag,.nk-code ::slotted(.tag){color:var(--nk-accent)}.nk-code .attr,.nk-code ::slotted(.attr){color:var(--nk-color-orange)}.nk-database{margin:12px 0 8px}.nk-db-tabs{display:flex;gap:2px;align-items:center;padding:0 0 6px;margin-bottom:0;font-size:14px}.nk-db-tab{padding:4px 8px;cursor:pointer;color:var(--nk-text-secondary);border-radius:var(--nk-radius);user-select:none;line-height:20px;display:flex;align-items:center;gap:6px;flex-shrink:0;white-space:nowrap}.nk-db-tab:hover{color:var(--nk-text);background:var(--nk-bg-hover)}.nk-db-tab.active{color:var(--nk-text);background:var(--nk-bg-active);font-weight:500}.nk-db-tab.add{color:var(--nk-text-tertiary)}.nk-db-tab .badge,.nk-db-tab ::slotted(.badge){background:var(--nk-bg-callout);border-radius:8px;font-size:11px;padding:0 6px;color:var(--nk-text-tertiary)}.nk-db-toolbar{display:flex;align-items:center;gap:8px;min-width:0;padding-bottom:6px}.nk-db-toolbar>.nk-db-tabs{flex:1 1 auto;min-width:0;padding-bottom:0;overflow-x:auto;scrollbar-width:none}.nk-db-toolbar>.nk-db-tabs::-webkit-scrollbar{display:none}.nk-db-toolbar .tools{flex:none;display:flex;align-items:center;gap:4px;margin-left:auto}.nk-db-tool{display:inline-flex;align-items:center;gap:4px;height:28px;padding:0 8px;border:none;border-radius:var(--nk-radius);background:transparent;font-family:inherit;font-size:14px;color:var(--nk-text-secondary);white-space:nowrap;cursor:pointer;user-select:none}.nk-db-tool:hover{background:var(--nk-bg-hover);color:var(--nk-text)}.nk-db-tool.active{color:var(--nk-accent)}.nk-filter-row{display:flex;align-items:center;flex-wrap:wrap;gap:6px;padding:2px 0 8px}.nk-filter-pill{display:inline-flex;align-items:center;gap:4px;height:24px;padding:0 8px;border:1px solid var(--nk-border-strong);border-radius:12px;background:transparent;font-family:inherit;font-size:13px;line-height:1;color:var(--nk-text-secondary);white-space:nowrap;cursor:pointer;user-select:none}.nk-filter-pill:hover{background:var(--nk-bg-hover)}.nk-filter-pill.active{color:var(--nk-accent);border-color:color-mix(in srgb,var(--nk-accent) 35%,transparent);background:color-mix(in srgb,var(--nk-accent) 6%,transparent)}.nk-filter-pill.add{border-color:transparent;color:var(--nk-text-tertiary)}.nk-filter-pill.add:hover{color:var(--nk-text-secondary)}.nk-filter-pill button{padding:0;border:none;background:none;font:inherit;color:inherit;cursor:pointer}.nk-filter-pill .fp-remove{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;margin-right:-4px;border-radius:50%;font-size:13px}.nk-filter-pill .fp-remove:hover{background:color-mix(in srgb,currentColor 15%,transparent)}.nk-table-wrap{overflow-x:auto}.nk-table{width:100%;border-collapse:collapse;font-size:14px}.nk-table th{text-align:left;font-weight:400;color:var(--nk-text-secondary);height:36px;padding:0 8px;border-bottom:1px solid var(--nk-border);border-right:1px solid var(--nk-border);font-size:14px;white-space:nowrap;user-select:none;cursor:pointer}.nk-table th:hover{background:var(--nk-bg-hover)}.nk-table th .th-icon,.nk-table th ::slotted(.th-icon){margin-right:6px;font-size:13px;color:var(--nk-text-tertiary)}.nk-table td{height:36px;padding:6px 8px;line-height:1.5;border-bottom:1px solid var(--nk-border);border-right:1px solid var(--nk-border);white-space:nowrap;vertical-align:middle}.nk-table th:last-child,.nk-table td:last-child{border-right:none}.nk-table.wrap td,.nk-table td.wrap{white-space:normal;vertical-align:top}.nk-table tbody tr:hover{background:var(--nk-bg-hover)}.nk-table .row-title{display:flex;align-items:center;gap:7px;font-weight:500;cursor:pointer}.nk-table .row-title:hover{text-decoration:underline;text-decoration-color:var(--nk-text-tertiary)}.nk-table .date-cell{color:var(--nk-text-secondary)}.nk-table .num{text-align:right;font-variant-numeric:tabular-nums}.nk-table .person-cell{display:flex;align-items:center;gap:6px;color:var(--nk-text-secondary)}.nk-table .person-cell .mini-avatar,.nk-table .person-cell ::slotted(.mini-avatar){width:20px;height:20px;border-radius:50%;font-size:10px;color:var(--nk-on-accent);display:inline-flex;align-items:center;justify-content:center;font-weight:600}.nk-new-row,.nk-table .new-row{color:var(--nk-text-tertiary);cursor:pointer;padding:8px;display:flex;align-items:center;gap:7px;font-size:14px}.nk-new-row:hover,.nk-table .new-row:hover{background:var(--nk-bg-hover)}.nk-tag{display:inline-flex;align-items:center;max-width:100%;height:20px;padding:0 6px;border-radius:3px;font-size:14px;font-weight:400;line-height:20px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;vertical-align:middle;background:var(--nk-tag-gray-bg);color:var(--nk-tag-gray-text)}.nk-tag.gray{background:var(--nk-tag-gray-bg);color:var(--nk-tag-gray-text)}.nk-tag.brown{background:var(--nk-tag-brown-bg);color:var(--nk-tag-brown-text)}.nk-tag.orange{background:var(--nk-tag-orange-bg);color:var(--nk-tag-orange-text)}.nk-tag.yellow{background:var(--nk-tag-yellow-bg);color:var(--nk-tag-yellow-text)}.nk-tag.green{background:var(--nk-tag-green-bg);color:var(--nk-tag-green-text)}.nk-tag.blue{background:var(--nk-tag-blue-bg);color:var(--nk-tag-blue-text)}.nk-tag.purple{background:var(--nk-tag-purple-bg);color:var(--nk-tag-purple-text)}.nk-tag.pink{background:var(--nk-tag-pink-bg);color:var(--nk-tag-pink-text)}.nk-tag.red{background:var(--nk-tag-red-bg);color:var(--nk-tag-red-text)}.nk-progress{width:110px;height:6px;border-radius:3px;background:var(--nk-tint-blue);overflow:hidden;display:inline-block}.nk-progress>i{display:block;height:100%;background:var(--nk-color-blue);border-radius:3px}.nk-progress.wide{width:100%;flex:1 1 60px}.nk-progress-label{font-size:12px;color:var(--nk-text-tertiary);margin-left:7px;white-space:nowrap}.nk-list{display:flex;flex-direction:column;font-size:14px}.nk-list-item{display:flex;align-items:center;gap:8px;min-width:0;overflow:hidden;min-height:36px;padding:4px 6px;border-bottom:1px solid var(--nk-border);color:inherit;text-decoration:none;cursor:pointer}.nk-list-item:hover{background:var(--nk-bg-hover)}.nk-list>.nk-list-item:last-child,.nk-list ::slotted(.nk-list-item:last-child),.nk-list-item.last{border-bottom:none}.nk-list-item .l-icon,.nk-list-item ::slotted([slot=\"icon\"]){width:20px;flex-shrink:0;text-align:center;font-size:15px}.nk-list-item .l-title,.nk-list-item ::slotted(.l-title){flex:1 1 auto;min-width:0;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.nk-list-item .l-meta,.nk-list-item ::slotted(.l-meta){flex:none;display:flex;align-items:center;gap:8px;margin-left:auto;font-size:12px;color:var(--nk-text-secondary);white-space:nowrap}.nk-board{display:none;gap:12px;padding:14px 2px;overflow-x:auto}.nk-board.active{display:flex}.nk-board-col{min-width:220px;width:220px;flex-shrink:0}.nk-board-col-header{display:flex;align-items:center;gap:7px;margin-bottom:8px;font-size:13.5px;font-weight:500}.nk-board-col-header .count{color:var(--nk-text-tertiary);font-weight:400}.nk-card{background:var(--nk-bg-card);border:1px solid var(--nk-border);border-radius:8px;padding:10px 12px;margin-bottom:8px;cursor:grab;box-shadow:var(--nk-shadow-card);transition:border-color .15s}.nk-card:hover{border-color:var(--nk-border-strong)}.nk-card .card-title,.nk-card ::slotted(.card-title){font-weight:500;margin-bottom:7px;display:flex;gap:6px;align-items:center}.nk-card .card-meta,.nk-card ::slotted(.card-meta){display:flex;gap:6px;flex-wrap:wrap;align-items:center;font-size:12px;color:var(--nk-text-secondary)}.nk-field{display:flex;align-items:center;justify-content:space-between;gap:24px;padding:9px 0}.nk-field .f-label,.nk-field ::slotted(.f-label),.nk-field ::slotted([slot=\"label\"]){font-size:14px}.nk-field .f-desc,.nk-field ::slotted(.f-desc),.nk-field ::slotted([slot=\"desc\"]){font-size:12px;color:var(--nk-text-secondary);margin-top:2px;line-height:1.45}.nk-field .f-control,.nk-field ::slotted(.f-control){flex-shrink:0}.nk-field.stacked,.nk-fields>.nk-field{flex-direction:column;align-items:stretch;gap:6px;min-width:0}.nk-field.stacked .f-control,.nk-fields>.nk-field .f-control{width:100%;min-width:0}.nk-field.stacked .nk-input,.nk-field.stacked .nk-textarea,.nk-field.stacked .nk-select,.nk-fields>.nk-field .nk-input,.nk-fields>.nk-field .nk-textarea,.nk-fields>.nk-field .nk-select{width:100%;min-width:0}.nk-field.compact,.nk-fields>.nk-field{padding:0;gap:4px;min-width:0}.nk-field.compact .f-label,.nk-field.compact ::slotted([slot=\"label\"]),.nk-fields>.nk-field .f-label,.nk-fields>.nk-field ::slotted([slot=\"label\"]){font-size:12px;color:var(--nk-text-tertiary)}.nk-fields{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px 12px;padding:9px 0}.nk-fields>.nk-field{min-width:0}.nk-input,.nk-select,.nk-textarea{font-family:inherit;font-size:14px;line-height:20px;color:var(--nk-text);background:var(--nk-bg-input);border:1px solid var(--nk-border);border-radius:var(--nk-radius);padding:5px 10px;outline:none;transition:border-color .15s,box-shadow .15s;min-width:210px}.nk-input:hover,.nk-select:hover,.nk-textarea:hover{border-color:var(--nk-border-strong)}.nk-input:focus,.nk-select:focus,.nk-textarea:focus{border-color:color-mix(in srgb,var(--nk-accent) 60%,transparent);box-shadow:0 0 0 2px color-mix(in srgb,var(--nk-accent) 30%,transparent)}.nk-input::placeholder,.nk-textarea::placeholder{color:var(--nk-text-tertiary)}.nk-input.wide,.nk-textarea.wide,.nk-select.wide{width:100%;min-width:0}.nk-input[type=date],.nk-input[type=time],.nk-input[type=datetime-local],.nk-input[type=month]{appearance:none}.nk-input::-webkit-date-and-time-value{text-align:start;min-height:1lh}.nk-select.compact{min-width:120px}.nk-textarea{resize:vertical;min-height:70px;line-height:1.5}.nk-select{appearance:none;cursor:pointer;padding-right:26px;background-image:linear-gradient(45deg,transparent 50%,var(--nk-text-tertiary) 50%),linear-gradient(135deg,var(--nk-text-tertiary) 50%,transparent 50%);background-position:calc(100% - 14px) 55%,calc(100% - 10px) 55%;background-size:4px 4px;background-repeat:no-repeat}.nk-btn{font-family:inherit;font-size:14px;line-height:20px;font-weight:500;border-radius:var(--nk-radius);cursor:pointer;padding:3px 12px;border:1px solid transparent;transition:background .15s,border-color .15s,box-shadow .15s,opacity .15s;display:inline-flex;align-items:center;gap:6px;white-space:nowrap}.nk-btn svg,.nk-btn ::slotted(svg){width:15px;height:15px;flex-shrink:0;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}.nk-btn.primary{background:var(--nk-accent);color:var(--nk-on-accent)}.nk-btn.primary:hover{opacity:.88}.nk-btn.secondary{background:var(--nk-bg-card);color:var(--nk-text);box-shadow:var(--nk-shadow-btn)}.nk-btn.secondary:hover{background:color-mix(in srgb,var(--nk-bg-card),var(--nk-text) 6%)}.nk-btn.danger{background:var(--nk-bg-card);color:var(--nk-danger);box-shadow:var(--nk-shadow-btn)}.nk-btn.danger:hover{background:color-mix(in srgb,var(--nk-danger) 8%,var(--nk-bg-card))}.nk-btn.danger-solid{background:var(--nk-danger);color:var(--nk-on-accent)}.nk-btn.danger-solid:hover{opacity:.88}.nk-btn.small{padding:1px 8px;font-size:13px;line-height:20px}a.nk-btn{text-decoration:none}.nk-btn:disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.nk-switch{position:relative;width:34px;height:20px;flex-shrink:0;appearance:none;border:none;cursor:pointer;border-radius:20px;background:var(--nk-border-strong);transition:background .2s}.nk-switch:after{content:\"\";position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;background:var(--nk-on-accent);transition:transform .2s;box-shadow:var(--nk-shadow-knob)}.nk-switch:checked,.nk-switch[aria-checked=true]{background:var(--nk-accent)}.nk-switch:checked:after,.nk-switch[aria-checked=true]:after{transform:translate(14px)}.nk-switch:disabled{opacity:.5;cursor:not-allowed}.nk-switch-label{display:inline-flex;align-items:flex-start;gap:8px;font-size:14px;cursor:pointer}.nk-switch-label>.nk-switch{font-size:inherit;line-height:inherit;margin-top:max(0px,calc((1lh - 20px)/2))}.nk-switch-label>span{padding-top:max(0px,calc((20px - 1lh)/2))}.nk-switch-label:has(.nk-switch:disabled){cursor:not-allowed;color:var(--nk-text-tertiary)}.nk-check{display:flex;align-items:flex-start;gap:8px;padding:4px 0;font-size:14px;cursor:pointer}.nk-check input{appearance:none;width:16px;height:16px;flex-shrink:0;border:1.4px solid var(--nk-border-strong);border-radius:3px;cursor:pointer;position:relative;background:var(--nk-bg);font-size:inherit;line-height:inherit;margin-top:max(0px,calc((1lh - 16px)/2))}.nk-check input[type=radio]{border-radius:50%}.nk-check input:checked{background:var(--nk-accent);border-color:var(--nk-accent)}.nk-check input:checked:after{content:\"\\2713\";color:var(--nk-on-accent);font-size:10.5px;position:absolute;inset:0;display:flex;align-items:center;justify-content:center}.nk-check input[type=radio]:checked:after{content:\"\\25cf\";font-size:7px}.nk-check input:disabled{opacity:.5;cursor:not-allowed}.nk-check input:disabled+*{opacity:.6}.nk-slider{width:210px;accent-color:var(--nk-accent);cursor:pointer}.nk-slider-value{font-size:12.5px;color:var(--nk-text-tertiary);margin-top:3px}.nk-profile-row{display:flex;align-items:center;gap:14px;padding:8px 0}.nk-profile-row .big-avatar,.nk-profile-row ::slotted(.big-avatar),.nk-profile-row ::slotted([slot=\"avatar\"]){width:56px;height:56px;border-radius:50%;background:linear-gradient(135deg,var(--nk-decor-purple),var(--nk-decor-blue));color:var(--nk-on-accent);font-size:20px;font-weight:600;display:flex;align-items:center;justify-content:center}.nk-model-card{border:1px solid var(--nk-border-strong);border-radius:8px;padding:12px 14px;margin-bottom:10px;cursor:pointer;display:flex;align-items:flex-start;gap:11px;transition:border-color .15s,background .15s}.nk-model-card:hover{background:var(--nk-bg-hover)}.nk-model-card.selected{border-color:var(--nk-accent);background:color-mix(in srgb,var(--nk-accent) 6%,transparent)}.nk-model-card .m-radio{width:15px;height:15px;border-radius:50%;flex-shrink:0;margin-top:2px;border:1.4px solid var(--nk-border-strong);position:relative}.nk-model-card.selected .m-radio{border-color:var(--nk-accent)}.nk-model-card.selected .m-radio:after{content:\"\";position:absolute;inset:3px;border-radius:50%;background:var(--nk-accent)}.nk-model-card .m-name,.nk-model-card ::slotted(.m-name),.nk-model-card ::slotted([slot=\"title\"]){font-weight:500;font-size:14px;display:flex;align-items:center;gap:7px}.nk-model-card .m-desc,.nk-model-card ::slotted(.m-desc),.nk-model-card ::slotted([slot=\"desc\"]){font-size:12px;color:var(--nk-text-secondary);margin-top:2px;line-height:1.45}.nk-danger-zone{border:1px solid color-mix(in srgb,var(--nk-danger) 40%,transparent);border-radius:8px;padding:14px 16px;margin-top:26px}.nk-danger-zone .dz-title{color:var(--nk-danger);font-weight:600;font-size:13px;margin-bottom:8px}.nk-member-row{display:flex;align-items:center;gap:10px;padding:8px 0;border-bottom:1px solid var(--nk-border)}.nk-member-list>.nk-member-row:last-child,.nk-member-list ::slotted(.nk-member-row:last-child),.nk-member-row.last{border-bottom:none}.nk-member-row .mini-avatar,.nk-member-row .nk-avatar,.nk-member-row ::slotted(.mini-avatar),.nk-member-row ::slotted([slot=\"avatar\"]){width:28px;height:28px;border-radius:50%;color:var(--nk-on-accent);display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600;flex-shrink:0}.nk-member-row>:has(>.m-mail){min-width:0}.nk-member-row .m-mail{font-size:12px;color:var(--nk-text-secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nk-member-row .nk-select{min-width:120px;margin-left:auto}.nk-member-row ::slotted([slot=\"role\"]){margin-left:auto}.nk-modal-backdrop{position:fixed;inset:0;background:var(--nk-scrim);padding:env(safe-area-inset-top,0px) env(safe-area-inset-right,0px) env(safe-area-inset-bottom,0px) env(safe-area-inset-left,0px);display:flex;align-items:center;justify-content:center;z-index:100;opacity:0;pointer-events:none;transition:opacity .2s ease}.nk-modal-backdrop.open{opacity:1;pointer-events:auto}.nk-modal{width:min(1150px,92vw);height:min(715px,86vh);max-width:100%;max-height:100%;background:var(--nk-bg);border-radius:10px;box-shadow:var(--nk-shadow-menu);display:flex;overflow:hidden;transform:scale(.98) translateY(6px);transition:transform .2s ease}.nk-modal-backdrop.open .nk-modal{transform:scale(1) translateY(0)}.nk-settings-nav{width:240px;min-width:240px;background:var(--nk-bg-sidebar);border-right:1px solid var(--nk-border);padding:10px 8px;overflow-y:auto;flex-shrink:0}.nk-settings-user{display:flex;align-items:center;gap:9px;padding:6px 10px 12px;margin-bottom:4px}.nk-settings-user .avatar,.nk-settings-user ::slotted(.avatar),.nk-settings-user ::slotted([slot=\"avatar\"]){width:34px;height:34px;border-radius:50%;background:linear-gradient(135deg,var(--nk-decor-purple),var(--nk-decor-blue));color:var(--nk-on-accent);font-weight:600;font-size:13px;display:flex;align-items:center;justify-content:center}.nk-settings-user .name{font-weight:500;font-size:14px}.nk-settings-user .mail{font-size:12px;color:var(--nk-text-secondary)}.nk-settings-nav .nk-tree-item{min-height:28px}.nk-settings-nav .nk-tree-item.active{background:var(--nk-bg-active);color:var(--nk-text);font-weight:500}.nk-settings-content{flex:1;overflow-y:auto;padding:36px 60px 80px;min-width:0}.nk-settings-content::-webkit-scrollbar{width:10px}.nk-settings-content::-webkit-scrollbar-thumb{background:var(--nk-border-strong);border-radius:5px;border:2px solid var(--nk-bg)}.nk-settings-pane{display:none;max-width:800px}.nk-settings-pane.active{display:block}.nk-settings-pane>h2{font-size:22px;font-weight:600;line-height:1.3;margin-bottom:20px}.nk-settings-pane>h3{font-size:16px;font-weight:500;padding-bottom:8px;border-bottom:1px solid var(--nk-border);margin:30px 0 12px}.nk-settings-pane ::slotted(h2){font-size:22px;font-weight:600;line-height:1.3;padding:0!important;margin:0 0 20px!important}.nk-settings-pane ::slotted(h3){font-size:16px;font-weight:500;border:0;border-bottom:1px solid var(--nk-border);padding:0 0 8px!important;margin:30px 0 12px!important}.nk-pop{background:var(--nk-bg);border-radius:10px;box-shadow:var(--nk-shadow-menu);padding:10px;width:296px}.nk-emoji-search{width:100%;font-family:inherit;font-size:14px;color:var(--nk-text);background:var(--nk-bg-input);border:1px solid var(--nk-border);border-radius:var(--nk-radius);padding:6px 10px;outline:none;margin-bottom:8px}.nk-emoji-grid{display:grid;grid-template-columns:repeat(8,1fr);gap:2px}.nk-emoji-grid span,.nk-emoji-grid ::slotted(span){font-size:18px;text-align:center;padding:4px 0;border-radius:5px;cursor:pointer;user-select:none}.nk-emoji-grid span:hover{background:var(--nk-bg-hover)}.nk-emoji-cats{display:flex;gap:2px;margin-top:8px;padding-top:8px;border-top:1px solid var(--nk-border)}.nk-emoji-cats span{font-size:14px;padding:3px 7px;border-radius:5px;cursor:pointer;color:var(--nk-text-tertiary);filter:grayscale(1);opacity:.6}.nk-emoji-cats span.active,.nk-emoji-cats span:hover{filter:none;opacity:1;background:var(--nk-bg-hover)}.nk-menu{padding:5px;width:230px}.nk-menu-item{display:flex;align-items:center;gap:9px;padding:4px 8px;min-height:var(--_nk-row, 28px);border-radius:5px;cursor:pointer;font-size:14px;user-select:none}.nk-menu-item:hover{background:var(--nk-bg-hover)}.nk-menu-item .m-icon,.nk-menu-item ::slotted(.m-icon),.nk-menu-item ::slotted([slot=\"icon\"]){width:17px;text-align:center;font-size:14px}.nk-menu-item .m-shortcut,.nk-menu-item ::slotted(.m-shortcut){margin-left:auto;font-size:12px;color:var(--nk-text-tertiary)}.nk-menu-item.danger{color:var(--nk-danger)}.nk-menu-item>.nk-switch{margin-left:auto}.nk-menu-sep{border-top:1px solid var(--nk-border);margin:5px 4px}.nk-menu-label{font-size:12px;color:var(--nk-text-tertiary);padding:5px 8px 2px}.nk-pop.floating{z-index:60;opacity:0;visibility:hidden;pointer-events:none;transform:translateY(-4px) scale(.98);transform-origin:top;transition:opacity .15s ease,transform .15s ease,visibility 0s linear .15s}.nk-pop.floating.open{opacity:1;visibility:visible;pointer-events:auto;transform:none;transition:opacity .15s ease,transform .15s ease,visibility 0s}.nk-cmdk-backdrop{position:fixed;inset:0;background:var(--nk-scrim-soft);display:flex;justify-content:center;align-items:flex-start;padding:max(14vh,env(safe-area-inset-top,0px)) env(safe-area-inset-right,0px) env(safe-area-inset-bottom,0px) env(safe-area-inset-left,0px);z-index:110;opacity:0;pointer-events:none;transition:opacity .18s ease}.nk-cmdk-backdrop.open{opacity:1;pointer-events:auto}.nk-cmdk{max-width:100%;width:min(560px,92vw);background:var(--nk-bg);border-radius:12px;box-shadow:var(--nk-shadow-menu);overflow:hidden;transform:scale(.98);transition:transform .18s ease}.nk-cmdk-backdrop.open .nk-cmdk{transform:scale(1)}.nk-cmdk-input-row{display:flex;align-items:center;gap:10px;padding:14px 16px;border-bottom:1px solid var(--nk-border)}.nk-cmdk-input-row input{flex:1;border:none;outline:none;background:transparent;font-family:inherit;font-size:16px;color:var(--nk-text)}.nk-cmdk-input-row input::placeholder{color:var(--nk-text-tertiary)}.nk-cmdk-list{max-height:320px;overflow-y:auto;padding:6px}.nk-cmdk-group{font-size:12px;color:var(--nk-text-tertiary);padding:8px 10px 3px}.nk-cmdk-item{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:6px;cursor:pointer;font-size:14px;user-select:none}.nk-cmdk-item.selected{background:var(--nk-bg-active)}.nk-cmdk-item .m-icon,.nk-cmdk-item ::slotted(.m-icon),.nk-cmdk-item ::slotted([slot=\"icon\"]){width:17px;text-align:center;font-size:14px}.nk-cmdk-item .m-shortcut,.nk-cmdk-item ::slotted(.m-shortcut){margin-left:auto;font-size:12px;color:var(--nk-text-tertiary)}.nk-cmdk-empty{padding:30px;text-align:center;color:var(--nk-text-tertiary);font-size:13.5px}.nk-cmdk-footer{display:flex;gap:14px;padding:8px 16px;border-top:1px solid var(--nk-border);font-size:11.5px;color:var(--nk-text-tertiary)}.nk-sheet-backdrop{position:fixed;inset:0;z-index:100;display:none;flex-direction:column;align-items:center;justify-content:flex-end;padding-top:max(24px,env(safe-area-inset-top,0px));background:var(--nk-scrim-soft);opacity:0;transition:opacity .2s ease,display .25s allow-discrete}.nk-sheet-backdrop.open{display:flex;opacity:1}@starting-style{.nk-sheet-backdrop.open{opacity:0}}.nk-sheet{--_nk-row: 40px;width:100%;max-width:640px;max-height:100%;overflow-y:auto;overscroll-behavior:contain;padding:6px max(10px,env(safe-area-inset-right,0px)) max(16px,env(safe-area-inset-bottom,0px)) max(10px,env(safe-area-inset-left,0px));background:var(--nk-bg);color:var(--nk-text);border-radius:14px 14px 0 0;box-shadow:var(--nk-shadow-menu);translate:0 100%;transition:translate .25s cubic-bezier(.2,.8,.2,1)}.nk-sheet-backdrop.open .nk-sheet{translate:0 0}@starting-style{.nk-sheet-backdrop.open .nk-sheet{translate:0 100%}}.nk-sheet .sh-grabber,.nk-sheet ::slotted(.sh-grabber){width:36px;height:4px;margin:4px auto 10px;border-radius:2px;background:var(--nk-border-strong)}.nk-sheet .sh-title,.nk-sheet ::slotted(.sh-title){font-size:14px;font-weight:600;text-align:center;padding:0 8px 10px}.nk-toast{position:fixed;bottom:max(20px,calc(env(safe-area-inset-bottom,0px) + 12px));left:50%;transform:translate(-50%) translateY(80px);z-index:120;width:max-content;max-width:calc(100% - 32px);background:var(--nk-text);color:var(--nk-bg);padding:8px 16px;border-radius:8px;font-size:14px;opacity:0;transition:all .3s ease;pointer-events:none;box-shadow:var(--nk-shadow-menu);display:flex;gap:8px;align-items:center}.nk-toast.show{opacity:1;transform:translate(-50%) translateY(0)}.nk-gallery-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(280px,100%),1fr));gap:20px 32px;margin:12px 0}.nk-g-item>h4{font-size:12px;font-weight:500;color:var(--nk-text-tertiary);text-transform:uppercase;letter-spacing:.04em;margin-bottom:8px}.nk-g-item ::slotted(h4){font-size:12px;font-weight:500;color:var(--nk-text-tertiary);text-transform:uppercase;letter-spacing:.04em;margin-bottom:8px!important}.nk-tabs{display:flex;gap:2px;border-bottom:1px solid var(--nk-border);font-size:14px}.nk-tab{padding:7px 11px;cursor:pointer;color:var(--nk-text-secondary);border-bottom:2px solid transparent;margin-bottom:-1px;user-select:none}.nk-tab:hover{color:var(--nk-text)}.nk-tab.active{color:var(--nk-text);border-bottom-color:var(--nk-text);font-weight:500}.nk-tab-panel{padding:12px 2px;color:var(--nk-text-secondary);line-height:1.55;font-size:14px}.nk-template-btn{display:flex;align-items:center;gap:8px;width:100%;font-family:inherit;font-size:14px;color:var(--nk-text-secondary);background:var(--nk-bg-callout);border:none;border-radius:var(--nk-radius);padding:8px 12px;cursor:pointer;margin-bottom:6px;text-align:left}.nk-template-btn:hover{background:var(--nk-bg-hover)}.nk-stats{display:flex;gap:10px}.nk-stat{flex:1;border:1px solid var(--nk-border);border-radius:8px;padding:12px 14px}.nk-stat .s-label,.nk-stat ::slotted(.s-label),.nk-stat ::slotted([slot=\"label\"]){font-size:12px;color:var(--nk-text-secondary);margin-bottom:4px}.nk-stat .s-value,.nk-stat ::slotted(.s-value),.nk-stat ::slotted([slot=\"value\"]){font-size:22px;font-weight:600;letter-spacing:-.01em}.nk-stat .s-delta,.nk-stat ::slotted(.s-delta),.nk-stat ::slotted([slot=\"delta\"]){font-size:12px;margin-top:3px}.nk-stat .s-delta.up,.nk-stat ::slotted(.s-delta.up),.nk-stat ::slotted([slot=\"delta\"].up){color:var(--nk-color-green)}.nk-stat .s-delta.down,.nk-stat ::slotted(.s-delta.down),.nk-stat ::slotted([slot=\"delta\"].down){color:var(--nk-danger)}.nk-synced{border:1.5px solid color-mix(in srgb,var(--nk-danger) 55%,transparent);border-radius:8px;padding:12px 14px;position:relative;margin:8px 0}.nk-synced .synced-badge{position:absolute;top:-9px;right:10px;font-size:11px;background:var(--nk-danger);color:var(--nk-on-accent);border-radius:8px;padding:1px 8px}.nk-segmented{display:inline-flex;background:var(--nk-bg-callout);border-radius:7px;padding:2px}.nk-segmented button{font-family:inherit;font-size:14px;border:none;background:transparent;color:var(--nk-text-secondary);padding:4px 12px;border-radius:5px;cursor:pointer}.nk-segmented ::slotted(button){font-family:inherit;font-size:14px;border:none;background:transparent;color:var(--nk-text-secondary);padding:4px 12px!important;border-radius:5px;cursor:pointer}.nk-segmented button.active,.nk-segmented ::slotted(button.active){background:var(--nk-bg);color:var(--nk-text);font-weight:500;box-shadow:var(--nk-shadow-segment)}.nk-segmented.wrap{flex-wrap:wrap}.nk-segmented.scroll{max-width:100%;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}.nk-segmented.scroll::-webkit-scrollbar{display:none}.nk-segmented.scroll button,.nk-segmented.scroll ::slotted(button){flex-shrink:0;white-space:nowrap}.nk-banner{display:flex;align-items:center;gap:10px;font-size:14px;border-radius:8px;padding:10px 14px;margin-bottom:8px;color:var(--nk-text)}.nk-banner.info{background:var(--nk-tint-blue)}.nk-banner.success{background:var(--nk-tint-green)}.nk-banner.warning{background:var(--nk-tint-yellow)}.nk-banner.danger{background:var(--nk-tint-red)}.nk-banner .b-action,.nk-banner ::slotted(.b-action),.nk-banner ::slotted([slot=\"action\"]){margin-left:auto;font-weight:500;cursor:pointer;text-decoration:underline;text-underline-offset:2px}.nk-avatar-group{display:flex}.nk-avatar-group .mini-avatar,.nk-avatar-group .nk-avatar,.nk-avatar-group ::slotted(.mini-avatar),.nk-avatar-group ::slotted(.nk-avatar){width:26px;height:26px;border-radius:50%;color:var(--nk-on-accent);font-size:10.5px;font-weight:600;border:2px solid var(--nk-bg);display:flex;align-items:center;justify-content:center;margin-left:-7px}.nk-avatar-group .mini-avatar:first-child,.nk-avatar-group .nk-avatar:first-child,.nk-avatar-group ::slotted(.mini-avatar:first-child),.nk-avatar-group ::slotted(.nk-avatar:first-child){margin-left:0}.nk-avatar-group .more,.nk-avatar-group ::slotted(.more){background:var(--nk-bg-callout);color:var(--nk-text-secondary)}.nk-avatar{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:24px;height:24px;border-radius:50%;overflow:hidden;vertical-align:middle;font-size:10px;font-weight:600;line-height:1;color:var(--nk-on-accent);user-select:none;background:linear-gradient(135deg,var(--nk-decor-purple),var(--nk-decor-blue));object-fit:cover}.nk-avatar.small{width:20px;height:20px;font-size:9px}.nk-avatar.large{width:32px;height:32px;font-size:12px}.nk-avatar.xlarge{width:56px;height:56px;font-size:20px}.nk-avatar.square{border-radius:4px}.nk-avatar>img,.nk-avatar ::slotted(img){display:block;width:100%;height:100%;object-fit:cover}.nk-avatar.gray{background:var(--nk-color-gray)}.nk-avatar.brown{background:var(--nk-color-brown)}.nk-avatar.orange{background:var(--nk-color-orange)}.nk-avatar.yellow{background:var(--nk-color-yellow)}.nk-avatar.green{background:var(--nk-color-green)}.nk-avatar.blue{background:var(--nk-color-blue)}.nk-avatar.purple{background:var(--nk-color-purple)}.nk-avatar.pink{background:var(--nk-color-pink)}.nk-avatar.red{background:var(--nk-color-red)}.nk-panels{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(200px,100%),1fr));gap:12px;margin:12px 0}.nk-panel{display:flex;flex-direction:column;gap:6px;min-width:0;padding:14px 16px;border:1px solid var(--nk-border);border-radius:10px;background:var(--nk-bg-card);box-shadow:var(--nk-shadow-card);font-size:14px;line-height:1.5;color:inherit;text-decoration:none;text-align:left}:is(a,button).nk-panel{cursor:pointer;font-family:inherit;transition:border-color .15s,background .15s}:is(a,button).nk-panel:hover{border-color:var(--nk-border-strong)}.nk-panel>h3{font-size:14px;font-weight:600;line-height:1.4}.nk-panel ::slotted(h3){font-size:14px;font-weight:600;line-height:1.4;margin:0!important}.nk-panel>p{font-size:13px;color:var(--nk-text-secondary)}.nk-panel ::slotted(p){font-size:13px;color:var(--nk-text-secondary);margin:0!important}.nk-panel>.nk-cover{flex:none;height:64px;margin:-14px -16px 2px;border-radius:9px 9px 0 0}.nk-panel>.nk-page-icon{font-size:28px}.nk-panel>.nk-cover+.nk-page-icon{margin-top:-24px}.nk-skeleton{border-radius:5px;margin-bottom:10px;background:linear-gradient(90deg,var(--nk-bg-callout) 25%,var(--nk-bg-hover) 50%,var(--nk-bg-callout) 75%);background-size:200% 100%;animation:nk-shimmer 1.6s infinite}@keyframes nk-shimmer{to{background-position:-200% 0}}.nk-empty{text-align:center;padding:36px 20px;border:1.5px dashed var(--nk-border-strong);border-radius:10px;color:var(--nk-text-tertiary)}.nk-empty .e-icon,.nk-empty ::slotted(.e-icon),.nk-empty ::slotted([slot=\"icon\"]){font-size:30px;margin-bottom:8px}.nk-empty .e-title,.nk-empty ::slotted(.e-title),.nk-empty ::slotted([slot=\"title\"]){font-weight:500;color:var(--nk-text-secondary);margin-bottom:3px;font-size:14px}.nk-empty .e-desc,.nk-empty ::slotted(.e-desc),.nk-empty ::slotted([slot=\"desc\"]){font-size:13px;margin-bottom:12px}.nk-empty .e-actions,.nk-empty ::slotted(.e-actions){display:flex;flex-wrap:wrap;justify-content:center;gap:8px}.nk-steps{display:flex;flex-direction:column;margin:8px 0;padding:0;list-style:none;font-size:14px}.nk-step{position:relative;display:flex;align-items:flex-start;gap:10px;padding-bottom:14px;line-height:20px;color:var(--nk-text-tertiary)}.nk-step:last-child{padding-bottom:0}.nk-step:not(:last-child):after{content:\"\";position:absolute;left:10px;top:24px;bottom:4px;width:1px;background:var(--nk-border)}.nk-step .st-mark{flex:none;width:20px;height:20px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--nk-border-strong);background:var(--nk-bg);font-size:11px;font-weight:600;line-height:1}.nk-step .st-desc{display:block;font-size:12px;line-height:18px;color:var(--nk-text-tertiary);font-weight:400}.nk-step.done{color:var(--nk-text-secondary)}.nk-step.done .st-mark{background:var(--nk-tag-green-bg);color:var(--nk-tag-green-text);border-color:transparent}.nk-step.current{color:var(--nk-text);font-weight:500}.nk-step.current .st-mark{border-color:var(--nk-accent);color:var(--nk-accent)}.nk-comments{border-left:1px solid var(--nk-border);padding:4px 0 4px 18px;margin:8px 0 8px 8px}.nk-comment{display:flex;gap:9px;margin-bottom:14px}.nk-comment .mini-avatar,.nk-comment ::slotted(.mini-avatar),.nk-comment ::slotted([slot=\"avatar\"]){width:24px;height:24px;border-radius:50%;color:var(--nk-on-accent);flex-shrink:0;font-size:10px;font-weight:600;display:flex;align-items:center;justify-content:center}.nk-comment .c-head,.nk-comment ::slotted(.c-head){font-size:12px;color:var(--nk-text-tertiary);margin-bottom:2px}.nk-comment .c-head b{color:var(--nk-text);font-weight:600}.nk-comment .c-body,.nk-comment ::slotted(.c-body){font-size:14px;line-height:1.5}.nk-comment-input{display:flex;gap:8px;align-items:center;margin-top:4px}.nk-comment-input input{min-width:0;flex:1}.nk-ai-thread{display:flex;flex-direction:column;gap:14px}.nk-ai-msg{display:flex;gap:9px}.nk-ai-msg .mini-avatar,.nk-ai-msg ::slotted(.mini-avatar),.nk-ai-msg ::slotted([slot=\"avatar\"]){width:24px;height:24px;border-radius:50%;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:12px;background:var(--nk-bg-callout)}.nk-ai-msg.user .mini-avatar,.nk-ai-msg.user ::slotted(.mini-avatar),.nk-ai-msg.user ::slotted([slot=\"avatar\"]){background:linear-gradient(135deg,var(--nk-decor-purple),var(--nk-decor-blue));color:var(--nk-on-accent);font-size:9.5px;font-weight:600}.nk-ai-msg .a-body,.nk-ai-msg ::slotted(.a-body){font-size:14px;line-height:1.55;padding-top:2px}.nk-ai-msg .a-name,.nk-ai-msg ::slotted(.a-name){font-size:12px;font-weight:600;margin-bottom:2px}.nk-ai-msg .a-name span{color:var(--nk-text-tertiary);font-weight:400}.nk-ai-msg.user.bubble{justify-content:flex-end}.nk-ai-msg.bubble .a-body,.nk-ai-msg.bubble ::slotted(.a-body){max-width:85%;padding:6px 12px;border-radius:16px;background:var(--nk-bg-callout)}.nk-ai-actions{display:flex;gap:4px;margin-top:6px}.nk-ai-actions button{font-family:inherit;font-size:12px;color:var(--nk-text-secondary);background:transparent;border:1px solid var(--nk-border);border-radius:5px;padding:2px 8px;cursor:pointer}.nk-ai-actions ::slotted(button){font-family:inherit;font-size:12px;color:var(--nk-text-secondary);background:transparent;border:1px solid var(--nk-border);border-radius:5px;padding:2px 8px!important;cursor:pointer}.nk-ai-actions button:hover,.nk-ai-actions ::slotted(button:hover){background:var(--nk-bg-hover);color:var(--nk-text)}.nk-ai-input-row{display:flex;align-items:center;gap:8px;margin-top:14px;border:1px solid var(--nk-border-strong);border-radius:10px;padding:8px 12px}.nk-ai-input-row:focus-within{border-color:var(--nk-accent)}.nk-ai-input-row input{flex:1;border:none;outline:none;background:transparent;font-family:inherit;font-size:14px;color:var(--nk-text);min-width:0}.nk-ai-input-row input::placeholder{color:var(--nk-text-tertiary)}.nk-ai-send{border:none;background:var(--nk-accent);color:var(--nk-on-accent);border-radius:6px;width:26px;height:26px;cursor:pointer;font-size:13px;flex-shrink:0}.nk-block-host{position:relative;border-radius:var(--nk-radius);margin:8px 0;padding:2px 0 2px 2px;transition:background .15s,box-shadow .15s}.nk-block-host:hover{background:var(--nk-bg-hover)}.nk-block-host:focus-within{background:transparent;box-shadow:0 0 0 2px color-mix(in srgb,var(--nk-accent) 25%,transparent)}.nk-block-host.nk-drop-target{box-shadow:0 -2px 0 0 var(--nk-accent);background:transparent}.nk-block-host .nk-block-handle,.nk-block-host ::slotted(.nk-block-handle){position:absolute;left:-26px;top:4px;width:18px;height:20px;border-radius:4px;display:flex;align-items:center;justify-content:center;color:var(--nk-text-tertiary);font-size:13px;cursor:grab;opacity:0;transition:opacity .15s;user-select:none}.nk-block-host:hover .nk-block-handle{opacity:1}.nk-block-host .nk-block-actions{position:absolute;display:flex;gap:1px;z-index:2;opacity:0;transition:opacity .15s;pointer-events:none}.nk-block-host .nk-block-actions.show{opacity:1;pointer-events:auto}.nk-block-host .nk-block-actions button,.nk-block-host .nk-block-actions ::slotted(button){width:20px;height:22px;padding:0;border:none;border-radius:4px;background:transparent;color:var(--nk-text-tertiary);font-family:inherit;font-size:14px;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center}.nk-block-host .nk-block-actions button:hover{background:var(--nk-bg-hover);color:var(--nk-text)}.nk-block-host .nk-block-actions .drag{cursor:grab}.nk-block-host .nk-block-actions .drag:active{cursor:grabbing}.nk-prose,.nk-block-host .ProseMirror{font-family:var(--nk-font);line-height:1.5;color:var(--nk-text);overflow-wrap:break-word}.nk-block-host .ProseMirror{outline:none;min-height:60px;padding:4px 2px}.nk-prose>*+*,.nk-block-host .ProseMirror>*+*{margin-top:6px}.nk-prose h1,.nk-block-host .ProseMirror h1{font-size:1.875em;font-weight:600;line-height:1.3;letter-spacing:-.01em;margin:32px 0 4px}.nk-prose h2,.nk-block-host .ProseMirror h2{font-size:1.5em;font-weight:600;line-height:1.3;margin:24px 0 4px}.nk-prose h3,.nk-block-host .ProseMirror h3{font-size:1.25em;font-weight:600;line-height:1.3;margin:16px 0 2px}.nk-prose :is(h4,h5,h6),.nk-block-host .ProseMirror :is(h4,h5,h6){font-size:1em;font-weight:600;margin:12px 0 0}.nk-prose>:first-child,.nk-block-host .ProseMirror>:first-child{margin-top:0}.nk-prose>:last-child,.nk-block-host .ProseMirror>:last-child{margin-bottom:0}.nk-prose p:empty:before{content:\"\";display:inline-block}.nk-prose :is(strong,b),.nk-block-host .ProseMirror :is(strong,b){font-weight:600}.nk-prose :is(ul,ol),.nk-block-host .ProseMirror :is(ul,ol){padding-left:24px;margin:4px 0}.nk-prose ul,.nk-block-host .ProseMirror ul{list-style:disc}.nk-prose ol,.nk-block-host .ProseMirror ol{list-style:decimal}.nk-prose li,.nk-block-host .ProseMirror li{margin:2px 0}.nk-prose li::marker,.nk-block-host .ProseMirror li::marker{color:var(--nk-text-tertiary)}.nk-prose ul[data-type=taskList],.nk-block-host .ProseMirror ul[data-type=taskList]{list-style:none;padding-left:2px}.nk-prose ul[data-type=taskList] li,.nk-block-host .ProseMirror ul[data-type=taskList] li{display:flex;gap:8px;align-items:flex-start}.nk-prose ul[data-type=taskList] li>label,.nk-block-host .ProseMirror ul[data-type=taskList] li>label{flex-shrink:0;margin-top:max(0px,calc((1lh - 16px)/2));user-select:none}.nk-prose ul[data-type=taskList] li>div,.nk-block-host .ProseMirror ul[data-type=taskList] li>div{flex:1;min-width:0}.nk-prose ul[data-type=taskList] input[type=checkbox],.nk-block-host .ProseMirror ul[data-type=taskList] input[type=checkbox]{appearance:none;width:16px;height:16px;margin:0;border:1.4px solid var(--nk-border-strong);border-radius:2px;cursor:pointer;position:relative;background:var(--nk-bg);display:block}.nk-prose ul[data-type=taskList] input[type=checkbox]:checked,.nk-block-host .ProseMirror ul[data-type=taskList] input[type=checkbox]:checked{background:var(--nk-accent);border-color:var(--nk-accent)}.nk-prose ul[data-type=taskList] input[type=checkbox]:checked:after,.nk-block-host .ProseMirror ul[data-type=taskList] input[type=checkbox]:checked:after{content:\"\\2713\";color:var(--nk-on-accent);font-size:11px;position:absolute;inset:0;display:flex;align-items:center;justify-content:center}.nk-prose li[data-checked=true]>div,.nk-block-host .ProseMirror li[data-checked=true]>div{text-decoration:line-through;color:var(--nk-text-tertiary)}.nk-prose blockquote,.nk-block-host .ProseMirror blockquote{border-left:3px solid var(--nk-text);padding:2px 0 2px 14px;margin:12px 0;color:var(--nk-text-secondary)}.nk-prose code,.nk-block-host .ProseMirror code{font-family:var(--nk-font-mono);font-size:85%;color:var(--nk-danger);background:color-mix(in srgb,var(--nk-danger) 8%,transparent);border-radius:4px;padding:1px 5px}.nk-prose pre,.nk-block-host .ProseMirror pre{background:var(--nk-bg-code);border:1px solid var(--nk-border);border-radius:var(--nk-radius);padding:16px 20px;margin:12px 0;font-family:var(--nk-font-mono);font-size:13px;line-height:1.6;color:var(--nk-text-secondary);overflow-x:auto}.nk-prose pre code,.nk-block-host .ProseMirror pre code{background:none;color:inherit;padding:0;font-size:inherit}.nk-prose hr,.nk-block-host .ProseMirror hr{border:none;border-top:1px solid var(--nk-border);margin:20px 0}.nk-prose a,.nk-block-host .ProseMirror a{color:var(--nk-accent);text-decoration:underline;text-underline-offset:2px}.nk-prose img{max-width:100%;height:auto}.nk-prose table{display:block;width:max-content;max-width:100%;overflow-x:auto;border-collapse:collapse;font-size:14px;margin:12px 0}.nk-prose :is(th,td){padding:6px 10px;border:1px solid var(--nk-border);text-align:left;vertical-align:top}.nk-prose th{font-weight:600}.nk-block-host .ProseMirror-gapcursor:after{border-top-color:var(--nk-text)}.nk-block-host .ProseMirror .ProseMirror-selectednode{background:color-mix(in srgb,var(--nk-accent) 8%,transparent)}.nk-block-host .ProseMirror-selectednode{box-shadow:0 0 0 2px color-mix(in srgb,var(--nk-accent) 35%,transparent);border-radius:3px}.nk-block-host .ProseMirror ::selection{background:color-mix(in srgb,var(--nk-accent) 25%,transparent)}.nk-block-host .ProseMirror p.is-editor-empty:first-child:before,.nk-block-host .ProseMirror .is-empty:before{content:attr(data-placeholder);color:var(--nk-text-tertiary);float:left;height:0;pointer-events:none}.nk-block-host .bn-container{font-family:var(--nk-font);color:var(--nk-text);background:transparent}.nk-block-host .bn-editor{padding:4px 2px}.nk-block-host .bn-block-content{font-size:14px;line-height:1.6}.nk-block-host .bn-side-menu{color:var(--nk-text-tertiary)}.nk-block-host .bn-drag-handle{border-radius:4px}.nk-block-host .bn-drag-handle:hover{background:var(--nk-bg-hover)}.nk-block-host .novel-editor{font-family:var(--nk-font);color:var(--nk-text)}.nk-block-host .novel-prose{max-width:none}.nk-slash-menu,.nk-block-host .bn-suggestion-menu,.nk-block-host .tippy-box{background:var(--nk-bg);border-radius:10px;box-shadow:var(--nk-shadow-menu);padding:6px;width:280px;max-height:320px;overflow-y:auto;font-family:var(--nk-font);font-size:14px;color:var(--nk-text)}.nk-slash-menu-label{font-size:12px;color:var(--nk-text-tertiary);padding:6px 9px 2px}.nk-slash-item{display:flex;align-items:center;gap:10px;padding:6px 9px;border-radius:5px;cursor:pointer;user-select:none}.nk-slash-item:hover,.nk-slash-item.selected{background:var(--nk-bg-hover)}.nk-slash-item .m-icon,.nk-slash-item ::slotted(.m-icon){width:28px;height:28px;flex-shrink:0;border-radius:4px;background:var(--nk-bg-callout);border:1px solid var(--nk-border);display:flex;align-items:center;justify-content:center;font-size:15px}.nk-slash-item .m-desc{font-size:12px;color:var(--nk-text-tertiary)}.nk-bubble-menu{display:flex;align-items:center;gap:2px;background:var(--nk-bg);border-radius:8px;box-shadow:var(--nk-shadow-menu);padding:4px}.nk-bubble-menu button{font-family:inherit;font-size:13px;border:none;background:transparent;color:var(--nk-text-secondary);padding:4px 8px;border-radius:5px;cursor:pointer}.nk-bubble-menu ::slotted(button){font-family:inherit;font-size:13px;border:none;background:transparent;color:var(--nk-text-secondary);padding:4px 8px!important;border-radius:5px;cursor:pointer}.nk-bubble-menu button:hover,.nk-bubble-menu ::slotted(button:hover){background:var(--nk-bg-hover);color:var(--nk-text)}.nk-bubble-menu button.active,.nk-bubble-menu ::slotted(button.active){color:var(--nk-accent)}@media(max-width:860px){.nk-sidebar{display:none;position:fixed;inset:0 auto 0 0;z-index:60;transform:translate(-100%);transition:background .25s ease,transform .24s cubic-bezier(.2,.8,.25,1),display .24s allow-discrete}.nk-sidebar.open{display:flex;transform:none}@starting-style{.nk-sidebar.open{transform:translate(-100%)}}.nk-sidebar-backdrop{opacity:0;transition:opacity .24s ease,display .24s allow-discrete}.nk-sidebar-backdrop.open{display:block;opacity:1}@starting-style{.nk-sidebar-backdrop.open{opacity:0}}.nk-sidebar-toggle{display:inline-flex}.nk-tab-bar{display:flex}.nk-tab-bar.fixed+.nk-tab-bar-spacer{display:block}.nk-page{padding-left:max(24px,env(safe-area-inset-left,0px));padding-right:max(24px,env(safe-area-inset-right,0px));padding-bottom:80px}.nk-settings-nav{width:60px;min-width:60px}.nk-settings-nav .label,.nk-settings-nav .nk-section-label,.nk-settings-user .u-text{display:none}.nk-settings-content{padding:24px}.nk-cmdk-backdrop{padding-top:max(6vh,env(safe-area-inset-top,0px))}.nk-cmdk{width:min(560px,96vw)}.nk-stats{flex-wrap:wrap}.nk-breadcrumb{min-width:0}.nk-breadcrumb>.crumb:not(:last-child),.nk-breadcrumb ::slotted(.crumb:not(:last-child)),.nk-breadcrumb>.sep,.nk-breadcrumb ::slotted(.sep),.nk-topbar-meta,.nk-topbar-actions ::slotted(.nk-topbar-meta){display:none}.nk-breadcrumb>.crumb:last-child,.nk-breadcrumb ::slotted(.crumb:last-child){display:block;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.nk-topbar-actions{flex-shrink:0}.nk-field{flex-wrap:wrap;row-gap:6px}.nk-field .f-control,.nk-field ::slotted(.f-control){max-width:100%;min-width:0}.nk-input,.nk-select,.nk-textarea,.nk-slider{max-width:100%}.nk-prop{flex-direction:column;align-items:stretch}.nk-prop .p-name{flex:none;min-height:26px}.nk-prop .p-value{min-height:30px;padding:3px 6px 7px}.nk-pop.sheet{position:fixed!important;inset:auto 0 0!important;width:auto!important;transform:none!important;z-index:100;--_nk-row: 40px;max-height:85dvh;overflow-y:auto;overscroll-behavior:contain;border-radius:14px 14px 0 0;padding:6px max(8px,env(safe-area-inset-right,0px)) max(12px,env(safe-area-inset-bottom,0px)) max(8px,env(safe-area-inset-left,0px));box-shadow:0 0 0 100vmax var(--nk-scrim-soft),var(--nk-shadow-menu)}.nk-pop.sheet:before{content:\"\";display:block;width:36px;height:4px;margin:4px auto 8px;border-radius:2px;background:var(--nk-border-strong)}.nk-pop.sheet.floating{translate:0 100%;transition:opacity .2s ease,translate .25s cubic-bezier(.2,.8,.2,1),visibility 0s linear .25s}.nk-pop.sheet.floating.open{translate:0 0;transition:opacity .2s ease,translate .25s cubic-bezier(.2,.8,.2,1),visibility 0s}:root:has(.nk-tab-bar:not([hidden])) .nk-toast{bottom:calc(var(--nk-tab-bar-height) + max(6px,env(safe-area-inset-bottom,0px)) + 6px)}:root:has(.nk-tab-bar.floating:not([hidden])) .nk-toast{bottom:calc(var(--nk-tab-bar-height) + 24px + env(safe-area-inset-bottom,0px))}}@media(prefers-reduced-motion:reduce){.nk-skeleton{animation:none;background:var(--nk-bg-callout)}[class*=nk-],[class*=nk-]:before,[class*=nk-]:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}}\n/*# sourceMappingURL=notionkit.min.css.map */\n";
13
13
 
14
14
  const componentsCss = componentsHead + componentsTail;
15
15
  const css = componentsHead + tokensCss + componentsTail;
@@ -369,13 +369,16 @@ var NotionKitElements = (function (exports) {
369
369
  // <nk-btn variant="primary" small>Save</nk-btn> → <button class="nk-btn primary small">
370
370
  // <nk-btn href="/docs" variant="secondary">Docs</nk-btn> → <a class="nk-btn secondary">
371
371
  // <nk-btn variant="topbar">⭐</nk-btn> → <button class="nk-topbar-btn">
372
+ // <nk-btn variant="tool" active>Filter</nk-btn> → <button class="nk-db-tool active"> (slot="tools" of nk-database)
373
+ // <nk-btn variant="sidebar" aria-label="Menu">☰</nk-btn> → <button class="nk-topbar-btn nk-sidebar-toggle">:
374
+ // shown on phones only, it opens the page's <nk-sidebar> as a drawer.
372
375
  //
373
376
  // Modifier classes become attributes. A slotted <svg> is sized by the
374
377
  // `.nk-btn ::slotted(svg)` twin; pass the icon itself, never wrapped.
375
378
  const VARIANTS$1 = ['primary', 'secondary', 'danger', 'danger-solid', 'topbar', 'share'];
376
379
 
377
380
  class NkBtn extends NkElement {
378
- static get observedAttributes() { return ['variant', 'small', 'disabled', 'type', 'href', 'title', 'aria-label']; }
381
+ static get observedAttributes() { return ['variant', 'small', 'disabled', 'type', 'href', 'title', 'aria-label', 'aria-haspopup', 'active']; }
379
382
 
380
383
  render() {
381
384
  this._build();
@@ -403,13 +406,22 @@ var NotionKitElements = (function (exports) {
403
406
  else el.setAttribute('aria-disabled', disabled ? 'true' : 'false');
404
407
  const title = this.getAttribute('title');
405
408
  title ? el.setAttribute('title', title) : el.removeAttribute('title');
406
- const label = this.getAttribute('aria-label');
407
- label ? el.setAttribute('aria-label', label) : el.removeAttribute('aria-label');
409
+ // The accessible name and the popup hint belong on the button itself.
410
+ for (const name of ['aria-label', 'aria-haspopup']) {
411
+ const v = this.getAttribute(name);
412
+ v ? el.setAttribute(name, v) : el.removeAttribute(name);
413
+ }
414
+ if (this.getAttribute('variant') === 'sidebar') el.setAttribute('aria-expanded', this._sidebar()?.open ? 'true' : 'false');
415
+ else el.removeAttribute('aria-expanded');
408
416
  }
409
417
 
418
+ /** The sidebar the ☰ opens: the one in its own app, else the page's. */
419
+ _sidebar() { return this.closest('nk-app')?.querySelector('nk-sidebar') ?? document.querySelector('nk-sidebar'); }
420
+
410
421
  setupEvents() {
411
422
  this._onClick = (e) => {
412
423
  if (this.getBoolAttr('disabled')) { e.preventDefault(); e.stopPropagation(); return; }
424
+ if (this.getAttribute('variant') === 'sidebar') { this._sidebar()?.toggle?.(); return; }
413
425
  // A button inside a shadow root is not a submit button of the outer
414
426
  // form; forward the intent to the form the host sits in.
415
427
  const type = this.getAttribute('type');
@@ -418,11 +430,17 @@ var NotionKitElements = (function (exports) {
418
430
  if (form) type === 'submit' ? form.requestSubmit() : form.reset();
419
431
  }
420
432
  };
433
+ // The ☰ says whether its drawer is open, however the drawer closed.
434
+ this._onToggle = (e) => {
435
+ if (this.getAttribute('variant') === 'sidebar' && e.target === this._sidebar()) this._btn.setAttribute('aria-expanded', e.detail.open ? 'true' : 'false');
436
+ };
421
437
  this._btn.addEventListener('click', this._onClick);
438
+ document.addEventListener('nk-toggle', this._onToggle);
422
439
  }
423
440
 
424
441
  teardownEvents() {
425
442
  this._btn?.removeEventListener('click', this._onClick);
443
+ document.removeEventListener('nk-toggle', this._onToggle);
426
444
  }
427
445
 
428
446
  onAttributeChanged(name) {
@@ -432,7 +450,11 @@ var NotionKitElements = (function (exports) {
432
450
  this._build();
433
451
  break;
434
452
  case 'variant':
453
+ this._btn.className = this._computeClasses().join(' ');
454
+ this._applyState(this._btn);
455
+ break;
435
456
  case 'small':
457
+ case 'active':
436
458
  this._btn.className = this._computeClasses().join(' ');
437
459
  break;
438
460
  case 'type':
@@ -447,6 +469,8 @@ var NotionKitElements = (function (exports) {
447
469
  const variant = this.getAttribute('variant');
448
470
  if (variant === 'topbar') return ['nk-topbar-btn'];
449
471
  if (variant === 'share') return ['nk-topbar-btn', 'nk-share-btn'];
472
+ if (variant === 'sidebar') return ['nk-topbar-btn', 'nk-sidebar-toggle'];
473
+ if (variant === 'tool') return this.getBoolAttr('active') ? ['nk-db-tool', 'active'] : ['nk-db-tool'];
450
474
  const classes = ['nk-btn'];
451
475
  if (VARIANTS$1.includes(variant)) classes.push(variant);
452
476
  if (this.getBoolAttr('small')) classes.push('small');
@@ -458,6 +482,8 @@ var NotionKitElements = (function (exports) {
458
482
 
459
483
  get variant() { return this.getAttribute('variant'); }
460
484
  set variant(v) { v ? this.setAttribute('variant', v) : this.removeAttribute('variant'); }
485
+ get active() { return this.getBoolAttr('active'); }
486
+ set active(v) { this.setBoolAttr('active', v); }
461
487
  get small() { return this.getBoolAttr('small'); }
462
488
  set small(v) { this.setBoolAttr('small', v); }
463
489
  get disabled() { return this.getBoolAttr('disabled'); }
@@ -1348,9 +1374,10 @@ var NotionKitElements = (function (exports) {
1348
1374
  customElements.define('nk-tag', NkTag);
1349
1375
 
1350
1376
  // <nk-progress value="72" label="72%"></nk-progress>
1377
+ // <nk-progress value="72" label="72 %" wide></nk-progress> → fills its row, the label stays beside it
1351
1378
  // The bar is `.nk-progress > i` — a child combinator, so both nodes live here.
1352
1379
  class NkProgress extends NkElement {
1353
- static get observedAttributes() { return ['value', 'max', 'label']; }
1380
+ static get observedAttributes() { return ['value', 'max', 'label', 'wide']; }
1354
1381
 
1355
1382
  render() {
1356
1383
  this._bar = this.createElement('span', ['nk-progress'], { role: 'progressbar' });
@@ -1369,6 +1396,7 @@ var NotionKitElements = (function (exports) {
1369
1396
  const max = Number(this.getAttribute('max')) || 100;
1370
1397
  const value = Math.min(max, Math.max(0, Number(this.getAttribute('value')) || 0));
1371
1398
  this._fill.style.width = `${(value / max) * 100}%`;
1399
+ this._bar.classList.toggle('wide', this.getBoolAttr('wide'));
1372
1400
  this._bar.setAttribute('aria-valuenow', value);
1373
1401
  this._bar.setAttribute('aria-valuemin', 0);
1374
1402
  this._bar.setAttribute('aria-valuemax', max);
@@ -1712,42 +1740,12 @@ var NotionKitElements = (function (exports) {
1712
1740
  //
1713
1741
  // The host is display:contents so the <aside> is a direct flex child of
1714
1742
  // .nk-app, exactly like the class markup. Below 860px notionkit.css hides the
1715
- // aside; `open` brings it back as an off-canvas drawer (position only – the
1716
- // look is still the stylesheet's).
1717
- //
1718
- // The drawer slides and the scrim fades without a line of JavaScript:
1719
- // `display` transitions with transition-behavior: allow-discrete (the old
1720
- // value is held for the whole duration, so closing animates too) and
1721
- // @starting-style gives the first frame after display: none its start
1722
- // values. `position: fixed` lives on the plain .nk-sidebar, not on the open
1723
- // state – while closing, the aside is still displayed and must not fall
1724
- // back into the flow. Browsers without either feature switch hard, as
1725
- // before; prefers-reduced-motion switches hard on purpose.
1726
- const drawerSheet = new CSSStyleSheet();
1727
- drawerSheet.replaceSync(`
1728
- .nk-sidebar-backdrop { display: none; position: fixed; inset: 0; z-index: 59; background: var(--nk-scrim-soft); }
1729
- @media (max-width: 860px) {
1730
- .nk-sidebar {
1731
- position: fixed; inset: 0 auto 0 0; z-index: 60;
1732
- transform: translateX(-100%);
1733
- transition: background .25s ease, transform .24s cubic-bezier(.2, .8, .25, 1), display .24s;
1734
- transition-behavior: allow-discrete;
1735
- }
1736
- :host([open]) .nk-sidebar { display: flex; transform: none; }
1737
- @starting-style { :host([open]) .nk-sidebar { transform: translateX(-100%); } }
1738
- .nk-sidebar-backdrop {
1739
- opacity: 0;
1740
- transition: opacity .24s ease, display .24s;
1741
- transition-behavior: allow-discrete;
1742
- }
1743
- :host([open]) .nk-sidebar-backdrop { display: block; opacity: 1; }
1744
- @starting-style { :host([open]) .nk-sidebar-backdrop { opacity: 0; } }
1745
- }
1746
- @media (prefers-reduced-motion: reduce) { .nk-sidebar, .nk-sidebar-backdrop { transition: none; } }
1747
- `);
1748
-
1743
+ // aside; `open` brings it back as a drawer over the page. The drawer is the
1744
+ // stylesheet's since NotionKit 1.7.0 (.nk-sidebar.open, .nk-sidebar-backdrop
1745
+ // .open) – the sidebar slides and the scrim fades by the same rules as the
1746
+ // class markup; the element toggles the two classes. <nk-btn variant="sidebar">
1747
+ // in the topbar is the ☰ that opens it.
1749
1748
  class NkSidebar extends NkElement {
1750
- static get hostStyles() { return drawerSheet; }
1751
1749
  static get observedAttributes() { return ['open']; }
1752
1750
 
1753
1751
  render() {
@@ -1764,6 +1762,13 @@ var NotionKitElements = (function (exports) {
1764
1762
  this._wrapper.appendChild(this._backdrop);
1765
1763
  this._wrapper.appendChild(this._aside);
1766
1764
  this._syncFooter();
1765
+ this._syncOpen();
1766
+ }
1767
+
1768
+ _syncOpen() {
1769
+ const open = this.getBoolAttr('open');
1770
+ this._aside.classList.toggle('open', open);
1771
+ this._backdrop.classList.toggle('open', open);
1767
1772
  }
1768
1773
 
1769
1774
  _syncFooter() {
@@ -1790,7 +1795,9 @@ var NotionKitElements = (function (exports) {
1790
1795
  }
1791
1796
 
1792
1797
  onAttributeChanged(name) {
1793
- if (name === 'open') this.emit('nk-toggle', { open: this.getBoolAttr('open') });
1798
+ if (name !== 'open') return;
1799
+ this._syncOpen();
1800
+ this.emit('nk-toggle', { open: this.getBoolAttr('open') });
1794
1801
  }
1795
1802
 
1796
1803
  show() { this.setBoolAttr('open', true); }
@@ -2520,7 +2527,7 @@ var NotionKitElements = (function (exports) {
2520
2527
 
2521
2528
  customElements.define('nk-tab-bar-item', NkTabBarItem);
2522
2529
 
2523
- // <nk-page icon="🚀" cover>
2530
+ // <nk-page icon="🚀" cover full small>
2524
2531
  // <nk-page-title>NotionKit MVP</nk-page-title>
2525
2532
  // <nk-page-actions>…</nk-page-actions>
2526
2533
  // <p class="lead">…</p>
@@ -2532,9 +2539,10 @@ var NotionKitElements = (function (exports) {
2532
2539
  // The host is display:contents, so .nk-page-scroll is the flex child of
2533
2540
  // .nk-main that scrolls. `narrow` drops the scroll wrapper for pages that are
2534
2541
  // the document itself (landing / docs skeleton). The page icon is rendered
2535
- // here because its ::slotted twin is keyed on the parent (.nk-page).
2542
+ // here because its ::slotted twin is keyed on the parent (.nk-page). `full` and
2543
+ // `small` are Notion's page options – full width, 14px text – set on the page.
2536
2544
  class NkPage extends NkElement {
2537
- static get observedAttributes() { return ['icon', 'cover', 'narrow']; }
2545
+ static get observedAttributes() { return ['icon', 'cover', 'narrow', 'full', 'small']; }
2538
2546
 
2539
2547
  render() {
2540
2548
  this._page = this.createElement('div', ['nk-page']);
@@ -2571,6 +2579,8 @@ var NotionKitElements = (function (exports) {
2571
2579
  // (attribute or a slotted nk-page-cover) the icon sits in the padding.
2572
2580
  const slotted = this._coverSlot.assignedNodes().some(n => n.nodeType === Node.ELEMENT_NODE || n.data.trim());
2573
2581
  this._page.classList.toggle('covered', this.getBoolAttr('cover') || slotted);
2582
+ this._page.classList.toggle('full', this.getBoolAttr('full'));
2583
+ this._page.classList.toggle('small', this.getBoolAttr('small'));
2574
2584
  }
2575
2585
 
2576
2586
  setupEvents() {
@@ -2592,17 +2602,25 @@ var NotionKitElements = (function (exports) {
2592
2602
  set icon(v) { v == null ? this.removeAttribute('icon') : this.setAttribute('icon', v); }
2593
2603
  get cover() { return this.getBoolAttr('cover'); }
2594
2604
  set cover(v) { this.setBoolAttr('cover', v); }
2605
+ get full() { return this.getBoolAttr('full'); }
2606
+ set full(v) { this.setBoolAttr('full', v); }
2607
+ get small() { return this.getBoolAttr('small'); }
2608
+ set small(v) { this.setBoolAttr('small', v); }
2595
2609
  }
2596
2610
 
2597
2611
  customElements.define('nk-page', NkPage);
2598
2612
 
2599
2613
  // <nk-page-cover slot="cover"></nk-page-cover> → the token gradient
2600
- // <nk-page-cover slot="cover" src="cover.jpg"></nk-page-cover> → an image
2614
+ // <nk-page-cover slot="cover" src="cover.jpg" position="center 30%"></nk-page-cover> → a picture
2615
+ // → <div class="nk-cover"><img src="cover.jpg" alt=""></div>: the picture fills
2616
+ // the band, cropped rather than stretched; `position` moves the crop, as
2617
+ // Notion's "Reposition" does. The gradient stays underneath while it loads.
2601
2618
  class NkPageCover extends NkElement {
2602
- static get observedAttributes() { return ['src']; }
2619
+ static get observedAttributes() { return ['src', 'position']; }
2603
2620
 
2604
2621
  render() {
2605
2622
  this._cover = this.createElement('div', ['nk-cover']);
2623
+ this._img = this.createElement('img', [], { alt: '' });
2606
2624
  this._wrapper.appendChild(this._cover);
2607
2625
  this._sync();
2608
2626
  }
@@ -2610,14 +2628,10 @@ var NotionKitElements = (function (exports) {
2610
2628
  _sync() {
2611
2629
  const src = this.getAttribute('src');
2612
2630
  if (src) {
2613
- this._cover.style.backgroundImage = `url("${src}")`;
2614
- this._cover.style.backgroundSize = 'cover';
2615
- this._cover.style.backgroundPosition = 'center';
2616
- } else {
2617
- this._cover.style.backgroundImage = '';
2618
- this._cover.style.backgroundSize = '';
2619
- this._cover.style.backgroundPosition = '';
2620
- }
2631
+ this._img.src = src;
2632
+ this._img.style.objectPosition = this.getAttribute('position') || '';
2633
+ if (!this._img.isConnected) this._cover.appendChild(this._img);
2634
+ } else this._img.remove();
2621
2635
  }
2622
2636
 
2623
2637
  onAttributeChanged() { this._sync(); }
@@ -2998,6 +3012,9 @@ var NotionKitElements = (function (exports) {
2998
3012
  // → <div class="nk-segmented">…</div> with .active on the chosen button.
2999
3013
  // The buttons stay in the light DOM (their look comes from the ::slotted
3000
3014
  // twins); the element sets type/role, moves .active and submits the value.
3015
+ // With `scroll` the chosen option is kept in view – after the first layout,
3016
+ // on every change and when the row's width changes – by scrolling the row
3017
+ // alone, never the page, by a relative distance, so right-to-left works too.
3001
3018
  const KEYS = { ArrowRight: 1, ArrowDown: 1, ArrowLeft: -1, ArrowUp: -1 };
3002
3019
 
3003
3020
  class NkSegmented extends NkFormElement {
@@ -3041,6 +3058,19 @@ var NotionKitElements = (function (exports) {
3041
3058
  }
3042
3059
  this._value = value;
3043
3060
  this.setFormValue(value);
3061
+ this._reveal(this._revealed ? 'smooth' : 'instant');
3062
+ }
3063
+
3064
+ /** Scrolls the row the least distance that shows the chosen button whole. */
3065
+ _reveal(behavior) {
3066
+ if (!this.getBoolAttr('scroll') || !this._box?.clientWidth) return;
3067
+ const btn = this.buttons.find(b => b.classList.contains('active'));
3068
+ if (!btn) return;
3069
+ const row = this._box.getBoundingClientRect(), r = btn.getBoundingClientRect(), pad = 8;
3070
+ const delta = r.left < row.left ? r.left - row.left - pad : r.right > row.right ? r.right - row.right + pad : 0;
3071
+ const smooth = behavior === 'smooth' && !matchMedia('(prefers-reduced-motion: reduce)').matches;
3072
+ if (delta) this._box.scrollBy({ left: delta, behavior: smooth ? 'smooth' : 'instant' });
3073
+ this._revealed = true;
3044
3074
  }
3045
3075
 
3046
3076
  setupEvents() {
@@ -3064,6 +3094,8 @@ var NotionKitElements = (function (exports) {
3064
3094
  this._slot.addEventListener('slotchange', this._onSlot);
3065
3095
  this.addEventListener('click', this._onClick);
3066
3096
  this.addEventListener('keydown', this._onKey);
3097
+ this._resize = new ResizeObserver(() => this._reveal('instant'));
3098
+ this._resize.observe(this._box);
3067
3099
  this._sync();
3068
3100
  }
3069
3101
 
@@ -3071,6 +3103,7 @@ var NotionKitElements = (function (exports) {
3071
3103
  this._slot?.removeEventListener('slotchange', this._onSlot);
3072
3104
  this.removeEventListener('click', this._onClick);
3073
3105
  this.removeEventListener('keydown', this._onKey);
3106
+ this._resize?.disconnect();
3074
3107
  }
3075
3108
 
3076
3109
  _choose(value) {
@@ -3182,6 +3215,76 @@ var NotionKitElements = (function (exports) {
3182
3215
 
3183
3216
  customElements.define('nk-avatar-group', NkAvatarGroup);
3184
3217
 
3218
+ // Shared by every element that draws an avatar: nk-avatar itself, member
3219
+ // rows, comments and the person cells of a database view.
3220
+ const AVATAR_COLORS = ['gray', 'brown', 'orange', 'yellow', 'green', 'blue', 'purple', 'pink', 'red'];
3221
+
3222
+ /**
3223
+ * Paints an .nk-avatar. One of Notion's nine colour names becomes its class,
3224
+ * so the tokens decide the shade in each theme; any other value – a hex, a
3225
+ * gradient, a var() – is taken as an inline background, as before 1.6.0.
3226
+ * Without a colour the avatar keeps the stylesheet's gradient.
3227
+ */
3228
+ function paintAvatar(el, color) {
3229
+ for (const c of AVATAR_COLORS) el.classList.toggle(c, c === color);
3230
+ el.style.background = color && !AVATAR_COLORS.includes(color) ? color : '';
3231
+ }
3232
+
3233
+ /** "Sara Lindt" → "SL". */
3234
+ const initialsOf = name => String(name || '').split(/\s+/).map(w => w[0]).filter(Boolean).join('').slice(0, 2).toUpperCase();
3235
+
3236
+ // <nk-avatar>MK</nk-avatar> → <span class="nk-avatar">MK</span>
3237
+ // <nk-avatar size="small" color="green">SL</nk-avatar>
3238
+ // <nk-avatar name="Ada Lovelace" size="large"></nk-avatar> → initials "AL"
3239
+ // <nk-avatar src="ada.jpg" name="Ada Lovelace" size="xlarge"></nk-avatar>
3240
+ // <nk-avatar square>A</nk-avatar> → a workspace icon
3241
+ // size: small (20px) · default 24px · large (32px) · xlarge (56px). color: one
3242
+ // of Notion's nine names, or any CSS background. Without content the initials
3243
+ // come from `name`; with `src` a photo fills the circle and `name` is its alt.
3244
+ class NkAvatar extends NkElement {
3245
+ static get observedAttributes() { return ['size', 'color', 'square', 'src', 'name']; }
3246
+
3247
+ render() {
3248
+ this._box = this.createElement('span', ['nk-avatar']);
3249
+ this._slot = document.createElement('slot');
3250
+ this._initials = document.createTextNode('');
3251
+ this._slot.appendChild(this._initials);
3252
+ this._img = this.createElement('img', [], { alt: '' });
3253
+ this._box.appendChild(this._slot);
3254
+ this._wrapper.appendChild(this._box);
3255
+ this._sync();
3256
+ }
3257
+
3258
+ _sync() {
3259
+ const size = this.getAttribute('size');
3260
+ for (const s of ['small', 'large', 'xlarge']) this._box.classList.toggle(s, s === size);
3261
+ this._box.classList.toggle('square', this.getBoolAttr('square'));
3262
+ paintAvatar(this._box, this.getAttribute('color'));
3263
+ const name = this.getAttribute('name');
3264
+ this._initials.data = initialsOf(name);
3265
+ const src = this.getAttribute('src');
3266
+ if (src) {
3267
+ this._img.src = src;
3268
+ this._img.alt = name || '';
3269
+ if (this._slot.isConnected) this._slot.replaceWith(this._img);
3270
+ } else if (this._img.isConnected) this._img.replaceWith(this._slot);
3271
+ // A picture or initials with a name speak for themselves; a bare glyph is decoration.
3272
+ if (name && !src) { this._box.setAttribute('role', 'img'); this._box.setAttribute('aria-label', name); }
3273
+ else { this._box.removeAttribute('role'); this._box.removeAttribute('aria-label'); }
3274
+ }
3275
+
3276
+ onAttributeChanged() { this._sync(); }
3277
+
3278
+ get size() { return this.getAttribute('size'); }
3279
+ set size(v) { v == null ? this.removeAttribute('size') : this.setAttribute('size', v); }
3280
+ get color() { return this.getAttribute('color'); }
3281
+ set color(v) { v == null ? this.removeAttribute('color') : this.setAttribute('color', v); }
3282
+ get src() { return this.getAttribute('src'); }
3283
+ set src(v) { v == null ? this.removeAttribute('src') : this.setAttribute('src', v); }
3284
+ }
3285
+
3286
+ customElements.define('nk-avatar', NkAvatar);
3287
+
3185
3288
  // <nk-mention type="person"><span slot="avatar" class="mini-avatar" style="background:#448361">SL</span>Sara Lindt</nk-mention>
3186
3289
  // <nk-mention type="page">📄 Onboarding</nk-mention> <nk-mention type="date">📅 May 20</nk-mention>
3187
3290
  // → <span class="nk-mention person">…</span>
@@ -3423,16 +3526,18 @@ var NotionKitElements = (function (exports) {
3423
3526
 
3424
3527
  customElements.define('nk-member-list', NkMemberList);
3425
3528
 
3426
- // <nk-member-row name="Sara Lindt" mail="sara@…" avatar="SL" color="#448361">
3529
+ // <nk-member-row name="Sara Lindt" mail="sara@…" avatar="SL" color="green">
3427
3530
  // <nk-select slot="role" compact>…</nk-select>
3428
3531
  // </nk-member-row>
3429
- // → <div class="nk-member-row"><span class="mini-avatar">SL</span><div>Sara Lindt<div class="m-mail">…</div></div><select …></div>
3532
+ // → <div class="nk-member-row"><span class="nk-avatar green">SL</span><div>Sara Lindt<div class="m-mail">…</div></div><select …></div>
3533
+ // color: one of Notion's nine names, or any CSS background; without it the
3534
+ // avatar gradient. The row sizes the avatar to 28px.
3430
3535
  class NkMemberRow extends NkElement {
3431
3536
  static get observedAttributes() { return ['name', 'mail', 'avatar', 'color', 'last']; }
3432
3537
 
3433
3538
  render() {
3434
3539
  this._row = this.createElement('div', ['nk-member-row']);
3435
- this._avatar = this.createElement('span', ['mini-avatar']);
3540
+ this._avatar = this.createElement('span', ['nk-avatar']);
3436
3541
  const avatarSlot = this.createElement('slot', [], { name: 'avatar' });
3437
3542
  avatarSlot.appendChild(this._avatar);
3438
3543
  const text = document.createElement('div');
@@ -3456,8 +3561,8 @@ var NotionKitElements = (function (exports) {
3456
3561
  this._mail.textContent = mail || '';
3457
3562
  this._mail.style.display = mail ? '' : 'none';
3458
3563
  const avatar = this.getAttribute('avatar');
3459
- this._avatar.textContent = avatar || (this.getAttribute('name') || '').split(/\s+/).map(w => w[0]).join('').slice(0, 2).toUpperCase();
3460
- this._avatar.style.background = this.getAttribute('color') || 'var(--nk-text-tertiary)';
3564
+ this._avatar.textContent = avatar || initialsOf(this.getAttribute('name'));
3565
+ paintAvatar(this._avatar, this.getAttribute('color'));
3461
3566
  this._row.classList.toggle('last', this.getBoolAttr('last'));
3462
3567
  }
3463
3568
 
@@ -3466,9 +3571,148 @@ var NotionKitElements = (function (exports) {
3466
3571
 
3467
3572
  customElements.define('nk-member-row', NkMemberRow);
3468
3573
 
3469
- // Overlay plumbing shared by nk-modal and nk-cmdk: body scroll lock with a
3470
- // refcount, and `inert` on everything outside the overlay so focus and
3471
- // assistive technology stay inside – nested shadow roots included.
3574
+ // <nk-props>
3575
+ // <nk-prop label="Status" icon="◉"><nk-tag color="blue">In progress</nk-tag></nk-prop>
3576
+ // <nk-prop label="Owner" icon="👤"><nk-avatar size="small">MK</nk-avatar>Marcel Karas</nk-prop>
3577
+ // </nk-props>
3578
+ // → <dl class="nk-props">…</dl> – the properties under a page title. The rows
3579
+ // are <nk-prop> hosts with display: contents, so each .nk-prop is a row of
3580
+ // this list.
3581
+ class NkProps extends NkElement {
3582
+ render() {
3583
+ const list = this.createElement('dl', ['nk-props']);
3584
+ list.appendChild(document.createElement('slot'));
3585
+ this._wrapper.appendChild(list);
3586
+ }
3587
+ }
3588
+
3589
+ customElements.define('nk-props', NkProps);
3590
+
3591
+ // <nk-prop label="Due" icon="📅">2 June 2026</nk-prop>
3592
+ // → <div class="nk-prop"><dt class="p-name"><span class="p-icon">📅</span>Due</dt><dd class="p-value">2 June 2026</dd></div>
3593
+ // The value is the element's content – tags, an avatar and a name, a date, a
3594
+ // <nk-progress wide>. slot="icon" replaces the icon glyph. A click on the
3595
+ // name or the value fires nk-action { action: 'name' | 'value', label }, the
3596
+ // moment Notion opens the property's editor.
3597
+ class NkProp extends NkElement {
3598
+ static get observedAttributes() { return ['label', 'icon']; }
3599
+
3600
+ render() {
3601
+ this._row = this.createElement('div', ['nk-prop']);
3602
+ this._name = this.createElement('dt', ['p-name']);
3603
+ this._icon = this.createElement('span', ['p-icon']);
3604
+ const iconSlot = this.createElement('slot', [], { name: 'icon' });
3605
+ iconSlot.appendChild(this._icon);
3606
+ this._label = document.createTextNode('');
3607
+ this._name.append(iconSlot, this._label);
3608
+ this._value = this.createElement('dd', ['p-value']);
3609
+ this._value.appendChild(document.createElement('slot'));
3610
+ this._row.append(this._name, this._value);
3611
+ this._wrapper.appendChild(this._row);
3612
+ this._sync();
3613
+ }
3614
+
3615
+ _sync() {
3616
+ const icon = this.getAttribute('icon');
3617
+ this._icon.textContent = icon || '';
3618
+ this._icon.style.display = icon ? '' : 'none';
3619
+ this._label.data = this.getAttribute('label') || '';
3620
+ }
3621
+
3622
+ setupEvents() {
3623
+ this._onClick = (e) => {
3624
+ const part = e.composedPath().includes(this._name) ? 'name' : 'value';
3625
+ this.emit('nk-action', { action: part, label: this.label });
3626
+ };
3627
+ this._row.addEventListener('click', this._onClick);
3628
+ }
3629
+
3630
+ teardownEvents() { this._row?.removeEventListener('click', this._onClick); }
3631
+ onAttributeChanged() { this._sync(); }
3632
+
3633
+ get label() { return this.getAttribute('label') || ''; }
3634
+ set label(v) { this.setAttribute('label', v); }
3635
+ get icon() { return this.getAttribute('icon'); }
3636
+ set icon(v) { v == null ? this.removeAttribute('icon') : this.setAttribute('icon', v); }
3637
+ }
3638
+
3639
+ customElements.define('nk-prop', NkProp);
3640
+
3641
+ // <nk-panels><nk-panel …></nk-panel><nk-panel …></nk-panel></nk-panels>
3642
+ // → <div class="nk-panels">…</div>: columns of at least 200px that share the
3643
+ // row and fall to one on a phone. The <nk-panel> hosts are display: contents,
3644
+ // so each .nk-panel is a cell of this grid.
3645
+ class NkPanels extends NkElement {
3646
+ render() {
3647
+ const grid = this.createElement('div', ['nk-panels']);
3648
+ grid.appendChild(document.createElement('slot'));
3649
+ this._wrapper.appendChild(grid);
3650
+ }
3651
+ }
3652
+
3653
+ customElements.define('nk-panels', NkPanels);
3654
+
3655
+ // <nk-panel title="Weekly review"><p>Three pages changed.</p></nk-panel>
3656
+ // <nk-panel href="/roadmap" cover="covers/aurora.svg" icon="🚀" title="Roadmap"><p>2 min ago</p></nk-panel>
3657
+ // → <a class="nk-panel" href="/roadmap"><div class="nk-cover"><img src="…" alt=""></div>
3658
+ // <div class="nk-page-icon">🚀</div><h3>Roadmap</h3>…</a>
3659
+ // `cover` without a value draws the token gradient, with one a picture; `icon`
3660
+ // overlaps the cover as on a page – a page tile, as on Notion's Home. With
3661
+ // `href` the panel is a link. `title` is the heading, never a tooltip.
3662
+ class NkPanel extends NkElement {
3663
+ static get observedAttributes() { return ['title', 'icon', 'cover', 'href', 'target']; }
3664
+
3665
+ render() {
3666
+ this._cover = this.createElement('div', ['nk-cover']);
3667
+ this._img = this.createElement('img', [], { alt: '' });
3668
+ this._icon = this.createElement('div', ['nk-page-icon']);
3669
+ this._heading = document.createElement('h3');
3670
+ this._slot = document.createElement('slot');
3671
+ this.takeTitle();
3672
+ this._build();
3673
+ }
3674
+
3675
+ _build() {
3676
+ const href = this.getAttribute('href');
3677
+ const box = this.createElement(href ? 'a' : 'div', ['nk-panel']);
3678
+ box.append(this._cover, this._icon, this._heading, this._slot);
3679
+ this._wrapper.replaceChildren(box);
3680
+ this._box = box;
3681
+ this._sync();
3682
+ }
3683
+
3684
+ _sync() {
3685
+ const href = this.getAttribute('href');
3686
+ if (href) { this._box.setAttribute('href', href); this._box.target = this.getAttribute('target') || ''; }
3687
+ const cover = this.getAttribute('cover');
3688
+ this._cover.style.display = cover === null ? 'none' : '';
3689
+ if (cover) { this._img.src = cover; if (!this._img.isConnected) this._cover.appendChild(this._img); }
3690
+ else this._img.remove();
3691
+ const icon = this.getAttribute('icon');
3692
+ this._icon.textContent = icon || '';
3693
+ this._icon.style.display = icon ? '' : 'none';
3694
+ this._heading.textContent = this._titleText || '';
3695
+ this._heading.style.display = this._titleText ? '' : 'none';
3696
+ }
3697
+
3698
+ onAttributeChanged(name, _old, value) {
3699
+ if (name === 'title' && !this.takeTitle(value)) return;
3700
+ if (name === 'href' && (value === null) !== (this._box.localName === 'div')) { this._build(); return; }
3701
+ this._sync();
3702
+ }
3703
+
3704
+ get title() { return this._titleText ?? ''; }
3705
+ set title(v) { this._titleText = v == null ? '' : String(v); if (this._initialized) this._sync(); }
3706
+ get href() { return this.getAttribute('href'); }
3707
+ set href(v) { v == null ? this.removeAttribute('href') : this.setAttribute('href', v); }
3708
+ }
3709
+
3710
+ customElements.define('nk-panel', NkPanel);
3711
+
3712
+ // Overlay plumbing shared by nk-modal, nk-sheet, nk-cmdk and nk-menu: body
3713
+ // scroll lock with a refcount, `inert` on everything outside the overlay so
3714
+ // focus and assistive technology stay inside – nested shadow roots included –
3715
+ // and the focused element behind shadow hosts, to return focus to.
3472
3716
  let locks = 0, previousOverflow = '';
3473
3717
 
3474
3718
  function lockScroll() {
@@ -3499,6 +3743,13 @@ var NotionKitElements = (function (exports) {
3499
3743
  return () => { for (const c of made) c.inert = false; };
3500
3744
  }
3501
3745
 
3746
+ /** The focused element itself, looking into shadow roots (document.activeElement stops at the host). */
3747
+ function deepActiveElement() {
3748
+ let el = document.activeElement;
3749
+ while (el?.shadowRoot?.activeElement) el = el.shadowRoot.activeElement;
3750
+ return el;
3751
+ }
3752
+
3502
3753
  /** The first tabbable element inside a light-DOM subtree, looking into shadow roots. */
3503
3754
  function firstFocusable(root) {
3504
3755
  const SEL = 'a[href], button:not([disabled]), input:not([disabled]):not([type=hidden]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"]), [contenteditable="true"], [contenteditable="plaintext-only"]';
@@ -3512,6 +3763,155 @@ var NotionKitElements = (function (exports) {
3512
3763
  return walk(root);
3513
3764
  }
3514
3765
 
3766
+ // <nk-sheet id="more" title="More">
3767
+ // <nk-tree manual>
3768
+ // <nk-section-label>Favourites</nk-section-label>
3769
+ // <nk-tree-item icon="🚀">NotionKit MVP</nk-tree-item>
3770
+ // </nk-tree>
3771
+ // </nk-sheet>
3772
+ // → <div class="nk-sheet-backdrop open"><div class="nk-sheet" role="dialog">
3773
+ // <div class="sh-grabber"></div><div class="sh-title">More</div>…</div></div>
3774
+ //
3775
+ // A bottom sheet (NotionKit 1.7.0) with nk-modal's contract: show(), close()
3776
+ // and toggle(), Escape and the backdrop close it, focus moves in and back
3777
+ // out, the page behind is scroll-locked and inert. It lies above the tab
3778
+ // bar; rows inside are 40px high. `title` is the heading shown under the
3779
+ // grabber and the dialog's name, never a tooltip – see NkElement.takeTitle().
3780
+ // Choosing a row does not close the sheet – the app decides (nk-select
3781
+ // bubbles out). Put the element directly under <body>: a transformed
3782
+ // ancestor would trap the fixed backdrop.
3783
+ class NkSheet extends NkElement {
3784
+ static get observedAttributes() { return ['open', 'title']; }
3785
+
3786
+ render() {
3787
+ this.takeTitle();
3788
+ this._backdrop = this.createElement('div', ['nk-sheet-backdrop']);
3789
+ this._backdrop.inert = true;
3790
+ this._box = this.createElement('div', ['nk-sheet'], { role: 'dialog', 'aria-modal': 'true', tabindex: '-1' });
3791
+ this._heading = this.createElement('div', ['sh-title'], { id: 'title' });
3792
+ this._box.append(this.createElement('div', ['sh-grabber']), this._heading, document.createElement('slot'));
3793
+ this._backdrop.appendChild(this._box);
3794
+ this._wrapper.appendChild(this._backdrop);
3795
+ this._syncTitle();
3796
+ this._syncOpen();
3797
+ }
3798
+
3799
+ _syncTitle() {
3800
+ const text = this._titleText || '';
3801
+ this._heading.textContent = text;
3802
+ this._heading.hidden = !text;
3803
+ if (text) this._box.setAttribute('aria-labelledby', 'title');
3804
+ else this._box.removeAttribute('aria-labelledby');
3805
+ }
3806
+
3807
+ _syncOpen() {
3808
+ const open = this.getBoolAttr('open');
3809
+ this._backdrop.classList.toggle('open', open);
3810
+ this._backdrop.inert = !open;
3811
+ if (open === this._wasOpen) return;
3812
+ this._wasOpen = open;
3813
+ if (open) {
3814
+ this._returnFocus = deepActiveElement();
3815
+ lockScroll();
3816
+ this._undoInert = inertOutside(this);
3817
+ requestAnimationFrame(() => (firstFocusable(this) || this._box).focus({ preventScroll: true }));
3818
+ } else {
3819
+ unlockScroll();
3820
+ this._undoInert?.(); this._undoInert = null;
3821
+ const back = this._returnFocus;
3822
+ if (back && typeof back.focus === 'function' && back.isConnected) back.focus({ preventScroll: true });
3823
+ this._returnFocus = null;
3824
+ }
3825
+ }
3826
+
3827
+ setupEvents() {
3828
+ this._onBackdrop = (e) => { if (e.target === this._backdrop) this.close(); };
3829
+ this._onKey = (e) => { if (e.key === 'Escape' && this.getBoolAttr('open')) { e.stopPropagation(); this.close(); } };
3830
+ this._backdrop.addEventListener('click', this._onBackdrop);
3831
+ document.addEventListener('keydown', this._onKey);
3832
+ }
3833
+
3834
+ teardownEvents() {
3835
+ this._backdrop?.removeEventListener('click', this._onBackdrop);
3836
+ document.removeEventListener('keydown', this._onKey);
3837
+ if (this._wasOpen) { unlockScroll(); this._undoInert?.(); this._undoInert = null; this._wasOpen = false; }
3838
+ }
3839
+
3840
+ onAttributeChanged(name, oldValue, value) {
3841
+ if (name === 'title') { if (this.takeTitle(value)) this._syncTitle(); return; }
3842
+ this._syncOpen();
3843
+ this.emit('nk-toggle', { open: this.getBoolAttr('open') });
3844
+ }
3845
+
3846
+ show() { this.setBoolAttr('open', true); }
3847
+ close() { this.setBoolAttr('open', false); }
3848
+ toggle() { this.setBoolAttr('open', !this.getBoolAttr('open')); }
3849
+
3850
+ get open() { return this.getBoolAttr('open'); }
3851
+ set open(v) { this.setBoolAttr('open', v); }
3852
+ get title() { return this._titleText ?? ''; }
3853
+ set title(v) { this._titleText = v == null ? '' : String(v); if (this._initialized) this._syncTitle(); }
3854
+ }
3855
+
3856
+ customElements.define('nk-sheet', NkSheet);
3857
+
3858
+ // <nk-steps label="Connect your own model" current="2"
3859
+ // steps="Choose a provider, Enter the API key, Test the connection"></nk-steps>
3860
+ // steps.steps = [{ label: 'Choose a provider', desc: 'Anthropic' }, 'Enter the API key', …];
3861
+ // → <ol class="nk-steps" aria-label="…">
3862
+ // <li class="nk-step done"><span class="st-mark">✓</span><span>Choose a provider<span class="st-desc">Anthropic</span></span></li>
3863
+ // <li class="nk-step current" aria-current="step"><span class="st-mark">2</span><span>Enter the API key</span></li>
3864
+ // <li class="nk-step"><span class="st-mark">3</span><span>Test the connection</span></li></ol>
3865
+ // A setup in a few steps (NotionKit 1.7.0). `current` counts from 1; the
3866
+ // steps before it are done, one past the last marks all of them done. The
3867
+ // `steps` attribute is a comma-separated list; the property also takes
3868
+ // { label, desc } objects for a line under the label.
3869
+ class NkSteps extends NkElement {
3870
+ static get observedAttributes() { return ['steps', 'current', 'label']; }
3871
+
3872
+ render() {
3873
+ this._list = this.createElement('ol', ['nk-steps']);
3874
+ this._wrapper.appendChild(this._list);
3875
+ this._sync();
3876
+ }
3877
+
3878
+ _items() {
3879
+ if (this._steps) return this._steps;
3880
+ return (this.getAttribute('steps') || '').split(',').map(s => s.trim()).filter(Boolean);
3881
+ }
3882
+
3883
+ _sync() {
3884
+ const label = this.getAttribute('label');
3885
+ if (label) this._list.setAttribute('aria-label', label); else this._list.removeAttribute('aria-label');
3886
+ const current = this.current;
3887
+ this._list.replaceChildren(...this._items().map((step, i) => {
3888
+ const n = i + 1, { label: text, desc } = typeof step === 'object' && step ? step : { label: String(step) };
3889
+ const li = this.createElement('li', ['nk-step']);
3890
+ li.classList.toggle('done', n < current);
3891
+ li.classList.toggle('current', n === current);
3892
+ if (n === current) li.setAttribute('aria-current', 'step');
3893
+ const mark = this.createElement('span', ['st-mark'], { 'aria-hidden': 'true' });
3894
+ mark.textContent = n < current ? '✓' : String(n);
3895
+ const body = document.createElement('span');
3896
+ body.textContent = text ?? '';
3897
+ if (desc) { const d = this.createElement('span', ['st-desc']); d.textContent = desc; body.appendChild(d); }
3898
+ li.append(mark, body);
3899
+ return li;
3900
+ }));
3901
+ }
3902
+
3903
+ onAttributeChanged() { this._sync(); }
3904
+
3905
+ get steps() { return this._items(); }
3906
+ set steps(v) { this._steps = Array.isArray(v) ? v : null; if (this._list) this._sync(); }
3907
+ get current() { const n = parseInt(this.getAttribute('current'), 10); return Number.isFinite(n) ? n : 1; }
3908
+ set current(v) { this.setAttribute('current', String(v)); }
3909
+ /** Moves on to the next step; returns the new current step. */
3910
+ next() { this.current = Math.min(this.current + 1, this._items().length + 1); return this.current; }
3911
+ }
3912
+
3913
+ customElements.define('nk-steps', NkSteps);
3914
+
3515
3915
  // <nk-modal id="settings">
3516
3916
  // <nk-settings-user slot="user" name="…" mail="…"></nk-settings-user>
3517
3917
  // <nk-settings-pane name="profile" group="Account" icon="👤" label="My profile" title="My profile" active>…</nk-settings-pane>
@@ -3974,13 +4374,79 @@ var NotionKitElements = (function (exports) {
3974
4374
  // </nk-menu>
3975
4375
  // → <div class="nk-pop nk-menu" role="menu">…</div>
3976
4376
  // ↑↓ move between items, Enter selects, nk-select bubbles from the item.
4377
+ //
4378
+ // <nk-menu floating sheet> is a menu over the page (NotionKit 1.7.0): it
4379
+ // fades in like the palette when `open` is set and is a bottom sheet on a
4380
+ // phone. The host becomes the fixed box you position – show(anchor) puts it
4381
+ // under the anchor, right edges aligned (align="start": left edges). A tap
4382
+ // outside closes it and reaches nothing else; Escape and a chosen item
4383
+ // close it too, a switch row does not. Opened from the keyboard, focus moves
4384
+ // to the first item; closing returns it to where it was.
4385
+ const floatSheet = new CSSStyleSheet();
4386
+ floatSheet.replaceSync(`:host([floating]) { display: block; position: fixed; z-index: 60; pointer-events: none; }`);
4387
+
4388
+ /** The border box of an element, or of the first descendant with one (display: contents hosts). */
4389
+ function boxOf(el) {
4390
+ if (el.getClientRects().length) return el.getBoundingClientRect();
4391
+ for (const child of [...(el.shadowRoot?.children ?? []), ...el.children]) {
4392
+ const r = boxOf(child);
4393
+ if (r.width || r.height) return r;
4394
+ }
4395
+ return el.getBoundingClientRect();
4396
+ }
4397
+
3977
4398
  class NkMenu extends NkElement {
4399
+ static get hostStyles() { return floatSheet; }
4400
+ static get observedAttributes() { return ['floating', 'sheet', 'open', 'align']; }
4401
+
3978
4402
  render() {
3979
4403
  this._box = this.createElement('div', ['nk-pop', 'nk-menu'], { role: 'menu' });
3980
4404
  this._box.appendChild(document.createElement('slot'));
3981
4405
  this._wrapper.appendChild(this._box);
4406
+ this._syncMode();
4407
+ }
4408
+
4409
+ _syncMode() {
4410
+ this._box.classList.toggle('floating', this.getBoolAttr('floating'));
4411
+ this._box.classList.toggle('sheet', this.getBoolAttr('sheet'));
4412
+ this._box.classList.toggle('open', this.getBoolAttr('open'));
4413
+ }
4414
+
4415
+ onAttributeChanged(name) {
4416
+ this._syncMode();
4417
+ if (name !== 'open') return;
4418
+ const open = this.getBoolAttr('open');
4419
+ // aria-expanded belongs on the control itself, inside a host such as <nk-btn>.
4420
+ if (this._anchor) (this._anchor.shadowRoot?.querySelector('button, a[href]') ?? this._anchor).setAttribute('aria-expanded', String(open));
4421
+ if (open) {
4422
+ this._returnFocus = deepActiveElement();
4423
+ if (this._returnFocus?.matches(':focus-visible')) requestAnimationFrame(() => this.focusFirst());
4424
+ document.addEventListener('click', this._onOutside, true);
4425
+ } else {
4426
+ document.removeEventListener('click', this._onOutside, true);
4427
+ const back = this._returnFocus;
4428
+ this._returnFocus = null;
4429
+ if (back?.isConnected && this.contains(document.activeElement)) back.focus({ preventScroll: true });
4430
+ }
4431
+ this.emit('nk-toggle', { open });
3982
4432
  }
3983
4433
 
4434
+ /** Opens under `anchor` (any element, display: contents hosts included). */
4435
+ show(anchor) {
4436
+ if (anchor) {
4437
+ this._anchor = anchor;
4438
+ const r = boxOf(anchor);
4439
+ this.style.top = `${r.bottom + 6}px`;
4440
+ if (this.getAttribute('align') === 'start') { this.style.left = `${r.left}px`; this.style.right = ''; }
4441
+ else { this.style.right = `${Math.max(8, innerWidth - r.right)}px`; this.style.left = ''; }
4442
+ }
4443
+ this.setBoolAttr('open', true);
4444
+ }
4445
+ close() { this.setBoolAttr('open', false); }
4446
+ toggle(anchor) { this.getBoolAttr('open') ? this.close() : this.show(anchor); }
4447
+ get open() { return this.getBoolAttr('open'); }
4448
+ set open(v) { this.setBoolAttr('open', v); }
4449
+
3984
4450
  get items() { return [...this.querySelectorAll(':scope > nk-menu-item')].filter(i => i.selectable); }
3985
4451
 
3986
4452
  setupEvents() {
@@ -3998,9 +4464,27 @@ var NotionKitElements = (function (exports) {
3998
4464
  }
3999
4465
  };
4000
4466
  this.addEventListener('keydown', this._onKey);
4467
+ // Floating: outside taps close and go nowhere else; Escape and a chosen item close.
4468
+ this._onOutside = (e) => {
4469
+ const path = e.composedPath();
4470
+ if (path.includes(this) || (this._anchor && path.includes(this._anchor))) return;
4471
+ e.preventDefault(); e.stopPropagation();
4472
+ this.close();
4473
+ };
4474
+ // Captured, so a menu inside a modal or sheet closes before they do.
4475
+ this._onEscape = (e) => { if (e.key === 'Escape' && this.getBoolAttr('floating') && this.getBoolAttr('open')) { e.stopPropagation(); this.close(); } };
4476
+ this._onSelect = () => { if (this.getBoolAttr('floating')) this.close(); };
4477
+ document.addEventListener('keydown', this._onEscape, true);
4478
+ this.addEventListener('nk-select', this._onSelect);
4479
+ if (this.getBoolAttr('open')) document.addEventListener('click', this._onOutside, true);
4001
4480
  }
4002
4481
 
4003
- teardownEvents() { this.removeEventListener('keydown', this._onKey); }
4482
+ teardownEvents() {
4483
+ this.removeEventListener('keydown', this._onKey);
4484
+ document.removeEventListener('keydown', this._onEscape, true);
4485
+ this.removeEventListener('nk-select', this._onSelect);
4486
+ document.removeEventListener('click', this._onOutside, true);
4487
+ }
4004
4488
 
4005
4489
  /** Focuses the first item (called by a popover when it opens). */
4006
4490
  focusFirst() { this.items[0]?.focus(); }
@@ -4011,9 +4495,15 @@ var NotionKitElements = (function (exports) {
4011
4495
  // <nk-menu-item icon="✏️" shortcut="⌘E" value="rename">Rename</nk-menu-item>
4012
4496
  // <nk-menu-item type="separator"></nk-menu-item> <nk-menu-item type="label">Danger</nk-menu-item>
4013
4497
  // <nk-menu-item icon="🗑️" danger value="delete">Delete</nk-menu-item>
4498
+ // <nk-menu-item type="switch" icon="🔡" value="small" checked>Small text</nk-menu-item>
4499
+ // <nk-menu-item type="check" icon="◉" value="open" checked>Status: Open</nk-menu-item>
4014
4500
  // → <div class="nk-menu-item danger"><span class="m-icon">🗑️</span>Delete<span class="m-shortcut">…</span></div>
4501
+ // A switch item carries a .nk-switch on the right, as "Small text" does in
4502
+ // Notion's page menu; a check item a ✓ where the shortcut stands, as in a
4503
+ // filter menu. A click on either flips `checked` and fires nk-change
4504
+ // { value, checked } instead of nk-select, so the menu around it stays open.
4015
4505
  class NkMenuItem extends NkElement {
4016
- static get observedAttributes() { return ['icon', 'shortcut', 'danger', 'value', 'type', 'disabled']; }
4506
+ static get observedAttributes() { return ['icon', 'shortcut', 'danger', 'value', 'type', 'disabled', 'checked']; }
4017
4507
 
4018
4508
  render() { this._build(); }
4019
4509
 
@@ -4026,12 +4516,16 @@ var NotionKitElements = (function (exports) {
4026
4516
  el = this.createElement('div', ['nk-menu-label']);
4027
4517
  el.appendChild(document.createElement('slot'));
4028
4518
  } else {
4029
- el = this.createElement('div', ['nk-menu-item'], { role: 'menuitem', tabindex: '-1' });
4519
+ const isSwitch = type === 'switch';
4520
+ this._check = type === 'check';
4521
+ el = this.createElement('div', ['nk-menu-item'], { role: isSwitch || this._check ? 'menuitemcheckbox' : 'menuitem', tabindex: '-1' });
4030
4522
  this._icon = this.createElement('span', ['m-icon']);
4031
4523
  const iconSlot = this.createElement('slot', [], { name: 'icon' });
4032
4524
  iconSlot.appendChild(this._icon);
4033
4525
  this._shortcut = this.createElement('span', ['m-shortcut']);
4034
4526
  el.append(iconSlot, document.createElement('slot'), this._shortcut);
4527
+ this._switch = isSwitch ? this.createElement('span', ['nk-switch'], { 'aria-hidden': 'true' }) : null;
4528
+ if (this._switch) el.appendChild(this._switch);
4035
4529
  }
4036
4530
  if (this._el) { this._el.removeEventListener('click', this._onClick); this._el.replaceWith(el); } else this._wrapper.appendChild(el);
4037
4531
  this._el = el;
@@ -4049,6 +4543,12 @@ var NotionKitElements = (function (exports) {
4049
4543
  this._shortcut.style.display = sc ? '' : 'none';
4050
4544
  this._el.classList.toggle('danger', this.getBoolAttr('danger'));
4051
4545
  this._el.setAttribute('aria-disabled', this.getBoolAttr('disabled') ? 'true' : 'false');
4546
+ if (this._switch || this._check) {
4547
+ const on = this.getBoolAttr('checked') ? 'true' : 'false';
4548
+ this._el.setAttribute('aria-checked', on);
4549
+ if (this._switch) this._switch.setAttribute('aria-checked', on);
4550
+ if (this._check) { this._shortcut.textContent = on === 'true' ? '✓' : ''; this._shortcut.style.display = ''; }
4551
+ }
4052
4552
  }
4053
4553
 
4054
4554
  setupEvents() {
@@ -4060,6 +4560,11 @@ var NotionKitElements = (function (exports) {
4060
4560
 
4061
4561
  select() {
4062
4562
  if (!this._el.classList.contains('nk-menu-item') || this.getBoolAttr('disabled')) return;
4563
+ if (this._switch || this._check) {
4564
+ this.checked = !this.checked;
4565
+ this.emit('nk-change', { value: this.value, checked: this.checked, item: this });
4566
+ return;
4567
+ }
4063
4568
  this.emit('nk-select', { value: this.value, label: this.textContent.trim(), item: this });
4064
4569
  }
4065
4570
 
@@ -4067,6 +4572,8 @@ var NotionKitElements = (function (exports) {
4067
4572
  focus(o) { this._el?.focus(o); }
4068
4573
  get selectable() { return this._el?.classList.contains('nk-menu-item') && !this.getBoolAttr('disabled'); }
4069
4574
 
4575
+ get checked() { return this.getBoolAttr('checked'); }
4576
+ set checked(v) { this.setBoolAttr('checked', v); }
4070
4577
  get value() { return this.getAttribute('value') ?? this.textContent.trim(); }
4071
4578
  set value(v) { this.setAttribute('value', v); }
4072
4579
  }
@@ -4341,16 +4848,24 @@ var NotionKitElements = (function (exports) {
4341
4848
  // </nk-database>
4342
4849
  // db.columns = [{ key: 'name', label: 'Name', type: 'text', icon: '📄', title: true }, { key: 'status', type: 'select', options: [...] }, …];
4343
4850
  // db.rows = [{ id: 1, icon: '🧭', name: '…', status: 'done', … }];
4344
- // → <div class="nk-database"><div class="nk-db-tabs">…</div>…active view…</div>
4851
+ // <nk-btn slot="tools" variant="tool">Filter</nk-btn> … sit right of the tabs,
4852
+ // <nk-filter-bar slot="filters"> under them (NotionKit 1.7.0's toolbar).
4853
+ // → <div class="nk-database"><div class="nk-db-toolbar"><div class="nk-db-tabs">…</div>
4854
+ // <div class="tools">…</div></div>…filters…active view…</div>
4345
4855
  // The tabs come from the child views; data is pushed into every view.
4346
4856
  class NkDatabase extends NkElement {
4347
4857
  static get observedAttributes() { return ['view', 'add-view']; }
4348
4858
 
4349
4859
  render() {
4350
4860
  this._box = this.createElement('div', ['nk-database']);
4861
+ this._toolbar = this.createElement('div', ['nk-db-toolbar']);
4351
4862
  this._tabs = this.createElement('div', ['nk-db-tabs'], { role: 'tablist' });
4863
+ const tools = this.createElement('div', ['tools']);
4864
+ this._toolsSlot = this.createElement('slot', [], { name: 'tools' });
4865
+ tools.appendChild(this._toolsSlot);
4866
+ this._toolbar.append(this._tabs, tools);
4352
4867
  this._slot = document.createElement('slot');
4353
- this._box.append(this._tabs, this._slot);
4868
+ this._box.append(this._toolbar, this.createElement('slot', [], { name: 'filters' }), this._slot);
4354
4869
  this._wrapper.appendChild(this._box);
4355
4870
  this._columns = []; this._rows = [];
4356
4871
  this._sync();
@@ -4378,12 +4893,11 @@ var NotionKitElements = (function (exports) {
4378
4893
  v.setData?.(this._columns, this._rows);
4379
4894
  }
4380
4895
  if (this.getBoolAttr('add-view')) {
4381
- const add = this.createElement('span', ['nk-db-tab'], { role: 'button', 'data-add': '', tabindex: '0' });
4382
- add.style.color = 'var(--nk-text-tertiary)';
4896
+ const add = this.createElement('span', ['nk-db-tab', 'add'], { role: 'button', 'data-add': '', tabindex: '0' });
4383
4897
  add.textContent = '+';
4384
4898
  this._tabs.appendChild(add);
4385
4899
  }
4386
- this._tabs.style.display = views.length ? '' : 'none';
4900
+ this._toolbar.hidden = !views.length && !this._toolsSlot.assignedElements().length;
4387
4901
  this._current = current;
4388
4902
  }
4389
4903
 
@@ -4405,6 +4919,7 @@ var NotionKitElements = (function (exports) {
4405
4919
  this._tabs.addEventListener('click', this._onClick);
4406
4920
  this._tabs.addEventListener('keydown', this._onKey);
4407
4921
  this._slot.addEventListener('slotchange', this._onSlot);
4922
+ this._toolsSlot.addEventListener('slotchange', this._onSlot);
4408
4923
  this._sync();
4409
4924
  }
4410
4925
 
@@ -4412,6 +4927,7 @@ var NotionKitElements = (function (exports) {
4412
4927
  this._tabs?.removeEventListener('click', this._onClick);
4413
4928
  this._tabs?.removeEventListener('keydown', this._onKey);
4414
4929
  this._slot?.removeEventListener('slotchange', this._onSlot);
4930
+ this._toolsSlot?.removeEventListener('slotchange', this._onSlot);
4415
4931
  }
4416
4932
 
4417
4933
  onAttributeChanged(name) {
@@ -4439,6 +4955,7 @@ var NotionKitElements = (function (exports) {
4439
4955
  //
4440
4956
  // column: { key, label, type, icon, options: [{ value, label, color }], title }
4441
4957
  // types: text | select | multi-select | date | person | checkbox | url | number | progress
4958
+
4442
4959
  const el = (tag, cls, text) => { const n = document.createElement(tag); if (cls) n.className = cls; if (text != null) n.textContent = text; return n; };
4443
4960
  const COLORS = ['gray', 'brown', 'orange', 'yellow', 'green', 'blue', 'purple', 'pink', 'red'];
4444
4961
 
@@ -4472,14 +4989,16 @@ var NotionKitElements = (function (exports) {
4472
4989
  case 'person': {
4473
4990
  const cell = el('span', 'person-cell');
4474
4991
  const p = typeof value === 'string' ? { name: value } : value;
4475
- const avatar = el('span', 'mini-avatar', p.initials || p.avatar || (p.name || '').split(/\s+/).map(w => w[0]).join('').slice(0, 2).toUpperCase());
4476
- avatar.style.background = p.color || 'var(--nk-text-tertiary)';
4992
+ // color: one of Notion's nine names, or any CSS background; none – the avatar gradient.
4993
+ const avatar = el('span', 'nk-avatar small', p.initials || p.avatar || initialsOf(p.name));
4994
+ paintAvatar(avatar, p.color);
4477
4995
  cell.append(avatar, document.createTextNode(' ' + (p.name || '')));
4478
4996
  return cell;
4479
4997
  }
4480
4998
  case 'checkbox': return checkbox(column, !!value, row);
4481
4999
  case 'url': { const a = el('a', null, String(value).replace(/^https?:\/\//, '')); a.href = String(value); a.target = '_blank'; a.rel = 'noopener'; return a; }
4482
- case 'number': return el('span', null, typeof value === 'number' ? value.toLocaleString() : String(value));
5000
+ // column.locale / column.format: Intl.NumberFormat locale and options, e.g. { minimumFractionDigits: 1 }.
5001
+ case 'number': return el('span', null, typeof value === 'number' ? value.toLocaleString(column.locale, column.format) : String(value));
4483
5002
  case 'progress': return progress(Number(value) || 0);
4484
5003
  default: {
4485
5004
  if (column.title) {
@@ -4572,6 +5091,8 @@ var NotionKitElements = (function (exports) {
4572
5091
  const r = this.createElement('tr', [], { 'data-id': row.id ?? '' });
4573
5092
  for (const col of this._columns) {
4574
5093
  const td = document.createElement('td');
5094
+ // Numbers right-aligned in figures of equal width, as Notion sets them.
5095
+ if (col.type === 'number') td.className = 'num';
4575
5096
  td.appendChild(renderPropertyCell(col, row[col.key], row));
4576
5097
  r.appendChild(td);
4577
5098
  }
@@ -4755,61 +5276,167 @@ var NotionKitElements = (function (exports) {
4755
5276
 
4756
5277
  customElements.define('nk-board-view', NkBoardView);
4757
5278
 
4758
- // <nk-filter-bar search placeholder="Search rows …"></nk-filter-bar>
4759
- // bar.filters = [{ key: 'status', label: 'Status: Done', value: 'done' }];
4760
- // Composed from existing classes (nk-btn secondary small, nk-input, nk-tag):
4761
- // filter / sort buttons fire nk-action, chips remove on ×, search and chip
4762
- // changes fire nk-change { filters, search }. The wrapper is layout only.
5279
+ // <nk-list-view name="list" label="☰ List" meta-keys="due,status" new-row></nk-list-view>
5280
+ // The third database view: one line per row – icon and title, the `meta-keys`
5281
+ // on the right (default: the select and date columns, in column order). Dates
5282
+ // and text stand as text, selects as tags, a person as avatar and name.
5283
+ // Standalone: view.columns = […]; view.rows = […]. Inside <nk-database> the
5284
+ // database pushes the data. Rows fire nk-select, the add row nk-action
5285
+ // { action: 'new-row' }.
5286
+ // → <div class="nk-list"><div class="nk-list-item"><span class="l-icon">…</span><span class="l-title">…</span><span class="l-meta">…</span></div>…</div>
5287
+ class NkListView extends NkElement {
5288
+ static get observedAttributes() { return ['name', 'label', 'badge', 'count', 'title-key', 'meta-keys', 'new-row', 'new-row-label']; }
5289
+
5290
+ render() {
5291
+ this._box = document.createElement('div');
5292
+ this._list = this.createElement('div', ['nk-list'], { role: 'list' });
5293
+ this._newRow = this.createElement('div', ['nk-new-row'], { role: 'button', tabindex: '0' });
5294
+ this._box.append(this._list, this._newRow);
5295
+ this._wrapper.appendChild(this._box);
5296
+ this._columns ??= []; this._rows ??= [];
5297
+ this._render();
5298
+ this.closest('nk-database')?.requestSync?.();
5299
+ }
5300
+
5301
+ _titleColumn() {
5302
+ const key = this.getAttribute('title-key');
5303
+ return this._columns.find(c => c.key === key) || this._columns.find(c => c.title) || this._columns[0] || null;
5304
+ }
5305
+ _metaColumns() {
5306
+ const keys = (this.getAttribute('meta-keys') || '').split(',').map(s => s.trim()).filter(Boolean);
5307
+ if (keys.length) return keys.map(k => this._columns.find(c => c.key === k)).filter(Boolean);
5308
+ return this._columns.filter(c => c.type === 'select' || c.type === 'date');
5309
+ }
5310
+
5311
+ _render() {
5312
+ if (!this._list) return;
5313
+ const title = this._titleColumn(), meta = this._metaColumns();
5314
+ this._list.replaceChildren();
5315
+ for (const row of this._rows) {
5316
+ const item = this.createElement('div', ['nk-list-item'], { role: 'listitem', tabindex: '0', 'data-id': row.id ?? '' });
5317
+ const icon = this.createElement('span', ['l-icon']);
5318
+ icon.textContent = row.icon || '';
5319
+ if (!row.icon) icon.style.display = 'none';
5320
+ const t = this.createElement('span', ['l-title']);
5321
+ t.textContent = title ? String(row[title.key] ?? '') : '';
5322
+ const m = this.createElement('span', ['l-meta']);
5323
+ for (const c of meta) {
5324
+ const v = row[c.key];
5325
+ if (v === undefined || v === null || v === '') continue;
5326
+ m.appendChild(c.type === 'date' || c.type === 'text' || !c.type ? document.createTextNode(String(v)) : renderPropertyCell(c, v, row));
5327
+ }
5328
+ item.append(icon, t, m);
5329
+ this._list.appendChild(item);
5330
+ }
5331
+ this._newRow.textContent = this.getAttribute('new-row-label') || '+ New page';
5332
+ this._newRow.style.display = this.getBoolAttr('new-row') ? '' : 'none';
5333
+ }
5334
+
5335
+ setupEvents() {
5336
+ this._onClick = (e) => {
5337
+ if (this._newRow.contains(e.target)) { this.emit('nk-action', { action: 'new-row' }); return; }
5338
+ const item = e.target.closest('.nk-list-item');
5339
+ if (item) { const row = this._rowById(item.dataset.id); this.emit('nk-select', { row, id: row?.id, value: row?.id }); }
5340
+ };
5341
+ this._onKey = (e) => {
5342
+ if (e.key !== 'Enter' && e.key !== ' ') return;
5343
+ if (e.target === this._newRow || e.target.classList?.contains('nk-list-item')) { e.preventDefault(); e.target.click(); }
5344
+ };
5345
+ this._box.addEventListener('click', this._onClick);
5346
+ this._box.addEventListener('keydown', this._onKey);
5347
+ }
5348
+
5349
+ teardownEvents() {
5350
+ this._box?.removeEventListener('click', this._onClick);
5351
+ this._box?.removeEventListener('keydown', this._onKey);
5352
+ }
5353
+
5354
+ _rowById(id) { return this._rows.find(r => String(r.id) === String(id)); }
5355
+ onAttributeChanged() { this._render(); }
5356
+
5357
+ get name() { return this.getAttribute('name') || 'list'; }
5358
+ get columns() { return this._columns; }
5359
+ set columns(v) { this._columns = Array.isArray(v) ? v : []; this._render(); }
5360
+ get rows() { return this._rows; }
5361
+ set rows(v) { this._rows = Array.isArray(v) ? v : []; this._render(); }
5362
+ set data({ columns, rows }) { this.setData(columns, rows); }
5363
+ setData(columns, rows) { this._columns = columns || []; this._rows = rows || []; this._render(); }
5364
+ refresh() { this._render(); }
5365
+ }
5366
+
5367
+ customElements.define('nk-list-view', NkListView);
5368
+
5369
+ // <nk-filter-bar add no-filter no-sort></nk-filter-bar>
5370
+ // bar.filters = [{ key: 'status', value: 'done', op: 'is-not', label: 'Status: Open' }];
5371
+ // The filters in effect as NotionKit's filter pills (1.7.0), no inline style:
5372
+ // → <div class="nk-filter-row">[Filter][Sort]
5373
+ // <span class="nk-filter-pill active"><button>Status: Open</button><button class="fp-remove">×</button></span>…
5374
+ // <button class="nk-filter-pill add">+ Filter</button> …slot… [search]</div>
5375
+ // Filter and Sort are .nk-db-tool buttons (hide them with no-filter / no-sort
5376
+ // when the database toolbar carries its own); they fire nk-action. A pill's
5377
+ // label fires nk-action { action: 'edit', index, filter }, the add pill
5378
+ // nk-action { action: 'add' } – each with the clicked button as `anchor`, to
5379
+ // open a menu under it. × removes the filter; every change to filters or
5380
+ // search fires nk-change { filters, search }. In slot="filters" of
5381
+ // <nk-database> the row sits right under the view tabs. The texts are
5382
+ // attributes, for other languages: filter-label, sort-label, add-label,
5383
+ // remove-label (the × reads "<remove-label>: <pill>") and placeholder.
4763
5384
  class NkFilterBar extends NkElement {
4764
- static get observedAttributes() { return ['search', 'placeholder', 'no-filter', 'no-sort', 'value']; }
5385
+ static get observedAttributes() { return ['search', 'placeholder', 'no-filter', 'no-sort', 'value', 'add', 'add-label', 'filter-label', 'sort-label', 'remove-label']; }
4765
5386
 
4766
5387
  render() {
4767
- this._bar = document.createElement('div');
4768
- this._bar.style.cssText = 'display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin:8px 0';
4769
- this._filterBtn = this.createElement('button', ['nk-btn', 'secondary', 'small'], { type: 'button', 'data-action': 'filter' });
4770
- this._filterBtn.textContent = '⚲ Filter';
4771
- this._sortBtn = this.createElement('button', ['nk-btn', 'secondary', 'small'], { type: 'button', 'data-action': 'sort' });
4772
- this._sortBtn.textContent = '↕ Sort';
4773
- this._chips = document.createElement('span');
4774
- this._chips.style.cssText = 'display:inline-flex;gap:4px;flex-wrap:wrap';
5388
+ this._row = this.createElement('div', ['nk-filter-row']);
5389
+ this._filterBtn = this.createElement('button', ['nk-db-tool'], { type: 'button', 'data-action': 'filter' });
5390
+ this._sortBtn = this.createElement('button', ['nk-db-tool'], { type: 'button', 'data-action': 'sort' });
5391
+ this._pillStart = document.createComment('pills');
5392
+ this._addBtn = this.createElement('button', ['nk-filter-pill', 'add'], { type: 'button', 'data-action': 'add' });
4775
5393
  this._input = this.createElement('input', ['nk-input'], { type: 'search', autocomplete: 'off' });
4776
- this._input.style.marginLeft = 'auto';
4777
- this._bar.append(this._filterBtn, this._sortBtn, this._chips, document.createElement('slot'), this._input);
4778
- this._wrapper.appendChild(this._bar);
5394
+ this._row.append(this._filterBtn, this._sortBtn, this._pillStart, this._addBtn, document.createElement('slot'), this._input);
5395
+ this._wrapper.appendChild(this._row);
4779
5396
  this._filters = [];
4780
5397
  this._sync();
4781
5398
  }
4782
5399
 
4783
5400
  _sync() {
4784
- this._filterBtn.style.display = this.getBoolAttr('no-filter') ? 'none' : '';
4785
- this._sortBtn.style.display = this.getBoolAttr('no-sort') ? 'none' : '';
4786
- this._input.style.display = this.getBoolAttr('search') ? '' : 'none';
5401
+ this._filterBtn.textContent = this.getAttribute('filter-label') || 'Filter';
5402
+ this._filterBtn.hidden = this.getBoolAttr('no-filter');
5403
+ this._filterBtn.classList.toggle('active', this._filters.length > 0);
5404
+ this._sortBtn.textContent = this.getAttribute('sort-label') || 'Sort';
5405
+ this._sortBtn.hidden = this.getBoolAttr('no-sort');
5406
+ this._addBtn.textContent = this.getAttribute('add-label') || '+ Filter';
5407
+ this._addBtn.hidden = !this.getBoolAttr('add');
5408
+ this._input.hidden = !this.getBoolAttr('search');
4787
5409
  this._input.placeholder = this.getAttribute('placeholder') || 'Search …';
4788
5410
  if (this.hasAttribute('value') && this._input.value !== this.getAttribute('value')) this._input.value = this.getAttribute('value');
4789
- this._chips.replaceChildren();
4790
- this._filters.forEach((f, i) => {
4791
- const chip = this.createElement('span', ['nk-tag', f.color || 'blue'], { 'data-index': i });
4792
- chip.style.cursor = 'pointer';
4793
- chip.textContent = `${f.label ?? `${f.key}: ${f.value}`} ×`;
4794
- chip.title = 'Remove filter';
4795
- this._chips.appendChild(chip);
4796
- });
5411
+ for (const old of this._row.querySelectorAll('[data-pill]')) old.remove();
5412
+ const removeLabel = this.getAttribute('remove-label') || 'Remove filter';
5413
+ this._pillStart.after(...this._filters.map((f, i) => {
5414
+ const pill = this.createElement('span', ['nk-filter-pill', 'active'], { 'data-pill': i });
5415
+ const label = this.createElement('button', [], { type: 'button', 'data-edit': i });
5416
+ label.textContent = f.label ?? `${f.key}: ${f.value}`;
5417
+ const remove = this.createElement('button', ['fp-remove'], { type: 'button', 'data-remove': i, 'aria-label': `${removeLabel}: ${label.textContent}` });
5418
+ remove.textContent = '×';
5419
+ pill.append(label, remove);
5420
+ return pill;
5421
+ }));
4797
5422
  }
4798
5423
 
4799
5424
  setupEvents() {
4800
5425
  this._onClick = (e) => {
5426
+ const remove = e.target.closest('[data-remove]');
5427
+ if (remove) { this._filters.splice(Number(remove.dataset.remove), 1); this._sync(); this._emitChange(); return; }
5428
+ const edit = e.target.closest('[data-edit]');
5429
+ if (edit) { const index = Number(edit.dataset.edit); this.emit('nk-action', { action: 'edit', index, filter: this._filters[index], anchor: edit }); return; }
4801
5430
  const btn = e.target.closest('[data-action]');
4802
- if (btn) { this.emit('nk-action', { action: btn.dataset.action }); return; }
4803
- const chip = e.target.closest('[data-index]');
4804
- if (chip) { this._filters.splice(Number(chip.dataset.index), 1); this._sync(); this._emitChange(); }
5431
+ if (btn) this.emit('nk-action', { action: btn.dataset.action, anchor: btn });
4805
5432
  };
4806
5433
  this._onInput = () => { clearTimeout(this._debounce); this._debounce = setTimeout(() => this._emitChange(), 150); };
4807
- this._bar.addEventListener('click', this._onClick);
5434
+ this._row.addEventListener('click', this._onClick);
4808
5435
  this._input.addEventListener('input', this._onInput);
4809
5436
  }
4810
5437
 
4811
5438
  teardownEvents() {
4812
- this._bar?.removeEventListener('click', this._onClick);
5439
+ this._row?.removeEventListener('click', this._onClick);
4813
5440
  this._input?.removeEventListener('input', this._onInput);
4814
5441
  clearTimeout(this._debounce);
4815
5442
  }
@@ -4818,13 +5445,18 @@ var NotionKitElements = (function (exports) {
4818
5445
  onAttributeChanged() { this._sync(); }
4819
5446
 
4820
5447
  get filters() { return this._filters; }
4821
- set filters(v) { this._filters = Array.isArray(v) ? v : []; this._sync(); }
5448
+ set filters(v) { this._filters = Array.isArray(v) ? v : []; if (this._row) this._sync(); }
4822
5449
  get value() { return this._input?.value ?? ''; }
4823
5450
  set value(v) { if (this._input) this._input.value = v ?? ''; }
4824
- /** Applies filters + search to rows: equality per filter key, substring search over every string field. */
5451
+ /**
5452
+ * Applies filters and search to rows: a filter keeps rows where row[key]
5453
+ * equals value – or differs from it with op: 'is-not'; the search looks
5454
+ * for the text in every string field (a person's name).
5455
+ */
4825
5456
  apply(rows) {
4826
5457
  const q = this.value.trim().toLowerCase();
4827
- return rows.filter(r => this._filters.every(f => r[f.key] === f.value) && (!q || Object.values(r).some(v => String(typeof v === 'object' && v ? v.name ?? '' : v ?? '').toLowerCase().includes(q))));
5458
+ return rows.filter(r => this._filters.every(f => (f.op === 'is-not' ? r[f.key] !== f.value : r[f.key] === f.value))
5459
+ && (!q || Object.values(r).some(v => String(typeof v === 'object' && v ? v.name ?? '' : v ?? '').toLowerCase().includes(q))));
4828
5460
  }
4829
5461
  }
4830
5462
 
@@ -4884,15 +5516,16 @@ var NotionKitElements = (function (exports) {
4884
5516
 
4885
5517
  customElements.define('nk-comments', NkComments);
4886
5518
 
4887
- // <nk-comment author="Sara Lindt" time="1 hr ago" avatar="SL" color="#448361">The board view feels close.</nk-comment>
4888
- // → <div class="nk-comment"><span class="mini-avatar">SL</span><div><div class="c-head"><b>Sara Lindt</b> · 1 hr ago</div><div class="c-body">…</div></div></div>
5519
+ // <nk-comment author="Sara Lindt" time="1 hr ago" avatar="SL" color="green">The board view feels close.</nk-comment>
5520
+ // → <div class="nk-comment"><span class="nk-avatar green">SL</span><div><div class="c-head"><b>Sara Lindt</b> · 1 hr ago</div><div class="c-body">…</div></div></div>
5521
+ // color: one of Notion's nine names, or any CSS background; without it the avatar gradient.
4889
5522
  // slot="head" adds content after the name (e.g. an <nk-tag>).
4890
5523
  class NkComment extends NkElement {
4891
5524
  static get observedAttributes() { return ['author', 'time', 'avatar', 'color']; }
4892
5525
 
4893
5526
  render() {
4894
5527
  const box = this.createElement('div', ['nk-comment']);
4895
- this._avatar = this.createElement('span', ['mini-avatar']);
5528
+ this._avatar = this.createElement('span', ['nk-avatar']);
4896
5529
  const avatarSlot = this.createElement('slot', [], { name: 'avatar' });
4897
5530
  avatarSlot.appendChild(this._avatar);
4898
5531
  const text = document.createElement('div');
@@ -4913,8 +5546,8 @@ var NotionKitElements = (function (exports) {
4913
5546
  this._author.textContent = author;
4914
5547
  const time = this.getAttribute('time');
4915
5548
  this._time.data = time ? ` · ${time}` : '';
4916
- this._avatar.textContent = this.getAttribute('avatar') || author.split(/\s+/).map(w => w[0]).join('').slice(0, 2).toUpperCase();
4917
- this._avatar.style.background = this.getAttribute('color') || 'var(--nk-text-tertiary)';
5549
+ this._avatar.textContent = this.getAttribute('avatar') || initialsOf(author);
5550
+ paintAvatar(this._avatar, this.getAttribute('color'));
4918
5551
  }
4919
5552
 
4920
5553
  onAttributeChanged() { this._sync(); }
@@ -4938,16 +5571,18 @@ var NotionKitElements = (function (exports) {
4938
5571
  // Two tasks are open …
4939
5572
  // <button slot="actions" value="copy">📋 Copy</button><button slot="actions" value="retry">↻ Rephrase</button>
4940
5573
  // </nk-ai-msg>
5574
+ // <nk-ai-msg role="user" bubble>What is still open?</nk-ai-msg> → a grey bubble on the right, as in Notion's AI chat
4941
5575
  // → <div class="nk-ai-msg user"><span class="mini-avatar">MK</span><div class="a-body"><div class="a-name">You</div>…<div class="nk-ai-actions">…</div></div></div>
4942
5576
  // Action buttons stay in the light DOM (slotted twins) and fire nk-action { action: value }.
4943
5577
  class NkAiMsg extends NkElement {
4944
- static get observedAttributes() { return ['role', 'name', 'badge', 'avatar', 'color']; }
5578
+ static get observedAttributes() { return ['role', 'name', 'badge', 'avatar', 'color', 'bubble']; }
4945
5579
 
4946
5580
  render() {
4947
5581
  this._box = this.createElement('div', ['nk-ai-msg']);
4948
5582
  this._avatar = this.createElement('span', ['mini-avatar']);
4949
5583
  const avatarSlot = this.createElement('slot', [], { name: 'avatar' });
4950
5584
  avatarSlot.appendChild(this._avatar);
5585
+ this._avatarSlot = avatarSlot;
4951
5586
  const body = this.createElement('div', ['a-body']);
4952
5587
  this._name = this.createElement('div', ['a-name']);
4953
5588
  this._nameText = document.createTextNode('');
@@ -4964,12 +5599,16 @@ var NotionKitElements = (function (exports) {
4964
5599
 
4965
5600
  _sync() {
4966
5601
  const user = this.getAttribute('role') === 'user';
5602
+ const bubble = this.getBoolAttr('bubble');
4967
5603
  this._box.classList.toggle('user', user);
5604
+ this._box.classList.toggle('bubble', bubble);
4968
5605
  const name = this.getAttribute('name');
4969
5606
  this._nameText.data = name || '';
4970
5607
  const badge = this.getAttribute('badge');
4971
5608
  this._badge.textContent = badge ? ` ${badge}` : '';
4972
- this._name.style.display = name ? '' : 'none';
5609
+ // A bubble stands without avatar and name; the text says who asked.
5610
+ this._name.style.display = name && !bubble ? '' : 'none';
5611
+ this._avatarSlot.style.display = bubble ? 'none' : '';
4973
5612
  this._avatar.textContent = this.getAttribute('avatar') || (user ? (name || 'U').slice(0, 2).toUpperCase() : '✨');
4974
5613
  const color = this.getAttribute('color');
4975
5614
  this._avatar.style.background = color || '';
@@ -5055,6 +5694,7 @@ var NotionKitElements = (function (exports) {
5055
5694
  exports.NkAiMsg = NkAiMsg;
5056
5695
  exports.NkAiThread = NkAiThread;
5057
5696
  exports.NkApp = NkApp;
5697
+ exports.NkAvatar = NkAvatar;
5058
5698
  exports.NkAvatarGroup = NkAvatarGroup;
5059
5699
  exports.NkBanner = NkBanner;
5060
5700
  exports.NkBlockHost = NkBlockHost;
@@ -5080,6 +5720,7 @@ var NotionKitElements = (function (exports) {
5080
5720
  exports.NkHeading = NkHeading;
5081
5721
  exports.NkInput = NkInput;
5082
5722
  exports.NkKbd = NkKbd;
5723
+ exports.NkListView = NkListView;
5083
5724
  exports.NkMemberList = NkMemberList;
5084
5725
  exports.NkMemberRow = NkMemberRow;
5085
5726
  exports.NkMention = NkMention;
@@ -5091,9 +5732,13 @@ var NotionKitElements = (function (exports) {
5091
5732
  exports.NkPageActions = NkPageActions;
5092
5733
  exports.NkPageCover = NkPageCover;
5093
5734
  exports.NkPageTitle = NkPageTitle;
5735
+ exports.NkPanel = NkPanel;
5736
+ exports.NkPanels = NkPanels;
5094
5737
  exports.NkPop = NkPop;
5095
5738
  exports.NkProfileRow = NkProfileRow;
5096
5739
  exports.NkProgress = NkProgress;
5740
+ exports.NkProp = NkProp;
5741
+ exports.NkProps = NkProps;
5097
5742
  exports.NkQuote = NkQuote;
5098
5743
  exports.NkRadio = NkRadio;
5099
5744
  exports.NkSectionLabel = NkSectionLabel;
@@ -5101,11 +5746,13 @@ var NotionKitElements = (function (exports) {
5101
5746
  exports.NkSelect = NkSelect;
5102
5747
  exports.NkSettingsPane = NkSettingsPane;
5103
5748
  exports.NkSettingsUser = NkSettingsUser;
5749
+ exports.NkSheet = NkSheet;
5104
5750
  exports.NkSidebar = NkSidebar;
5105
5751
  exports.NkSkeleton = NkSkeleton;
5106
5752
  exports.NkSlider = NkSlider;
5107
5753
  exports.NkStat = NkStat;
5108
5754
  exports.NkStats = NkStats;
5755
+ exports.NkSteps = NkSteps;
5109
5756
  exports.NkSwitch = NkSwitch;
5110
5757
  exports.NkSynced = NkSynced;
5111
5758
  exports.NkTab = NkTab;
@@ -5125,6 +5772,7 @@ var NotionKitElements = (function (exports) {
5125
5772
  exports.NkTreeItem = NkTreeItem;
5126
5773
  exports.NkWorkspaceSwitcher = NkWorkspaceSwitcher;
5127
5774
  exports.compareBy = compareBy;
5775
+ exports.componentsSheet = componentsSheet;
5128
5776
  exports.renderPropertyCell = renderPropertyCell;
5129
5777
  exports.tagFor = tagFor;
5130
5778