@openpresentation/opf-editor 0.27.0 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/README.md +23 -9
  2. package/dist/canvas.d.ts +13 -1
  3. package/dist/canvas.js +39 -9
  4. package/dist/chart-options-panel.js +16 -16
  5. package/dist/codemirror-guard.js +69 -0
  6. package/dist/content-controls.js +127 -74
  7. package/dist/data-grid.js +15 -7
  8. package/dist/design-controls.d.ts +13 -0
  9. package/dist/design-controls.js +136 -125
  10. package/dist/design-options.js +1 -1
  11. package/dist/exact-source.d.ts +30 -0
  12. package/dist/font-gate.js +20 -1
  13. package/dist/json-editor.d.ts +33 -0
  14. package/dist/json-editor.js +91 -4
  15. package/dist/json-options.d.ts +2 -1
  16. package/dist/json-options.js +7 -6
  17. package/dist/layout-adapter.js +96 -0
  18. package/dist/layout-canvas.js +122 -232
  19. package/dist/layout-editor-ui.js +46 -185
  20. package/dist/layout-inspector.js +36 -99
  21. package/dist/layout-layers.js +75 -92
  22. package/dist/layout-model.js +62 -103
  23. package/dist/layout-templates.d.ts +8 -3
  24. package/dist/layout-templates.js +30 -16
  25. package/dist/numbering-panel.js +2 -3
  26. package/dist/react.d.ts +16 -4
  27. package/dist/react.js +47 -6
  28. package/dist/slide-adapter.d.ts +49 -0
  29. package/dist/slide-adapter.js +289 -0
  30. package/dist/slide-edits.d.ts +46 -0
  31. package/dist/slide-edits.js +629 -0
  32. package/dist/slide-manager.js +2 -1
  33. package/dist/slide-scene.d.ts +96 -0
  34. package/dist/slide-scene.js +413 -0
  35. package/dist/source-checker.js +45 -6
  36. package/dist/source-color-scheme.js +60 -0
  37. package/dist/source-completions.js +6 -4
  38. package/dist/source-pane.d.ts +103 -6
  39. package/dist/source-pane.js +196 -9
  40. package/dist/source-worker.js +8 -4
  41. package/dist/studio-canvas.d.ts +34 -0
  42. package/dist/studio-canvas.js +586 -0
  43. package/dist/studio-commands.d.ts +15 -0
  44. package/dist/studio-commands.js +155 -0
  45. package/dist/studio-design.d.ts +16 -0
  46. package/dist/studio-design.js +354 -0
  47. package/dist/studio-kit/commands.d.ts +38 -0
  48. package/dist/studio-kit/commands.js +148 -0
  49. package/dist/studio-kit/dom.d.ts +52 -0
  50. package/dist/studio-kit/dom.js +198 -0
  51. package/dist/studio-kit/drag.d.ts +26 -0
  52. package/dist/studio-kit/drag.js +127 -0
  53. package/dist/studio-kit/gesture.d.ts +29 -0
  54. package/dist/studio-kit/gesture.js +87 -0
  55. package/dist/studio-kit/index.d.ts +29 -0
  56. package/dist/studio-kit/index.js +12 -0
  57. package/dist/studio-kit/inspector.d.ts +22 -0
  58. package/dist/studio-kit/inspector.js +119 -0
  59. package/dist/studio-kit/overlay.d.ts +29 -0
  60. package/dist/studio-kit/overlay.js +182 -0
  61. package/dist/studio-kit/selection.d.ts +30 -0
  62. package/dist/studio-kit/selection.js +106 -0
  63. package/dist/studio-kit/tree.d.ts +9 -0
  64. package/dist/studio-kit/tree.js +82 -0
  65. package/dist/studio-kit/viewport.d.ts +29 -0
  66. package/dist/studio-kit/viewport.js +153 -0
  67. package/dist/studio-layers.d.ts +12 -0
  68. package/dist/studio-layers.js +218 -0
  69. package/dist/studio.d.ts +31 -0
  70. package/dist/studio.js +1608 -0
  71. package/dist/styles.css +1573 -123
  72. package/dist/thumbnail-cache.d.ts +2 -0
  73. package/dist/thumbnail-cache.js +10 -1
  74. package/dist/workspace-measure.js +6 -4
  75. package/dist/workspace-parts.js +20 -0
  76. package/dist/workspace-shell.js +25 -15
  77. package/dist/workspace-theme.js +3 -0
  78. package/dist/workspace.d.ts +114 -10
  79. package/dist/workspace.js +223 -49
  80. package/package.json +30 -19
package/dist/styles.css CHANGED
@@ -19,10 +19,13 @@
19
19
  --opf-ui-border-strong: hsl(214 22% 72%);
20
20
  --opf-ui-ring: hsl(214 57% 28%);
21
21
  --opf-ui-danger: hsl(0 72% 45%);
22
- --opf-ui-warn: hsl(28 75% 38%);
22
+ --opf-ui-warn: hsl(28 75% 30%);
23
23
  --opf-ui-success: hsl(152 76% 26%);
24
24
  --opf-ui-code-bg: hsl(220 30% 96%);
25
25
  --opf-ui-code-border: hsl(214 18% 84%);
26
+ --opf-ui-selection: hsl(214 57% 28%);
27
+ --opf-ui-hover: hsl(214 57% 52%);
28
+ --opf-ui-studio-canvas-bg: hsl(214 20% 90%);
26
29
 
27
30
  --opf-ui-font: Inter, system-ui, sans-serif;
28
31
  --opf-ui-mono: "Geist Mono", ui-monospace, Menlo, monospace;
@@ -61,6 +64,9 @@
61
64
  --opf-ui-success: hsl(152 60% 70%);
62
65
  --opf-ui-code-bg: hsl(222 22% 13%);
63
66
  --opf-ui-code-border: hsl(220 16% 24%);
67
+ --opf-ui-selection: hsl(214 90% 72%);
68
+ --opf-ui-hover: hsl(214 70% 60%);
69
+ --opf-ui-studio-canvas-bg: hsl(220 22% 6%);
64
70
 
65
71
  --opf-ui-shadow-pop: 0 8px 24px rgba(0, 0, 0, 0.4);
66
72
 
@@ -90,10 +96,13 @@
90
96
  --opf-ui-border-strong: hsl(214 22% 72%);
91
97
  --opf-ui-ring: hsl(214 57% 28%);
92
98
  --opf-ui-danger: hsl(0 72% 45%);
93
- --opf-ui-warn: hsl(28 75% 38%);
99
+ --opf-ui-warn: hsl(28 75% 30%);
94
100
  --opf-ui-success: hsl(152 76% 26%);
95
101
  --opf-ui-code-bg: hsl(220 30% 96%);
96
102
  --opf-ui-code-border: hsl(214 18% 84%);
103
+ --opf-ui-selection: hsl(214 57% 28%);
104
+ --opf-ui-hover: hsl(214 57% 52%);
105
+ --opf-ui-studio-canvas-bg: hsl(214 20% 90%);
97
106
 
98
107
  --opf-ui-shadow-pop: 0 8px 24px rgba(0, 0, 0, 0.1);
99
108
 
@@ -1778,19 +1787,14 @@ input.opf-lx-input[data-field="max"] { font-family: var(--opf-ui-mono); font-siz
1778
1787
  font-weight: 400;
1779
1788
  }
1780
1789
 
1781
- .opf-dc-check .opf-dc-help {
1782
- flex-basis: 100%;
1783
- }
1784
-
1785
1790
  .opf-dc-note {
1786
1791
  font-weight: 400;
1787
1792
  color: var(--opf-ui-muted-fg);
1788
1793
  }
1789
1794
 
