:root {
  /* The colours, in both schemes, are the first look's in themes.json: the
     paper --bg, the ink --fg, --muted text at 4.5:1 against the paper and
     --faint marks at 3:1, the --edge of what lies over the page, --error; and
     the text as it is written, the turns and optional notes in --turn, the
     options in --option, the alternatives in --alternative. */

  /* What stands out: a turn looked at, a switch that is on, a choice filling,
     a stated key, the file's name; a progression's tab; what is not current. */
  --highlight: var(--fg);
  --switch-on: var(--muted);
  --choice-ink: var(--fg);
  --key-ink: var(--muted);
  --file-name-ink: var(--muted);
  --tab-fill: var(--fg);
  --tab-ink: var(--bg);
  --dim: 0.35;

  /* The faces: the page's text; the chord names and the notes under the grids;
     ♭ ♯ 𝄫 𝄪, which a face that has none takes from the next in its list; the
     text as it is written. The page loads the faces these name before it
     measures the sheet. */
  --face: system-ui, -apple-system, "Segoe UI", sans-serif;
  --chord-face: var(--face);
  --accidentals: system-ui;
  --chart: "Menlo", "DejaVu Sans Mono", "Consolas", "Liberation Mono", monospace;
  --leading: 1.4;
  --strong: 600;
  --file-name-size: 1.6em;
  --file-name-weight: normal;
  --chord-name-weight: normal;
  --margin: clamp(16px, 2.5vw, 56px);

  /* The page's own text, and the surfaces that lie over it. A control is at
     least --target tall and wide, the least target of WCAG 2.5.8. */
  --text: 14px;
  --small: 12px;
  --round: 6px;
  --round-small: 4px;
  --target: 24px;
  --focus: 2px;
  --heading-gap: 1.8em;
  --sound-gap: 4px 1.4em;
  --actions-gap: 4px 20px;
  --choice-gap: 14px;
  --words-gap: 16px;
  --file-buttons-gap: 8px;
  --guide-gap: 22px;
  --guide-docked-gap: 22px 36px;
  --panel-pad: 14px;
  --panel-pad-coarse: 20px;
  --files-pad: 16px 18px;
  --sounding-pad: 8px 12px;

  /* Motion: the change between the pages and a chosen alternative's move; a
     switch; the fading of what is not current; the choices appearing, rising
     this far. */
  --morph: 0.45s;
  --morph-easing: ease;
  --switch-motion: 0.15s;
  --fade: 0.2s;
  --choices-in: 0s;
  --choices-rise: 0px;

  /* The sheet, in drawing units: one unit is --chord-scale pixels, chosen by
     the page between these two. At the smallest, a note under a grid is 12px. */
  --scale-min: 1.1;
  --scale-max: 3;
  --alternative-scale: 0.667;  /* the alternatives hanging under a span, a share of the sheet's scale */
  --gap: 6;         /* between chords of a progression */
  --between: 40;    /* between progressions side by side */
  --row-gap: 40;    /* between rows of progressions */
  --continued: 10;  /* above the rest of a progression that did not fit its row, and around the alternatives under a span */
  --tab: 18;        /* the width of a progression's tab, before its first chord */
  --tab-title: 11;  /* the title, set upright in the tab */
  --tab-edge: 1;    /* the outline of a continued progression's tab */
  --tab-rule: 0;    /* a rule down the tab's left side, a continued tab's at least --tab-edge */
  --tab-inset: 7;   /* from the tab's foot to its title */
  --description-inset: 6;  /* around an opened description */
  --description-round: 2;
  --description: 11;
  --name: 14;
  --flow: 2;           /* the fewest chords a progression is cut into when rows flow */
  --settle-tries: 8;   /* steps down from the computed scale, should the page not fit it */

  /* The float on the writing page: the sheet again, compact, in the right margin:
     this share of the viewport's width, and at least this many pixels wide, else
     docked at the bottom. */
  --float-scale-min: 0.7;
  --float-scale-max: 1;
  --float-share: 0.33;
  --float-least: 260;
  --float-height: 70vh;
  --float-height-share: 0.7;  /* the same, as a share, where the page computes it */
  --float-docked-height: 32vh;

  /* The guide: a float as tall as the drawing's and this wide. Its grids take the
     largest scale between these two at which the widest leaves this many pixels
     for its comment and the tallest fills at most this share of the guide's
     height; its rows of notes need letters at least this many pixels tall. */
  --guide-width: 380px;
  --guide-part-least: 320px;
  --guide-scale-min: 0.4;
  --guide-scale-max: 0.8;
  --guide-comment: 150;
  --guide-share: 0.6;
  --guide-letter-least: 8;

  /* Clickless, in milliseconds and pixels (the Dwell setting scales the times):
     the pointer rests --settle on a chord, moving less than --still, to open its
     choices; they stay --grace after it has left; a choice fills in --audition,
     or --lasting for a sound that lasts, while the pointer strays at most
     --tolerance; the circle's note is taken after --circle-settle. */
  --settle: 400;
  --still: 6;
  --grace: 500;
  --audition: 300;
  --lasting: 700;
  --tolerance: 20;
  --circle-settle: 150;
  --choices-gap: 4;
  --circle-radius: 64px;

  /* The files dialog and the settings dialog: at most this wide, and this tall. */
  --files-width: 560px;
  --settings-width: 460px;
  --files-height: 70vh;
  --setting-gap: 4px 1.2em;
  --small-screen: 0;
  color-scheme: light dark;
}
/* The scheme the address or the settings force, else the system's. */
:root[data-scheme="light"] { color-scheme: light; }
:root[data-scheme="dark"] { color-scheme: dark; }
* { box-sizing: border-box; }
html { scrollbar-gutter: stable; }
body {
  margin: 0;
  background: var(--bg); color: var(--fg);
  font: var(--text)/var(--leading) var(--face);
}
[hidden] { display: none !important; }

