@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.
- package/README.md +27 -18
- package/dist/components/base.js +346 -0
- package/dist/components/nk-ai-input-row.js +2 -1
- package/dist/components/nk-ai-msg.js +10 -3
- package/dist/components/nk-ai-thread.js +2 -1
- package/dist/components/nk-app.js +2 -1
- package/dist/components/nk-avatar-group.js +2 -1
- package/dist/components/nk-avatar.js +57 -0
- package/dist/components/nk-banner.js +2 -1
- package/dist/components/nk-block-host.js +2 -1
- package/dist/components/nk-board-view.js +4 -2
- package/dist/components/nk-breadcrumb.js +2 -1
- package/dist/components/nk-btn.js +31 -4
- package/dist/components/nk-callout.js +2 -1
- package/dist/components/nk-check.js +2 -1
- package/dist/components/nk-cmdk.js +3 -2
- package/dist/components/nk-code.js +2 -1
- package/dist/components/nk-comment.js +9 -6
- package/dist/components/nk-comments.js +2 -1
- package/dist/components/nk-danger-zone.js +2 -1
- package/dist/components/nk-database.js +16 -6
- package/dist/components/nk-divider.js +2 -1
- package/dist/components/nk-emoji-picker.js +2 -1
- package/dist/components/nk-empty.js +2 -1
- package/dist/components/nk-field.js +2 -1
- package/dist/components/nk-fields.js +2 -1
- package/dist/components/nk-filter-bar.js +59 -37
- package/dist/components/nk-heading.js +2 -1
- package/dist/components/nk-input.js +2 -1
- package/dist/components/nk-kbd.js +2 -1
- package/dist/components/nk-list-view.js +96 -0
- package/dist/components/nk-member-list.js +2 -1
- package/dist/components/nk-member-row.js +10 -6
- package/dist/components/nk-mention.js +2 -1
- package/dist/components/nk-menu-item.js +27 -3
- package/dist/components/nk-menu.js +88 -2
- package/dist/components/nk-modal.js +3 -2
- package/dist/components/nk-model-card.js +2 -1
- package/dist/components/nk-page-actions.js +2 -1
- package/dist/components/nk-page-cover.js +12 -11
- package/dist/components/nk-page-title.js +2 -1
- package/dist/components/nk-page.js +12 -4
- package/dist/components/nk-panel.js +61 -0
- package/dist/components/nk-panels.js +18 -0
- package/dist/components/nk-pop.js +2 -1
- package/dist/components/nk-profile-row.js +2 -1
- package/dist/components/nk-progress.js +5 -2
- package/dist/components/nk-prop.js +54 -0
- package/dist/components/nk-props.js +21 -0
- package/dist/components/nk-quote.js +2 -1
- package/dist/components/nk-radio.js +2 -1
- package/dist/components/nk-section-label.js +2 -1
- package/dist/components/nk-segmented.js +21 -1
- package/dist/components/nk-select.js +2 -1
- package/dist/components/nk-settings-pane.js +2 -1
- package/dist/components/nk-settings-user.js +2 -1
- package/dist/components/nk-sheet.js +97 -0
- package/dist/components/nk-sidebar.js +17 -37
- package/dist/components/nk-skeleton.js +2 -1
- package/dist/components/nk-slider.js +2 -1
- package/dist/components/nk-stat.js +2 -1
- package/dist/components/nk-stats.js +2 -1
- package/dist/components/nk-steps.js +61 -0
- package/dist/components/nk-switch.js +2 -1
- package/dist/components/nk-synced.js +2 -1
- package/dist/components/nk-tab-bar-item.js +2 -1
- package/dist/components/nk-tab-bar.js +2 -1
- package/dist/components/nk-tab.js +2 -1
- package/dist/components/nk-table-view.js +6 -2
- package/dist/components/nk-tabs.js +2 -1
- package/dist/components/nk-tag.js +2 -1
- package/dist/components/nk-template-btn.js +2 -1
- package/dist/components/nk-textarea.js +2 -1
- package/dist/components/nk-theme-toggle.js +2 -1
- package/dist/components/nk-toast.js +2 -1
- package/dist/components/nk-todo.js +2 -1
- package/dist/components/nk-toggle.js +2 -1
- package/dist/components/nk-topbar.js +2 -1
- package/dist/components/nk-tree-item.js +2 -1
- package/dist/components/nk-tree.js +2 -1
- package/dist/components/nk-workspace-switcher.js +2 -1
- package/dist/components/shared/avatar-BiqCaHOt.js +19 -0
- package/dist/components/shared/{focus-DXrK9oLe.js → focus-BNAChOXO.js} +12 -4
- package/dist/components/shared/{property-cell-CtXQpUjQ.js → property-cell-o7N30kAQ.js} +8 -3
- package/dist/notionkit-elements.esm.js +759 -120
- package/dist/notionkit-elements.js +767 -119
- package/dist/notionkit-elements.min.js +1 -1
- package/package.json +7 -6
- package/src/components/content/nk-progress.js +3 -1
- package/src/components/data/nk-ai-msg.js +8 -2
- package/src/components/data/nk-comment.js +7 -5
- package/src/components/data/nk-database.js +14 -5
- package/src/components/data/nk-filter-bar.js +57 -36
- package/src/components/data/nk-list-view.js +93 -0
- package/src/components/data/nk-table-view.js +2 -0
- package/src/components/forms/nk-btn.js +29 -3
- package/src/components/overlays/nk-menu-item.js +25 -2
- package/src/components/overlays/nk-menu.js +86 -1
- package/src/components/overlays/nk-sheet.js +95 -0
- package/src/components/page/nk-avatar.js +55 -0
- package/src/components/page/nk-member-row.js +8 -5
- package/src/components/page/nk-page-cover.js +10 -10
- package/src/components/page/nk-page.js +10 -3
- package/src/components/page/nk-panel.js +59 -0
- package/src/components/page/nk-panels.js +16 -0
- package/src/components/page/nk-prop.js +52 -0
- package/src/components/page/nk-props.js +19 -0
- package/src/components/page/nk-segmented.js +19 -0
- package/src/components/page/nk-steps.js +59 -0
- package/src/components/shell/nk-sidebar.js +15 -36
- package/src/index.js +18 -0
- package/src/util/avatar.js +17 -0
- package/src/util/focus.js +11 -3
- package/src/util/property-cell.js +7 -3
- 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.
|
|
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
|
|
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-]
|
|
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
|
-
|
|
407
|
-
|
|
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
|
|
1716
|
-
//
|
|
1717
|
-
//
|
|
1718
|
-
//
|
|
1719
|
-
//
|
|
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
|
|
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> →
|
|
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.
|
|
2614
|
-
this.
|
|
2615
|
-
this._cover.
|
|
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="
|
|
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="
|
|
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', ['
|
|
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')
|
|
3460
|
-
this._avatar
|
|
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
|
-
//
|
|
3470
|
-
//
|
|
3471
|
-
//
|
|
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() {
|
|
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
|
-
|
|
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
|
-
//
|
|
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.
|
|
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.
|
|
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
|
-
|
|
4476
|
-
avatar
|
|
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
|
-
|
|
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-
|
|
4759
|
-
//
|
|
4760
|
-
//
|
|
4761
|
-
//
|
|
4762
|
-
//
|
|
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.
|
|
4768
|
-
this.
|
|
4769
|
-
this.
|
|
4770
|
-
this.
|
|
4771
|
-
this.
|
|
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.
|
|
4777
|
-
this.
|
|
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.
|
|
4785
|
-
this.
|
|
4786
|
-
this.
|
|
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.
|
|
4790
|
-
this.
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
this.
|
|
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)
|
|
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.
|
|
5434
|
+
this._row.addEventListener('click', this._onClick);
|
|
4808
5435
|
this._input.addEventListener('input', this._onInput);
|
|
4809
5436
|
}
|
|
4810
5437
|
|
|
4811
5438
|
teardownEvents() {
|
|
4812
|
-
this.
|
|
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
|
-
/**
|
|
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]
|
|
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="
|
|
4888
|
-
// → <div class="nk-comment"><span class="
|
|
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', ['
|
|
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
|
|
4917
|
-
this._avatar
|
|
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
|
-
|
|
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
|
|