glideshow 0.1.2__py3-none-any.whl

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 (103) hide show
  1. glideshow/__init__.py +15 -0
  2. glideshow/__main__.py +3 -0
  3. glideshow/agent.py +681 -0
  4. glideshow/build.py +54 -0
  5. glideshow/cli.py +320 -0
  6. glideshow/comments.py +35 -0
  7. glideshow/decks.py +230 -0
  8. glideshow/docs/agents.md +223 -0
  9. glideshow/docs/deck-format.md +125 -0
  10. glideshow/editor/.assetsignore +5 -0
  11. glideshow/editor/apple-touch-icon.png +0 -0
  12. glideshow/editor/data/font-metrics.json +1 -0
  13. glideshow/editor/data/fonts.json +1 -0
  14. glideshow/editor/data/icons.json +1 -0
  15. glideshow/editor/data/symbols.js +42 -0
  16. glideshow/editor/data/themes.js +15 -0
  17. glideshow/editor/deck/base.css +92 -0
  18. glideshow/editor/deck/present.js +222 -0
  19. glideshow/editor/deck/shapes.js +377 -0
  20. glideshow/editor/deck/template.html +37 -0
  21. glideshow/editor/editor.css +657 -0
  22. glideshow/editor/glideshow-1024.png +0 -0
  23. glideshow/editor/glideshow.svg +10 -0
  24. glideshow/editor/globals.d.ts +21 -0
  25. glideshow/editor/home.html +358 -0
  26. glideshow/editor/index.html +386 -0
  27. glideshow/editor/js/arrange.js +122 -0
  28. glideshow/editor/js/boot.js +66 -0
  29. glideshow/editor/js/boxes.js +25 -0
  30. glideshow/editor/js/comments.js +85 -0
  31. glideshow/editor/js/context-menus.js +93 -0
  32. glideshow/editor/js/dialogs.js +168 -0
  33. glideshow/editor/js/dock.js +22 -0
  34. glideshow/editor/js/draw.js +107 -0
  35. glideshow/editor/js/file.js +318 -0
  36. glideshow/editor/js/find.js +72 -0
  37. glideshow/editor/js/format-panel.js +101 -0
  38. glideshow/editor/js/geometry.js +153 -0
  39. glideshow/editor/js/guides.js +37 -0
  40. glideshow/editor/js/insert.js +73 -0
  41. glideshow/editor/js/keyboard.js +256 -0
  42. glideshow/editor/js/live.js +48 -0
  43. glideshow/editor/js/menubar.js +290 -0
  44. glideshow/editor/js/menus.js +93 -0
  45. glideshow/editor/js/motion.js +148 -0
  46. glideshow/editor/js/notes.js +63 -0
  47. glideshow/editor/js/objects.js +202 -0
  48. glideshow/editor/js/people.js +73 -0
  49. glideshow/editor/js/phone-comments.js +43 -0
  50. glideshow/editor/js/phone-edit.js +253 -0
  51. glideshow/editor/js/phone-home.js +51 -0
  52. glideshow/editor/js/phone-mode.js +73 -0
  53. glideshow/editor/js/phone-sheets.js +153 -0
  54. glideshow/editor/js/phone-touch.js +145 -0
  55. glideshow/editor/js/phone-view.js +150 -0
  56. glideshow/editor/js/pointer.js +407 -0
  57. glideshow/editor/js/render.js +353 -0
  58. glideshow/editor/js/shortcuts.js +67 -0
  59. glideshow/editor/js/slides.js +120 -0
  60. glideshow/editor/js/spacing.js +23 -0
  61. glideshow/editor/js/state.js +58 -0
  62. glideshow/editor/js/storage.js +250 -0
  63. glideshow/editor/js/text.js +366 -0
  64. glideshow/editor/js/theme-toggle.js +41 -0
  65. glideshow/editor/js/theme.js +173 -0
  66. glideshow/editor/js/toolbar-groups.js +109 -0
  67. glideshow/editor/js/toolbar.js +372 -0
  68. glideshow/editor/lib/browser-db.js +47 -0
  69. glideshow/editor/lib/library.js +612 -0
  70. glideshow/editor/lib/merge.js +174 -0
  71. glideshow/editor/lib/move-local.js +51 -0
  72. glideshow/editor/lib/onefile.js +108 -0
  73. glideshow/editor/lib/store-browser.js +75 -0
  74. glideshow/editor/lib/store-folder.js +109 -0
  75. glideshow/editor/local/sw.js +66 -0
  76. glideshow/editor/local/tsconfig.json +5 -0
  77. glideshow/editor/looks/glider.svg +9 -0
  78. glideshow/editor/looks/thermal-phone.css +144 -0
  79. glideshow/editor/looks/thermal.css +268 -0
  80. glideshow/editor/manifest.json +23 -0
  81. glideshow/editor/phone.css +345 -0
  82. glideshow/editor/share/share.css +124 -0
  83. glideshow/editor/share/share.js +256 -0
  84. glideshow/editor/share/speaker.html +88 -0
  85. glideshow/editor/tsconfig.json +6 -0
  86. glideshow/figure.py +33 -0
  87. glideshow/fonts.py +63 -0
  88. glideshow/gslides.py +1065 -0
  89. glideshow/history.py +210 -0
  90. glideshow/merge.py +210 -0
  91. glideshow/osutil.py +44 -0
  92. glideshow/pptx_export.py +207 -0
  93. glideshow/pptx_import.py +115 -0
  94. glideshow/publish.py +106 -0
  95. glideshow/render.py +288 -0
  96. glideshow/server.py +549 -0
  97. glideshow/service.py +65 -0
  98. glideshow/skills/glideshow/SKILL.md +85 -0
  99. glideshow-0.1.2.dist-info/METADATA +69 -0
  100. glideshow-0.1.2.dist-info/RECORD +103 -0
  101. glideshow-0.1.2.dist-info/WHEEL +4 -0
  102. glideshow-0.1.2.dist-info/entry_points.txt +2 -0
  103. glideshow-0.1.2.dist-info/licenses/LICENSE +662 -0