#file-name, #name { view-transition-name: file-name; }

/* The sheet */
#sheet {
  min-height: 100vh; display: flex; flex-direction: column;
  padding: var(--margin); touch-action: pan-y pinch-zoom;
}
@media (pointer: coarse) { #sheet { user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; } }
#music, #float-music {
  --u: var(--chord-scale);
  --chord-ink: var(--fg); --chord-quiet: var(--muted);
  --chord-paper: var(--bg); --chord-highlight: var(--highlight); --chord-font: var(--chord-face);
  width: max-content; max-width: 100%; margin: 0 auto;
}
#heading { margin: 0 0 18px; line-height: 1.2; color: var(--muted); }
/* The file name and the page's words, on one line: the words fold into
   Settings until they fit, and a name longer than the rest of the line is cut
   short. */
#heading-line { display: flex; align-items: baseline; column-gap: var(--heading-gap); }
:root:not([data-folded]) #heading-line { visibility: hidden; }
#heading-line > button { flex: none; white-space: nowrap; }
#file-name {
  margin: 0 0.4em 0 0; font: inherit; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: var(--file-name-size); font-weight: var(--file-name-weight); color: var(--file-name-ink);
}
:is(#heading, #sound-row) button {
  font: inherit; color: var(--muted); background: none; border: 0; padding: 0; cursor: pointer;
}
:is(#heading, #sound-row) button:hover, #sound[aria-expanded="true"] { color: var(--fg); }
#sound-row {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--sound-gap);
  margin: 0.3em 0 0; color: var(--muted);
}
#settings #sound-row { margin: 2px 0 0; }
#sound-row a { color: var(--muted); }
/* A value keeps one width as it steps, the widest its format writes below ten:
   d.dd× and d.dd s. */
