Full document, spreadsheet, slideshow, and diagram tooling
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request 'refactor: consolidate z-index into documented CSS custom properties' (#271) from refactor/z-index-scale into main

scott 97d0e7f2 f07f77c2

+66 -48
+2
CHANGELOG.md
··· 8 8 ## [0.23.5] — 2026-04-06 9 9 10 10 ### Fixed 11 + - Fix PDF export hardcoded colors and button-cells default (#449) 12 + - Replace hardcoded hex colors in TypeScript with CSS variable references (#448) 11 13 - Improve keyboard focus visibility for accessibility (#447) 12 14 - CSS polish: replace hardcoded transition durations with CSS variables (#446) 13 15 - CSS polish: define missing variables, fix hardcoded colors, focus styles (#445)
+64 -48
src/css/app.css
··· 82 82 83 83 /* Shadows (use dark base) */ 84 84 --shadow-color: oklch(0.22 0.02 55); 85 + 86 + /* Z-Index Scale — documented stacking context hierarchy. 87 + Grid-internal micro-stacking (0-6) uses literal values. 88 + Everything above uses these tokens for consistency. */ 89 + --z-component: 10; /* toolbar, cell editor, diagram panels */ 90 + --z-float: 50; /* dropdowns, block handle, version badge */ 91 + --z-popover: 60; /* comment popover, block context menu */ 92 + --z-sticky: 80; /* sort indicator, validation dropdown */ 93 + --z-overlay: 100; /* resize lines, autocomplete, slash menu */ 94 + --z-tooltip: 200; /* tooltips, link preview, suggestions */ 95 + --z-drop: 300; /* drop zone overlay, notification toast */ 96 + --z-panel: 900; /* gallery sidebar, floating panels */ 97 + --z-modal: 1000; /* modal dialog, print preview, presenter */ 98 + --z-above-modal: 1100; /* formula tooltip, find-replace overlay */ 99 + --z-menu: 9999; /* context menu, command palette */ 100 + --z-skip: 10000;/* skip-to-content link */ 85 101 } 86 102 87 103 /* --- Dark theme --- */ ··· 395 411 pointer-events: none; 396 412 opacity: 0; 397 413 transition: opacity var(--transition-fast); 398 - z-index: 9999; 414 + z-index: var(--z-menu); 399 415 } 400 416 [data-tooltip]:hover::after { 401 417 opacity: 1; ··· 1016 1032 border: 1px solid var(--color-border); 1017 1033 border-radius: var(--radius-md); 1018 1034 box-shadow: var(--shadow-md); 1019 - z-index: 100; 1035 + z-index: var(--z-overlay); 1020 1036 overflow: hidden; 1021 1037 } 1022 1038 .sort-menu.open { ··· 1203 1219 display: flex; 1204 1220 align-items: center; 1205 1221 justify-content: center; 1206 - z-index: 1000; 1222 + z-index: var(--z-modal); 1207 1223 } 1208 1224 1209 1225 .modal { ··· 1748 1764 /* Toolbar must sit above editor-container's stacking context so dropdowns aren't clipped */ 1749 1765 .toolbar { 1750 1766 position: relative; 1751 - z-index: 10; 1767 + z-index: var(--z-component); 1752 1768 } 1753 1769 1754 1770 .editor-wrapper { ··· 2102 2118 width: 2px; 2103 2119 height: 100%; 2104 2120 background: var(--color-teal); 2105 - z-index: 100; 2121 + z-index: var(--z-overlay); 2106 2122 pointer-events: none; 2107 2123 opacity: 0.7; 2108 2124 } ··· 2176 2192 height: 2px; 2177 2193 width: 100%; 2178 2194 background: var(--color-teal); 2179 - z-index: 100; 2195 + z-index: var(--z-overlay); 2180 2196 pointer-events: none; 2181 2197 opacity: 0.7; 2182 2198 } ··· 2647 2663 outline: none; 2648 2664 background: var(--color-cell-editor-bg); 2649 2665 color: var(--color-text); 2650 - z-index: 10; 2666 + z-index: var(--z-component); 2651 2667 box-shadow: 0 2px 8px oklch(0.48 0.1 195 / 0.15); 2652 2668 box-sizing: border-box; 2653 2669 } ··· 2958 2974 display: flex; 2959 2975 align-items: center; 2960 2976 justify-content: center; 2961 - z-index: 100; 2977 + z-index: var(--z-overlay); 2962 2978 backdrop-filter: blur(4px); 2963 2979 } 2964 2980 ··· 3077 3093 position: absolute; 3078 3094 top: 100%; 3079 3095 left: 0; 3080 - z-index: 50; 3096 + z-index: var(--z-float); 3081 3097 min-width: 10rem; 3082 3098 padding: var(--space-xs) 0; 3083 3099 margin-top: 2px; ··· 3167 3183 position: absolute; 3168 3184 top: 100%; 3169 3185 right: 0; 3170 - z-index: 50; 3186 + z-index: var(--z-float); 3171 3187 min-width: 13rem; 3172 3188 padding: var(--space-xs) 0; 3173 3189 margin-top: 2px; ··· 3408 3424 3409 3425 .comment-popover { 3410 3426 position: fixed; 3411 - z-index: 60; 3427 + z-index: var(--z-popover); 3412 3428 min-width: 14rem; 3413 3429 max-width: 22rem; 3414 3430 padding: var(--space-sm) var(--space-md); ··· 3486 3502 box-shadow: var(--shadow-lg); 3487 3503 opacity: 0; 3488 3504 transition: opacity var(--transition-med), transform var(--transition-med); 3489 - z-index: 200; 3505 + z-index: var(--z-tooltip); 3490 3506 pointer-events: none; 3491 3507 } 3492 3508 .toast-notification.toast-visible { ··· 3514 3530 .drop-overlay { 3515 3531 position: fixed; 3516 3532 inset: 0; 3517 - z-index: 300; 3533 + z-index: var(--z-drop); 3518 3534 background: var(--color-modal-backdrop); 3519 3535 backdrop-filter: blur(2px); 3520 3536 display: flex; ··· 3563 3579 position: absolute; 3564 3580 top: 0; 3565 3581 right: var(--space-md); 3566 - z-index: 50; 3582 + z-index: var(--z-float); 3567 3583 background: var(--color-bg); 3568 3584 border: 1px solid var(--color-border); 3569 3585 border-top: none; ··· 3754 3770 background: var(--color-surface); 3755 3771 border-left: 1px solid var(--color-border); 3756 3772 overflow: hidden; 3757 - z-index: 10; 3773 + z-index: var(--z-component); 3758 3774 font-size: 0.65rem; 3759 3775 line-height: 1.3; 3760 3776 } ··· 3859 3875 background: var(--color-accent); 3860 3876 border: 1px solid var(--color-bg); 3861 3877 border-radius: 2px; 3862 - z-index: 10; 3878 + z-index: var(--z-component); 3863 3879 } 3864 3880 3865 3881 .tiptap .resizable-image-wrapper.selected .resize-handle { ··· 3909 3925 3910 3926 .context-menu { 3911 3927 position: fixed; 3912 - z-index: 9999; 3928 + z-index: var(--z-menu); 3913 3929 min-width: 12rem; 3914 3930 padding: var(--space-xs) 0; 3915 3931 background: var(--color-bg); ··· 3989 4005 .print-preview-overlay { 3990 4006 position: fixed; 3991 4007 inset: 0; 3992 - z-index: 1000; 4008 + z-index: var(--z-modal); 3993 4009 background: var(--color-modal-backdrop); 3994 4010 display: flex; 3995 4011 align-items: flex-start; ··· 4166 4182 position: fixed; 4167 4183 inset: 0; 4168 4184 background: var(--color-modal-backdrop); 4169 - z-index: 100; 4185 + z-index: var(--z-overlay); 4170 4186 display: flex; 4171 4187 align-items: center; 4172 4188 justify-content: center; ··· 4343 4359 border: 1px solid var(--color-border); 4344 4360 border-radius: var(--radius-md); 4345 4361 box-shadow: var(--shadow-md); 4346 - z-index: 80; 4362 + z-index: var(--z-sticky); 4347 4363 padding: var(--space-xs) 0; 4348 4364 font-size: 0.8rem; 4349 4365 } ··· 4460 4476 /* --- Validation Dropdown Menu --- */ 4461 4477 .validation-dropdown { 4462 4478 position: fixed; 4463 - z-index: 80; 4479 + z-index: var(--z-sticky); 4464 4480 min-width: 8rem; 4465 4481 max-height: 12rem; 4466 4482 overflow-y: auto; ··· 4902 4918 /* Suggestion popover (similar to comment popover) */ 4903 4919 .suggestion-popover { 4904 4920 position: fixed; 4905 - z-index: 200; 4921 + z-index: var(--z-tooltip); 4906 4922 background: var(--color-surface); 4907 4923 border: 1px solid var(--color-border); 4908 4924 border-radius: var(--radius-md); ··· 4980 4996 background: var(--color-accent); 4981 4997 color: var(--color-btn-primary-text); 4982 4998 padding: var(--space-sm) var(--space-md); 4983 - z-index: 10000; 4999 + z-index: var(--z-skip); 4984 5000 font-size: 0.9rem; 4985 5001 font-weight: 600; 4986 5002 text-decoration: none; ··· 5074 5090 display: flex; 5075 5091 align-items: center; 5076 5092 justify-content: center; 5077 - z-index: 1000; 5093 + z-index: var(--z-modal); 5078 5094 } 5079 5095 5080 5096 .share-dialog { ··· 5501 5517 5502 5518 .table-toolbar { 5503 5519 position: fixed; 5504 - z-index: 100; 5520 + z-index: var(--z-overlay); 5505 5521 display: flex; 5506 5522 align-items: center; 5507 5523 gap: 2px; ··· 5574 5590 5575 5591 .link-preview-tooltip { 5576 5592 position: fixed; 5577 - z-index: 200; 5593 + z-index: var(--z-tooltip); 5578 5594 background: var(--color-surface); 5579 5595 border: 1px solid var(--color-border); 5580 5596 border-radius: var(--radius-md); ··· 5652 5668 position: fixed; 5653 5669 top: var(--space-md); 5654 5670 right: var(--space-md); 5655 - z-index: 300; 5671 + z-index: var(--z-drop); 5656 5672 padding: 6px 14px; 5657 5673 border: 1px solid var(--color-border); 5658 5674 border-radius: var(--radius-md); ··· 5824 5840 5825 5841 .formula-autocomplete { 5826 5842 position: absolute; 5827 - z-index: 1000; 5843 + z-index: var(--z-modal); 5828 5844 min-width: 240px; 5829 5845 max-width: 380px; 5830 5846 max-height: 260px; ··· 6022 6038 6023 6039 .formula-tooltip { 6024 6040 position: fixed; 6025 - z-index: 1100; 6041 + z-index: var(--z-above-modal); 6026 6042 min-width: 200px; 6027 6043 max-width: 420px; 6028 6044 padding: 6px 10px; ··· 6143 6159 6144 6160 .cell-note-tooltip { 6145 6161 position: absolute; 6146 - z-index: 1001; 6162 + z-index: calc(var(--z-modal) + 1); 6147 6163 max-width: 280px; 6148 6164 padding: 6px 10px; 6149 6165 background: var(--color-surface-alt); ··· 6183 6199 6184 6200 .error-tooltip { 6185 6201 position: absolute; 6186 - z-index: 1002; 6202 + z-index: calc(var(--z-modal) + 2); 6187 6203 max-width: 300px; 6188 6204 padding: 8px 12px; 6189 6205 background: var(--color-surface-alt); ··· 6322 6338 .onboarding-overlay { 6323 6339 position: fixed; 6324 6340 inset: 0; 6325 - z-index: 200; 6341 + z-index: var(--z-tooltip); 6326 6342 display: flex; 6327 6343 align-items: center; 6328 6344 justify-content: center; ··· 6511 6527 /* --- Slash Command Menu --- */ 6512 6528 .slash-menu { 6513 6529 position: fixed; 6514 - z-index: 100; 6530 + z-index: var(--z-overlay); 6515 6531 background: var(--color-surface); 6516 6532 border: 1px solid var(--color-border); 6517 6533 border-radius: var(--radius-md); ··· 6602 6618 /* --- Block Handle --- */ 6603 6619 .block-handle { 6604 6620 position: fixed; 6605 - z-index: 50; 6621 + z-index: var(--z-float); 6606 6622 display: flex; 6607 6623 align-items: center; 6608 6624 gap: 2px; ··· 6651 6667 /* --- Block Context Menu --- */ 6652 6668 .block-context-menu { 6653 6669 position: fixed; 6654 - z-index: 60; 6670 + z-index: var(--z-popover); 6655 6671 background: var(--color-surface); 6656 6672 border: 1px solid var(--color-border); 6657 6673 border-radius: var(--radius-md); ··· 6829 6845 align-items: flex-start; 6830 6846 justify-content: center; 6831 6847 padding-top: min(20vh, 160px); 6832 - z-index: 9999; 6848 + z-index: var(--z-menu); 6833 6849 opacity: 0; 6834 6850 transition: opacity var(--transition-fast); 6835 6851 } ··· 6998 7014 box-shadow: var(--shadow-lg); 6999 7015 display: flex; 7000 7016 flex-direction: column; 7001 - z-index: 900; 7017 + z-index: var(--z-panel); 7002 7018 transition: right var(--transition-med); 7003 7019 overflow: hidden; 7004 7020 } ··· 7172 7188 position: fixed; 7173 7189 inset: 0; 7174 7190 background: var(--color-modal-backdrop); 7175 - z-index: 1100; 7191 + z-index: var(--z-above-modal); 7176 7192 display: flex; 7177 7193 align-items: center; 7178 7194 justify-content: center; ··· 7385 7401 color: var(--color-text-faint, oklch(0.6 0 0)); 7386 7402 opacity: 0.5; 7387 7403 pointer-events: none; 7388 - z-index: 50; 7404 + z-index: var(--z-float); 7389 7405 user-select: none; 7390 7406 } 7391 7407 ··· 7892 7908 right: 0; 7893 7909 bottom: 0; 7894 7910 width: 100%; 7895 - z-index: 200; 7911 + z-index: var(--z-tooltip); 7896 7912 } 7897 7913 } 7898 7914 ··· 8101 8117 .presenter-overlay { 8102 8118 position: fixed; 8103 8119 inset: 0; 8104 - z-index: 1000; 8120 + z-index: var(--z-modal); 8105 8121 background: oklch(0.10 0 0); 8106 8122 color: oklch(0.90 0 0); 8107 8123 display: flex; ··· 8206 8222 border: 1px solid var(--color-border); 8207 8223 border-radius: var(--radius-lg); 8208 8224 box-shadow: var(--shadow-md); 8209 - z-index: 10; 8225 + z-index: var(--z-component); 8210 8226 } 8211 8227 8212 8228 .diagrams-tool.active { ··· 8363 8379 border-radius: var(--radius-md); 8364 8380 box-shadow: var(--shadow-md); 8365 8381 padding: var(--space-sm); 8366 - z-index: 10; 8382 + z-index: var(--z-component); 8367 8383 } 8368 8384 8369 8385 .diagrams-style-row { ··· 8419 8435 border-radius: var(--radius-md); 8420 8436 box-shadow: var(--shadow-lg); 8421 8437 padding: 4px 0; 8422 - z-index: 100; 8438 + z-index: var(--z-overlay); 8423 8439 min-width: 160px; 8424 8440 } 8425 8441 .diagrams-context-menu button { ··· 8468 8484 border-radius: var(--radius-lg); 8469 8485 box-shadow: var(--shadow-lg); 8470 8486 padding: var(--space-lg); 8471 - z-index: 200; 8487 + z-index: var(--z-tooltip); 8472 8488 max-width: 480px; 8473 8489 width: 90vw; 8474 8490 max-height: 80vh; ··· 8497 8513 position: fixed; 8498 8514 inset: 0; 8499 8515 background: rgba(0,0,0,0.3); 8500 - z-index: 199; 8516 + z-index: calc(var(--z-tooltip) - 1); 8501 8517 } 8502 8518 8503 8519 /* ── Comments Sidebar ───────────────────────────────────────────────── */ ··· 8614 8630 border-radius: 999px; 8615 8631 font-size: 0.75rem; 8616 8632 font-weight: 600; 8617 - z-index: 100; 8633 + z-index: var(--z-overlay); 8618 8634 display: flex; 8619 8635 align-items: center; 8620 8636 gap: var(--space-sm); ··· 8705 8721 right: 0; 8706 8722 bottom: 0; 8707 8723 width: 100%; 8708 - z-index: 200; 8724 + z-index: var(--z-tooltip); 8709 8725 } 8710 8726 } 8711 8727