@@ -0,0 +1,144 @@
1
+ /* Thermal on a phone: the Google Slides iPhone app's layout and controls (editor/phone.css), dressed in Thermal
2
+ (editor/looks/thermal.css): cool paper by day and graphite at dusk; the mascot's canopy blue for what's chosen and
3
+ its navy for text; Hanken Grotesk, with IBM Plex Mono for numbers; hairlines instead of shadows; the sky as the one
4
+ brand moment, washed behind the top of Home only. It redefines phone.css's --ph-* tokens and dresses the few
5
+ surfaces that phone.css paints directly. Opt-in on a phone with ?look=thermal (remembered), off with ?look=google. */
6
+
7
+ html.phone[data-look="thermal"] body {
8
+ --ph-bar: #f7f9fb; --ph-canvas: #eef2f6; --ph-page: #eef2f6; --ph-ink: #14204a; --ph-muted: #5c6b87; --ph-rule: #dbe2ea;
9
+ --ph-accent: #d9e4ff; --ph-accent-ink: #2f6bff; --ph-select: #2f6bff; --ph-halo: rgba(47, 107, 255, .22); --ph-adjust: #f2b33d;
10
+ --ph-surface: #ffffff; --ph-field: #eaf0f6; --ph-press: #e6ecf5; --ph-cell-ink: #2f6bff;
11
+ --ph-sky: radial-gradient(120% 140% at 88% 130%, #ffe1a8 0%, rgba(255, 225, 168, 0) 58%), linear-gradient(180deg, #a9c8ff 0%, #d4e3ff 48%, #eef2f6 100%);
12
+ --font: "Hanken Grotesk", -apple-system, system-ui, "Helvetica Neue", Arial, sans-serif;
13
+ --mono: "IBM Plex Mono", ui-monospace, Menlo, monospace;
14
+ --icon: #3b4a6b; --toolbar: var(--ph-field); --hover: var(--ph-press); --selected: var(--ph-accent); --surface: var(--ph-surface);
15
+ --menu-shadow: 0 0 0 1px var(--ph-rule), 0 8px 24px rgba(20, 32, 74, .08);
16
+ color-scheme: light;
17
+ }
18
+ /* dusk: graphite surfaces, the canopy blue paler, the evening sky (violet, a peach glow) behind Home's top */
19
+ html.phone[data-look="thermal"] body.dark {
20
+ --ph-bar: #17181d; --ph-canvas: #111216; --ph-page: #111216; --ph-ink: #ececee; --ph-muted: #a1a3aa; --ph-rule: #2e2f33;
21
+ --ph-accent: #2b3447; --ph-accent-ink: #8aaeff; --ph-select: #6f97ff; --ph-halo: rgba(138, 174, 255, .25);
22
+ --ph-surface: #1d1e25; --ph-field: #232427; --ph-press: #2a2b2f; --ph-cell-ink: #8aaeff;
23
+ --ph-sky: radial-gradient(120% 140% at 88% 130%, rgba(226, 140, 112, .5) 0%, rgba(226, 140, 112, 0) 58%), radial-gradient(140% 70% at 15% 120%, rgba(150, 88, 140, .45) 0%, rgba(150, 88, 140, 0) 70%), linear-gradient(180deg, #18182c 0%, #221e41 50%, #111216 100%);
24
+ --icon: #c6c7cc; --menu-shadow: 0 0 0 1px var(--ph-rule), 0 8px 24px rgba(0, 0, 0, .4);
25
+ color-scheme: dark;
26
+ }
27
+
28
+ /* ---- Home: the sky washes down behind the search; decks as rounded thumbnails on hairlines; + in canopy blue ---- */
29
+ html.phone[data-look="thermal"] body:has(> .hm-bar) { background: var(--ph-page); isolation: isolate; }
30
+ html.phone[data-look="thermal"] body:has(> .hm-bar)::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 320px; z-index: -1; background: var(--ph-sky);
31
+ -webkit-mask-image: linear-gradient(180deg, #000 30%, transparent); mask-image: linear-gradient(180deg, #000 30%, transparent); }
32
+ html.phone[data-look="thermal"] .hm-bar { background: transparent !important; border: 0 !important; display: flex !important; }
33
+ html.phone[data-look="thermal"] .ph-search { border-radius: 14px; background: color-mix(in srgb, var(--ph-surface) 72%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ph-ink) 10%, transparent);
34
+ -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); }
35
+ html.phone[data-look="thermal"] .ph-search .ph-icon-btn:first-child { color: var(--icon); }
36
+ html.phone[data-look="thermal"] .ph-avatar { background: var(--ph-accent-ink); color: var(--ph-surface); }
37
+ html.phone[data-look="thermal"] .ph-avatar img { background: #fff; }
38
+ html.phone[data-look="thermal"] .ph-sort { font: 500 11px/1 var(--mono); letter-spacing: .08em; text-transform: uppercase; }
39
+ html.phone[data-look="thermal"] .ph-sort .icon { font-size: 15px; }
40
+ html.phone[data-look="thermal"] .hm-grid:not(.list) .hm-card .pic { border-radius: 12px; box-shadow: 0 0 0 1px var(--ph-rule); }
41
+ html.phone[data-look="thermal"] .hm-card .meta::before { content: none; } /* no file icon: the thumbnail says what it is */
42
+ html.phone[data-look="thermal"] .hm-card .meta { padding: 10px 0 0 4px; min-height: 0; align-items: flex-start; }
43
+ html.phone[data-look="thermal"] .hm-card .title { text-align: left; font: 500 15px/20px var(--font); color: var(--ph-ink); }
44
+ html.phone[data-look="thermal"] .hm-card .more { height: 24px; margin-top: -2px; color: var(--ph-muted); }
45
+ html.phone[data-look="thermal"] .hm-grid:not(.list) { row-gap: 18px; }
46
+ html.phone[data-look="thermal"] .hm-folder { background: var(--ph-surface) !important; box-shadow: 0 0 0 1px var(--ph-rule) !important; }
47
+ html.phone[data-look="thermal"] .hm-move { background: var(--ph-surface); box-shadow: inset 0 0 0 1px var(--ph-rule); }
48
+ html.phone[data-look="thermal"] .hm-move-go { background: var(--ph-accent-ink); color: var(--ph-surface); }
49
+ html.phone[data-look="thermal"] #hm-new.ph-fab { background: var(--ph-accent-ink); color: #fff; box-shadow: 0 0 0 1px color-mix(in srgb, #14204a 12%, transparent); }
50
+ html.phone[data-look="thermal"] body.dark #hm-new.ph-fab { background: #ececee; color: #18182c; } /* dusk: the mascot's white, as the desktop's New presentation */
51
+ html.phone[data-look="thermal"] .menu { border-radius: 14px; }
52
+
53
+ /* ---- view mode and the editor: calm bars with a hairline, the slide on paper with a soft edge ---- */
54
+ html.phone[data-look="thermal"] .ph-top, html.phone[data-look="thermal"] .ph-show-bar { border-bottom-color: var(--ph-rule); }
55
+ html.phone[data-look="thermal"] .ph-bar .ph-icon-btn { color: var(--icon); }
56
+ html.phone[data-look="thermal"] .ph-bar-edit .ph-done { color: var(--ph-accent-ink); }
57
+ html.phone[data-look="thermal"] .ph-vslide { margin-bottom: 8px; background: var(--ph-field); }
58
+ html.phone[data-look="thermal"] .ph-vslide.cur::after { box-shadow: inset 0 0 0 2px var(--ph-accent-ink); }
59
+ html.phone[data-look="thermal"] .ph-chip { border-radius: 999px; padding: 4px 10px; background: color-mix(in srgb, var(--ph-surface) 80%, transparent); color: var(--ph-ink);
60
+ box-shadow: 0 0 0 1px var(--ph-rule); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); font: 500 12px/1 var(--mono); }
61
+ html.phone[data-look="thermal"] #ed-frame { box-shadow: 0 0 0 1px rgba(20, 32, 74, .06), 0 6px 20px rgba(20, 32, 74, .06); border-radius: 4px; }
62
+ html.phone[data-look="thermal"] body.dark #ed-frame { box-shadow: 0 0 0 1px #2e2f33; }
63
+ /* the filmstrip: rounded thumbnails on hairlines; the current one ringed in blue on a pale tint, its number in mono */
64
+ html.phone[data-look="thermal"] .ph-film, html.phone[data-look="thermal"] .ph-tools { border-top-color: var(--ph-rule); }
65
+ html.phone[data-look="thermal"] .ph-cell { border-radius: 12px; }
66
+ html.phone[data-look="thermal"] .ph-thumb { border-radius: 6px; box-shadow: 0 0 0 1px var(--ph-rule); }
67
+ html.phone[data-look="thermal"] .ph-cell.cur .ph-thumb, html.phone[data-look="thermal"] .ph-cell.picked .ph-thumb { box-shadow: 0 0 0 2px var(--ph-accent-ink); }
68
+ html.phone[data-look="thermal"] .ph-num { font: 400 12px/1 var(--mono); color: var(--ph-muted); }
69
+ html.phone[data-look="thermal"] .ph-cell.cur .ph-num, html.phone[data-look="thermal"] .ph-cell.picked .ph-num { color: var(--ph-cell-ink); font-weight: 500; }
70
+ html.phone[data-look="thermal"] .ph-film-new { color: var(--icon); }
71
+ html.phone[data-look="thermal"] .ph-count { color: var(--ph-accent-ink); font-family: var(--mono); }
72
+ /* toolbars: the active button a pale blue tile */
73
+ html.phone[data-look="thermal"] .ph-tools .ph-icon-btn { color: var(--icon); }
74
+ html.phone[data-look="thermal"] .ph-tools .ph-icon-btn.on .icon { border-radius: 8px; }
75
+ /* selection: the canopy blue */
76
+ html.phone[data-look="thermal"] .sel-box, html.phone[data-look="thermal"] .sel-box.editing { box-shadow: 0 0 0 calc(var(--k, 1px) * .75) var(--ph-select), 0 0 0 calc(var(--k, 1px) * 3.25) var(--ph-halo); }
77
+ html.phone[data-look="thermal"] .handle:not(.adjust):not(.crop):not(.rotate) { border-radius: calc(var(--k, 1px) * 2); }
78
+ /* the iOS-style edit menu: frosted paper with a hairline rather than grey glass */
79
+ html.phone[data-look="thermal"] .ph-editmenu { background: color-mix(in srgb, var(--ph-surface) 85%, transparent); box-shadow: 0 0 0 1px var(--ph-rule), 0 8px 24px rgba(20, 32, 74, .10); }
80
+ html.phone[data-look="thermal"] .ph-editmenu button { color: var(--ph-ink); }
81
+ html.phone[data-look="thermal"] .ph-editmenu button + button { border-left-color: var(--ph-rule); }
82
+
83
+ /* ---- sheets: paper with rounded top corners and a hairline; rows on hairlines; tabs and picks in canopy blue ---- */
84
+ html.phone[data-look="thermal"] .ph-sheet { border-radius: 18px 18px 0 0; box-shadow: 0 0 0 1px var(--ph-rule); background: var(--ph-surface); }
85
+ html.phone[data-look="thermal"] .ph-page { background: var(--ph-surface); }
86
+ html.phone[data-look="thermal"] .ph-page-title { font-weight: 500; }
87
+ html.phone[data-look="thermal"] .ph-row > .icon:first-child, html.phone[data-look="thermal"] .ph-row .ph-more { color: var(--icon); }
88
+ html.phone[data-look="thermal"] .ph-row:active:not(:disabled), html.phone[data-look="thermal"] .ph-shape-cell:active { background: var(--ph-press); }
89
+ html.phone[data-look="thermal"] .ph-tabs button.on { color: var(--ph-accent-ink); }
90
+ html.phone[data-look="thermal"] .ph-tabs button.on::after { background: var(--ph-accent-ink); }
91
+ html.phone[data-look="thermal"] .ph-shape-cell svg * { fill: var(--ph-field); stroke: color-mix(in srgb, var(--ph-ink) 45%, transparent); }
92
+ html.phone[data-look="thermal"] .ph-swatch-cell { border-color: var(--ph-rule); border-radius: 8px; }
93
+ html.phone[data-look="thermal"] .ph-swatch-cell.on::after { background: var(--ph-accent-ink); color: #fff; }
94
+ html.phone[data-look="thermal"] .ph-hue:first-child { border-radius: 8px 0 0 8px; } html.phone[data-look="thermal"] .ph-hue:last-child { border-radius: 0 8px 8px 0; }
95
+ html.phone[data-look="thermal"] .ph-hue.on { box-shadow: 0 0 0 3px var(--ph-surface), 0 0 0 4px var(--ph-ink); }
96
+ html.phone[data-look="thermal"] .ph-label { font: 500 11px/1 var(--mono); letter-spacing: .08em; text-transform: uppercase; color: var(--ph-muted); }
97
+ html.phone[data-look="thermal"] .ph-addslide { background: var(--ph-page); }
98
+ html.phone[data-look="thermal"] .ph-layout svg { outline-color: var(--ph-rule); border-radius: 6px; }
99
+ html.phone[data-look="thermal"] .ph-layout { font-weight: 500; }
100
+
101
+ /* ---- comments: the bar and field on paper ---- */
102
+ html.phone[data-look="thermal"] .ph-cm-cancel { background: var(--ph-surface); box-shadow: 0 0 0 1px var(--ph-rule); }
103
+ html.phone[data-look="thermal"] .ph-cm-hint { box-shadow: 0 0 0 1px var(--ph-rule); color: #14204a; }
104
+ html.phone[data-look="thermal"] .ph-cm-field { background: var(--ph-field); }
105
+
106
+ /* desktop Thermal's home layout that the phone doesn't take: the gap left for the actions pill */
107
+ html.phone[data-look="thermal"] .hm-main { padding-top: 0; }
108
+
109
+ /* ---- Round two: light / dark on the phone, and a little further from the app ---- */
110
+ html.phone[data-look="thermal"] .ph-theme { display: grid !important; }
111
+ html.phone[data-look="thermal"] .ph-sortrow .ph-theme { width: 40px; height: 48px; color: var(--ph-muted); }
112
+ html.phone[data-look="thermal"] .ph-sortrow .ph-theme .icon { font-size: 22px; }
113
+ /* bars the colour of the page, set apart by a hairline only */
114
+ html.phone[data-look="thermal"] body { --ph-bar: var(--ph-canvas); }
115
+ /* a deck: the slides one after another, a hairline between them */
116
+ html.phone[data-look="thermal"] .ph-vslide { margin-bottom: 0; border-bottom: 1px solid var(--ph-rule); }
117
+ /* the filmstrip: the current slide marked by its blue ring and number only, no band; New slide a dashed tile */
118
+ html.phone[data-look="thermal"] .ph-cell.cur, html.phone[data-look="thermal"] .ph-cell.picked { background: none; }
119
+ /* handles: round, white with a blue ring (friendlier than the app's blue squares) */
120
+ html.phone[data-look="thermal"] .handle:not(.adjust):not(.crop):not(.rotate) { border-radius: 50%; background: #fff; box-shadow: 0 0 0 calc(var(--k, 1px) * 2) var(--ph-select); }
121
+ /* + : a rounded square, not the app's circle */
122
+ html.phone[data-look="thermal"] #hm-new.ph-fab { border-radius: 18px; }
123
+ /* sheets: a grab handle on top, as iOS sheets have */
124
+ html.phone[data-look="thermal"] .ph-sheet::before { content: ""; position: absolute; z-index: 2; left: 50%; top: 6px; width: 36px; height: 4px; translate: -50% 0; border-radius: 2px; background: color-mix(in srgb, var(--ph-ink) 22%, transparent); }
125
+ html.phone[data-look="thermal"] body.dark { --ph-bar: var(--ph-canvas); }
126
+ html.phone[data-look="thermal"] .handle:not(.adjust):not(.crop):not(.rotate) { box-shadow: 0 0 0 calc(var(--k, 1px) * 1.5) var(--ph-select); }
127
+
128
+ /* New slide: a dashed tile the size of a thumbnail, right after the last slide in the strip (phone-edit.js), never clipped
129
+ at the strip's end; its + drawn (two bars), not the icon font's ligature, so it is always there and always centred */
130
+ html.phone[data-look="thermal"] .ph-film-strip { padding-right: 10px; }
131
+ html.phone[data-look="thermal"] .ph-film-strip > .ph-film-new { flex: none; display: flex; flex-direction: column; align-items: flex-start; width: 98px; height: 87px; padding: 9px 9px 0; border: 0 !important; border-radius: 12px; background: none; color: var(--icon); }
132
+ html.phone[data-look="thermal"] .ph-film-new .icon { position: relative; display: block; width: 80px; height: 45px; font-size: 0; border-radius: 6px; outline: 1.5px dashed color-mix(in srgb, var(--ph-ink) 30%, transparent); outline-offset: -1px; }
133
+ html.phone[data-look="thermal"] .ph-film-new .icon::after { content: ""; position: absolute; left: 50%; top: 50%; width: 18px; height: 18px; translate: -50% -50%;
134
+ background: linear-gradient(currentColor, currentColor) center / 100% 2px no-repeat, linear-gradient(currentColor, currentColor) center / 2px 100% no-repeat; }
135
+
136
+ /* presenting: no title bar; the slide on all of the visible height; a tap shows a small ✕ and "n / N" in the corner,
137
+ which fade away again (phone-view.js) */
138
+ html.phone[data-look="thermal"] .ph-show-bar { left: max(12px, env(safe-area-inset-left)); right: auto; top: max(12px, env(safe-area-inset-top)); height: 40px; padding: 0 14px 0 2px; gap: 2px;
139
+ border: 0; border-radius: 20px; background: rgba(18, 18, 22, .55); color: #fff; backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); transition: opacity .3s ease; }
140
+ html.phone[data-look="thermal"] .ph-show-bar.away { transform: none; opacity: 0; pointer-events: none; }
141
+ html.phone[data-look="thermal"] .ph-show-bar .ph-icon-btn { color: #fff; width: 32px; height: 40px; margin-left: 3px; } /* the ✕ as far from the pill's
142
+ left end as "n / N" is from its right (the 48 px button sat 19 px in, and stood taller than the pill) */
143
+ html.phone[data-look="thermal"] .ph-show-title { display: none; }
144
+ html.phone[data-look="thermal"] .ph-show-count { display: inline; font: 500 13px/1 var(--mono); color: rgba(255, 255, 255, .9); }
@@ -0,0 +1,268 @@
1
+ /* Thermal, a look for Glideshow's own screens (the editor's chrome and the home screen; never a deck): the mascot's
2
+ colors, its blue canopy and navy eyes, on cool paper, Hanken Grotesk, soft shadows instead of hairline outlines, and
3
+ one brand moment, a morning sky with a little grain, behind the mascot on the home screen. Google Slides' behavior is
4
+ untouched: this file only redefines the tokens of editor.css and dresses a few surfaces.
5
+ On with ?look=thermal (remembered), off with ?look= ; see the <head> script in index.html and home.html. */
6
+ @import url("https://fonts.googleapis.com/css2?family=Hanken+Grotesk:wght@300;400;500;600&family=IBM+Plex+Mono:wght@400;500&display=swap");
7
+
8
+ html[data-look="thermal"] body {
9
+ --font: "Hanken Grotesk", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
10
+ --mono: "IBM Plex Mono", ui-monospace, Menlo, monospace;
11
+ --blue: #2f6bff; --blue-hover: #1f58e6; --hover: #e6ecf5; --selected: #d9e4ff;
12
+ --ink: #14204a; --muted: #5c6b87; --divider: #dbe2ea; --icon: #3b4a6b; --outline: #c3ccd9;
13
+ --chrome: #f7f9fb; --surface: #ffffff; --stage: #eef2f6; --toolbar: #eaf0f6; --tip: #14204a;
14
+ --slide-shadow: 0 1px 2px rgba(20, 32, 74, .08), 0 10px 30px rgba(20, 32, 74, .08);
15
+ --menu-shadow: 0 10px 30px rgba(20, 32, 74, .14), 0 1px 3px rgba(20, 32, 74, .12);
16
+ --radius: 6px;
17
+ --sky: radial-gradient(120% 140% at 88% 130%, #ffe1a8 0%, rgba(255, 225, 168, 0) 58%), linear-gradient(180deg, #a9c8ff 0%, #d4e3ff 48%, #f3f6fb 100%);
18
+ --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
19
+ }
20
+ /* Dusk: the same look at night (View → Dark mode, or the system's dark setting) */
21
+ html[data-look="thermal"] body.dark {
22
+ --blue: #7aa2ff; --blue-hover: #9ab8ff; --hover: #212b47; --selected: #223a78;
23
+ --ink: #e6ebf7; --muted: #9aa7c2; --divider: #26304a; --icon: #b8c3dc; --outline: #3a4766;
24
+ --chrome: #10172b; --surface: #18213a; --stage: #0b1121; --toolbar: #1a2340; --tip: #e6ebf7;
25
+ --slide-shadow: 0 0 0 1px #26304a, 0 10px 30px rgba(0, 0, 0, .35);
26
+ --menu-shadow: 0 10px 30px rgba(0, 0, 0, .5), 0 1px 3px rgba(0, 0, 0, .5);
27
+ --sky: radial-gradient(120% 140% at 88% 130%, rgba(255, 170, 120, .35) 0%, rgba(255, 170, 120, 0) 58%), linear-gradient(180deg, #1c2a5c 0%, #18213a 60%, #10172b 100%);
28
+ }
29
+
30
+ /* The editor: a calm top bar with a hint of sky at its right edge, rounder controls, the deck's date in mono. */
31
+ html[data-look="thermal"] #ed-bar { background: linear-gradient(90deg, var(--chrome) 0 60%, color-mix(in srgb, var(--chrome) 80%, #a9c8ff) 85%, color-mix(in srgb, var(--chrome) 82%, #ffe1a8) 100%); border-bottom: 1px solid var(--divider); }
32
+ html[data-look="thermal"] body.dark #ed-bar { background: linear-gradient(90deg, var(--chrome) 0 60%, #16224a 100%); }
33
+ html[data-look="thermal"] input#ed-title { font-weight: 500; letter-spacing: -.01em; }
34
+ html[data-look="thermal"] input#ed-date { font-family: var(--mono); font-size: 12px; }
35
+ html[data-look="thermal"] #ed-toolbar { background: var(--surface); box-shadow: 0 0 0 1px var(--divider); }
36
+ html[data-look="thermal"] #ed-share { background: var(--blue); color: #fff; }
37
+ html[data-look="thermal"] #ed-share .icon { color: #fff; }
38
+ html[data-look="thermal"] body.dark #ed-share { color: #0b1121; } html[data-look="thermal"] body.dark #ed-share .icon { color: #0b1121; }
39
+ html[data-look="thermal"] body.dark button.primary { color: #0b1121; } /* dark ink on dusk's paler blue, as Share */
40
+ html[data-look="thermal"] .menu, html[data-look="thermal"] .dialog { border-radius: 12px; }
41
+
42
+ /* The home screen: the sky with the mascot gliding across it, above the library. */
43
+ .hm-sky { display: none; }
44
+ html[data-look="thermal"] .hm-sky { display: flex; align-items: center; justify-content: space-between; gap: 16px; position: relative; overflow: hidden;
45
+ margin: 0 0 24px; padding: 28px 32px; min-height: 168px; border-radius: 18px; background: var(--sky); }
46
+ html[data-look="thermal"] .hm-sky::after { content: ""; position: absolute; inset: 0; pointer-events: none; opacity: .16; mix-blend-mode: multiply; background-image: var(--grain); }
47
+ html[data-look="thermal"] .hm-sky p { margin: 0; font: 300 clamp(24px, 3.4vw, 36px)/1.15 var(--font); letter-spacing: -.02em; color: var(--ink); max-width: 22ch; position: relative; z-index: 1; }
48
+ html[data-look="thermal"] .hm-sky p em { font-style: normal; color: var(--blue); }
49
+ html[data-look="thermal"] .hm-sky img { width: clamp(84px, 11vw, 132px); flex: none; position: relative; z-index: 1; filter: drop-shadow(0 6px 14px rgba(20, 32, 74, .18)); animation: hm-glide 7s ease-in-out infinite; }
50
+ @keyframes hm-glide { 0%, 100% { transform: translate(0, 0) rotate(0deg); } 50% { transform: translate(-8px, -10px) rotate(-2deg); } }
51
+ @media (prefers-reduced-motion: reduce) { html[data-look="thermal"] .hm-sky img { animation: none; } }
52
+ html[data-look="thermal"] .hm-card { border-radius: 12px; border-color: var(--divider); box-shadow: 0 1px 2px rgba(20, 32, 74, .04); }
53
+ html[data-look="thermal"] .hm-card:hover { border-color: var(--blue); box-shadow: 0 6px 20px rgba(20, 32, 74, .10); }
54
+ html[data-look="thermal"] .hm-folder { border-radius: 18px; background: var(--toolbar); }
55
+ html[data-look="thermal"] .hm-card .sub, html[data-look="thermal"] .hm-folder .n { font-family: var(--mono); font-size: 11px; }
56
+
57
+ /* ---- Later rounds, layered over the above ---- */
58
+
59
+ /* Thermal v2: the sky as a slim top bar instead of a banner, no
60
+ shadow on the mascot, and layouts pushed away from Google Slides' while keeping its controls. */
61
+
62
+ /* ---- home ---- */
63
+ html[data-look="thermal"] .hm-sky { display: none !important; }
64
+ html[data-look="thermal"] .hm-bar { height: 60px; background: linear-gradient(90deg, #dce8ff 0%, #eef3ff 45%, #fbf5ea 85%, #fff1d6 100%); border-bottom: 1px solid var(--divider); }
65
+ html[data-look="thermal"] body.dark .hm-bar { background: linear-gradient(90deg, #1a2752 0%, #18213a 55%, #2a2440 100%); }
66
+ html[data-look="thermal"] .hm-bar .brand { font-weight: 500; letter-spacing: -.01em; min-width: 0; gap: 10px; }
67
+ html[data-look="thermal"] .hm-bar .brand .logo { filter: none; }
68
+ html[data-look="thermal"] .hm-bar .brand::after { content: "Slides you own, gliding where you work."; margin-left: 14px; padding-left: 14px; border-left: 1px solid color-mix(in srgb, var(--ink) 18%, transparent);
69
+ font: 300 14px/1 var(--font); letter-spacing: 0; color: var(--muted); white-space: nowrap; }
70
+ @media (max-width: 900px) { html[data-look="thermal"] .hm-bar .brand::after { display: none; } }
71
+ html[data-look="thermal"] .hm-search { flex: 0 1 460px; margin-left: auto; height: 40px; background: color-mix(in srgb, var(--surface) 70%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 10%, transparent); }
72
+ html[data-look="thermal"] .hm-head h1, html[data-look="thermal"] .hm-crumbs { font-weight: 300; font-size: 28px; letter-spacing: -.02em; }
73
+ html[data-look="thermal"] .hm-section { font: 500 11px/1 var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--muted); margin: 28px 0 14px; }
74
+ /* decks: thumbnail first (a document browser), no box around the card */
75
+ html[data-look="thermal"] .hm-grid:not(.list) .hm-card { border: 0; background: transparent; box-shadow: none; overflow: visible; }
76
+ html[data-look="thermal"] .hm-grid:not(.list) .hm-card .pic { border: 0; border-radius: 12px; box-shadow: 0 0 0 1px var(--divider), 0 2px 10px rgba(20, 32, 74, .06); transition: box-shadow .15s, transform .15s; }
77
+ html[data-look="thermal"] .hm-grid:not(.list) .hm-card:hover .pic { box-shadow: 0 0 0 2px var(--blue), 0 10px 28px rgba(20, 32, 74, .14); transform: translateY(-2px); }
78
+ html[data-look="thermal"] .hm-grid:not(.list) .hm-card .meta { padding: 10px 2px 2px 4px; }
79
+ html[data-look="thermal"] .hm-card .title { font-size: 15px; font-weight: 500; }
80
+ html[data-look="thermal"] .hm-folder { background: var(--surface); box-shadow: 0 0 0 1px var(--divider); }
81
+ html[data-look="thermal"] .hm-folder:hover { box-shadow: 0 0 0 2px var(--blue); background: var(--surface); }
82
+ html[data-look="thermal"] .hm-folder .peek .hm-pic, html[data-look="thermal"] .hm-folder .peek > * { border-radius: 8px; }
83
+ html[data-look="thermal"] #hm-new { border-radius: 12px; }
84
+
85
+ /* ---- editor ---- */
86
+ html[data-look="thermal"] #ed-top { padding-top: 10px; }
87
+ html[data-look="thermal"] input#ed-title { font-size: 20px; font-weight: 500; }
88
+ html[data-look="thermal"] #ed-menubar button { font-size: 13px; color: var(--muted); padding: 0 8px; }
89
+ html[data-look="thermal"] #ed-menubar button:hover, html[data-look="thermal"] #ed-menubar button.open { color: var(--ink); }
90
+ html[data-look="thermal"] #ed-toolbar { margin: 6px 12px 10px; border-radius: 14px; box-shadow: 0 0 0 1px var(--divider), 0 2px 8px rgba(20, 32, 74, .05); }
91
+ /* the slide list floats on the stage: no band of its own, rounder thumbnails, the number in mono */
92
+ html[data-look="thermal"] #ed-side { background: var(--stage); }
93
+ html[data-look="thermal"] .thumb .num { font: 400 11px/16px var(--mono); }
94
+ html[data-look="thermal"] .thumb-view { border-radius: 10px; box-shadow: 0 0 0 1px var(--divider), 0 2px 8px rgba(20, 32, 74, .06); }
95
+ html[data-look="thermal"] .thumb.active .thumb-view, html[data-look="thermal"] .thumb.picked .thumb-view { box-shadow: 0 0 0 2px var(--blue), 0 6px 18px color-mix(in srgb, var(--blue) 25%, transparent); }
96
+ html[data-look="thermal"] .ruler { opacity: .5; } /* quieter (View → Show ruler hides them) */
97
+ html[data-look="thermal"] #ed-frame { border-radius: 4px; }
98
+ /* Format options: a floating card */
99
+ html[data-look="thermal"] .panel { margin: 10px 12px 12px 0; border-radius: 18px; box-shadow: var(--menu-shadow); border: 0; }
100
+ /* the insert bar: frosted, floating */
101
+ html[data-look="thermal"] #ed-dock { background: color-mix(in srgb, var(--surface) 78%, transparent); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
102
+ box-shadow: 0 0 0 1px var(--divider), 0 10px 28px rgba(20, 32, 74, .12); border-radius: 22px; padding: 4px; }
103
+ html[data-look="thermal"] #ed-dock button { border-radius: 14px; }
104
+
105
+ /* Thermal v3: v2's layout with almost no shadows: hairlines everywhere, one soft shadow under the slide. */
106
+ html[data-look="thermal"] .hm-grid:not(.list) .hm-card .pic { box-shadow: 0 0 0 1px var(--divider) !important; }
107
+ html[data-look="thermal"] .hm-grid:not(.list) .hm-card:hover .pic { box-shadow: 0 0 0 2px var(--blue) !important; transform: none !important; }
108
+ html[data-look="thermal"] .hm-card { box-shadow: none !important; }
109
+ html[data-look="thermal"] #ed-toolbar { box-shadow: 0 0 0 1px var(--divider) !important; }
110
+ html[data-look="thermal"] .thumb-view { box-shadow: 0 0 0 1px var(--divider) !important; }
111
+ html[data-look="thermal"] .thumb.active .thumb-view, html[data-look="thermal"] .thumb.picked .thumb-view { box-shadow: 0 0 0 2px var(--blue) !important; }
112
+ html[data-look="thermal"] .panel { box-shadow: none !important; border: 1px solid var(--divider) !important; }
113
+ html[data-look="thermal"] #ed-dock { box-shadow: 0 0 0 1px var(--divider) !important; }
114
+ html[data-look="thermal"] body { --slide-shadow: 0 0 0 1px rgba(20, 32, 74, .06), 0 6px 20px rgba(20, 32, 74, .06); --menu-shadow: 0 0 0 1px var(--divider), 0 8px 24px rgba(20, 32, 74, .08); }
115
+
116
+ /* Dusk: v1's evening sky (dark blue fading down, a warm glow at the bottom right) with the blue turned down,
117
+ over graphite surfaces; the canopy blue only as the accent. */
118
+ html[data-look="thermal"] body.dark {
119
+ --blue: #8aaeff; --blue-hover: #a6c1ff; --hover: #2a2b2f; --selected: #2b3447;
120
+ --ink: #ececee; --muted: #a1a3aa; --divider: #2e2f33; --icon: #c6c7cc; --outline: #3f4045;
121
+ --chrome: #17181d; --surface: #1d1e25; --stage: #111216; --toolbar: #232427; --tip: #ececee;
122
+ --slide-shadow: 0 0 0 1px #2e2f33, 0 6px 20px rgba(0, 0, 0, .3);
123
+ --menu-shadow: 0 0 0 1px #2e2f33, 0 8px 24px rgba(0, 0, 0, .4);
124
+ --sky: radial-gradient(120% 140% at 88% 130%, rgba(255, 170, 120, .5) 0%, rgba(255, 170, 120, 0) 58%), linear-gradient(180deg, #2d3352 0%, #23252f 60%, #1d1e25 100%);
125
+ }
126
+ html[data-look="thermal"] body.dark .hm-bar { background: linear-gradient(90deg, #22253a 0%, #1f2130 55%, #2d2630 85%, #3a2c2c 100%) !important; }
127
+ html[data-look="thermal"] body.dark #ed-bar { background: linear-gradient(90deg, var(--chrome) 0 60%, #20233a 85%, #2e2629 100%) !important; }
128
+ html[data-look="thermal"] body.dark #ed-share, html[data-look="thermal"] body.dark #ed-share .icon { color: #121314; }
129
+
130
+ /* Home v4: the front page's sky as a wash behind the top of the page (no banner), the latest deck larger, folders compact. */
131
+ html[data-look="thermal"] body { --home-sky: radial-gradient(120% 140% at 88% 130%, #ffe1a8 0%, rgba(255, 225, 168, 0) 58%), linear-gradient(180deg, #a9c8ff 0%, #d4e3ff 48%, #f3f6fb 100%); }
132
+ html[data-look="thermal"] body.dark { --home-sky: radial-gradient(120% 140% at 88% 130%, rgba(226, 140, 112, .5) 0%, rgba(226, 140, 112, 0) 58%), radial-gradient(140% 70% at 15% 120%, rgba(150, 88, 140, .45) 0%, rgba(150, 88, 140, 0) 70%), linear-gradient(180deg, #18182c 0%, #221e41 50%, #2f2749 100%); }
133
+ html[data-look="thermal"] body:has(> .hm-bar)::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 480px; z-index: -1; background: var(--home-sky);
134
+ -webkit-mask-image: linear-gradient(180deg, #000 40%, transparent); mask-image: linear-gradient(180deg, #000 40%, transparent); }
135
+ html[data-look="thermal"] body:has(> .hm-bar) { isolation: isolate; background: var(--stage); }
136
+ html[data-look="thermal"] .hm-bar { background: transparent !important; border-bottom: 0 !important; position: relative; }
137
+ html[data-look="thermal"] .hm-bar .brand::after { display: none; }
138
+ html[data-look="thermal"] .hm-search { background: color-mix(in srgb, var(--surface) 75%, transparent) !important; backdrop-filter: blur(8px); }
139
+ html[data-look="thermal"] .hm-head h1, html[data-look="thermal"] .hm-crumbs { font-size: 32px; }
140
+ /* folders: one row each, the latest deck's slide beside the name; no empty slots */
141
+ html[data-look="thermal"] .hm-folder { flex-direction: row; align-items: center; gap: 12px; padding: 8px 4px 8px 8px; border-radius: 14px; background: var(--surface) !important; }
142
+ html[data-look="thermal"] .hm-folder .peek { width: 76px; flex: none; margin: 0; grid-template-columns: 1fr; }
143
+ html[data-look="thermal"] .hm-folder .peek .slot:not(:first-child) { display: none; }
144
+ html[data-look="thermal"] .hm-folder .row { flex: 1; min-width: 0; }
145
+ html[data-look="thermal"] .hm-folder .row > .icon:not(.more):first-child { display: none; }
146
+ /* the latest deck, larger: where you left off */
147
+ html[data-look="thermal"] .hm-grid:not(.list) > .hm-card:first-child { grid-column: span 2; grid-row: span 2; }
148
+ html[data-look="thermal"] .hm-grid:not(.list) > .hm-card:first-child .title { font-size: 20px; }
149
+ html[data-look="thermal"] .hm-grid:not(.list) > .hm-card:first-child .meta { padding-top: 14px; }
150
+ html[data-look="thermal"] .hm-folder .more { flex: none; }
151
+ html[data-look="thermal"] .hm-folder .n { white-space: nowrap; }
152
+ /* the name gets the row's width; the count goes under it, so a long name isn't cut to a few letters */
153
+ html[data-look="thermal"] .hm-folder .row { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; row-gap: 3px; }
154
+ html[data-look="thermal"] .hm-folder .row .name { grid-area: 1 / 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
155
+ html[data-look="thermal"] .hm-folder .row .n { grid-area: 2 / 1; }
156
+ html[data-look="thermal"] .hm-folder .row .more { grid-area: 1 / 2 / 3 / 3; }
157
+ html[data-look="thermal"] .hm-grid:not(.list) > .hm-card:first-child { display: flex; flex-direction: column; }
158
+ html[data-look="thermal"] body.dark .hm-bar { background: transparent !important; }
159
+ /* the search truly centred: brand | search | menu as three columns */
160
+ html[data-look="thermal"] .hm-bar { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 640px) minmax(0, 1fr); }
161
+ html[data-look="thermal"] .hm-bar .brand { justify-self: start; min-width: 0; }
162
+ html[data-look="thermal"] .hm-search { justify-self: stretch; margin: 0 !important; }
163
+ html[data-look="thermal"] #hm-app-more { justify-self: end; margin: 0; }
164
+ /* at the top level, no "My decks" heading: the actions share the Folders line (inside a folder the path still shows) */
165
+ html[data-look="thermal"] .hm-head:not(:has(.hm-crumbs .icon)) { position: relative; z-index: 1; margin: 18px 0 -54px; pointer-events: none; }
166
+ html[data-look="thermal"] .hm-head:not(:has(.hm-crumbs .icon)) .hm-crumbs { visibility: hidden; }
167
+ html[data-look="thermal"] .hm-head .hm-actions { pointer-events: auto; }
168
+ html[data-look="thermal"] #hm-folders-head { margin: 22px 0 24px; }
169
+ html[data-look="thermal"] .hm-folders:not(:empty) { margin-bottom: 28px; }
170
+ /* dusk: New presentation in the mascot's white rather than a pale blue slab */
171
+ html[data-look="thermal"] body.dark #hm-new { background: #ececee; color: #18182c; }
172
+ html[data-look="thermal"] body.dark #hm-new .icon { color: inherit; }
173
+ html[data-look="thermal"] body.dark #hm-new:hover { background: #ffffff; }
174
+
175
+ /* Home: the actions leave the Folders line and sit just under the search, in a frosted pill */
176
+ html[data-look="thermal"] .hm-head { position: static !important; }
177
+ html[data-look="thermal"] .hm-head:not(:has(.hm-crumbs .icon)) { margin: 0 !important; min-height: 0; height: 0; }
178
+ html[data-look="thermal"] .hm-main { padding-top: 64px; }
179
+ html[data-look="thermal"] .hm-actions { position: absolute; top: 70px; left: 50%; transform: translateX(-50%); z-index: 6; pointer-events: auto; gap: 2px; padding: 4px; border-radius: 999px;
180
+ background: color-mix(in srgb, var(--surface) 75%, transparent); backdrop-filter: blur(14px) saturate(1.3); -webkit-backdrop-filter: blur(14px) saturate(1.3); box-shadow: 0 0 0 1px var(--divider); }
181
+ html[data-look="thermal"] .hm-actions .hm-tool { width: 36px; height: 36px; color: var(--icon); }
182
+ html[data-look="thermal"] body.dark .hm-actions .hm-tool { color: var(--ink); }
183
+ html[data-look="thermal"] #hm-new { margin: 0 4px 0 0; height: 36px; border-radius: 18px; }
184
+
185
+ /* The editor's shorter toolbar (js/toolbar-groups.js): inserting is the insert bar's, Print and Paint format are in the menus,
186
+ related controls sit in a tray under one ▾ button, and a plain text box shows no fill or border until it has one. */
187
+ html.tb-grouped #ed-toolbar > .grp[data-i="1"], html.tb-grouped #ed-toolbar > .grp[data-i="4"], html.tb-grouped #ed-print, html.tb-grouped #ed-paint-format, html.tb-grouped #ed-animate { display: none !important; }
188
+ html.tb-grouped body.sel-plaintext :is(.swatch[data-for=fill], #ed-border) { display: none !important; }
189
+ html.tb-grouped #ed-toolbar .tray-btn { display: inline-flex; align-items: center; gap: 0; padding: 0 0 0 4px; }
190
+ html.tb-grouped #ed-toolbar .tray-btn .caret { font-size: 18px; margin-left: -2px; color: var(--muted); }
191
+ html.tb-grouped #ed-toolbar .tray-btn.open { background: var(--selected); }
192
+ html.tb-grouped #ed-toolbar .tray-btn .sw { display: inline-flex; flex-direction: column; align-items: center; gap: 2px; }
193
+ html.tb-grouped #ed-toolbar .tray-btn .sw .icon { font-size: 18px; line-height: 18px; height: 14px; overflow: hidden; } /* the glyph's own bar cut off; ours shows the color */
194
+ html.tb-grouped #ed-toolbar .tray-btn .sw .bar { width: 16px; height: 3px; margin: 0; border-radius: 2px; box-shadow: none; }
195
+ html.tb-grouped .tray { display: none; position: fixed; z-index: 21; align-items: center; gap: 2px; padding: 6px; border-radius: 12px; background: var(--surface); border: 1px solid var(--divider); box-shadow: var(--menu-shadow); }
196
+ html.tb-grouped .tray.open { display: flex; }
197
+
198
+ /* View → Floating toolbar (js/toolbar-groups.js): no menu bar (Menus browses and searches it), the deck's controls in the top
199
+ row, the toolbar as a small bar over the selection, and a larger insert bar, now the main one. */
200
+ #ed-deckrow:empty { display: none; }
201
+ html.tb-float #ed-menubar, html.tb-float #ed-toolbar > .grp[data-i="0"], html.tb-float #ed-toolbar > .grp.nosel-only, html.tb-float #ed-collapse, html.tb-float #ed-more-wrap { display: none !important; }
202
+ html.tb-float #ed-top { padding-bottom: 6px; }
203
+ html.tb-float #ed-deckrow { display: flex; align-items: center; gap: 2px; margin: 0 8px 0 auto; }
204
+ html.tb-float #ed-deckrow > button { height: 36px; min-width: 36px; padding: 0 6px; display: inline-flex; align-items: center; justify-content: center; border-radius: 10px; color: var(--icon); }
205
+ html.tb-float #ed-deckrow > button:hover { background: var(--hover); }
206
+ html.tb-float #ed-deckrow #ed-zoom { gap: 2px; font-size: 14px; color: var(--ink); }
207
+ html.tb-float #ed-deckrow #ed-zoom .zoom-glyph { display: none; }
208
+ html.tb-float #ed-deckrow #ed-menus { width: 220px; height: 36px; margin: 0 8px 0 0; padding: 0 12px; border-radius: 10px; background: var(--toolbar); }
209
+ html.tb-float #ed-deckrow #ed-menus input { flex: 1; width: auto; }
210
+ html.tb-float #ed-toolbar { display: none; position: fixed; z-index: 15; width: max-content; max-width: calc(100vw - 16px); margin: 0 !important; padding: 4px 6px; border-radius: 12px; overflow: visible;
211
+ background: var(--surface); box-shadow: 0 0 0 1px var(--divider), 0 6px 18px rgba(20, 32, 74, .08) !important; }
212
+ html.tb-float #ed-toolbar.shown { display: flex; }
213
+ html.tb-float body.dark #ed-toolbar { box-shadow: 0 0 0 1px var(--divider), 0 6px 18px rgba(0, 0, 0, .35) !important; }
214
+ html.tb-float #ed-dock { padding: 6px; gap: 4px; border-radius: 22px; margin-bottom: 14px; }
215
+ html.tb-float #ed-dock button { width: 48px; height: 48px; border-radius: 16px; }
216
+ html.tb-float #ed-dock button .icon { font-size: 24px; }
217
+ html.tb-float #ed-dock .sep { height: 28px; margin: 0 6px; }
218
+
219
+ /* Home's list view: one rounded card, rows split by short hairlines, a soft rounded hover (no blue underline); smaller titles,
220
+ the folder, date and slide count in small mono, rounded thumbnails */
221
+ html[data-look="thermal"] .hm-grid.list .hm-card .title { font-size: 15px; font-weight: 500; }
222
+ html[data-look="thermal"] .hm-grid.list .hm-card .sub > span { font: 400 12px/1 var(--mono); }
223
+ html[data-look="thermal"] .hm-grid.list .hm-card .pic { width: 72px; height: 40.5px; border: 0; border-radius: 6px; box-shadow: 0 0 0 1px var(--divider); overflow: hidden; }
224
+ html[data-look="thermal"] .hm-grid.list .hm-card .pic .hm-pic { transform: scale(calc(72 / 210)); }
225
+ html[data-look="thermal"] .hm-grid.list .hm-card:hover { border-color: transparent; box-shadow: none; }
226
+ html[data-look="thermal"] .hm-grid.list { background: var(--surface); border-radius: 16px; padding: 6px; box-shadow: 0 0 0 1px var(--divider); }
227
+ html[data-look="thermal"] .hm-grid.list .hm-card { border: 0; border-radius: 10px; padding: 8px 6px 8px 10px; background: transparent; position: relative; }
228
+ html[data-look="thermal"] .hm-grid.list .hm-card + .hm-card::before { content: ""; position: absolute; left: 98px; right: 10px; top: 0; border-top: 1px solid var(--divider); }
229
+ html[data-look="thermal"] .hm-grid.list .hm-card:hover { background: var(--hover); }
230
+ html[data-look="thermal"] .hm-grid.list .hm-card:hover::before, html[data-look="thermal"] .hm-grid.list .hm-card:hover + .hm-card::before { border-color: transparent; }
231
+ html[data-look="thermal"] .hm-grid.list:empty { display: none; } /* no empty card where a section has no decks */
232
+
233
+ /* Dialogs: the canopy blue for the main button instead of Slides' yellow Done, rounder fields and buttons, the blue focus ring */
234
+ html[data-look="thermal"] .bg-dialog h2 { font-size: 20px; font-weight: 500; letter-spacing: -.01em; line-height: 1.25; }
235
+ html[data-look="thermal"] .bg-dialog .done { background: var(--blue); color: #fff; border-radius: 10px; }
236
+ html[data-look="thermal"] .bg-dialog .done:hover { background: var(--blue-hover); }
237
+ html[data-look="thermal"] body.dark .bg-dialog .done { color: #0b1121; }
238
+ html[data-look="thermal"] .bg-dialog .outlined, html[data-look="thermal"] .bg-dialog .primary { border-radius: 10px; }
239
+ html[data-look="thermal"] .bg-dialog :is(.url-in, textarea, select, input[type=date]) { border-radius: 10px; border: 1px solid var(--divider); background-color: var(--surface); color: var(--ink); }
240
+ html[data-look="thermal"] .bg-dialog :is(.url-in, textarea, select, input[type=date]):focus { outline: 2px solid var(--blue); outline-offset: -1px; box-shadow: none; }
241
+ html[data-look="thermal"] .bg-dialog select { appearance: none; padding: 0 34px 0 12px;
242
+ background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M3 4.5l3 3 3-3' fill='none' stroke='%235c6b87' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat right 12px center var(--surface); }
243
+ html[data-look="thermal"] .share-dialog .share-link .outlined { flex: none; height: 40px; white-space: nowrap; }
244
+ html[data-look="thermal"] .share-dialog .people-box { border-radius: 10px; background: var(--surface); padding: 6px 8px; }
245
+ html[data-look="thermal"] .share-dialog .person { height: 30px; border-radius: 999px; padding-left: 12px; font-weight: 500; }
246
+ html[data-look="thermal"] body.dark .share-dialog .person.bad { color: #ff8a80; box-shadow: inset 0 0 0 1px #ff8a80; }
247
+ html[data-look="thermal"] #ed-trans .play:not(:disabled) { background: var(--blue); color: #fff; border-radius: 10px; } /* Motion's Play: the canopy blue, not Slides' yellow */
248
+ html[data-look="thermal"] body.dark #ed-trans .play:not(:disabled) { color: #0b1121; }
249
+
250
+ /* Layout (the toolbar's, Slide → Apply layout): each layout a wireframe on a rounded card (theme.js layoutWire), the
251
+ current one ringed in canopy blue, names in the app's type */
252
+ html[data-look="thermal"] .menu.tile-grid { grid-template-columns: repeat(3, 152px); gap: 6px 6px; padding: 12px; border-radius: 16px; }
253
+ html[data-look="thermal"] .menu.tile-grid .menu-item { padding: 6px 6px 8px; border-radius: 12px; }
254
+ html[data-look="thermal"] .menu.tile-grid .menu-item:hover { background: var(--hover); }
255
+ html[data-look="thermal"] .menu.tile-grid .menu-label { gap: 8px; }
256
+ html[data-look="thermal"] .menu.tile-grid svg.lp { display: block; width: 140px; height: auto; border-radius: 8px; box-shadow: 0 0 0 1px var(--divider); transition: box-shadow .15s; }
257
+ html[data-look="thermal"] .menu.tile-grid .menu-item:hover svg.lp { box-shadow: 0 0 0 1px var(--outline), 0 6px 16px rgba(20, 32, 74, .10); }
258
+ html[data-look="thermal"] .menu.tile-grid .menu-item.on svg.lp { box-shadow: 0 0 0 2px var(--blue); }
259
+ html[data-look="thermal"] .menu.tile-grid .cap { font-size: 12.5px; line-height: 1.3; color: var(--ink); }
260
+ html[data-look="thermal"] .menu.tile-grid .menu-item.on .cap { color: var(--blue); font-weight: 500; }
261
+ html[data-look="thermal"] svg.lp .lp-bg { fill: #fff; }
262
+ html[data-look="thermal"] svg.lp .lp-pane { fill: #eef2f6; }
263
+ html[data-look="thermal"] svg.lp .lp-box { fill: #f5f7fa; }
264
+ html[data-look="thermal"] svg.lp .lp-title { fill: #2f6bff; }
265
+ html[data-look="thermal"] svg.lp .lp-sub { fill: #b8c3d6; }
266
+ html[data-look="thermal"] svg.lp .lp-line { fill: #d3dae5; }
267
+ html[data-look="thermal"] body.dark .menu.tile-grid svg.lp { box-shadow: 0 0 0 1px #3f4045; }
268
+ html[data-look="thermal"] body.dark .menu.tile-grid .menu-item.on svg.lp { box-shadow: 0 0 0 2px var(--blue); }
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "Glideshow",
3
+ "short_name": "Glideshow",
4
+ "description": "Slides you own.",
5
+ "start_url": "/",
6
+ "scope": "/",
7
+ "display": "standalone",
8
+ "background_color": "#eef2f6",
9
+ "theme_color": "#2f6bff",
10
+ "icons": [
11
+ {
12
+ "src": "/editor/apple-touch-icon.png",
13
+ "sizes": "180x180",
14
+ "type": "image/png"
15
+ },
16
+ {
17
+ "src": "/editor/glideshow-1024.png",
18
+ "sizes": "1024x1024",
19
+ "type": "image/png",
20
+ "purpose": "any"
21
+ }
22
+ ]
23
+ }