1790
- .opf-dc-help {
1791
- margin: 0;
1792
- font-size: 11.5px;
1793
- line-height: 1.55;
1795
+ .opf-dc-cell-label {
1796
+ margin: 0 0 8px;
1797
+ font-size: 12px;
1794
1798
  color: var(--opf-ui-muted-fg);
1795
1799
  }
1796
1800
 
@@ -1837,11 +1841,119 @@ input.opf-lx-input[data-field="max"] { font-family: var(--opf-ui-mono); font-siz
1837
1841
  align-self: flex-start;
1838
1842
  }
1839
1843
 
1840
- .opf-dc-action > button:disabled {
1844
+ .opf-dc-action > button:disabled,
1845
+ .opf-dc-action > button[aria-disabled="true"] {
1841
1846
  opacity: 0.55;
1842
1847
  cursor: not-allowed;
1843
1848
  }
1844
1849
 
1850
+ /* One row of icon buttons for a block's structural actions; each is named, with its label, shortcut or reason as its tooltip. */
1851
+ .opf-dc-toolbar {
1852
+ display: flex;
1853
+ flex-wrap: wrap;
1854
+ align-items: center;
1855
+ gap: 2px;
1856
+ margin: 0 0 10px;
1857
+ }
1858
+
1859
+ .opf-dc-toolbar[hidden],
1860
+ .opf-dc-row[hidden],
1861
+ .opf-dc-advanced[hidden] {
1862
+ display: none;
1863
+ }
1864
+
1865
+ .opf-dc-tool {
1866
+ display: inline-flex;
1867
+ flex: none;
1868
+ align-items: center;
1869
+ justify-content: center;
1870
+ width: 28px;
1871
+ height: 28px;
1872
+ min-height: 0;
1873
+ padding: 0;
1874
+ color: var(--opf-ui-fg);
1875
+ background: transparent;
1876
+ border: 1px solid transparent;
1877
+ border-radius: var(--opf-ui-radius);
1878
+ cursor: pointer;
1879
+ transition:
1880
+ background-color var(--opf-ui-ease),
1881
+ border-color var(--opf-ui-ease);
1882
+ }
1883
+
1884
+ .opf-dc-tool:hover:not([aria-disabled="true"]) {
1885
+ background: var(--opf-ui-muted);
1886
+ border-color: var(--opf-ui-border);
1887
+ }
1888
+
1889
+ .opf-dc-tool[aria-disabled="true"] {
1890
+ color: var(--opf-ui-muted-fg);
1891
+ opacity: 0.5;
1892
+ cursor: default;
1893
+ }
1894
+
1895
+ .opf-dc-toolbar-separator {
1896
+ width: 1px;
1897
+ height: 16px;
1898
+ margin: 0 4px;
1899
+ background: var(--opf-ui-border);
1900
+ }
1901
+
1902
+ /* A label and a toolbar on one line (List level). */
1903
+ .opf-dc-row {
1904
+ display: flex;
1905
+ align-items: center;
1906
+ justify-content: space-between;
1907
+ gap: 8px;
1908
+ margin: 0 0 10px;
1909
+ }
1910
+
1911
+ .opf-dc-row > .opf-dc-toolbar {
1912
+ margin: 0;
1913
+ }
1914
+
1915
+ .opf-dc-row-label {
1916
+ font-size: 12px;
1917
+ font-weight: 500;
1918
+ }
1919
+
1920
+ .opf-dc-advanced > summary {
1921
+ padding: 4px 0;
1922
+ font-size: 11.5px;
1923
+ font-weight: 500;
1924
+ color: var(--opf-ui-muted-fg);
1925
+ cursor: pointer;
1926
+ }
1927
+
1928
+ /* An internal path, as a chip that copies it. */
1929
+ .opf-dc-path {
1930
+ display: inline-flex;
1931
+ max-width: 100%;
1932
+ align-items: center;
1933
+ gap: 6px;
1934
+ min-height: 0;
1935
+ margin: 4px 0;
1936
+ padding: 2px 6px;
1937
+ font: 11.5px/1.5 var(--opf-ui-mono);
1938
+ color: var(--opf-ui-fg);
1939
+ background: var(--opf-ui-muted);
1940
+ border: 1px solid var(--opf-ui-border);
1941
+ border-radius: var(--opf-ui-radius-sm);
1942
+ cursor: pointer;
1943
+ }
1944
+
1945
+ .opf-dc-path > code {
1946
+ overflow: hidden;
1947
+ font: inherit;
1948
+ text-overflow: ellipsis;
1949
+ white-space: nowrap;
1950
+ }
1951
+
1952
+ .opf-dc-path > svg {
1953
+ flex: none;
1954
+ color: var(--opf-ui-muted-fg);
1955
+ }
1956
+
1845
1957
  .opf-dc-status {
1846
1958
  min-height: 1.2em;
1847
1959
  margin: 10px 0 0;
@@ -1860,6 +1972,12 @@ input.opf-lx-input[data-field="max"] { font-family: var(--opf-ui-mono); font-siz
1860
1972
  display: none;
1861
1973
  }
1862
1974
 
1975
+ /* An empty status line takes no room in a panel embedded in a host that shows its own (the Studio's status line). */
1976
+ .opf-studio-design .opf-dc-status:empty {
1977
+ min-height: 0;
1978
+ margin: 0;
1979
+ }
1980
+
1863
1981
  .opf-dc-warnings {
1864
1982
  margin: 0 0 10px;
1865
1983
  padding-left: 18px;
@@ -3234,7 +3352,6 @@ input.opf-lx-input[data-field="max"] { font-family: var(--opf-ui-mono); font-siz
3234
3352
  }
3235
3353
 
3236
3354
  .opf-numbering-note,
3237
- .opf-numbering-help,
3238
3355
  .opf-numbering-empty {
3239
3356
  font-size: 11.5px;
3240
3357
  color: var(--opf-ui-muted-fg);
@@ -3673,13 +3790,28 @@ input.opf-lx-input[data-field="max"] { font-family: var(--opf-ui-mono); font-siz
3673
3790
  background: color-mix(in srgb, var(--opf-ui-accent) 8%, transparent);
3674
3791
  }
3675
3792
 
3676
- :is(.opf-ui, .opf-json, .opf-code) .cm-selectionBackground,
3677
- :is(.opf-ui, .opf-json, .opf-code) .cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground {
3678
- background: color-mix(in srgb, var(--opf-ui-accent) 20%, transparent);
3793
+ /* The selection is a layer behind the text, so the text keeps its own colors: the tint is light enough that every token color (test/selection-contrast-browser.mjs
3794
+ measures each) keeps 4.5:1 against it, focused or not, in the light and the dark scheme. The focused rule of CodeMirror's base theme
3795
+ (`&light.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground`, `#d7d4f0` for light and `#233` for dark) has five classes, so
3796
+ the second selector has six and wins whichever stylesheet loads last; src/source-color-scheme.js flags the view dark so the rest of the base theme follows. */
3797
+ :is(.opf-ui, .opf-json, .opf-code) .cm-editor .cm-selectionLayer .cm-selectionBackground,
3798
+ :is(.opf-ui, .opf-json, .opf-code) .cm-editor.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground {
3799
+ background: color-mix(in srgb, var(--opf-ui-accent) 16%, transparent);
3800
+ }
3801
+
3802
+ /* A selection that is not drawn by CodeMirror (the handoff prompt, the data grid's text areas, the numbering preview) uses the browser's own, and a browser's
3803
+ default highlight is not made for our surfaces: the same tint, with the text color the surface already has, is 4.5:1 or better in both schemes. */
3804
+ :is(.opf-json, .opf-code, .opf-source-code, .opf-handoff-box, .opf-numbering-preview) ::selection,
3805
+ :is(.opf-handoff-prompt, .opf-numbering-preview, .opf-grid details textarea)::selection {
3806
+ background: color-mix(in srgb, var(--opf-ui-accent) 16%, transparent);
3807
+ color: var(--opf-ui-fg);
3679
3808
  }
3680
3809
 
3810
+ /* The other occurrences of the selected word: a 16% tint, so the lightest code text on it (a key in the dark scheme) keeps 4.5:1 (25% gave 4.2:1);
3811
+ the underline marks them at a glance. test/selection-contrast-browser.mjs measures it in both schemes. */
3681
3812
  :is(.opf-ui, .opf-json, .opf-code) .cm-selectionMatch {
3682
- background: color-mix(in srgb, var(--opf-ui-warn) 25%, transparent);
3813
+ background: color-mix(in srgb, var(--opf-ui-warn) 16%, transparent);
3814
+ box-shadow: inset 0 -1px 0 color-mix(in srgb, var(--opf-ui-warn) 70%, transparent);
3683
3815
  }
3684
3816
 
3685
3817
  :is(.opf-ui, .opf-json, .opf-code) .cm-matchingBracket {
@@ -4515,11 +4647,10 @@ input.opf-lx-input[data-field="max"] { font-family: var(--opf-ui-mono); font-siz
4515
4647
  .opf-source[data-density="touch"] .opf-source-code .cm-scroller { font-size: 13px; line-height: 21px; }
4516
4648
  .opf-source-code .cm-content { padding: 16px 16px 16px 4px; caret-color: var(--opf-ui-fg); }
4517
4649
  .opf-source-code .cm-line { --opf-line-start: 2px; padding-top: 0; padding-right: 2px; padding-bottom: 0; }
4518
- .opf-source-code .cm-gutters { border: 0; background: transparent; color: color-mix(in srgb, var(--opf-ui-muted-fg) 60%, transparent); }
4650
+ .opf-source-code .cm-gutters { border: 0; background: transparent; color: var(--opf-ui-muted-fg); }
4519
4651
  .opf-source-code .cm-lineNumbers .cm-gutterElement { min-width: 30px; padding: 0 12px 0 0; text-align: right; font-size: 11px; }
4520
4652
  .opf-source-code .cm-activeLine { background: transparent; }
4521
- .opf-source-code .cm-selectionBackground,
4522
- .opf-source-code .cm-focused .cm-selectionBackground { background: color-mix(in srgb, var(--opf-ui-accent) 16%, transparent); }
4653
+ /* The selection color is the shared one in panels.css (JSON editor section). */
4523
4654
  .opf-source-code .cm-cursor { border-left-color: var(--opf-ui-fg); }
4524
4655
  .opf-source-code .tok-key { color: var(--opf-ui-accent-strong); }
4525
4656
  .opf-source-code .tok-str { color: var(--opf-ui-fg); }
@@ -4532,6 +4663,16 @@ input.opf-lx-input[data-field="max"] { font-family: var(--opf-ui-mono); font-siz
4532
4663
  .opf-source-code .tok-comment { font-style: italic; }
4533
4664
  .opf-source-code .code-key.is-active { background: color-mix(in srgb, var(--opf-ui-accent) 10%, transparent); border-radius: var(--opf-ui-radius-sm); }
4534
4665
  .opf-source-code .cm-line.is-hover { background: color-mix(in srgb, var(--opf-ui-accent) 6%, transparent); }
4666
+ /* CE-17: decorations a host draws (setDecorations) and the flash of revealPath; the host styles any other kind as .opf-source-decoration-<kind>. */
4667
+ .opf-source-code .opf-source-decoration { background: color-mix(in srgb, var(--opf-ui-accent) 16%, transparent); border-radius: var(--opf-ui-radius-sm); }
4668
+ .opf-source-code .opf-source-decoration-error { background: color-mix(in srgb, var(--opf-ui-danger) 18%, transparent); }
4669
+ .opf-source-code .opf-source-decoration-warning { background: color-mix(in srgb, var(--opf-ui-warn) 20%, transparent); }
4670
+ .opf-source-code .opf-source-decoration-info { background: color-mix(in srgb, var(--opf-ui-accent) 10%, transparent); }
4671
+ .opf-source-code .opf-source-decoration-added { background: color-mix(in srgb, var(--opf-ui-success) 20%, transparent); }
4672
+ .opf-source-code .opf-source-decoration-changed { background: color-mix(in srgb, var(--opf-ui-warn) 14%, transparent); }
4673
+ .opf-source-code .cm-line.opf-source-flash { animation: opf-source-flash 1.2s ease-out; }
4674
+ @keyframes opf-source-flash { from { background: color-mix(in srgb, var(--opf-ui-accent) 32%, transparent); } to { background: transparent; } }
4675
+ @media (prefers-reduced-motion: reduce) { .opf-source-code .cm-line.opf-source-flash { animation: none; background: color-mix(in srgb, var(--opf-ui-accent) 20%, transparent); } }
4535
4676
  .opf-source-code .cm-panels { background: var(--opf-ui-surface); color: var(--opf-ui-fg); border-color: var(--opf-ui-border); }
4536
4677
  .opf-source-code .cm-tooltip { background: var(--opf-ui-surface); border: 1px solid var(--opf-ui-border); border-radius: var(--opf-ui-radius); color: var(--opf-ui-fg); }
4537
4678
  .opf-source-code .cm-lintRange-error { background-image: none; text-decoration: underline wavy var(--opf-ui-danger); }
@@ -4711,134 +4852,1430 @@ input.opf-lx-input[data-field="max"] { font-family: var(--opf-ui-mono); font-siz
4711
4852
  .cm-tooltip, .cm-tooltip * { animation: none !important; transition: none !important; }
4712
4853
  }
4713
4854
 
4714
- /* thumbnails.css */
4715
- /* Thumbnail strip (RR-98). Uses only --opf-ui-* tokens. */
4716
- .opf-thumbs {
4855
+ /* studio.css */
4856
+ /* CE-20: the Studio (`createOpfEditor(el, { layout: "studio" | "playground" })`). Only --opf-ui-* tokens. The arrangement follows data
4857
+ attributes on the root: data-preset (studio, playground), data-source (off, right, bottom, left), data-panels (shown, hidden),
4858
+ data-width (wide, medium, narrow), data-sheet (a phone's bottom sheet), data-view (slide, layouts) and data-editing. */
4859
+ .opf-studio {
4860
+ --opf-studio-bar: 40px;
4861
+ --opf-studio-statusbar: 28px;
4717
4862
  position: relative;
4718
- box-sizing: border-box;
4719
- min-width: 0;
4720
- min-height: 0;
4721
- font-family: var(--opf-ui-font);
4722
- color: var(--opf-ui-fg);
4723
- scrollbar-width: thin;
4724
- }
4725
- .opf-thumbs[data-orientation="horizontal"] {
4726
- overflow-x: auto;
4727
- overflow-y: hidden;
4863
+ display: flex;
4864
+ flex-direction: column;
4865
+ overflow: hidden;
4728
4866
  }
4729
- .opf-thumbs[data-orientation="vertical"] {
4730
- overflow-x: hidden;
4731
- overflow-y: auto;
4867
+ .opf-studio [hidden] {
4868
+ display: none !important;
4732
4869
  }
4733
- .opf-thumbs-list {
4870
+
4871
+ /* ---- the bar ----------------------------------------------------------------------------------------------------------------------- */
4872
+ .opf-studio-bar {
4734
4873
  display: flex;
4735
- gap: 12px;
4736
- margin: 0;
4737
- /* Room for the 2px ring and its 2px offset, which the scroll container would otherwise clip. */
4738
- padding: 6px 6px 6px;
4739
- list-style: none;
4740
- }
4741
- .opf-thumbs[data-orientation="horizontal"] .opf-thumbs-list {
4742
- flex-direction: row;
4743
- align-items: flex-start;
4744
- width: max-content;
4874
+ flex: none;
4875
+ align-items: center;
4876
+ gap: 4px;
4877
+ min-height: var(--opf-studio-bar);
4878
+ padding: 0 8px;
4879
+ border-bottom: 1px solid var(--opf-ui-border);
4880
+ background: var(--opf-ui-surface);
4881
+ overflow-x: auto;
4882
+ scrollbar-width: none;
4883
+ }
4884
+ .opf-studio-tools,
4885
+ .opf-studio-history,
4886
+ .opf-studio-views,
4887
+ .opf-studio-zoombar,
4888
+ .opf-studio-rail,
4889
+ .opf-studio-sheetbar,
4890
+ .opf-studio-actions {
4891
+ display: inline-flex;
4892
+ align-items: center;
4893
+ gap: 2px;
4745
4894
  }
4746
- .opf-thumbs[data-orientation="vertical"] .opf-thumbs-list {
4747
- flex-direction: column;
4895
+ .opf-studio-actions {
4896
+ flex-wrap: wrap;
4897
+ gap: 6px;
4748
4898
  }
4749
- .opf-thumbs[data-density="touch"] .opf-thumbs-list {
4750
- gap: 16px;
4899
+ .opf-studio-spacer {
4900
+ flex: 1 1 0;
4751
4901
  }
4752
- .opf-thumbs-slot {
4902
+ .opf-studio-barbutton,
4903
+ .opf-studio-iconbutton,
4904
+ .opf-studio-segment,
4905
+ .opf-studio-action,
4906
+ .opf-studio-validity,
4907
+ .opf-studio-linkbutton {
4908
+ display: inline-flex;
4753
4909
  flex: none;
4754
- width: var(--opf-thumbs-w);
4755
- }
4756
- .opf-thumbs-item {
4757
- display: flex;
4758
- flex-direction: column;
4759
- align-items: stretch;
4760
- justify-content: flex-start;
4910
+ align-items: center;
4911
+ justify-content: center;
4761
4912
  gap: 6px;
4762
4913
  box-sizing: border-box;
4763
- width: 100%;
4764
- min-height: 0;
4765
- margin: 0;
4766
- padding: 0;
4767
- font-weight: 400;
4768
- white-space: normal;
4769
- border: 0;
4770
- border-radius: var(--opf-ui-radius-sm);
4914
+ min-height: min(var(--opf-ui-control-h), 32px);
4915
+ padding: 0 8px;
4916
+ border: 1px solid transparent;
4917
+ border-radius: var(--opf-ui-radius);
4771
4918
  background: transparent;
4772
- color: var(--opf-ui-muted-fg);
4773
- font: inherit;
4774
- text-align: left;
4919
+ color: var(--opf-ui-fg);
4920
+ font: 500 13px/1 var(--opf-ui-font);
4921
+ white-space: nowrap;
4775
4922
  cursor: pointer;
4776
- transition: color var(--opf-ui-ease);
4923
+ transition: background-color var(--opf-ui-ease), border-color var(--opf-ui-ease), color var(--opf-ui-ease);
4777
4924
  }
4778
- .opf-thumbs-item:hover {
4779
- color: var(--opf-ui-fg);
4925
+ .opf-studio-iconbutton {
4926
+ min-width: min(var(--opf-ui-control-h), 32px);
4927
+ padding: 0;
4780
4928
  }
4781
- .opf-thumbs-item[aria-current="true"] {
4782
- color: var(--opf-ui-accent-strong);
4929
+ .opf-studio-action {
4930
+ border-color: var(--opf-ui-border);
4931
+ background: var(--opf-ui-surface);
4783
4932
  }
4784
- .opf-thumbs-item:focus-visible {
4785
- outline: 2px solid var(--opf-ui-ring);
4786
- outline-offset: 2px;
4933
+ .opf-studio-primary {
4934
+ border-color: var(--opf-ui-accent);
4935
+ background: var(--opf-ui-accent);
4936
+ color: var(--opf-ui-accent-fg);
4787
4937
  }
4788
- .opf-thumbs-frame {
4789
- display: block;
4790
- box-sizing: border-box;
4791
- width: 100%;
4792
- overflow: hidden;
4793
- aspect-ratio: var(--opf-thumbs-ratio);
4794
- border-radius: 3px;
4795
- background: var(--opf-ui-muted-2);
4796
- box-shadow: 0 0 0 1px var(--opf-ui-border);
4797
- outline: 2px solid transparent;
4798
- outline-offset: 2px;
4799
- transition: outline-color var(--opf-ui-ease);
4800
- pointer-events: none;
4938
+ .opf-studio-barbutton:hover:not(:disabled),
4939
+ .opf-studio-iconbutton:hover:not(:disabled),
4940
+ .opf-studio-segment:hover:not(:disabled),
4941
+ .opf-studio-action:hover:not(:disabled):not(.opf-studio-primary),
4942
+ .opf-studio-validity:hover {
4943
+ background: var(--opf-ui-muted);
4801
4944
  }
4802
- .opf-thumbs-item[aria-current="true"] .opf-thumbs-frame {
4803
- outline-color: var(--opf-ui-accent);
4945
+ .opf-studio-barbutton[aria-pressed="true"],
4946
+ .opf-studio-iconbutton[aria-pressed="true"],
4947
+ .opf-studio-segment[aria-pressed="true"],
4948
+ .opf-studio-barbutton[aria-expanded="true"] {
4949
+ border-color: var(--opf-ui-border-strong);
4950
+ background: var(--opf-ui-muted);
4951
+ color: var(--opf-ui-accent-strong);
4804
4952
  }
4805
- .opf-thumbs-frame > svg {
4806
- display: block;
4807
- width: 100%;
4808
- height: auto;
4953
+ .opf-studio button:disabled {
4954
+ opacity: 0.45;
4955
+ cursor: default;
4809
4956
  }
4810
- .opf-thumbs-frame[data-state="error"] {
4811
- display: grid;
4812
- place-items: center;
4813
- padding: 4px;
4814
- font: 11.5px/1.3 var(--opf-ui-mono);
4815
- text-align: center;
4816
- color: var(--opf-ui-muted-fg);
4957
+ .opf-studio-name {
4958
+ flex: 0 1 200px;
4959
+ min-width: 80px;
4960
+ height: 28px;
4961
+ padding: 0 8px;
4962
+ border: 1px solid transparent;
4963
+ border-radius: var(--opf-ui-radius-sm);
4964
+ background: transparent;
4965
+ color: var(--opf-ui-fg);
4966
+ font: 600 13px var(--opf-ui-font);
4967
+ text-overflow: ellipsis;
4817
4968
  }
4818
- .opf-thumbs-item[data-hidden="true"] .opf-thumbs-frame {
4819
- opacity: 0.55;
4969
+ .opf-studio-name:hover,
4970
+ .opf-studio-name:focus {
4971
+ border-color: var(--opf-ui-border);
4972
+ background: var(--opf-ui-surface);
4820
4973
  }
4821
- .opf-thumbs-label {
4822
- position: relative;
4823
- display: flex;
4824
- gap: 6px;
4825
- width: 100%;
4826
- min-width: 0;
4827
- font-size: 12px;
4828
- line-height: 1.4;
4829
- white-space: nowrap;
4974
+ .opf-studio-views {
4975
+ padding: 2px;
4976
+ border: 1px solid var(--opf-ui-border);
4977
+ border-radius: var(--opf-ui-radius);
4830
4978
  }
4831
- .opf-thumbs-index {
4832
- flex: none;
4833
- font-family: var(--opf-ui-mono);
4979
+ .opf-studio-zoombutton {
4980
+ min-width: 64px;
4981
+ font-variant-numeric: tabular-nums;
4834
4982
  }
4835
- .opf-thumbs-title {
4836
- min-width: 0;
4837
- overflow: hidden;
4838
- text-overflow: ellipsis;
4983
+ .opf-studio-topbar-end:empty {
4984
+ display: none;
4839
4985
  }
4840
- .opf-thumbs-title[data-untitled="true"] {
4841
- font-style: italic;
4986
+ .opf-studio-topbar-end,
4987
+ .opf-studio-present,
4988
+ .opf-studio-export {
4989
+ display: inline-flex;
4990
+ flex: none;
4991
+ align-items: center;
4992
+ gap: 4px;
4993
+ }
4994
+
4995
+ /* ---- the main row -------------------------------------------------------------------------------------------------------------------- */
4996
+ .opf-studio-main {
4997
+ position: relative;
4998
+ display: grid;
4999
+ flex: 1 1 0;
5000
+ grid-template-columns: var(--opf-studio-left, 232px) 4px minmax(0, 1fr) 4px var(--opf-studio-right, 280px);
5001
+ min-height: 0;
5002
+ }
5003
+ .opf-studio[data-panels="hidden"] .opf-studio-main,
5004
+ .opf-studio[data-preset="playground"] .opf-studio-main {
5005
+ grid-template-columns: 0 0 minmax(0, 1fr) 0 0;
5006
+ }
5007
+ .opf-studio[data-panels="hidden"] :is(.opf-studio-left, .opf-studio-right, .opf-studio-main > .opf-studio-splitter),
5008
+ .opf-studio[data-preset="playground"] :is(.opf-studio-left, .opf-studio-right, .opf-studio-main > .opf-studio-splitter) {
5009
+ display: none;
5010
+ }
5011
+ /* Each part keeps its column when a neighbor is not shown (a hidden aside would otherwise pull the slide into its column). */
5012
+ .opf-studio-main > .opf-studio-left {
5013
+ grid-column: 1;
5014
+ }
5015
+ .opf-studio-main > [data-resize="left"] {
5016
+ grid-column: 2;
5017
+ }
5018
+ .opf-studio-main > .opf-studio-center {
5019
+ grid-column: 3;
5020
+ }
5021
+ .opf-studio-main > [data-resize="right"] {
5022
+ grid-column: 4;
5023
+ }
5024
+ .opf-studio-main > .opf-studio-right {
5025
+ grid-column: 5;
5026
+ }
5027
+ .opf-studio-main > * {
5028
+ grid-row: 1;
5029
+ }
5030
+ .opf-studio-left,
5031
+ .opf-studio-right {
5032
+ display: flex;
5033
+ flex-direction: column;
5034
+ min-width: 0;
5035
+ min-height: 0;
5036
+ background: var(--opf-ui-surface);
5037
+ }
5038
+ .opf-studio-left {
5039
+ border-right: 1px solid var(--opf-ui-border);
5040
+ }
5041
+ .opf-studio-right {
5042
+ border-left: 1px solid var(--opf-ui-border);
5043
+ }
5044
+ .opf-studio-rail {
5045
+ display: none;
5046
+ }
5047
+ .opf-studio-slides {
5048
+ display: flex;
5049
+ flex: var(--opf-studio-stack, 0.5) 1 0;
5050
+ flex-direction: column;
5051
+ min-height: 80px;
5052
+ }
5053
+ .opf-studio-layers {
5054
+ display: flex;
5055
+ flex: calc(1 - var(--opf-studio-stack, 0.5)) 1 0;
5056
+ flex-direction: column;
5057
+ min-height: 80px;
5058
+ }
5059
+ .opf-studio-panelhead {
5060
+ display: flex;
5061
+ flex: none;
5062
+ align-items: center;
5063
+ gap: 4px;
5064
+ min-height: 32px;
5065
+ padding: 0 8px;
5066
+ }
5067
+ .opf-studio-paneltitle {
5068
+ flex: 1;
5069
+ margin: 0;
5070
+ color: var(--opf-ui-muted-fg);
5071
+ font: 600 11px var(--opf-ui-font);
5072
+ letter-spacing: 0.06em;
5073
+ text-transform: uppercase;
5074
+ }
5075
+ .opf-studio-slidetools {
5076
+ display: inline-flex;
5077
+ gap: 2px;
5078
+ }
5079
+ .opf-studio-filmstrip {
5080
+ flex: 1 1 0;
5081
+ min-height: 0;
5082
+ padding: 0 8px 8px;
5083
+ overflow: auto;
5084
+ }
5085
+ .opf-studio-splitter {
5086
+ position: relative;
5087
+ z-index: 3;
5088
+ background: transparent;
5089
+ touch-action: none;
5090
+ }
5091
+ .opf-studio-splitter::after {
5092
+ content: "";
5093
+ position: absolute;
5094
+ inset: 0;
5095
+ background: transparent;
5096
+ transition: background-color var(--opf-ui-ease);
5097
+ }
5098
+ .opf-studio-splitter:hover::after,
5099
+ .opf-studio-splitter:focus-visible::after {
5100
+ background: var(--opf-ui-accent);
5101
+ }
5102
+ .opf-studio-main > .opf-studio-splitter {
5103
+ cursor: col-resize;
5104
+ }
5105
+ .opf-studio-left > .opf-studio-splitter {
5106
+ flex: none;
5107
+ height: 4px;
5108
+ border-top: 1px solid var(--opf-ui-border);
5109
+ cursor: row-resize;
5110
+ }
5111
+
5112
+ /* ---- the layers ------------------------------------------------------------------------------------------------------------------- */
5113
+ .opf-studio-layershost {
5114
+ display: flex;
5115
+ flex: 1 1 0;
5116
+ min-height: 0;
5117
+ }
5118
+ .opf-studio-layers-scroll {
5119
+ position: relative;
5120
+ flex: 1;
5121
+ min-height: 0;
5122
+ overflow: auto;
5123
+ }
5124
+ .opf-studio-tree,
5125
+ .opf-studio-tree-group {
5126
+ margin: 0;
5127
+ padding: 0;
5128
+ list-style: none;
5129
+ }
5130
+ .opf-studio-row {
5131
+ outline: none;
5132
+ }
5133
+ .opf-studio-row-label {
5134
+ display: flex;
5135
+ align-items: center;
5136
+ gap: 4px;
5137
+ min-height: 26px;
5138
+ padding: 0 8px 0 calc(4px + var(--opf-studio-level, 0) * 14px);
5139
+ border-radius: var(--opf-ui-radius-sm);
5140
+ color: var(--opf-ui-fg);
5141
+ font: 12.5px var(--opf-ui-font);
5142
+ cursor: default;
5143
+ user-select: none;
5144
+ }
5145
+ .opf-studio-row[aria-selected="true"] > .opf-studio-row-label {
5146
+ background: color-mix(in srgb, var(--opf-ui-selection) 16%, transparent);
5147
+ color: var(--opf-ui-fg);
5148
+ }
5149
+ .opf-studio-row > .opf-studio-row-label:hover {
5150
+ background: var(--opf-ui-muted);
5151
+ }
5152
+ .opf-studio-row:focus-visible > .opf-studio-row-label {
5153
+ outline: 2px solid var(--opf-ui-ring);
5154
+ outline-offset: -2px;
5155
+ }
5156
+ .opf-studio-row-text {
5157
+ flex: 1;
5158
+ min-width: 0;
5159
+ overflow: hidden;
5160
+ text-overflow: ellipsis;
5161
+ white-space: nowrap;
5162
+ }
5163
+ .opf-studio-caret {
5164
+ display: inline-flex;
5165
+ flex: none;
5166
+ width: 14px;
5167
+ color: var(--opf-ui-muted-fg);
5168
+ }
5169
+ .opf-studio-row-badge {
5170
+ flex: none;
5171
+ min-width: 16px;
5172
+ padding: 0 4px;
5173
+ border-radius: 8px;
5174
+ background: var(--opf-ui-surface);
5175
+ color: var(--opf-ui-danger);
5176
+ font: 600 10.5px var(--opf-ui-font);
5177
+ text-align: center;
5178
+ box-shadow: inset 0 0 0 1px var(--opf-ui-danger);
5179
+ }
5180
+ .opf-studio-row-hidden {
5181
+ display: inline-flex;
5182
+ color: var(--opf-ui-muted-fg);
5183
+ }
5184
+ .opf-studio-tree-drop {
5185
+ position: absolute;
5186
+ z-index: 2;
5187
+ border-top: 2px solid var(--opf-ui-selection);
5188
+ pointer-events: none;
5189
+ }
5190
+ .opf-studio-tree-drop[data-mode="into"] {
5191
+ border: 2px solid var(--opf-ui-selection);
5192
+ border-radius: var(--opf-ui-radius-sm);
5193
+ }
5194
+ .opf-studio-tree-drop[data-state="refused"] {
5195
+ border-color: var(--opf-ui-danger);
5196
+ }
5197
+
5198
+ /* ---- the center: canvas, source, docks ---------------------------------------------------------------------------------------------- */
5199
+ .opf-studio-center {
5200
+ display: flex;
5201
+ min-width: 0;
5202
+ min-height: 0;
5203
+ }
5204
+ .opf-studio[data-source="bottom"] .opf-studio-center {
5205
+ flex-direction: column;
5206
+ }
5207
+ .opf-studio[data-source="left"] .opf-studio-center > :is(.opf-studio-sourcearea, .opf-studio-splitter) {
5208
+ order: -1;
5209
+ }
5210
+ .opf-studio-canvasarea {
5211
+ position: relative;
5212
+ display: flex;
5213
+ flex: 1 1 0;
5214
+ flex-direction: column;
5215
+ min-width: 0;
5216
+ min-height: 0;
5217
+ }
5218
+ .opf-studio-sourcearea {
5219
+ display: flex;
5220
+ flex: 0 0 calc(var(--opf-studio-split, 0.42) * 100%);
5221
+ flex-direction: column;
5222
+ min-width: 0;
5223
+ min-height: 0;
5224
+ background: var(--opf-ui-surface);
5225
+ }
5226
+ .opf-studio-source {
5227
+ display: flex;
5228
+ flex: 1;
5229
+ flex-direction: column;
5230
+ min-height: 0;
5231
+ }
5232
+ .opf-studio[data-source="off"] .opf-studio-center > :is(.opf-studio-sourcearea, .opf-studio-splitter) {
5233
+ display: none;
5234
+ }
5235
+ .opf-studio-center > .opf-studio-splitter {
5236
+ flex: none;
5237
+ width: 4px;
5238
+ border-left: 1px solid var(--opf-ui-border);
5239
+ cursor: col-resize;
5240
+ }
5241
+ .opf-studio[data-source="bottom"] .opf-studio-center > .opf-studio-splitter {
5242
+ width: auto;
5243
+ height: 4px;
5244
+ border-top: 1px solid var(--opf-ui-border);
5245
+ border-left: 0;
5246
+ cursor: row-resize;
5247
+ }
5248
+ .opf-studio[data-preset="playground"][data-playground-view="source"] .opf-studio-canvasarea {
5249
+ display: none;
5250
+ }
5251
+ .opf-studio[data-preset="playground"][data-playground-view="source"] .opf-studio-sourcearea {
5252
+ flex: 1 1 0;
5253
+ }
5254
+ .opf-studio[data-view="layouts"] .opf-studio-center > :not(.opf-studio-layoutsarea) {
5255
+ display: none;
5256
+ }
5257
+ .opf-studio-layoutsarea {
5258
+ display: flex;
5259
+ flex: 1 1 0;
5260
+ flex-direction: column;
5261
+ min-width: 0;
5262
+ min-height: 0;
5263
+ }
5264
+ .opf-studio-layouts {
5265
+ display: flex;
5266
+ flex: 1 1 0;
5267
+ flex-direction: column;
5268
+ min-height: 0;
5269
+ }
5270
+ .opf-studio-layouts .opf-ws-layouts-bar {
5271
+ display: none;
5272
+ }
5273
+ .opf-studio-layouts .opf-ws-layouts-host {
5274
+ flex: 1;
5275
+ min-height: 0;
5276
+ }
5277
+ .opf-studio-crumbs {
5278
+ display: flex;
5279
+ flex: none;
5280
+ align-items: center;
5281
+ gap: 8px;
5282
+ padding: 6px 8px;
5283
+ border-bottom: 1px solid var(--opf-ui-border);
5284
+ background: var(--opf-ui-surface);
5285
+ }
5286
+ .opf-studio-trail {
5287
+ display: flex;
5288
+ gap: 6px;
5289
+ margin: 0;
5290
+ padding: 0;
5291
+ list-style: none;
5292
+ font: 13px var(--opf-ui-font);
5293
+ }
5294
+ .opf-studio-trail li + li::before {
5295
+ content: "›";
5296
+ margin-right: 6px;
5297
+ color: var(--opf-ui-muted-fg);
5298
+ }
5299
+ .opf-studio-trail [aria-current="page"] {
5300
+ font-weight: 600;
5301
+ }
5302
+ .opf-studio-dock {
5303
+ display: none;
5304
+ flex: none;
5305
+ align-items: center;
5306
+ gap: 8px;
5307
+ padding: 4px 8px;
5308
+ border-top: 1px solid var(--opf-ui-border);
5309
+ background: var(--opf-ui-surface);
5310
+ }
5311
+ .opf-studio[data-preset="playground"] .opf-studio-dock {
5312
+ display: flex;
5313
+ }
5314
+ .opf-studio-thumbnails {
5315
+ flex: 1;
5316
+ min-width: 0;
5317
+ }
5318
+ .opf-studio-datadock {
5319
+ flex: none;
5320
+ max-height: 300px;
5321
+ overflow: auto;
5322
+ border-top: 1px solid var(--opf-ui-border);
5323
+ background: var(--opf-ui-surface);
5324
+ }
5325
+ .opf-studio-datahead {
5326
+ display: flex;
5327
+ align-items: center;
5328
+ gap: 4px;
5329
+ padding: 0 8px;
5330
+ }
5331
+
5332
+ /* ---- the viewport and the slide ------------------------------------------------------------------------------------------------------- */
5333
+ .opf-studio-viewport {
5334
+ display: flex;
5335
+ flex: 1 1 0;
5336
+ min-height: 0;
5337
+ overflow: auto;
5338
+ container-type: size;
5339
+ background: var(--opf-ui-studio-canvas-bg);
5340
+ overscroll-behavior: contain;
5341
+ }
5342
+ .opf-studio[data-preset="studio"] .opf-studio-viewport {
5343
+ touch-action: none;
5344
+ }
5345
+ .opf-studio-stage {
5346
+ flex: none;
5347
+ margin: auto;
5348
+ padding: 24px;
5349
+ }
5350
+ .opf-studio-frame {
5351
+ position: relative;
5352
+ width: calc(min(100cqw - 48px, (100cqh - 48px) * var(--opf-studio-aspect, 1.7778)) * var(--opf-studio-zoom, 1));
5353
+ min-width: 120px;
5354
+ background: var(--opf-ui-surface);
5355
+ box-shadow: var(--opf-ui-shadow-pop);
5356
+ outline: none;
5357
+ -webkit-user-select: none;
5358
+ user-select: none;
5359
+ }
5360
+ .opf-studio-frame:focus-visible {
5361
+ outline: 2px solid var(--opf-ui-ring);
5362
+ outline-offset: 2px;
5363
+ }
5364
+ .opf-studio-canvas,
5365
+ .opf-studio-canvas .opf-canvas {
5366
+ width: 100%;
5367
+ }
5368
+ .opf-studio[data-tool="hand"] .opf-studio-viewport,
5369
+ .opf-studio[data-space="true"] .opf-studio-viewport {
5370
+ cursor: grab;
5371
+ }
5372
+ .opf-studio[data-panning="true"] .opf-studio-viewport {
5373
+ cursor: grabbing;
5374
+ }
5375
+ .opf-studio[data-tool="text"] .opf-studio-overlay {
5376
+ cursor: text;
5377
+ }
5378
+ .opf-studio-overlay {
5379
+ position: absolute;
5380
+ inset: 0;
5381
+ z-index: 5;
5382
+ pointer-events: auto;
5383
+ }
5384
+ .opf-studio[data-overlay="off"] .opf-studio-overlay,
5385
+ .opf-studio[data-editing="true"] .opf-studio-overlay {
5386
+ pointer-events: none;
5387
+ }
5388
+ .opf-studio[data-overlay="off"] .opf-studio-overlay > *,
5389
+ .opf-studio[data-editing="true"] .opf-studio-overlay > :not(.opf-studio-markers) {
5390
+ visibility: hidden;
5391
+ }
5392
+ .opf-studio-layer,
5393
+ .opf-studio-dividers {
5394
+ position: absolute;
5395
+ inset: 0;
5396
+ pointer-events: none;
5397
+ }
5398
+ .opf-studio-box {
5399
+ position: absolute;
5400
+ border-radius: 2px;
5401
+ pointer-events: none;
5402
+ outline: none;
5403
+ }
5404
+ .opf-studio-box.is-selected {
5405
+ box-shadow: 0 0 0 1px var(--opf-ui-surface), 0 0 0 3px var(--opf-ui-selection), 0 0 0 4px var(--opf-ui-surface);
5406
+ }
5407
+ .opf-studio-box[data-kind="slide"].is-selected {
5408
+ box-shadow: inset 0 0 0 1px var(--opf-ui-surface), inset 0 0 0 3px var(--opf-ui-selection), inset 0 0 0 4px var(--opf-ui-surface);
5409
+ }
5410
+ .opf-studio-box:focus-visible {
5411
+ outline: 2px dashed var(--opf-ui-ring);
5412
+ outline-offset: 5px;
5413
+ }
5414
+ .opf-studio-box[data-kind="slide"]:focus-visible {
5415
+ outline-offset: -8px;
5416
+ }
5417
+ .opf-studio-box.is-dragging {
5418
+ background: color-mix(in srgb, var(--opf-ui-selection) 12%, transparent);
5419
+ opacity: 0.6;
5420
+ }
5421
+ .opf-studio-box[data-into="true"] {
5422
+ background: color-mix(in srgb, var(--opf-ui-selection) 10%, transparent);
5423
+ box-shadow: 0 0 0 2px var(--opf-ui-selection);
5424
+ }
5425
+ .opf-studio-box[data-finding="error"]:not(.is-selected) {
5426
+ box-shadow: 0 0 0 1px var(--opf-ui-danger);
5427
+ }
5428
+ .opf-studio-badge {
5429
+ position: absolute;
5430
+ top: -8px;
5431
+ right: -8px;
5432
+ display: inline-flex;
5433
+ border-radius: 50%;
5434
+ background: var(--opf-ui-surface);
5435
+ color: var(--opf-ui-danger);
5436
+ }
5437
+ .opf-studio-hover {
5438
+ position: absolute;
5439
+ border: 1px solid var(--opf-ui-hover);
5440
+ border-radius: 2px;
5441
+ pointer-events: none;
5442
+ }
5443
+ .opf-studio-parent {
5444
+ position: absolute;
5445
+ border: 1px dashed var(--opf-ui-selection);
5446
+ border-radius: 2px;
5447
+ pointer-events: none;
5448
+ }
5449
+ .opf-studio-chip {
5450
+ position: absolute;
5451
+ z-index: 3;
5452
+ max-width: 220px;
5453
+ margin-top: -4px;
5454
+ padding: 1px 6px;
5455
+ overflow: hidden;
5456
+ border-radius: var(--opf-ui-radius-sm);
5457
+ background: var(--opf-ui-selection);
5458
+ color: var(--opf-ui-surface);
5459
+ font: 500 11px/16px var(--opf-ui-mono);
5460
+ white-space: nowrap;
5461
+ text-overflow: ellipsis;
5462
+ translate: -1px -100%;
5463
+ pointer-events: none;
5464
+ }
5465
+ .opf-studio-divider {
5466
+ position: absolute;
5467
+ z-index: 4;
5468
+ pointer-events: auto;
5469
+ touch-action: none;
5470
+ }
5471
+ .opf-studio-divider[data-orientation="vertical"] {
5472
+ width: 12px !important;
5473
+ translate: -50% 0;
5474
+ cursor: col-resize;
5475
+ }
5476
+ .opf-studio-divider[data-orientation="horizontal"] {
5477
+ height: 12px !important;
5478
+ translate: 0 -50%;
5479
+ cursor: row-resize;
5480
+ }
5481
+ .opf-studio-divider::after {
5482
+ content: "";
5483
+ position: absolute;
5484
+ border-radius: 2px;
5485
+ background: color-mix(in srgb, var(--opf-ui-selection) 35%, transparent);
5486
+ transition: background-color var(--opf-ui-ease);
5487
+ }
5488
+ .opf-studio-divider[data-orientation="vertical"]::after {
5489
+ top: 6px;
5490
+ bottom: 6px;
5491
+ left: calc(50% - 1px);
5492
+ width: 2px;
5493
+ }
5494
+ .opf-studio-divider[data-orientation="horizontal"]::after {
5495
+ left: 6px;
5496
+ right: 6px;
5497
+ top: calc(50% - 1px);
5498
+ height: 2px;
5499
+ }
5500
+ .opf-studio-divider[data-fixed="false"]:hover::after,
5501
+ .opf-studio-divider[data-fixed="false"]:focus-visible::after,
5502
+ .opf-studio-divider[data-active="true"]::after {
5503
+ background: var(--opf-ui-selection);
5504
+ }
5505
+ .opf-studio-divider[data-fixed="true"] {
5506
+ pointer-events: none;
5507
+ }
5508
+ .opf-studio-divider:focus-visible {
5509
+ outline: 2px solid var(--opf-ui-ring);
5510
+ outline-offset: 1px;
5511
+ }
5512
+ .opf-studio[data-dragging="true"] .opf-studio-divider {
5513
+ pointer-events: none;
5514
+ }
5515
+ .opf-studio-drop {
5516
+ position: absolute;
5517
+ z-index: 6;
5518
+ border-radius: 2px;
5519
+ background: var(--opf-ui-selection);
5520
+ pointer-events: none;
5521
+ }
5522
+ .opf-studio-drop[data-orientation="vertical"] {
5523
+ width: 3px !important;
5524
+ translate: -50% 0;
5525
+ }
5526
+ .opf-studio-drop[data-orientation="horizontal"] {
5527
+ height: 3px !important;
5528
+ translate: 0 -50%;
5529
+ }
5530
+ .opf-studio-drop[data-state="refused"] {
5531
+ background: var(--opf-ui-danger);
5532
+ }
5533
+ .opf-studio-drop[data-state="same"] {
5534
+ background: var(--opf-ui-border-strong);
5535
+ }
5536
+ .opf-studio-ratio {
5537
+ position: absolute;
5538
+ z-index: 7;
5539
+ padding: 2px 8px;
5540
+ border-radius: var(--opf-ui-radius-sm);
5541
+ background: var(--opf-ui-selection);
5542
+ color: var(--opf-ui-surface);
5543
+ font: 500 11.5px var(--opf-ui-mono);
5544
+ white-space: nowrap;
5545
+ translate: -50% -50%;
5546
+ pointer-events: none;
5547
+ }
5548
+ .opf-studio-markers {
5549
+ position: absolute;
5550
+ inset: 0;
5551
+ pointer-events: none;
5552
+ }
5553
+ .opf-studio-ghost {
5554
+ position: absolute;
5555
+ z-index: 40;
5556
+ max-width: 220px;
5557
+ padding: 3px 10px;
5558
+ overflow: hidden;
5559
+ border: 1px solid var(--opf-ui-selection);
5560
+ border-radius: var(--opf-ui-radius);
5561
+ background: var(--opf-ui-surface);
5562
+ color: var(--opf-ui-accent-strong);
5563
+ font: 500 11.5px var(--opf-ui-mono);
5564
+ white-space: nowrap;
5565
+ text-overflow: ellipsis;
5566
+ pointer-events: none;
5567
+ }
5568
+ .opf-studio-placeholders {
5569
+ position: absolute;
5570
+ inset: 0;
5571
+ pointer-events: none;
5572
+ }
5573
+ .opf-studio-placeholder {
5574
+ position: absolute;
5575
+ display: flex;
5576
+ align-items: center;
5577
+ justify-content: center;
5578
+ gap: 6px;
5579
+ border: 1px dashed var(--opf-ui-border-strong);
5580
+ border-radius: var(--opf-ui-radius-sm);
5581
+ color: var(--opf-ui-muted-fg);
5582
+ font: 12px var(--opf-ui-font);
5583
+ }
5584
+ .opf-studio-placeholder-add {
5585
+ display: inline-flex;
5586
+ align-items: center;
5587
+ justify-content: center;
5588
+ width: 28px;
5589
+ height: 28px;
5590
+ padding: 0;
5591
+ border: 1px solid var(--opf-ui-border);
5592
+ border-radius: 50%;
5593
+ background: var(--opf-ui-surface);
5594
+ color: var(--opf-ui-fg);
5595
+ cursor: pointer;
5596
+ pointer-events: auto;
5597
+ }
5598
+ @media (pointer: coarse) {
5599
+ .opf-studio .opf-studio-placeholder-add {
5600
+ width: 44px;
5601
+ height: 44px;
5602
+ }
5603
+ }
5604
+ .opf-studio-empty {
5605
+ position: absolute;
5606
+ inset: 0;
5607
+ z-index: 2;
5608
+ display: flex;
5609
+ flex-wrap: wrap;
5610
+ align-content: center;
5611
+ align-items: center;
5612
+ justify-content: center;
5613
+ gap: 8px;
5614
+ pointer-events: none;
5615
+ }
5616
+ .opf-studio-empty > * {
5617
+ pointer-events: auto;
5618
+ }
5619
+ .opf-studio-empty-text {
5620
+ flex: 0 0 100%;
5621
+ margin: 0;
5622
+ color: var(--opf-ui-muted-fg);
5623
+ font: 14px var(--opf-ui-font);
5624
+ text-align: center;
5625
+ }
5626
+ .opf-studio-empty-button {
5627
+ display: inline-flex;
5628
+ align-items: center;
5629
+ gap: 6px;
5630
+ min-height: min(var(--opf-ui-control-h), 32px);
5631
+ padding: 0 10px;
5632
+ border: 1px solid var(--opf-ui-border);
5633
+ border-radius: var(--opf-ui-radius);
5634
+ background: var(--opf-ui-surface);
5635
+ color: var(--opf-ui-fg);
5636
+ font: 500 13px var(--opf-ui-font);
5637
+ cursor: pointer;
5638
+ }
5639
+ .opf-studio-actionbar {
5640
+ position: absolute;
5641
+ z-index: 20;
5642
+ display: flex;
5643
+ gap: 4px;
5644
+ padding: 4px;
5645
+ border: 1px solid var(--opf-ui-border);
5646
+ border-radius: var(--opf-ui-radius-md);
5647
+ background: var(--opf-ui-surface);
5648
+ box-shadow: var(--opf-ui-shadow-pop);
5649
+ }
5650
+ .opf-studio-actionbar .opf-studio-iconbutton {
5651
+ min-width: 44px;
5652
+ min-height: 44px;
5653
+ }
5654
+
5655
+ /* ---- the right panel -------------------------------------------------------------------------------------------------------------------- */
5656
+ .opf-studio-tabs {
5657
+ display: flex;
5658
+ flex: none;
5659
+ gap: 2px;
5660
+ padding: 4px 6px 0;
5661
+ border-bottom: 1px solid var(--opf-ui-border);
5662
+ }
5663
+ .opf-studio-tab {
5664
+ min-height: 30px;
5665
+ padding: 0 10px;
5666
+ border: 0;
5667
+ border-bottom: 2px solid transparent;
5668
+ background: transparent;
5669
+ color: var(--opf-ui-muted-fg);
5670
+ font: 500 13px var(--opf-ui-font);
5671
+ cursor: pointer;
5672
+ }
5673
+ .opf-studio-tab[aria-selected="true"] {
5674
+ border-bottom-color: var(--opf-ui-accent);
5675
+ color: var(--opf-ui-fg);
5676
+ }
5677
+ .opf-studio-tabpanel {
5678
+ flex: 1 1 0;
5679
+ min-height: 0;
5680
+ overflow: auto;
5681
+ }
5682
+ .opf-studio-design {
5683
+ display: flex;
5684
+ flex-direction: column;
5685
+ gap: 4px;
5686
+ padding: 8px 10px 16px;
5687
+ }
5688
+ .opf-studio-design-title {
5689
+ margin: 4px 0;
5690
+ overflow: hidden;
5691
+ font: 600 14px var(--opf-ui-font);
5692
+ text-overflow: ellipsis;
5693
+ white-space: nowrap;
5694
+ }
5695
+ .opf-studio-design-notice {
5696
+ margin: 0;
5697
+ padding: 6px 8px;
5698
+ border: 1px solid var(--opf-ui-border);
5699
+ border-radius: var(--opf-ui-radius);
5700
+ color: var(--opf-ui-warn);
5701
+ }
5702
+ .opf-studio-section {
5703
+ display: flex;
5704
+ flex-direction: column;
5705
+ gap: 8px;
5706
+ padding: 8px 0;
5707
+ border-bottom: 1px solid var(--opf-ui-border);
5708
+ }
5709
+ .opf-studio-section-title {
5710
+ margin: 0;
5711
+ color: var(--opf-ui-muted-fg);
5712
+ font: 600 11px var(--opf-ui-font);
5713
+ letter-spacing: 0.06em;
5714
+ text-transform: uppercase;
5715
+ }
5716
+ .opf-studio-field {
5717
+ display: grid;
5718
+ grid-template-columns: 96px minmax(0, 1fr);
5719
+ align-items: center;
5720
+ gap: 4px 8px;
5721
+ }
5722
+ .opf-studio-field-label {
5723
+ color: var(--opf-ui-muted-fg);
5724
+ font: 12.5px var(--opf-ui-font);
5725
+ }
5726
+ .opf-studio-scrub {
5727
+ cursor: ew-resize;
5728
+ user-select: none;
5729
+ }
5730
+ .opf-studio-number,
5731
+ .opf-studio-input,
5732
+ .opf-studio-notes {
5733
+ box-sizing: border-box;
5734
+ width: 100%;
5735
+ min-height: 28px;
5736
+ padding: 4px 6px;
5737
+ border: 1px solid var(--opf-ui-border);
5738
+ border-radius: var(--opf-ui-radius-sm);
5739
+ background: var(--opf-ui-surface);
5740
+ color: var(--opf-ui-fg);
5741
+ font: 13px var(--opf-ui-font);
5742
+ }
5743
+ .opf-studio-notes {
5744
+ grid-column: 1 / -1;
5745
+ resize: vertical;
5746
+ }
5747
+ /* An arrangement is one row of icon segments; each is named, with its name as its tooltip. */
5748
+ .opf-studio-segmented {
5749
+ display: grid;
5750
+ grid-template-columns: repeat(4, minmax(0, 1fr));
5751
+ gap: 2px;
5752
+ padding: 2px;
5753
+ border: 1px solid var(--opf-ui-border);
5754
+ border-radius: var(--opf-ui-radius);
5755
+ }
5756
+ .opf-studio-segmented .opf-studio-segment {
5757
+ min-height: 26px;
5758
+ padding: 0;
5759
+ }
5760
+ .opf-studio-design .opf-dc-toolbar {
5761
+ margin: 0;
5762
+ }
5763
+ .opf-studio-design button[aria-disabled="true"] {
5764
+ opacity: 0.45;
5765
+ cursor: default;
5766
+ }
5767
+ .opf-studio-path {
5768
+ display: inline-flex;
5769
+ max-width: 100%;
5770
+ align-items: center;
5771
+ align-self: flex-start;
5772
+ gap: 6px;
5773
+ margin: 0 0 8px;
5774
+ padding: 2px 6px;
5775
+ border: 1px solid var(--opf-ui-border);
5776
+ border-radius: var(--opf-ui-radius-sm);
5777
+ background: var(--opf-ui-muted);
5778
+ color: var(--opf-ui-fg);
5779
+ font: 11.5px/1.5 var(--opf-ui-mono);
5780
+ cursor: pointer;
5781
+ }
5782
+ .opf-studio-path[hidden] {
5783
+ display: none;
5784
+ }
5785
+ .opf-studio-path > code {
5786
+ overflow: hidden;
5787
+ font: inherit;
5788
+ text-overflow: ellipsis;
5789
+ white-space: nowrap;
5790
+ }
5791
+ .opf-studio-path > svg {
5792
+ flex: none;
5793
+ color: var(--opf-ui-muted-fg);
5794
+ }
5795
+ .opf-studio-weights {
5796
+ display: grid;
5797
+ gap: 4px;
5798
+ }
5799
+ .opf-studio-layout-row {
5800
+ display: flex;
5801
+ align-items: center;
5802
+ gap: 8px;
5803
+ }
5804
+ .opf-studio-layout-row .opf-layout-diagram,
5805
+ .opf-studio-menu .opf-layout-diagram {
5806
+ flex: none;
5807
+ width: 48px;
5808
+ height: 27px;
5809
+ }
5810
+ .opf-studio-layout-name {
5811
+ font: 500 13px var(--opf-ui-font);
5812
+ }
5813
+ .opf-studio-rules {
5814
+ display: grid;
5815
+ grid-template-columns: auto 1fr;
5816
+ gap: 4px 12px;
5817
+ margin: 0;
5818
+ font: 12.5px var(--opf-ui-font);
5819
+ }
5820
+ .opf-studio-rules dt {
5821
+ color: var(--opf-ui-muted-fg);
5822
+ }
5823
+ .opf-studio-rules dd {
5824
+ margin: 0;
5825
+ }
5826
+ .opf-studio-design-advanced > summary {
5827
+ padding: 8px 0;
5828
+ color: var(--opf-ui-muted-fg);
5829
+ font: 600 11px var(--opf-ui-font);
5830
+ letter-spacing: 0.06em;
5831
+ text-transform: uppercase;
5832
+ cursor: pointer;
5833
+ }
5834
+ .opf-studio-design-live {
5835
+ margin: 0;
5836
+ min-height: 0;
5837
+ font: 12px var(--opf-ui-font);
5838
+ }
5839
+
5840
+ /* ---- the status line ---------------------------------------------------------------------------------------------------------------- */
5841
+ .opf-studio-status {
5842
+ display: flex;
5843
+ flex: none;
5844
+ align-items: center;
5845
+ gap: 12px;
5846
+ min-height: var(--opf-studio-statusbar);
5847
+ padding: 0 8px;
5848
+ border-top: 1px solid var(--opf-ui-border);
5849
+ background: var(--opf-ui-surface);
5850
+ color: var(--opf-ui-muted-fg);
5851
+ font: 12px var(--opf-ui-font);
5852
+ }
5853
+ .opf-studio-status .opf-studio-iconbutton,
5854
+ .opf-studio-status .opf-studio-validity {
5855
+ min-width: 24px;
5856
+ min-height: 24px;
5857
+ font-size: 12px;
5858
+ }
5859
+ .opf-studio-validity[data-state="valid"] {
5860
+ color: var(--opf-ui-success);
5861
+ }
5862
+ .opf-studio-validity[data-state="findings"] {
5863
+ color: var(--opf-ui-warn);
5864
+ }
5865
+ .opf-studio-validity[data-state="error"] {
5866
+ color: var(--opf-ui-danger);
5867
+ }
5868
+ .opf-studio-counter,
5869
+ .opf-studio-zoomlabel {
5870
+ font-variant-numeric: tabular-nums;
5871
+ }
5872
+ .opf-studio-zoomlabel {
5873
+ min-width: 40px;
5874
+ text-align: center;
5875
+ }
5876
+ .opf-studio-message {
5877
+ flex: 1;
5878
+ min-width: 0;
5879
+ margin: 0;
5880
+ overflow: hidden;
5881
+ color: var(--opf-ui-fg);
5882
+ text-overflow: ellipsis;
5883
+ white-space: nowrap;
5884
+ }
5885
+ .opf-studio-sheetbar {
5886
+ display: none;
5887
+ }
5888
+ .opf-studio[data-preset="playground"] .opf-studio-zoombar {
5889
+ display: none;
5890
+ }
5891
+
5892
+ /* ---- menus and dialogs -------------------------------------------------------------------------------------------------------------- */
5893
+ .opf-studio-menu {
5894
+ position: absolute;
5895
+ z-index: 50;
5896
+ display: flex;
5897
+ flex-direction: column;
5898
+ min-width: 220px;
5899
+ max-width: min(360px, calc(100% - 16px));
5900
+ max-height: min(70vh, 560px);
5901
+ padding: 4px;
5902
+ overflow: auto;
5903
+ border: 1px solid var(--opf-ui-border);
5904
+ border-radius: var(--opf-ui-radius-md);
5905
+ background: var(--opf-ui-surface);
5906
+ box-shadow: var(--opf-ui-shadow-pop);
5907
+ }
5908
+ .opf-studio-menuitem {
5909
+ display: flex;
5910
+ align-items: center;
5911
+ gap: 8px;
5912
+ min-height: min(var(--opf-ui-control-h), 32px);
5913
+ padding: 4px 8px;
5914
+ border: 0;
5915
+ border-radius: var(--opf-ui-radius-sm);
5916
+ background: transparent;
5917
+ color: var(--opf-ui-fg);
5918
+ font: 13px var(--opf-ui-font);
5919
+ text-align: left;
5920
+ cursor: pointer;
5921
+ }
5922
+ .opf-studio-menuitem:hover,
5923
+ .opf-studio-menuitem:focus-visible {
5924
+ background: var(--opf-ui-muted);
5925
+ }
5926
+ .opf-studio-menuitem:focus-visible {
5927
+ outline: 2px solid var(--opf-ui-ring);
5928
+ outline-offset: -2px;
5929
+ }
5930
+ .opf-studio-menuitem[aria-disabled="true"] {
5931
+ color: var(--opf-ui-muted-fg);
5932
+ cursor: default;
5933
+ }
5934
+ .opf-studio-menu-label {
5935
+ flex: 1;
5936
+ }
5937
+ .opf-studio-menu-text {
5938
+ display: flex;
5939
+ flex: 1;
5940
+ flex-direction: column;
5941
+ gap: 1px;
5942
+ }
5943
+ .opf-studio-menu-description {
5944
+ color: var(--opf-ui-muted-fg);
5945
+ font-size: 11.5px;
5946
+ }
5947
+ .opf-studio-menu-hint {
5948
+ color: var(--opf-ui-muted-fg);
5949
+ font: 11.5px var(--opf-ui-mono);
5950
+ }
5951
+ .opf-studio-menu-heading {
5952
+ padding: 6px 8px 2px;
5953
+ color: var(--opf-ui-muted-fg);
5954
+ font: 600 11px var(--opf-ui-font);
5955
+ letter-spacing: 0.06em;
5956
+ text-transform: uppercase;
5957
+ }
5958
+ .opf-studio-menu-group {
5959
+ display: flex;
5960
+ flex-direction: column;
5961
+ }
5962
+ .opf-studio-menu-separator {
5963
+ margin: 4px 0;
5964
+ border-top: 1px solid var(--opf-ui-border);
5965
+ }
5966
+ .opf-studio-dialog {
5967
+ position: absolute;
5968
+ top: 10%;
5969
+ left: 50%;
5970
+ z-index: 60;
5971
+ display: flex;
5972
+ flex-direction: column;
5973
+ gap: 10px;
5974
+ width: min(560px, calc(100% - 32px));
5975
+ max-height: 80%;
5976
+ padding: 16px;
5977
+ overflow: auto;
5978
+ border: 1px solid var(--opf-ui-border);
5979
+ border-radius: var(--opf-ui-radius-lg);
5980
+ background: var(--opf-ui-surface);
5981
+ color: var(--opf-ui-fg);
5982
+ box-shadow: var(--opf-ui-shadow-pop);
5983
+ translate: -50% 0;
5984
+ }
5985
+ .opf-studio-dialoghead {
5986
+ display: flex;
5987
+ align-items: center;
5988
+ justify-content: space-between;
5989
+ }
5990
+ .opf-studio-dialog-title {
5991
+ margin: 0;
5992
+ font: 600 15px var(--opf-ui-font);
5993
+ }
5994
+ .opf-studio-shortcutgroup dl {
5995
+ display: grid;
5996
+ grid-template-columns: 1fr auto;
5997
+ gap: 2px 12px;
5998
+ margin: 4px 0 8px;
5999
+ }
6000
+ .opf-studio-shortcutgroup dt,
6001
+ .opf-studio-shortcutgroup dd {
6002
+ margin: 0;
6003
+ }
6004
+ .opf-studio-shortcutgroup dd {
6005
+ display: flex;
6006
+ gap: 4px;
6007
+ }
6008
+ .opf-studio-shortcutgroup kbd {
6009
+ padding: 1px 6px;
6010
+ border: 1px solid var(--opf-ui-border);
6011
+ border-radius: var(--opf-ui-radius-sm);
6012
+ background: var(--opf-ui-muted-2);
6013
+ font: 11.5px var(--opf-ui-mono);
6014
+ }
6015
+ .opf-studio-linkbutton {
6016
+ min-height: 24px;
6017
+ padding: 0;
6018
+ font-weight: 400;
6019
+ }
6020
+ .opf-studio-linkbutton[aria-disabled="true"] {
6021
+ color: var(--opf-ui-muted-fg);
6022
+ }
6023
+ .opf-studio-fileinput {
6024
+ display: none;
6025
+ }
6026
+
6027
+ /* ---- widths: medium (a rail of panels), narrow (a phone: bottom sheet, filmstrip strip) ------------------------------------------------------ */
6028
+ .opf-studio[data-width="medium"] .opf-studio-main {
6029
+ grid-template-columns: 48px 0 minmax(0, 1fr) 4px var(--opf-studio-right, 280px);
6030
+ }
6031
+ .opf-studio[data-width="medium"] .opf-studio-rail {
6032
+ display: flex;
6033
+ flex-direction: column;
6034
+ padding: 6px 0;
6035
+ }
6036
+ .opf-studio[data-width="medium"] .opf-studio-left > :not(.opf-studio-rail) {
6037
+ display: none;
6038
+ }
6039
+ .opf-studio[data-width="medium"][data-left-open="slides"] .opf-studio-left > .opf-studio-slides,
6040
+ .opf-studio[data-width="medium"][data-left-open="layers"] .opf-studio-left > .opf-studio-layers {
6041
+ position: absolute;
6042
+ top: 0;
6043
+ bottom: 0;
6044
+ left: 48px;
6045
+ z-index: 30;
6046
+ display: flex;
6047
+ width: 260px;
6048
+ border-right: 1px solid var(--opf-ui-border);
6049
+ background: var(--opf-ui-surface);
6050
+ box-shadow: var(--opf-ui-shadow-pop);
6051
+ }
6052
+ .opf-studio[data-width="medium"] .opf-studio-main > .opf-studio-splitter:first-of-type {
6053
+ display: none;
6054
+ }
6055
+ .opf-studio[data-width="narrow"] .opf-studio-main {
6056
+ grid-template-columns: 0 0 minmax(0, 1fr) 0 0;
6057
+ }
6058
+ .opf-studio[data-width="narrow"] :is(.opf-studio-left, .opf-studio-right, .opf-studio-main > .opf-studio-splitter) {
6059
+ display: none;
6060
+ }
6061
+ .opf-studio[data-width="narrow"][data-preset="studio"] .opf-studio-sheetbar {
6062
+ display: inline-flex;
6063
+ }
6064
+ .opf-studio[data-width="narrow"] :is(.opf-studio-format, .opf-studio-counter, .opf-studio-zoombar, .opf-studio-name) {
6065
+ display: none;
6066
+ }
6067
+ .opf-studio[data-width="narrow"][data-sheet="slides"] .opf-studio-left,
6068
+ .opf-studio[data-width="narrow"][data-sheet="layers"] .opf-studio-left,
6069
+ .opf-studio[data-width="narrow"][data-sheet="design"] .opf-studio-right,
6070
+ .opf-studio[data-width="narrow"][data-sheet="review"] .opf-studio-right {
6071
+ position: absolute;
6072
+ left: 0;
6073
+ right: 0;
6074
+ bottom: 0;
6075
+ z-index: 30;
6076
+ display: flex;
6077
+ grid-column: 1 / -1;
6078
+ height: 55%;
6079
+ border: 0;
6080
+ border-top: 1px solid var(--opf-ui-border);
6081
+ border-radius: var(--opf-ui-radius-lg) var(--opf-ui-radius-lg) 0 0;
6082
+ box-shadow: var(--opf-ui-shadow-pop);
6083
+ }
6084
+ .opf-studio[data-width="narrow"][data-sheet="slides"] .opf-studio-left > :not(.opf-studio-slides),
6085
+ .opf-studio[data-width="narrow"][data-sheet="layers"] .opf-studio-left > :not(.opf-studio-layers) {
6086
+ display: none;
6087
+ }
6088
+ .opf-studio[data-width="narrow"] .opf-studio-left > :is(.opf-studio-slides, .opf-studio-layers) {
6089
+ flex: 1 1 0;
6090
+ }
6091
+
6092
+ /* ---- touch: 44px targets ------------------------------------------------------------------------------------------------------------- */
6093
+ .opf-studio[data-density="touch"] :is(.opf-studio-barbutton, .opf-studio-iconbutton, .opf-studio-segment, .opf-studio-action, .opf-studio-tab, .opf-studio-menuitem, .opf-studio-validity, .opf-studio-path, .opf-dc-tool) {
6094
+ min-width: 44px;
6095
+ min-height: 44px;
6096
+ }
6097
+ .opf-studio[data-density="touch"] .opf-studio-row-label {
6098
+ min-height: 44px;
6099
+ }
6100
+ .opf-studio[data-density="touch"] .opf-studio-bar {
6101
+ min-height: 52px;
6102
+ }
6103
+ .opf-studio[data-density="touch"] .opf-studio-status {
6104
+ min-height: 48px;
6105
+ }
6106
+ @media (pointer: coarse) {
6107
+ .opf-studio :is(.opf-studio-barbutton, .opf-studio-iconbutton, .opf-studio-segment, .opf-studio-action, .opf-studio-tab, .opf-studio-menuitem, .opf-studio-validity, .opf-studio-path, .opf-dc-tool) {
6108
+ min-width: 44px;
6109
+ min-height: 44px;
6110
+ }
6111
+ .opf-studio .opf-studio-design-advanced > summary {
6112
+ padding-block: calc((44px - 1lh) / 2);
6113
+ }
6114
+ .opf-studio :is(.opf-studio-number, .opf-studio-input, .opf-studio-name) {
6115
+ min-height: 44px;
6116
+ font-size: 16px;
6117
+ }
6118
+ .opf-studio .opf-studio-row-label {
6119
+ min-height: 44px;
6120
+ }
6121
+ }
6122
+
6123
+ /* ---- forced colors -------------------------------------------------------------------------------------------------------------------- */
6124
+ @media (forced-colors: active) {
6125
+ .opf-studio-box.is-selected,
6126
+ .opf-studio-box[data-kind="slide"].is-selected {
6127
+ outline: 2px solid Highlight;
6128
+ box-shadow: none;
6129
+ }
6130
+ .opf-studio-drop,
6131
+ .opf-studio-chip,
6132
+ .opf-studio-ratio {
6133
+ background: Highlight;
6134
+ color: HighlightText;
6135
+ }
6136
+ }
6137
+
6138
+ /* The parts' screen-reader text (the slide manager's hint and live region) stays off screen inside the Studio. */
6139
+ .opf-studio .sr-only {
6140
+ position: absolute;
6141
+ width: 1px;
6142
+ height: 1px;
6143
+ margin: -1px;
6144
+ padding: 0;
6145
+ overflow: hidden;
6146
+ clip: rect(0 0 0 0);
6147
+ white-space: nowrap;
6148
+ border: 0;
6149
+ }
6150
+
6151
+ /* thumbnails.css */
6152
+ /* Thumbnail strip (RR-98). Uses only --opf-ui-* tokens. */
6153
+ .opf-thumbs {
6154
+ position: relative;
6155
+ box-sizing: border-box;
6156
+ min-width: 0;
6157
+ min-height: 0;
6158
+ font-family: var(--opf-ui-font);
6159
+ color: var(--opf-ui-fg);
6160
+ scrollbar-width: thin;
6161
+ }
6162
+ .opf-thumbs[data-orientation="horizontal"] {
6163
+ overflow-x: auto;
6164
+ overflow-y: hidden;
6165
+ }
6166
+ .opf-thumbs[data-orientation="vertical"] {
6167
+ overflow-x: hidden;
6168
+ overflow-y: auto;
6169
+ }
6170
+ .opf-thumbs-list {
6171
+ display: flex;
6172
+ gap: 12px;
6173
+ margin: 0;
6174
+ /* Room for the 2px ring and its 2px offset, which the scroll container would otherwise clip. */
6175
+ padding: 6px 6px 6px;
6176
+ list-style: none;
6177
+ }
6178
+ .opf-thumbs[data-orientation="horizontal"] .opf-thumbs-list {
6179
+ flex-direction: row;
6180
+ align-items: flex-start;
6181
+ width: max-content;
6182
+ }
6183
+ .opf-thumbs[data-orientation="vertical"] .opf-thumbs-list {
6184
+ flex-direction: column;
6185
+ }
6186
+ .opf-thumbs[data-density="touch"] .opf-thumbs-list {
6187
+ gap: 16px;
6188
+ }
6189
+ .opf-thumbs-slot {
6190
+ flex: none;
6191
+ width: var(--opf-thumbs-w);
6192
+ }
6193
+ .opf-thumbs-item {
6194
+ display: flex;
6195
+ flex-direction: column;
6196
+ align-items: stretch;
6197
+ justify-content: flex-start;
6198
+ gap: 6px;
6199
+ box-sizing: border-box;
6200
+ width: 100%;
6201
+ min-height: 0;
6202
+ margin: 0;
6203
+ padding: 0;
6204
+ font-weight: 400;
6205
+ white-space: normal;
6206
+ border: 0;
6207
+ border-radius: var(--opf-ui-radius-sm);
6208
+ background: transparent;
6209
+ color: var(--opf-ui-muted-fg);
6210
+ font: inherit;
6211
+ text-align: left;
6212
+ cursor: pointer;
6213
+ transition: color var(--opf-ui-ease);
6214
+ }
6215
+ .opf-thumbs-item:hover {
6216
+ color: var(--opf-ui-fg);
6217
+ }
6218
+ .opf-thumbs-item[aria-current="true"] {
6219
+ color: var(--opf-ui-accent-strong);
6220
+ }
6221
+ .opf-thumbs-item:focus-visible {
6222
+ outline: 2px solid var(--opf-ui-ring);
6223
+ outline-offset: 2px;
6224
+ }
6225
+ .opf-thumbs-frame {
6226
+ display: block;
6227
+ box-sizing: border-box;
6228
+ width: 100%;
6229
+ overflow: hidden;
6230
+ aspect-ratio: var(--opf-thumbs-ratio);
6231
+ border-radius: 3px;
6232
+ background: var(--opf-ui-muted-2);
6233
+ box-shadow: 0 0 0 1px var(--opf-ui-border);
6234
+ outline: 2px solid transparent;
6235
+ outline-offset: 2px;
6236
+ transition: outline-color var(--opf-ui-ease);
6237
+ pointer-events: none;
6238
+ }
6239
+ .opf-thumbs-item[aria-current="true"] .opf-thumbs-frame {
6240
+ outline-color: var(--opf-ui-accent);
6241
+ }
6242
+ .opf-thumbs-frame > svg {
6243
+ display: block;
6244
+ width: 100%;
6245
+ height: auto;
6246
+ }
6247
+ .opf-thumbs-frame[data-state="error"] {
6248
+ display: grid;
6249
+ place-items: center;
6250
+ padding: 4px;
6251
+ font: 11.5px/1.3 var(--opf-ui-mono);
6252
+ text-align: center;
6253
+ color: var(--opf-ui-muted-fg);
6254
+ }
6255
+ .opf-thumbs-item[data-hidden="true"] .opf-thumbs-frame {
6256
+ opacity: 0.55;
6257
+ }
6258
+ .opf-thumbs-label {
6259
+ position: relative;
6260
+ display: flex;
6261
+ gap: 6px;
6262
+ width: 100%;
6263
+ min-width: 0;
6264
+ font-size: 12px;
6265
+ line-height: 1.4;
6266
+ white-space: nowrap;
6267
+ }
6268
+ .opf-thumbs-index {
6269
+ flex: none;
6270
+ font-family: var(--opf-ui-mono);
6271
+ }
6272
+ .opf-thumbs-title {
6273
+ min-width: 0;
6274
+ overflow: hidden;
6275
+ text-overflow: ellipsis;
6276
+ }
6277
+ .opf-thumbs-title[data-untitled="true"] {
6278
+ font-style: italic;
4842
6279
  }
4843
6280
  /* The "hidden" note is for assistive technology; the dimmed thumbnail shows it visually. */
4844
6281
  .opf-thumbs-note {
@@ -5052,7 +6489,13 @@ input.opf-lx-input[data-field="max"] { font-family: var(--opf-ui-mono); font-siz
5052
6489
  :root .opf-find button[aria-label="Next match"] {
5053
6490
  min-width: 44px;
5054
6491
  }
6492
+ .opf-dc-tool,
6493
+ .opf-dc-path {
6494
+ min-width: 44px;
6495
+ min-height: 44px;
6496
+ }
5055
6497
  .opf-dc-group > summary,
6498
+ .opf-dc-advanced > summary,
5056
6499
  .opf-template-insert-section summary {
5057
6500
  min-height: 44px;
5058
6501
  padding-block: calc((44px - 1lh) / 2);
@@ -5166,6 +6609,13 @@ input.opf-lx-input[data-field="max"] { font-family: var(--opf-ui-mono); font-siz
5166
6609
  border-right: 1px solid var(--opf-ui-border);
5167
6610
  background: var(--opf-ui-surface);
5168
6611
  }
6612
+ /* Only the source pane (`layout: "source"`): it fills the editor, on a phone too. */
6613
+ .opf-ws-body > .opf-ws-source:only-child {
6614
+ flex: 1 1 auto;
6615
+ height: auto;
6616
+ min-width: 0;
6617
+ border: 0;
6618
+ }
5169
6619
  .opf-ws-source-host {
5170
6620
  flex: 1 1 auto;
5171
6621
  min-width: 0;