33 * Licensed under the MIT License. See License.txt in the project root for license information.
44 */
55
6+ @use " grid-shared" as score ;
7+
68@font-face {
79 font-family : " Fairytale" ;
810 src : url (" /fonts/FairytaleSerif-MediumItalic.woff2" ) format (" woff2" );
@@ -240,78 +242,7 @@ h6 {
240242 transition : left 0.050s linear ;
241243 }
242244
243- .grid-measure-viewer {
244- border-right : 2px solid var (--color-base-300 );
245- }
246-
247- .grid-measure-beam {
248- height : 20pt ;
249- margin-bottom : 5px ;
250- position : relative ;
251- overflow : hidden ;
252-
253- // Horizontal beam; left/right endpoints are set via CSS vars from GridMeasureBeam.tsx
254- // so that edge measures start/end exactly at the measured beat positions.
255- & ::before {
256- content : ' ' ;
257- position : absolute ;
258- top : 0 ;
259- left : var (--beam-left , 0 );
260- right : var (--beam-right , 0 );
261- height : 5px ;
262- background-color : var (--color-base-content );
263- }
264- }
265-
266- .grid-measure-number {
267- position : absolute ;
268- top : 10px ;
269- font-size : 11px ;
270- color : var (--color-base-content );
271- pointer-events : none ;
272- }
273-
274- .grid-measure-beat {
275- position : absolute ;
276- top : 0 ;
277- height : 100% ;
278- border-left : 1px solid var (--color-base-content );
279-
280- & .bar-start {
281- border-left-width : 2px ;
282- }
283- }
284-
285- .grid-measure-row {
286- margin : 2px 8px 14px 8px ;
287- }
288-
289- .subdivision {
290- position : relative ;
291- padding : 4px 0 4px 0 ;
292-
293- // Bracket color: neutral gray, level 1 ≈ #ccc (83 % L) getting 15 % darker
294- // per nesting level. Fixed lightness guarantees light → dark on every theme.
295- --subdivision-color : oklch (calc (83% - (var (--current-level , 1 ) - 1 ) * 15% ) 0 0 );
296-
297- & ::before {
298- content : ' ' ;
299- position : absolute ;
300- top : 2px ;
301- left : 0 ;
302- right : 0 ;
303- bottom : 2px ;
304- border-top : 3px solid var (--subdivision-color );
305- border-bottom : 3px solid var (--subdivision-color );
306- border-radius : 6px ;
307- pointer-events : none ;
308- z-index : 1 ;
309- }
310-
311- > .note-viewer {
312- height : calc (var (--note-height ) - var (--current-level ) * 8px );
313- }
314- }
245+ @include score .score-grid-rules ($useThemeColors : true, $renderBeam : true, $beatNumberTop : 10px );
315246 }
316247 }
317248
320251 --track-controls-expanded-width : clamp (200px , 24vw , 300px );
321252
322253 overflow : hidden ;
323- gap : 12 px ;
254+ gap : 8 px ;
324255
325256 flex : 0 0 var (--track-controls-collapsed-width );
326257 width : var (--track-controls-expanded-width );
@@ -424,14 +355,38 @@ h6 {
424355 justify-content : flex-start ;
425356 }
426357
427- .trackViewModeToggle {
358+ .trackViewModeToggleGroup {
428359 margin-left : 8px ;
429360 }
430361
362+ .trackViewModeIcons {
363+ height : 32px ;
364+ margin-top : 3px ;
365+ }
366+
367+ .trackViewModeGridIcon {
368+ width : 8px ;
369+ height : 8px ;
370+ flex : 0 0 auto ;
371+ border : 1px dashed currentColor ;
372+ }
373+
374+ .trackViewModeToggle {
375+ margin : 0 ;
376+ }
377+
431378 .trackViewModeToggle input [type = " checkbox" ] {
432379 width : 32px ;
433380 height : 18px ;
434381 }
382+
383+ .trackViewModeToggle.toggle-vertical {
384+ // daisyUI's toggle is horizontal. Rotate it 90° clockwise so the handle
385+ // moves vertically. With this rotation, the unchecked handle sits at the
386+ // top and the checked handle at the bottom.
387+ transform : rotate (90deg );
388+ margin-right : -2px ;
389+ }
435390}
436391
437392.guiderail {
923878 color : var (--color-base-content );
924879 }
925880
926- /* ---- Slap: cross inside square (uses ::before so ::after keeps the filled square) ---- */
927- & .slap ::before {
928- content : " " ;
881+ /* ---- Slap: white cross SVG drawn on top of the filled square head ---- */
882+ .staff-note-head-slap-svg {
929883 position : absolute ;
930884 left : calc (50% - 7px );
931885 bottom : 20px ;
@@ -934,14 +888,10 @@ h6 {
934888 transform : translate (-50% , -30% );
935889 pointer-events : none ;
936890 z-index : 1 ;
937- background-image :
938- linear-gradient (45deg ,
939- transparent 42% , var (--color-base-100 ) 42% , var (--color-base-100 ) 58% , transparent 58% ),
940- linear-gradient (-45deg ,
941- transparent 42% , var (--color-base-100 ) 42% , var (--color-base-100 ) 58% , transparent 58% );
891+ overflow : visible ;
942892 }
943893
944- /* ---- Hand + Cross → hollow square around the cross (Kessel ) ---- */
894+ /* ---- Hand + Cross → hollow square around the cross (body ) ---- */
945895 & .body-hand ::before {
946896 content : " " ;
947897 position : absolute ;
@@ -1126,6 +1076,14 @@ h6 {
11261076 border-radius : 8px ;
11271077}
11281078
1079+ /*
1080+ * In the grid view, the row is a CSS grid with `baseSteps` columns of `1fr`,
1081+ * and tuplet subdivisions span `subdivision.normal` columns while internally
1082+ * being grids of `subdivision.actual` columns. This makes a tuplet's outer
1083+ * width exactly equal to `normal` base cells regardless of margin, padding,
1084+ * border or grid `gap`, since `gap` is included in the spanned width.
1085+ */
1086+
11291087.note-viewer :active .hold-detector {
11301088 opacity : 30% ;
11311089}
@@ -1535,31 +1493,68 @@ h6 {
15351493 height : 100% ;
15361494}
15371495
1538- #settingsDialog #settingsGrid {
1496+ /*
1497+ * macOS-style settings card. A rounded container with horizontal hairline
1498+ * dividers between rows. Each row has its label on the left and its control
1499+ * on the right.
1500+ */
1501+ .settings-card {
15391502 margin : 16px 0 ;
1503+ background-color : color-mix (in srgb , var (--color-base-content ) 4% , var (--color-base-100 ));
1504+ border : 1px solid var (--color-base-300 );
1505+ border-radius : 10px ;
1506+ overflow : hidden ;
1507+ }
15401508
1541- .settingName {
1542- justify-content : center ;
1543- }
1509+ .settings-row {
1510+ padding : 10px 16px ;
1511+ min-height : 36px ;
1512+ border-bottom : 1px solid var (--color-base-300 );
15441513
1545- .settingValue {
1546- align-items : center ;
1547- justify-content : flex-end ;
1514+ & :last-child {
1515+ border-bottom : 0 ;
15481516 }
1517+ }
15491518
1550- .zoomButton {
1551- border : none ;
1552- width : 32px ;
1553- height : 32px ;
1554- margin : 0 2px ;
1555- }
1519+ .settings-row-stacked {
1520+ gap : 6px ;
1521+ }
15561522
1557- .resetButton {
1558- border : none ;
1559- height : 32px ;
1560- margin-left : 8px ;
1561- padding : 0 12px ;
1562- }
1523+ .settings-row-stacked > .settings-row-label {
1524+ margin-right : 0 ;
1525+ }
1526+
1527+ .settings-row-values {
1528+ margin-left : 4px ;
1529+ }
1530+
1531+ .settings-row-label {
1532+ font-size : 13px ;
1533+ color : var (--color-base-content );
1534+ margin-right : 16px ;
1535+ }
1536+
1537+ .settings-section-title {
1538+ font-size : 12px ;
1539+ font-weight : 600 ;
1540+ text-transform : uppercase ;
1541+ letter-spacing : 0.04em ;
1542+ color : color-mix (in srgb , var (--color-base-content ) 60% , transparent );
1543+ margin : 12px 4px 4px 4px ;
1544+ }
1545+
1546+ #settingsDialog .zoomButton {
1547+ border : none ;
1548+ width : 32px ;
1549+ height : 32px ;
1550+ margin : 0 2px ;
1551+ }
1552+
1553+ #settingsDialog .resetButton {
1554+ border : none ;
1555+ height : 32px ;
1556+ margin-left : 8px ;
1557+ padding : 0 12px ;
15631558}
15641559
15651560.arrangementViewer .minimap {
0 commit comments