#dwell, #chord-seconds, #note-seconds { display: inline-block; text-align: center; font-variant-numeric: tabular-nums; }
#dwell { min-width: 5ch; }
#chord-seconds, #note-seconds { min-width: 6ch; }
#feel, #drone-voice, #sound-state { display: inline-grid; }
:is(#feel, #drone-voice, #sound-state) > span { grid-area: 1 / 1; visibility: hidden; }
:is(#feel, #drone-voice, #sound-state) > .current { visibility: visible; }
#sound-row a:hover { color: var(--fg); }

/* Every word that acts is at least a target tall and wide, and shows the
   keyboard's focus in the page's ink. */
:is(#heading button, #sound-row :is(button, a), #actions :is(button, label), #shown button, .float-words button, .choice, .download > button, .download-links a) {
  min-width: var(--target); min-height: var(--target);
}
:is(#sound-row a, #actions label, .download-links a) { display: inline-flex; align-items: center; }
:is(#heading button, #sound-row :is(button, a), #actions :is(button, label), #shown button, .float-words button, .choice, .download > button, .download-links a, #drone-note, .file-buttons button, #circle .fifth):focus-visible {
  outline: var(--focus) solid var(--fg); outline-offset: var(--focus); border-radius: var(--focus);
}
#choices :focus-visible { outline-offset: calc(var(--inset-y) - var(--focus)); }

/* A switch: a track before its label, filled when on and outlined when off,
   its knob at the end it was switched to. */
[role="switch"]::before {
  content: ""; display: inline-block; vertical-align: -0.15em; margin-right: 0.35em;
  box-sizing: border-box; width: 1.75em; height: 1em; border-radius: 0.5em;
  border: 1px solid var(--muted);
  background: radial-gradient(circle closest-side, var(--muted) 70%, transparent 76%) 0 50% / calc(1em - 2px) calc(1em - 2px) no-repeat;
  transition: background-position var(--switch-motion), background-color var(--switch-motion);
}
[role="switch"][aria-checked="true"]::before {
  border-color: var(--switch-on); background-color: var(--switch-on);
  background-image: radial-gradient(circle closest-side, var(--bg) 72%, transparent 78%); background-position: 100% 50%;
}
@media (prefers-reduced-motion: reduce) { [role="switch"]::before { transition: none; } #choices:not([hidden]) { animation: none; } }

/* The words that are settings: the switches of what the sheet shows, then
   Other settings at the page's top right, on the heading's first line, its
   baseline the file name's. With a mouse or trackpad it is shown only while
   the pointer is in the corner or over the page's words, or the keyboard is on
   it. Where the heading's line cannot hold the switches, Settings stands among
   the page's words and the switches are in its dialog, and so, where the line
   needs it, are Sound and then Guide. */
#corner {
  position: absolute; top: 0; right: 0; padding: var(--margin) var(--margin) 0;
  display: flex; align-items: baseline; line-height: 1.2;
}
#corner::before { content: "\200b"; font-size: var(--file-name-size); font-weight: var(--file-name-weight); }
:root:has(#sheet[hidden]) #corner::before { content: none; }
#settings-word {
  min-width: var(--target); min-height: var(--target);
  font: inherit; color: var(--muted); background: none; border: 0; padding: 0; cursor: pointer;
}
#settings-word:hover { color: var(--fg); }
#settings-word:focus-visible { outline: var(--focus) solid var(--fg); outline-offset: var(--focus); border-radius: var(--focus); }
@media (any-hover: hover) and (any-pointer: fine) {
  #settings-word { opacity: 0; transition: opacity var(--fade); }
  :root:has(#corner:hover, #heading:hover, #actions:hover) #settings-word, #settings-word:focus-visible { opacity: 1; }
}
:is(#heading, #actions) .settings-word, #shown, #shown .guide-word, #sound-settings { display: none; }
:root[data-folded~="switches"] :is(#corner, #heading [data-show]) { display: none; }
:root[data-folded~="switches"] :is(#heading .settings-word, #actions .settings-word, #shown) { display: revert; }
:root[data-folded~="sound"] #sound { display: none; }
:root[data-folded~="sound"] #sound-settings { display: revert; }
:root[data-folded~="guide"] #heading .guide-word { display: none; }
:root[data-folded~="guide"] #shown .guide-word { display: revert; }
@media (max-width: 640px), (max-height: 500px) { :root { --small-screen: 1; } }

/* The dialogs, centred over the page, which they block. */
#files, #settings {
  width: min(var(--files-width), 100% - 2 * var(--margin)); max-width: none;
  max-height: min(var(--files-height), 100% - 2 * var(--margin));
  padding: var(--files-pad); color: var(--fg); background: var(--bg);
  border: 1px solid var(--edge); border-radius: var(--round);
}
#settings { width: min(var(--settings-width), 100% - 2 * var(--margin)); }
#files[open] { display: flex; flex-direction: column; }
/* Their own colours: a backdrop inherits no custom properties before Safari 17.4. */
:is(#files, #settings)::backdrop { background: rgb(0 0 0 / 0.35); }
@media (prefers-color-scheme: dark) { :root:not([data-scheme="light"]) :is(#files, #settings)::backdrop { background: rgb(0 0 0 / 0.6); } }
:root[data-scheme="dark"] :is(#files, #settings)::backdrop { background: rgb(0 0 0 / 0.6); }
:is(#files, #settings) h2 { margin: 0 0 10px; font-size: var(--text); font-weight: var(--strong); }
#files-list {
  flex: 0 1 auto; min-height: 0; overflow: auto; overscroll-behavior: contain;
  border: 1px solid var(--edge); border-radius: var(--round); outline: none;
}
#files-list:focus-visible { border-color: var(--muted); }
#files-list [role="option"] {
  display: grid; grid-template-columns: minmax(0, 1fr); padding: 6px 10px; cursor: default; user-select: none; -webkit-user-select: none;
}
#files-list [role="option"] + [role="option"] { border-top: 1px solid var(--edge); }
#files-list [aria-selected="true"] { background: var(--edge); }
#files-list:focus [aria-selected="true"] { background: var(--fg); color: var(--bg); }
#files-list:focus [aria-selected="true"] .file-about { color: var(--bg); opacity: 0.75; }
#files-list [aria-current="true"] .file-name { font-weight: var(--strong); }
#files-list .file-name { overflow-wrap: anywhere; }
#files-list .file-about { font-size: var(--small); color: var(--muted); }
#files-list .rename {
  font: inherit; color: var(--fg); background: var(--bg); border: 1px solid var(--muted); border-radius: var(--round-small); padding: 1px 4px; width: 100%;
}
#kept { margin: 10px 0 0; font-size: var(--small); color: var(--muted); }
#said { margin: 10px 0 0; font-size: var(--small); color: var(--muted); }
#said:empty { display: none; }
#said p { margin: 0; }
#said .error { color: var(--error); }
#confirm p { margin: 12px 0 0; }
.file-buttons { display: flex; flex-wrap: wrap; gap: var(--file-buttons-gap); margin: 14px 0 0; }
.file-buttons button {
  font: inherit; color: var(--fg); background: var(--bg); border: 1px solid var(--edge); border-radius: var(--round); padding: 4px 12px; cursor: pointer;
}
.file-buttons button:hover:not(:disabled) { border-color: var(--muted); }
.file-buttons button:disabled { color: var(--faint); cursor: default; }
.file-buttons .primary { color: var(--bg); background: var(--fg); border-color: var(--fg); }
.file-buttons .primary:disabled { color: var(--bg); background: var(--faint); border-color: var(--faint); }
.file-buttons .destructive { color: var(--bg); background: var(--error); border-color: var(--error); }
#close-files, #close-settings { margin-left: auto; }

/* The settings: each a row of words, the current one in ink. */
#settings { overflow: auto; overscroll-behavior: contain; }
#settings fieldset { margin: 0 0 12px; padding: 0; border: 0; min-width: 0; }
#settings legend { padding: 0; color: var(--muted); font-size: var(--small); }
.setting-words { display: flex; flex-wrap: wrap; gap: var(--setting-gap); margin: 2px 0 0; }
#shown button { font: inherit; color: var(--muted); background: none; border: 0; padding: 0; cursor: pointer; }
#shown button:hover { color: var(--fg); }
.setting-words label { display: inline-flex; align-items: center; min-width: var(--target); min-height: var(--target); color: var(--muted); cursor: pointer; }
.setting-words label:hover, .setting-words label:has(:checked) { color: var(--fg); }
.setting-words input { appearance: none; width: 0; height: 0; margin: 0; border: 0; outline: none; }
.setting-words label:has(:focus-visible) { outline: var(--focus) solid var(--fg); outline-offset: var(--focus); border-radius: var(--focus); }

#sheet-problems { margin: 0.3em 0 0; font-size: var(--small); color: var(--error); }
#sheet-problems:empty { display: none; }

/* A chord's or a tab's choices, over its name; a choice fills as the pointer
   rests in it. */
#choices {
  --inset-y: 3px; --inset-x: 8px;
  position: fixed; z-index: 3; display: flex; gap: var(--choice-gap); padding: var(--inset-y) var(--inset-x);
  background: var(--bg); border: 1px solid var(--edge); border-radius: var(--round);
}
#choices:not([hidden]) { animation: choices-in var(--choices-in) ease-out both; }
@keyframes choices-in { from { opacity: 0; translate: 0 var(--choices-rise); } }
.choice, .download > button { font: inherit; color: var(--fg); background: none; border: 0; padding: 0 0 3px; cursor: pointer; }
.choice {
  --fill: 0;
  background-image: linear-gradient(var(--choice-ink), var(--choice-ink)); background-repeat: no-repeat; background-position: 0 100%;
  background-size: calc(var(--fill) * 100%) 2px;
}
/* A tab's files hang from Download, joined to the choices, their names in line
   with it; they are links, quiet as the Sound row's. */
.download { position: relative; }
.download-links {
  position: absolute; top: calc(100% + var(--inset-y)); left: calc(var(--shift, 0px) - var(--inset-x) - 1px);
  display: flex; gap: var(--choice-gap); padding: var(--inset-y) var(--inset-x);
  white-space: nowrap;
  background: var(--bg); border: 1px solid var(--edge);
  border-radius: 0 0 var(--round) var(--round);
  visibility: hidden;
}
[aria-expanded="true"] + .download-links { visibility: visible; }
.download-links a { padding: 0 0 3px; color: var(--muted); }
.download-links a:hover { color: var(--fg); }

/* What sounds: the drone and its note, and the progression playing, each with
   its stop; the note opens the circle of fifths. */
#sounding {
  position: fixed; z-index: 3; right: var(--margin); bottom: var(--margin);
  padding: var(--sounding-pad); background: var(--bg); border: 1px solid var(--edge); border-radius: var(--round);
  color: var(--muted); cursor: grab; touch-action: none;
}
/* Above a docked float, which holds the bottom. */
html:is(.guided, :has(#writing.docked:not([hidden]))) #sounding { bottom: calc(var(--float-docked-height) + 2 * var(--margin)); }
#sounding p { margin: 0; display: flex; gap: 10px; align-items: baseline; }
#sounding p + p { margin-top: 4px; }
#drone-note { font: inherit; font-weight: var(--strong); color: var(--fg); background: none; border: 0; padding: 0; cursor: pointer; }
#drone-note:disabled { cursor: default; }
/* Over the float and touching it, so that the pointer stays within the float
   on its way to a note. */
#circle {
  position: absolute; left: 50%; bottom: 100%;
  width: calc(2 * var(--circle-radius) + 40px); aspect-ratio: 1; margin-left: calc(-1 * var(--circle-radius) - 20px);
}
#circle .fifth {
  position: absolute; width: 30px; height: 30px; margin: -15px 0 0 -15px; border-radius: 50%;
  left: calc(50% + sin(var(--i) * 30deg) * var(--circle-radius)); top: calc(50% - cos(var(--i) * 30deg) * var(--circle-radius));
  font: inherit; color: var(--fg); background: var(--bg); border: 1px solid var(--edge); cursor: pointer;
}
#circle .fifth.reading { border-color: var(--muted); }
#circle .fifth.current { background: var(--fg); color: var(--bg); }
.row + .row { margin-top: calc(var(--row-gap) * var(--u)); }
.row + .row.continued { margin-top: calc(var(--continued) * var(--u)); }
.row {
  display: grid; grid-auto-flow: column; grid-template-rows: repeat(4, auto);
  column-gap: calc(var(--between) * var(--u)); justify-content: start;
  min-width: calc(var(--row-least, 0) * var(--u));
}
/* A progression's rows: its chords' names, grids, and later turns, and the
   alternatives hanging under them. */
.progression {
  grid-row: span 4; display: grid; grid-template-rows: subgrid; grid-auto-columns: max-content;
  column-gap: calc(var(--gap) * var(--u));
}
/* The tab and the description: from the chord names to the grids' foot, their
   size the rows' and never their text's. The tab's title is a horizontal line as
   long as the tab is tall, turned a quarter about its lower left corner, so that
   no engine lays out vertical text. */
.progression .tab {
  grid-row: 1 / span 2; grid-column: 1; container-type: size; position: relative;
  width: calc(var(--tab) * var(--u)); margin: 0;
  background: var(--tab-fill); color: var(--tab-ink);
  border-left: calc(var(--tab-rule) * var(--u)) solid var(--fg);
  font-size: calc(var(--tab-title) * var(--u)); font-weight: var(--strong);
}
.progression .tab-title {
  position: absolute; left: 0; top: 100%; box-sizing: border-box;
  width: 100cqh; height: 100cqw; line-height: 100cqw;
  transform-origin: 0 0; transform: rotate(-90deg);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  padding-inline: calc(var(--tab-inset) * var(--u));
}
.progression .tab.continued {
  background: none; color: var(--muted);
  border: calc(var(--tab-edge) * var(--u)) solid var(--faint);
  border-left-width: calc(max(var(--tab-edge), var(--tab-rule)) * var(--u));
}
.description {
  grid-row: 1 / span 2; grid-column: 2; position: relative;
  width: calc(var(--description-width) * var(--u));
  color: var(--muted); font-size: calc(var(--description) * var(--u)); line-height: 1.35;
}
/* A stated key heads the column: in the description's type, on the line of the
   chords' names, its line box a name's, so that it shares their baseline. The
   description goes under it, beside the grids. */
.progression .key {
  grid-row: 1; grid-column: 2; align-self: end; justify-self: start;
  margin: 0 0 calc(0.5 * var(--u)); white-space: nowrap;
  width: calc(var(--key-width) * var(--u));
  font-size: calc(var(--name) * var(--u)); line-height: 1.2;
}
.progression .key-text { font-size: calc(var(--description) * var(--u)); font-weight: var(--strong); color: var(--key-ink); }
.description.keyed { grid-row: 2; }
.description-text { position: absolute; inset: 0 0 auto; max-height: 100%; overflow: hidden; margin: 0; overflow-wrap: anywhere; }
.description.clipped { cursor: pointer; }
.description.clipped:not(.open) .description-text { mask-image: linear-gradient(to bottom, #000 calc(100% - 2lh), transparent); }
/* Open, it lies on the paper over the rows below, which stay where they are. */
.description.open .description-text {
  z-index: 2; max-height: none;
  inset: calc(-1 * var(--description-inset) * var(--u)) calc(-1 * var(--description-inset) * var(--u)) auto;
  padding: calc(var(--description-inset) * var(--u));
  background: var(--bg); outline: 1px solid var(--edge); border-radius: calc(var(--description-round) * var(--u));
}
/* A chord: its first turn's names over the grid, its later turns' under it. */
.progression figure { grid-row: 1 / span 3; display: grid; grid-template-rows: subgrid; }
.progression figcaption {
  grid-row: 1 / span 3; grid-column: 1; display: grid; grid-template-rows: subgrid;
  padding-left: calc(var(--chord-margin) * var(--u));
  font-size: calc(var(--name) * var(--u)); line-height: 1.2;
}
.progression .chord-grid { grid-row: 2; grid-column: 1; }
.progression .chord-names { grid-row: 1; align-self: end; margin: 0 0 calc(0.5 * var(--u)); }
.progression .chord-names:not(.later) .name { font-weight: var(--chord-name-weight); }
.progression .chord-names.later { grid-row: 3; align-self: start; margin: calc(1.5 * var(--u)) 0 0; font-size: 0.85em; color: var(--muted); }
.progression .later .entry:has(.names:empty) { display: none; }
/* Under a span that offers alternatives, a line from its first string to its
   last, drawn as a diagram's lines are, and the others hanging from it,
   smaller, laid out as a sheet at their scale: each its label over its chords'
   names, each of its rows starting at its low string. */
.progression .hang {
  grid-row: 4; position: relative;
  margin-top: calc(var(--continued) * var(--u));
  height: calc(var(--stack) * var(--u));
}
.hang > .span-line {
  position: absolute; top: 0; left: calc(var(--low) * var(--u));
  width: calc((var(--high) - var(--low)) * var(--u)); height: calc(var(--chord-line) * var(--u));
  background: var(--faint);
}
/* A click on the line, or in the spaces over and under it, folds the
   alternatives away or brings them back; its word says which, set on the line
   at the size of the alternatives' labels, and it fits the space under the
   line. A mouse shows the word while it points at the line. */
.hang > .span-line { cursor: pointer; }
.hang > .span-line::before {
  content: ""; position: absolute; left: 0; right: 0;
  top: calc(-1 * var(--continued) * var(--u)); bottom: calc(-1 * var(--continued) * var(--hanging-scale));
}
.hang > .span-line > span {
  position: absolute; left: 50%; top: 50%; translate: -50% -50%;
  padding-inline: 0.25em;  /* a word space either side */
  font-size: calc(var(--name) * var(--hanging-scale)); line-height: 1.2; white-space: nowrap;
  color: var(--muted); background: var(--bg);
}
@media (any-hover: hover) and (any-pointer: fine) {
  .hang > .span-line > span { opacity: 0; transition: opacity var(--fade); }
  .hang > .span-line:hover > span { opacity: 1; }
}
.hang > .alternative {
  position: absolute; left: calc(var(--x) * var(--u)); top: calc(var(--y) * var(--u));
  display: flex; flex-direction: column; cursor: pointer;
}
.hang > .alternative > * { --u: var(--hanging-scale); --chord-scale: var(--hanging-scale); }
.alternative-label {
  contain: inline-size;
  font-size: calc(var(--name) * var(--u)); line-height: 1.2; color: var(--muted);
}
.alternative-row {
  display: grid; grid-auto-flow: column; grid-template-rows: repeat(3, auto); grid-auto-columns: max-content;
  column-gap: calc(var(--gap) * var(--u)); width: max-content;
}
.alternative-row + .alternative-row { margin-top: calc(var(--continued) * var(--u)); }
.alternative-row > figure:first-child { margin-left: calc(-1 * var(--chord-margin) * var(--u)); }
.empty { color: var(--muted); }

/* Writing */
#writing {
  max-width: calc(84ch + 2 * var(--margin)); margin: 0 auto; padding: var(--margin);
}
#actions { margin: 0 0 10px; line-height: 1.2; color: var(--faint); display: flex; flex-wrap: wrap; gap: var(--actions-gap); }
#actions button, #actions label {
  font: inherit; color: var(--muted); background: none; border: 0; padding: 0; cursor: pointer;
}
#actions button:hover, #actions label:hover { color: var(--fg); }
#actions #done { color: var(--fg); font-weight: var(--strong); }
#name { display: block; font: inherit; color: var(--muted); margin: 0 0 18px; width: 100%; padding: 0; border: 0; background: none; outline: none; }
#name:focus { color: var(--fg); }
#problems { color: var(--error); margin: 0 0 12px; font: var(--small)/1.45 var(--chart); }
#problems:empty { display: none; }
#problems p { margin: 0; }
/* A line height of whole pixels: WebKit rounds a text area's, and not that of
   the coloured copy under it. */
#paper { display: grid; grid-template-columns: minmax(0, 1fr); font: var(--text)/22px var(--chart); tab-size: 4; }
#lines, #text {
  grid-area: 1 / 1; margin: 0; padding: 0; border: 0;
  font: inherit; white-space: pre-wrap; overflow-wrap: break-word;
}
#lines { pointer-events: none; }
#lines .muted, #lines .keyword, #lines .separator { color: var(--faint); }
#lines .comment, #lines .text { color: var(--muted); }
#lines .title { font-weight: var(--strong); }
#lines .turn { color: var(--turn); }
#lines .optional { color: var(--turn); opacity: 0.7; }
#lines .option, #lines .value, #lines .fault { color: var(--option); }
#lines .fault { text-decoration: underline var(--error); }
#lines .alternative { color: var(--alternative); }
.line { min-height: 1lh; }
.group, .line { scroll-margin-block: var(--margin); }
#text { resize: none; overflow: hidden; background: none; color: transparent; caret-color: var(--fg); outline: none; min-height: 60vh; }

#float {
  position: fixed; z-index: 1; display: flex; flex-direction: column;
  height: var(--float-height); padding: var(--panel-pad);
  background: var(--bg); border: 1px solid var(--edge); border-radius: var(--round);
  touch-action: none; user-select: none; -webkit-user-select: none; cursor: grab;
}
#float:active, #guide:active { cursor: grabbing; }

#guide {
  position: fixed; z-index: 2; display: flex; flex-direction: column;
  width: min(var(--guide-width), calc(100% - 2 * var(--margin))); height: var(--float-height); padding: var(--panel-pad);
  background: var(--bg); border: 1px solid var(--edge); border-radius: var(--round);
  touch-action: none; cursor: grab;
}
#guide.docked { width: calc(100% - 2 * var(--margin)); height: var(--float-docked-height); }
html.guided #sheet { padding-bottom: calc(var(--float-docked-height) + 2 * var(--margin)); }
#guide-view {
  flex: 1; min-height: 0; overflow: auto; overscroll-behavior: contain; touch-action: pan-y; cursor: auto;
  --chord-ink: var(--fg); --chord-quiet: var(--muted); --chord-paper: var(--bg); --chord-highlight: var(--highlight); --chord-font: var(--chord-face);
}
.guide-part + .guide-part { margin-top: var(--guide-gap); }
/* Docked, as wide as the window, its parts side by side, at least this wide. */
#guide.docked #guide-view { display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--guide-part-least), 1fr)); gap: var(--guide-docked-gap); align-content: start; }
#guide.docked .guide-part + .guide-part { margin-top: 0; }
.guide-part { transition: opacity var(--fade); }
#guide-view:has(.current) .guide-part:not(.current) { opacity: var(--dim); }

/* The words over a float: while both floats are docked, a tab for each, the one
   shown in ink; over the guide on the editing page, Follow. */
.float-words { display: flex; gap: var(--words-gap); margin: 0 0 8px; }
#float .float-words, #writing[hidden] ~ #guide .float-words { display: none; }
html.tabbed #float .float-words { display: flex; }
.float-words button { font: inherit; color: var(--muted); background: none; border: 0; padding: 0; cursor: pointer; }
.float-words button:hover { color: var(--fg); }
.tab-word { display: none; }
html.tabbed .tab-word { display: inline; }
html.tabbed .tab-word[aria-pressed="true"] { color: var(--fg); font-weight: var(--strong); }
#follow { margin-left: auto; }

.guide-part h2 { margin: 0 0 4px; font-size: var(--text); font-weight: var(--strong); }
.guide-part p { margin: 0 0 6px; color: var(--muted); }
.guide-part .mark { color: var(--fg); }
/* An example: the line as it is written, then its chord and the line's comment. */
.guide-part .example { display: grid; grid-template-columns: auto 1fr; column-gap: 14px; align-items: center; margin-top: 12px; }
.guide-part .example code { grid-column: 1 / -1; margin-bottom: 4px; font: var(--small)/1.4 var(--chart); color: var(--fg); overflow-wrap: anywhere; }
.guide-part .example p { margin: 0; font-size: var(--small); }
/* A chord's names over its grid, as on the sheet. */
.guide-part figure { display: grid; font-size: var(--small); line-height: 1.2; }
.guide-part figcaption { display: contents; }
.guide-part .chord-names { grid-row: 1; padding-left: calc(var(--chord-margin) * var(--chord-scale)); margin: 0 0 2px; }
.guide-part .chord-grid { grid-row: 2; }
.guide-part .chord-names.later { grid-row: 3; margin: 4px 0 0; color: var(--muted); }
#float-music figure { cursor: pointer; }
#float-view { flex: 1; min-height: 0; overflow: auto; overscroll-behavior: contain; scrollbar-width: none; touch-action: pan-y; cursor: default; }
#writing.docked { padding-bottom: calc(var(--float-docked-height) + 2 * var(--margin)); }
/* The browser keeps the caret out from under the docked float as it scrolls to it. */
html:has(#writing.docked:not([hidden])) { scroll-padding-bottom: calc(var(--float-docked-height) + 2 * var(--margin)); }
#writing.docked #float { width: calc(100% - 2 * var(--margin)); height: var(--float-docked-height); }
/* Writing on a touch screen, the keyboard holds the bottom of the screen, and
   the docked floats step aside until the text is left. */
@media (pointer: coarse) {
  #writing.docked:has(#text:focus) { padding-bottom: var(--margin); }
  #writing.docked:has(#text:focus) #float, html:has(#text:focus) #guide.docked { display: none; }
  html:has(#writing.docked:not([hidden]) #text:focus) { scroll-padding-bottom: 0; }
}
#float-music .progression { transition: opacity var(--fade); }
#float-music:has(.current) .progression:not(.current) { opacity: var(--dim); }
#float-problem { margin: 10px 0 0; color: var(--error); font: var(--small)/1.4 var(--chart); }
#float-problem:empty { display: none; }

.progression, .group { view-transition-class: progression; }
::view-transition-group(*) { animation-duration: var(--morph); animation-timing-function: var(--morph-easing); }
/* The file name keeps its size as it moves between the heading and the name field. */
::view-transition-old(file-name), ::view-transition-new(file-name) { height: auto; object-fit: none; object-position: left center; }
@media (pointer: coarse) { #float, #guide { padding: var(--panel-pad-coarse); } }
::view-transition-old(.progression), ::view-transition-new(.progression) { block-size: 100%; object-fit: fill; }
