:root {
  --bg: #120f1a; --bg2: #1a1626; --card: #231d33; --line: #382f50; --text: #efe9fb; --muted: #a59dbb; --accent: #ff5c8a; --accent-ink: #2a0612; --paper: #f3eefb; --paper-ink: #211a2e;
  --danger: #e5604d; --ok: #5fb376; --amber: #e0a43a; --blue: #5b9bd5; --edit: #b388ff; /* edit days: a hue no theme uses for anything else */
  --radius: 14px; --pad: 16px; --hit: 44px; --focus: #4aa3ff;
  color-scheme: dark;
}
/* Themes: Stage is the default (above); the rest follow js/a11y.js PALETTES. Generated from one list, keep them in step. */
:root[data-scheme=light] { --bg: #efecf5; --bg2: #e5e0ef; --card: #fcfbff; --line: #d5cee5; --text: #1f1830; --muted: #6c6484; --accent: #c3265a; --accent-ink: #ffffff; --paper: #fcfbff; --paper-ink: #1f1830; color-scheme: light; --ok: #246b3c; --amber: #9a6200; --blue: #245f9c; --edit: #6a3fc9; --danger: #b3321c; }
@media (prefers-color-scheme: light) { :root:not([data-scheme]) { --bg: #efecf5; --bg2: #e5e0ef; --card: #fcfbff; --line: #d5cee5; --text: #1f1830; --muted: #6c6484; --accent: #c3265a; --accent-ink: #ffffff; --paper: #fcfbff; --paper-ink: #1f1830; color-scheme: light; --ok: #246b3c; --amber: #9a6200; --blue: #245f9c; --edit: #6a3fc9; --danger: #b3321c; } }
:root[data-palette=brass] { --bg: #14110f; --bg2: #1d1915; --card: #25201b; --line: #3a332b; --text: #f1e6cf; --muted: #a09584; --accent: #e0a43a; --accent-ink: #1a1305; --paper: #f1e6cf; --paper-ink: #2a2118; color-scheme: dark; --edit: #b388ff; --danger: #e5604d; }
:root[data-palette=brass][data-scheme=light] { --bg: #efe8da; --bg2: #e6dec9; --card: #fbf7ec; --line: #d4c9b0; --text: #2a2118; --muted: #756a58; --accent: #b87a10; --accent-ink: #ffffff; --paper: #fbf7ec; --paper-ink: #2a2118; color-scheme: light; --ok: #246b3c; --amber: #9a6200; --blue: #245f9c; --edit: #6a3fc9; --danger: #b3321c; }
:root[data-palette=noir] { --bg: #0b0b0c; --bg2: #141416; --card: #1b1b1e; --line: #2c2c31; --text: #f2f2f2; --muted: #9a9aa2; --accent: #e8412c; --accent-ink: #ffffff; --paper: #ececec; --paper-ink: #121214; color-scheme: dark; --edit: #b388ff; --danger: #e5604d; }
:root[data-palette=noir][data-scheme=light] { --bg: #f3f3f4; --bg2: #e9e9ec; --card: #ffffff; --line: #d6d6dc; --text: #151518; --muted: #6b6b74; --accent: #d2321e; --accent-ink: #ffffff; --paper: #ffffff; --paper-ink: #151518; color-scheme: light; --ok: #246b3c; --amber: #9a6200; --blue: #245f9c; --edit: #6a3fc9; --danger: #b3321c; }
:root[data-palette=forest] { --bg: #0f1712; --bg2: #16211a; --card: #1d2b22; --line: #2d4034; --text: #e9f0e4; --muted: #93a596; --accent: #c9b23a; --accent-ink: #141a0a; --paper: #e9f0e4; --paper-ink: #1a2a1f; color-scheme: dark; --edit: #b388ff; --danger: #e5604d; }
:root[data-palette=forest][data-scheme=light] { --bg: #e9efe5; --bg2: #dde6d7; --card: #f7faf4; --line: #c6d3bf; --text: #1b2a20; --muted: #5f7064; --accent: #7a8a13; --accent-ink: #ffffff; --paper: #f7faf4; --paper-ink: #1b2a20; color-scheme: light; --ok: #246b3c; --amber: #9a6200; --blue: #245f9c; --edit: #6a3fc9; --danger: #b3321c; }
:root[data-palette=ocean] { --bg: #0d141c; --bg2: #142030; --card: #1a2a3d; --line: #2b4258; --text: #e6eef5; --muted: #90a4b8; --accent: #3cc1b8; --accent-ink: #06211f; --paper: #e6eef5; --paper-ink: #13263a; color-scheme: dark; --edit: #b388ff; --danger: #e5604d; }
:root[data-palette=ocean][data-scheme=light] { --bg: #e7eef3; --bg2: #dbe5ec; --card: #f9fbfd; --line: #c3d2de; --text: #13263a; --muted: #5a6f82; --accent: #0f8f87; --accent-ink: #ffffff; --paper: #f9fbfd; --paper-ink: #13263a; color-scheme: light; --ok: #246b3c; --amber: #9a6200; --blue: #245f9c; --edit: #6a3fc9; --danger: #b3321c; }
:root[data-palette=mono] { --bg: #121212; --bg2: #1a1a1a; --card: #222222; --line: #343434; --text: #eeeeee; --muted: #9a9a9a; --accent: #e6e6e6; --accent-ink: #111111; --paper: #eeeeee; --paper-ink: #111111; color-scheme: dark; --edit: #b388ff; --danger: #e5604d; }
:root[data-palette=mono][data-scheme=light] { --bg: #f4f4f4; --bg2: #eaeaea; --card: #ffffff; --line: #d4d4d4; --text: #111111; --muted: #666666; --accent: #222222; --accent-ink: #ffffff; --paper: #ffffff; --paper-ink: #111111; color-scheme: light; --ok: #246b3c; --amber: #9a6200; --blue: #245f9c; --edit: #6a3fc9; --danger: #b3321c; }
:root[data-palette=neon] { --bg: #07090d; --bg2: #0e1218; --card: #141a22; --line: #24303d; --text: #e8f6fb; --muted: #8ea3b0; --accent: #22d3ee; --accent-ink: #03161b; --paper: #e8f6fb; --paper-ink: #0b1a22; color-scheme: dark; --edit: #b388ff; --danger: #e5604d; }
:root[data-palette=neon][data-scheme=light] { --bg: #eef5f8; --bg2: #e2edf1; --card: #ffffff; --line: #c9dbe2; --text: #0b1a22; --muted: #557080; --accent: #0e7f95; --accent-ink: #ffffff; --paper: #ffffff; --paper-ink: #0b1a22; color-scheme: light; --ok: #246b3c; --amber: #9a6200; --blue: #245f9c; --edit: #6a3fc9; --danger: #b3321c; }
:root[data-palette=vinyl] { --bg: #100e0d; --bg2: #181514; --card: #211d1b; --line: #36302c; --text: #f6ece4; --muted: #a89a90; --accent: #ff8a3d; --accent-ink: #2a1204; --paper: #f6ece4; --paper-ink: #241c17; color-scheme: dark; --edit: #b388ff; --danger: #e5604d; }
:root[data-palette=vinyl][data-scheme=light] { --bg: #f5eee8; --bg2: #ece2d9; --card: #fffaf6; --line: #dccdc0; --text: #241c17; --muted: #76675b; --accent: #c45a12; --accent-ink: #ffffff; --paper: #fffaf6; --paper-ink: #241c17; color-scheme: light; --ok: #246b3c; --amber: #9a6200; --blue: #245f9c; --edit: #6a3fc9; --danger: #b3321c; }
:root[data-palette=synth] { --bg: #140b24; --bg2: #1d1033; --card: #261642; --line: #3d2763; --text: #f5e9ff; --muted: #b29cc9; --accent: #ffb347; --accent-ink: #2a1300; --paper: #f5e9ff; --paper-ink: #22123a; color-scheme: dark; --edit: #b388ff; --danger: #e5604d; }
:root[data-palette=synth][data-scheme=light] { --bg: #f3ecfb; --bg2: #e8def5; --card: #fdfaff; --line: #d6c6ea; --text: #22123a; --muted: #6f5c88; --accent: #a8590a; --accent-ink: #ffffff; --paper: #fdfaff; --paper-ink: #22123a; color-scheme: light; --ok: #246b3c; --amber: #9a6200; --blue: #245f9c; --edit: #6a3fc9; --danger: #b3321c; }
:root[data-palette=tape] { --bg: #17130f; --bg2: #211b15; --card: #2b231c; --line: #45392d; --text: #f3e7d3; --muted: #ab9a85; --accent: #d9b26a; --accent-ink: #1f1607; --paper: #f3e7d3; --paper-ink: #2b2118; color-scheme: dark; --edit: #b388ff; --danger: #e5604d; }
:root[data-palette=tape][data-scheme=light] { --bg: #f4ecdc; --bg2: #ebe0c9; --card: #fffaf0; --line: #dacdb2; --text: #2b2118; --muted: #7a6a55; --accent: #8a5f17; --accent-ink: #ffffff; --paper: #fffaf0; --paper-ink: #2b2118; color-scheme: light; --ok: #246b3c; --amber: #9a6200; --blue: #245f9c; --edit: #6a3fc9; --danger: #b3321c; }

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; font-size: 100%; }
html[data-text=large] { font-size: 118%; } html[data-text=xlarge] { font-size: 138%; }
html[data-targets=large] { --hit: 54px; }
@media (pointer: coarse) { :root { --hit: 48px; } html[data-targets=large] { --hit: 58px; } }
body { margin: 0; -webkit-tap-highlight-color: transparent; background: var(--bg); color: var(--text); font: 16px/1.45 system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; overscroll-behavior-y: none; }
#app { max-width: 720px; margin: 0 auto; padding: 0 var(--pad) 48px; padding-bottom: calc(48px + env(safe-area-inset-bottom)); }
h1, h2, h3, h4 { margin: 0; line-height: 1.2; }
h1 { font-size: 1.5rem; } h2 { font-size: 1.2rem; } h3 { font-size: .8rem; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); margin: 22px 0 8px; }
h4 { font-size: .85rem; color: var(--accent); margin: 10px 0 4px; }
a { color: var(--accent); }
.muted { color: var(--muted); } .small { font-size: .85rem; } .prewrap { white-space: pre-wrap; }
.spacer, .grow { flex: 1; }
[hidden] { display: none !important; }

/* header */
.top { display: flex; justify-content: space-between; align-items: center; gap: 8px; padding: calc(6px + env(safe-area-inset-top)) 0 4px; }
.top .brand { flex: 1 1 auto; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.brand { font-weight: 800; letter-spacing: .14em; display: flex; align-items: center; gap: 8px; }
.brand small { font-weight: 500; letter-spacing: .04em; color: var(--muted); text-transform: lowercase; }
.brand .dot { width: 10px; height: 10px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 30%, transparent); }
.cloud { min-height: var(--hit); background: var(--card); border: 1px solid var(--line); color: var(--text); border-radius: 999px; padding: 0 10px; font: inherit; font-size: .85rem; cursor: pointer; display: flex; gap: 4px; align-items: center; }
.top .cloud-ico { font-size: 1.05rem; width: auto; min-width: 1.2rem; }
.cloud[data-state=synced] .cloud-ico { color: var(--ok); } .cloud[data-state=error] .cloud-ico, .cloud[data-state=needs-permission] .cloud-ico { color: var(--danger); } .cloud[data-state=saving] .cloud-ico { animation: pulse 1s infinite; }
@keyframes pulse { 50% { opacity: .3; } }

/* the section menu (js/deck.js): a record player, a tape deck or a digital player, sticky at the top; tucks away while the page scrolls down */
.deckbar { position: sticky; top: 0; z-index: 20; margin: 0 calc(-1 * var(--pad)); padding: 6px var(--pad) 10px; background: var(--bg); border-bottom: 1px solid var(--line); box-shadow: 0 8px 20px #0004; transition: transform .28s ease, box-shadow .28s ease; }
.deckbar.tucked { transform: translateY(-105%); box-shadow: none; pointer-events: none; }
.deck { max-width: 560px; margin: 0 auto; padding: 10px; border-radius: 18px; background: var(--bg2); border: 1px solid var(--line); display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 12px; }
.deck[data-style=tape] { flex-direction: column; align-items: stretch; gap: 10px; }
.dk-swipe { touch-action: pan-y pinch-zoom; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; cursor: pointer; }
.dk-still, .dk-still * { transition: none !important; }
.dk-record { position: relative; flex: none; width: 162px; height: 150px; margin-top: 8px; padding: 0; border: 0; background: transparent; } /* room above for the tonearm's weight */
.dk-record > span { position: absolute; display: block; }
.dk-platter { left: 0; top: 0; width: 146px; height: 146px; box-sizing: border-box; border-radius: 50%; background: var(--card); border: 2px solid var(--line); }
.dk-disc { left: 3px; top: 3px; width: 140px; height: 140px; border-radius: 50%; background: repeating-radial-gradient(circle at 50% 50%, #0c0a10 0 1.4px, #1c1923 1.4px 2.6px); transition: transform .8s cubic-bezier(.22, .9, .3, 1); }
.dk-disc svg { position: absolute; left: 0; top: 0; }
.dk-gap { fill: none; stroke: #3a3546; stroke-width: 1.4; }
.dk-band { fill: none; stroke: var(--accent); stroke-opacity: .6; stroke-width: 2.4; stroke-dasharray: 7 5; transition: r .6s ease; }
.dk-label-disc { fill: var(--accent); }
.dk-rim { font: 700 4.4px system-ui, sans-serif; letter-spacing: .8px; fill: var(--accent-ink); fill-opacity: .55; }
.dk-sheen { left: 3px; top: 3px; width: 140px; height: 140px; border-radius: 50%; pointer-events: none; background: conic-gradient(from 20deg, #fff0 0deg, #ffffff1c 28deg, #fff0 58deg, #fff0 180deg, #ffffff12 208deg, #fff0 238deg); }
.dk-record > .dk-label { left: 53px; top: 53px; width: 40px; height: 40px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; color: var(--accent-ink); pointer-events: none; }
.dk-label-id { font: 700 13px/1 ui-monospace, 'SF Mono', Menlo, Consolas, monospace; }
.dk-spindle { width: 5px; height: 5px; border-radius: 50%; background: #0c0a10; }
.dk-label-side { font-size: 6.5px; font-weight: 800; letter-spacing: .14em; line-height: 1; }
.dk-arm-base { left: 139px; top: -1px; width: 22px; height: 22px; box-sizing: border-box; border-radius: 50%; background: var(--card); border: 2px solid var(--line); }
.dk-arm { left: 150px; top: 10px; width: 0; height: 0; transition: transform .6s cubic-bezier(.3, .7, .3, 1); }
.dk-arm > span { position: absolute; display: block; }
.dk-weight { left: -26px; top: -7px; width: 14px; height: 14px; border-radius: 3px; background: var(--muted); }
.dk-bar { left: -12px; top: -2.5px; width: 96px; height: 5px; border-radius: 3px; background: var(--paper); box-shadow: 0 1px 2px #0006; }
.dk-head { left: 81px; top: -6px; width: 17px; height: 12px; box-sizing: border-box; border-radius: 3px; background: var(--paper); border: 1px solid var(--muted); }
.dk-tip { left: 94px; top: -1.5px; width: 3px; height: 3px; border-radius: 50%; background: var(--accent); }
.dk-arm-cap { left: 145px; top: 5px; width: 10px; height: 10px; border-radius: 50%; background: var(--muted); }
.dk-info { flex: 1 1 calc(3 * var(--hit) + 12px); min-width: calc(3 * var(--hit) + 12px); display: flex; flex-direction: column; gap: 5px; } /* drops under the record when the three buttons would not fit beside it */
.dk-eyebrow { font-size: .7rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--muted); }
.dk-name { font-size: 1.45rem; line-height: 1.05; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dk-meta { font: .78rem ui-monospace, 'SF Mono', Menlo, Consolas, monospace; color: var(--muted); }
.dk-transport { display: flex; align-items: center; gap: 6px; margin-top: 4px; }
.dk-btn { flex: 1; min-width: var(--hit); height: var(--hit); padding: 0 8px; border-radius: 10px; border: 1px solid var(--line); background: var(--card); color: var(--text); display: inline-flex; align-items: center; justify-content: center; gap: 6px; font: inherit; font-size: .9rem; font-weight: 600; cursor: pointer; }
.dk-btn:hover { border-color: var(--accent); }
.dk-cassette { position: relative; display: flex; flex-direction: column; gap: 8px; padding: 10px 12px 12px; border-radius: 12px; border: 1px solid var(--line); background: color-mix(in srgb, var(--card) 75%, var(--line)); color: inherit; font: inherit; text-align: left; }
.dk-screw { position: absolute; width: 5px; height: 5px; border-radius: 50%; background: var(--line); }
.dk-tl { left: 7px; top: 7px; } .dk-tr { right: 7px; top: 7px; } .dk-bl { left: 7px; bottom: 7px; } .dk-br { right: 7px; bottom: 7px; }
.dk-tape-label { display: flex; align-items: baseline; gap: 10px; padding: 5px 12px 6px; border-radius: 6px; background: var(--paper); color: var(--paper-ink); border-top: 5px solid var(--accent); }
.dk-tape-id, .dk-tape-side, .dk-counter { font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace; }
.dk-tape-id { font-size: .8rem; font-weight: 700; color: color-mix(in srgb, var(--accent) 35%, var(--paper-ink)); }
.dk-tape-name { flex: 1; min-width: 0; font: 700 clamp(1.15rem, 6.2vw, 1.6rem)/1.05 'Segoe Print', 'Bradley Hand', 'Marker Felt', 'Chalkboard SE', 'Comic Sans MS', cursive; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dk-tape-side { font-size: .7rem; letter-spacing: .12em; }
.dk-window { position: relative; display: block; align-self: center; width: 224px; height: 58px; border-radius: 29px; background: #0b0912; overflow: hidden; }
.dk-window > span { position: absolute; display: block; }
.dk-tape-run { left: 44px; right: 44px; bottom: 9px; height: 3px; background: #5b4034; }
.dk-pack { top: 29px; border-radius: 50%; background: #5b4034; transition: width .7s ease, height .7s ease, margin .7s ease; }
.dk-pack.dk-left { left: 44px; } .dk-pack.dk-right { left: 180px; }
.dk-reel { top: 10px; width: 38px; height: 38px; transition: transform .7s cubic-bezier(.2, .7, .2, 1); }
.dk-reel.dk-left { left: 25px; } .dk-reel.dk-right { left: 161px; }
.dk-reel-ring { fill: none; stroke: #e8e1f5; stroke-width: 2; } .dk-reel-hub { fill: #e8e1f5; } .dk-reel-hole { fill: #0b0912; } .dk-reel-teeth { stroke: #e8e1f5; stroke-width: 2.4; stroke-linecap: round; }
.dk-counter { flex: 1.4; min-width: 0; overflow: hidden; height: var(--hit); border-radius: 10px; background: #0b0912; color: color-mix(in srgb, var(--accent) 65%, #fff); display: flex; align-items: center; justify-content: center; gap: 10px; }
.dk-counter-n { font-size: 1.2rem; font-weight: 700; letter-spacing: .14em; } .dk-counter-of { font-size: .7rem; letter-spacing: .1em; opacity: .75; white-space: nowrap; }
.dk-tracks { flex: 1.6; }
.dk-sheet { display: grid; gap: 14px; }
.dk-sleeve-head { display: flex; align-items: center; gap: 12px; }
.dk-cover { flex: none; width: 52px; height: 52px; border-radius: 6px; background: var(--accent); color: var(--accent-ink); display: grid; place-content: center; justify-items: center; line-height: 1.1; font-weight: 800; letter-spacing: .1em; font-size: .75rem; } /* TOUR over BOOK, as wide as one word of four */
.dk-jcard { background: var(--paper); color: var(--paper-ink); border-radius: 12px; padding: 12px 14px; }
.dk-jcard-title { margin: 0; font: 700 1.6rem/1.1 'Segoe Print', 'Bradley Hand', 'Marker Felt', 'Chalkboard SE', 'Comic Sans MS', cursive; }
.dk-sides { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr)); gap: 14px; } /* one column when two would cut the names */
.dk-side { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.dk-bonus { margin-top: 14px; } .dk-bonus .dk-side-head { border-bottom-style: dashed; }
.dk-bonus-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr)); column-gap: 14px; row-gap: 2px; }
.dk-side-head { font-size: .7rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; padding-bottom: 4px; border-bottom: 2px solid var(--accent); }
.dk-track { display: flex; align-items: center; gap: 8px; width: 100%; min-height: var(--hit); padding: 0 8px; border: 0; border-bottom: 1px dotted var(--line); border-radius: 6px; background: transparent; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.dk-track.on { background: var(--accent); color: var(--accent-ink); }
.dk-track-id, .dk-track-n { flex: none; font: .72rem ui-monospace, 'SF Mono', Menlo, Consolas, monospace; } .dk-track-id { width: 22px; } .dk-track-n { opacity: .8; }
.dk-track-name { flex: 1; min-width: 0; font-weight: 600; overflow-wrap: anywhere; }
.dk-jcard .dk-track { border-bottom: 1px dashed color-mix(in srgb, var(--paper-ink) 25%, transparent); }
.dk-jcard .dk-track-name { font: 700 1.25rem/1.1 'Segoe Print', 'Bradley Hand', 'Marker Felt', 'Chalkboard SE', 'Comic Sans MS', cursive; }
/* the digital player: a slim bar (cover art, Now playing, the three keys, a line showing how far through the menu you are) and a row of tabs that scrolls sideways */
.deck[data-style=digital] { flex-direction: column; flex-wrap: nowrap; align-items: stretch; gap: 8px; padding: 8px; overflow: hidden; } /* the row of tabs runs out under the rounded edge */
.dk-player { --art: clamp(44px, calc(13.333vw - 4px), 52px); --gap: clamp(8px, calc(3.333vw - 4px), 10px); position: relative; display: flex; flex-wrap: wrap; align-items: center; gap: 8px var(--gap); padding-bottom: 8px; } /* the cover art is 52 px from 420 px wide, easing down to 44 px on a 360 px phone, and the gaps with it */
.dk-now { flex: 999 1 calc(var(--art) + var(--gap) + 6rem); min-width: 0; display: flex; align-items: center; gap: var(--gap); padding: 0; border: 0; border-radius: 10px; background: transparent; color: inherit; font: inherit; text-align: left; }
.dk-art { flex: none; width: var(--art); height: var(--art); border-radius: 10px; display: grid; place-items: center; font-size: 1.5rem; line-height: 1; background: radial-gradient(circle, color-mix(in srgb, var(--paper) 88%, transparent) 0 24%, transparent 70%), linear-gradient(135deg, var(--accent), color-mix(in srgb, var(--accent) 35%, var(--card))); } /* the accent as a gradient, with a soft light behind the icon: a dark icon (the clef, the people) reads on every theme's accent, Mono's near-black one too */
.dk-now-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.deck[data-style=digital] .dk-eyebrow { font-size: .64rem; letter-spacing: .12em; line-height: 1.3; }
.deck[data-style=digital] .dk-eyebrow, .deck[data-style=digital] .dk-meta { color: color-mix(in srgb, var(--muted) 70%, var(--text)); } /* the two small lines: a little stronger than --muted, which on the deck's --bg2 is under 4.5:1 in the light Stage theme */
.deck[data-style=digital] .dk-name { font-size: 1.1rem; line-height: 1.15; white-space: normal; overflow-wrap: anywhere; }
/* one line, always: the count ("2 acts") shows after the track when there is room for it and is left out whole when there is not, so no word is cut and the bar keeps its height */
.deck[data-style=digital] .dk-meta { display: flex; flex-wrap: wrap; column-gap: .35em; height: 1.4em; overflow: hidden; font: inherit; font-size: .78rem; line-height: 1.4; }
.dk-meta-at, .dk-meta-n { flex: none; white-space: nowrap; }
.dk-keys { flex: 1 0 auto; display: flex; gap: 6px; } /* beside the name, or on a line of their own (and then as wide as it) when they do not fit: a narrow phone with extra-large buttons */
.dk-keys .dk-btn { flex: 1 0 var(--hit); }
.dk-progress { position: absolute; left: 0; right: 0; bottom: 0; height: 3px; border-radius: 3px; background: var(--line); overflow: hidden; }
.dk-fill { display: block; height: 100%; border-radius: 3px; background: var(--accent); transition: width .25s ease; }
.dk-tabs { display: flex; gap: 6px; min-width: 0; margin: -5px -8px; padding: 5px 8px; overflow-x: auto; scroll-padding-inline: 28px; scrollbar-width: none; overscroll-behavior-inline: contain; } /* as wide as the deck, with room inside the scrolling row for a tab's focus ring */
.dk-tabs::-webkit-scrollbar { display: none; }
.dk-tab { flex: none; min-height: var(--hit); display: inline-flex; align-items: center; gap: 6px; padding: 0 13px; border: 1px solid var(--line); border-radius: 999px; background: var(--card); color: var(--text); font: inherit; font-size: .84rem; white-space: nowrap; cursor: pointer; }
@media (hover: hover) { .dk-tab:hover { border-color: var(--accent); } } /* not on a touch screen, where the edge would stay on the tab last tapped */
.dk-tab.on { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); font-weight: 700; }
.dk-tab-ico { display: inline-grid; place-items: center; width: 1.7em; height: 1.7em; margin: 0 -.3em; } .dk-tab.on .dk-tab-ico { background: radial-gradient(circle, color-mix(in srgb, var(--paper) 90%, transparent) 0 34%, transparent 72%); } /* the same soft light behind the current tab's icon, which sits on the accent too */
.dk-tab-name { display: inline-flex; flex-direction: column; } .dk-tab-name::after { content: attr(data-name); height: 0; overflow: hidden; visibility: hidden; font-weight: 700; } /* every tab keeps the width of its bold name, so the row does not shift when the current tab changes */
.dk-queue .dk-jcard-title { font-family: inherit; font-size: 1.25rem; }
@media (max-width: 370px) { .dk-record { zoom: .86; } }
@media (max-width: 380px) { .dk-art { font-size: 1.3rem; } .dk-keys { gap: 4px; } } /* a small phone: with the cover art eased down to 44 px (--art, above), the three keys still fit beside the name */
@media (max-width: 359px) { .dk-tracks-word, .dk-counter-of { display: none; } } /* the Tracks button keeps its name for screen readers; the counter keeps its number */
/* Mono: no colour at all, the tape and the digital player's icons included */
html[data-palette=mono] .dk-pack, html[data-palette=mono] .dk-tape-run { background: #555; }
html[data-palette=mono] .dk-art, html[data-palette=mono] .dk-tab-ico { filter: grayscale(1); }
button:focus-visible, a:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible, summary:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }

.page { outline: none; perspective: 1100px; }
.page-card { transform-origin: 50% 0; backface-visibility: hidden; }

/* common */
.page-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 10px; margin: 6px 0 12px; } /* the controls drop under the title when both do not fit */
.btn { max-width: 100%; overflow-wrap: anywhere; min-height: var(--hit); justify-content: center; font: inherit; font-weight: 600; border: 1px solid transparent; border-radius: 10px; padding: 9px 14px; cursor: pointer; text-decoration: none; display: inline-flex; align-items: center; gap: 6px; line-height: 1.2; color: inherit; }
.btn.primary { background: var(--accent); color: var(--accent-ink); }
.btn.ghost { background: transparent; border-color: var(--line); color: var(--text); }
.btn.ghost:hover { border-color: var(--accent); }
.btn.danger { background: transparent; border-color: var(--danger); color: var(--danger); }
.btn.small { padding: 6px 12px; font-size: .9rem; } .btn:disabled { opacity: .4; cursor: not-allowed; }
.icon-btn { background: transparent; border: 0; color: var(--muted); font-size: 1.15rem; cursor: pointer; width: var(--hit); height: var(--hit); border-radius: 10px; flex: none; } .icon-btn:hover { color: var(--accent); background: var(--bg2); }
.card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 14px; margin-bottom: 10px; display: block; width: 100%; text-align: left; color: inherit; font: inherit; }
.card.tap { cursor: pointer; } .card.tap:hover { border-color: var(--accent); }
.card.hero { border-left: 4px solid var(--accent); display: grid; gap: 4px; }
.card.center { text-align: center; }
.card-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.card-row > div:first-child { min-width: 0; overflow-wrap: break-word; } .card.stack { grid-template-columns: minmax(0, 1fr); } /* text wraps by word, buttons stay on screen */
.stack .card-row > .btn, .stack .card-row > button.btn { width: auto; flex: none; } /* a button beside text keeps its own size, never squeezing the text */
.list { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0; } .list > .card { margin-bottom: 10px; } /* a card never pushes the list wider than the page */
.actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; } .actions.center { justify-content: center; }
.empty { text-align: center; color: var(--muted); padding: 28px 12px; border: 1px dashed var(--line); border-radius: var(--radius); display: grid; gap: 12px; justify-items: center; }
.empty p { margin: 0; max-width: 34ch; }
.warn { background: color-mix(in srgb, var(--danger) 16%, transparent); border: 1px solid var(--danger); border-radius: 10px; padding: 8px 12px; margin: 8px 0; font-size: .9rem; }
.pill { font-size: .72rem; font-weight: 700; padding: 3px 9px; border-radius: 999px; white-space: nowrap; background: var(--bg2); color: var(--muted); border: 1px solid var(--line); }
.pill.st-confirmed { color: var(--ok); border-color: var(--ok); } .pill.st-enquiry { color: var(--accent); border-color: var(--accent); } .pill.st-shot { color: var(--blue); border-color: var(--blue); } .pill.st-cancelled { color: var(--danger); border-color: var(--danger); }
.stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-bottom: 10px; }
.stat { background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 8px 10px; display: grid; min-width: 0; } .stat b { font-size: 1.15rem; overflow-wrap: anywhere; } .stat span { font-size: .75rem; color: var(--muted); overflow-wrap: anywhere; } /* a wide font or big text wraps a figure rather than pushing the page sideways */
.search, input, select, textarea { min-height: var(--hit); font: inherit; color: var(--text); background: var(--bg2); border: 1px solid var(--line); border-radius: 10px; padding: 9px 11px; width: 100%; min-width: 0; }
.search { margin-bottom: 8px; }
.chips { display: flex; gap: 6px; overflow-x: auto; padding-bottom: 6px; margin-bottom: 4px; scrollbar-width: none; }
.chip { flex: none; min-height: var(--hit); background: var(--bg2); color: var(--text); border: 1px solid var(--line); border-radius: 999px; padding: 5px 12px; font: inherit; font-size: .85rem; cursor: pointer; } .chip.on { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.avatar { width: 40px; height: 40px; border-radius: 50%; background: var(--accent); color: var(--accent-ink); display: grid; place-items: center; font-weight: 800; flex: none; } .avatar.big { width: 58px; height: 58px; font-size: 1.3rem; }
 

.kv { display: grid; gap: 4px; margin: 8px 0 0; } .kv > div { display: flex; justify-content: space-between; gap: 12px; }
  

.block { margin-bottom: 6px; }

/* calendar */
.cal-nav { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; } .cal-title { flex: 1; font-weight: 700; text-align: center; }
.cal { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 3px; }
.wd { text-align: center; font-size: .7rem; color: var(--muted); padding: 4px 0; text-transform: uppercase; letter-spacing: .06em; }
.day { min-height: 62px; background: var(--card); border: 1px solid var(--line); border-radius: 8px; padding: 4px; display: flex; flex-direction: column; align-items: stretch; gap: 2px; font: inherit; color: var(--text); cursor: pointer; text-align: left; overflow: hidden; }
.day.blank { background: transparent; border-color: transparent; cursor: default; }
.day:not(.blank):hover { border-color: var(--accent); }
.day .num { font-size: .8rem; font-weight: 600; } .day.today .num { background: var(--accent); color: var(--accent-ink); border-radius: 999px; padding: 0 6px; align-self: flex-start; }
.day.has { background: color-mix(in srgb, var(--accent) 10%, var(--card)); }
.mini { display: none; font-size: .72rem; padding: 1px 4px; border-radius: 4px; background: var(--bg2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; border-left: 3px solid var(--muted); }
.mini.st-confirmed, .dots i.st-confirmed { border-color: var(--ok); background-color: color-mix(in srgb, var(--ok) 20%, transparent); } .mini.st-enquiry { border-color: var(--accent); } .mini.st-shot { border-color: var(--blue); } .mini.st-cancelled { border-color: var(--danger); text-decoration: line-through; }
.more { font-size: .65rem; color: var(--muted); }
.dots { display: flex; gap: 3px; margin-top: auto; } .dots i { width: 7px; height: 7px; border-radius: 50%; background: var(--muted); } .dots i.st-confirmed { background: var(--ok); } .dots i.st-enquiry { background: var(--accent); } .dots i.st-shot { background: var(--blue); } .dots i.st-cancelled { background: var(--danger); }
@media (min-width: 560px) { .mini { display: block; } .dots { display: none; } .day { min-height: 84px; } }

/* forms / sheets */
.sheet-back { position: fixed; inset: 0; background: #000a; z-index: 100; display: flex; align-items: flex-end; justify-content: center; animation: fade .2s; }
@keyframes fade { from { opacity: 0; } }
.sheet { background: var(--bg); border: 1px solid var(--line); border-radius: 18px 18px 0 0; width: min(640px, 100%); max-height: 92vh; display: flex; flex-direction: column; animation: rise .22s cubic-bezier(.2, .9, .3, 1); }
@keyframes rise { from { transform: translateY(24px); opacity: 0; } }
@media (min-width: 700px) { .sheet-back { align-items: center; } .sheet { border-radius: 18px; } }
.sheet-head { display: flex; justify-content: space-between; align-items: center; padding: 14px 16px 6px; } .sheet-body { overflow: auto; padding: 8px 16px 20px; padding-bottom: calc(20px + env(safe-area-inset-bottom)); }
.form { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; } .field { display: grid; gap: 4px; align-content: start; } .field.wide, .form-actions { grid-column: 1 / -1; } .field > label { font-size: .8rem; color: var(--muted); font-weight: 600; }
@media (max-width: 480px) { .form { grid-template-columns: 1fr; } }
.field textarea { resize: vertical; }
.rows { display: grid; gap: 6px; margin-bottom: 6px; } .row-edit { display: flex; gap: 6px; align-items: center; margin-top: 6px; }
.checks { display: grid; gap: 6px; max-height: 240px; overflow: auto; padding: 4px; border: 1px solid var(--line); border-radius: 10px; }
fieldset { border: 0; margin: 0; padding: 0; } legend { font-size: .75rem; color: var(--accent); font-weight: 700; padding: 4px 0; }
.check { display: flex; gap: 12px; align-items: center; padding: 6px 4px; min-height: var(--hit); cursor: pointer; } .check input { width: 26px; height: 26px; accent-color: var(--accent); flex: none; } .check em { color: var(--muted); font-style: normal; font-size: .85rem; }
.form-actions { display: flex; gap: 8px; position: sticky; bottom: -20px; background: var(--bg); padding: 10px 0; }
.toast { pointer-events: none; position: fixed; left: 50%; bottom: calc(24px + env(safe-area-inset-bottom)); transform: translateX(-50%); background: var(--text); color: var(--bg); padding: 10px 16px; border-radius: 999px; z-index: 320; font-size: .9rem; animation: rise .25s; max-width: 90vw; } .toast.out { opacity: 0; transition: opacity .4s; }
.stack { display: grid; gap: 8px; } .storage hr { border: 0; border-top: 1px solid var(--line); margin: 14px 0; }
 
 .note { color: var(--muted); font-size: .9rem; }

/* me */

 
.seg { display: inline-grid; grid-auto-flow: column; background: var(--bg2); border: 1px solid var(--line); border-radius: 10px; padding: 3px; gap: 3px; margin-bottom: 12px; }
.seg button { min-height: calc(var(--hit) - 6px); border: 0; background: transparent; color: var(--text); font: inherit; font-size: .9rem; padding: 7px 14px; border-radius: 8px; cursor: pointer; } .seg button.on { background: var(--accent); color: var(--accent-ink); font-weight: 700; }
.seg.tools { display: grid; grid-auto-flow: unset; grid-template-columns: repeat(4, 1fr); } .seg.tools button { padding: 8px 4px; font-size: .8rem; }
.qr { width: min(260px, 100%); margin: 0 auto; background: #fff; border-radius: 14px; padding: 10px; color: #333; min-height: 120px; display: grid; place-items: center; font-size: .9rem; } .qr svg { width: 100%; height: auto; display: block; }
.qr-cap { margin: 8px 0 12px; font-size: .85rem; word-break: break-all; }

/* field tools */
 
      
input[type=range] { min-height: var(--hit); padding: 0; accent-color: var(--accent); background: none; border: 0; }
 .readouts { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; } .readout { display: grid; background: var(--bg2); border-radius: 10px; padding: 6px 8px; text-align: left; } .readout span { font-size: .72rem; } .readouts.big .readout b { font-size: 1.3rem; }
.times { display: grid; gap: 2px; }   
.decl { display: flex; gap: 6px; align-items: center; } .decl input { width: 80px; }
  
.cam-wrap { position: relative; border-radius: 12px; overflow: hidden; background: #000; aspect-ratio: 4/3; } .cam { width: 100%; height: 100%; object-fit: cover; display: block; }

 

.db { font-size: 3.4rem; font-weight: 800; font-variant-numeric: tabular-nums; } 
.meter { height: 12px; border-radius: 6px; background: linear-gradient(90deg, var(--ok), var(--accent) 60%, var(--danger)); position: relative; overflow: hidden; }
.meter i { position: absolute; right: 0; top: 0; bottom: 0; display: block; width: 100%; background: var(--bg2); transition: width .1s; }

.provider { display: grid; gap: 8px; padding: 12px; border: 1px solid var(--line); border-radius: 12px; background: var(--card); }
.help summary { cursor: pointer; color: var(--accent); font-size: .85rem; } .help div { margin-top: 6px; word-break: break-word; }

/* accessibility */
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.skip { position: absolute; left: 8px; top: -60px; z-index: 300; background: var(--accent); color: var(--accent-ink); padding: 10px 14px; border-radius: 10px; font-weight: 700; } .skip:focus { top: 8px; }
.top-actions { display: flex; gap: 6px; flex-wrap: nowrap; justify-content: flex-end; flex: 0 0 auto; } /* one row, always: the brand gives way instead */
@media (max-width: 560px) { .top .cloud { width: var(--hit); padding: 0; justify-content: center; } .top .cloud-label { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; } } /* icons only; the labels stay for screen readers */
@media (max-width: 400px) { .top .brand { letter-spacing: .08em; font-size: min(.9rem, 14.4px); } }
/* The top bar on a phone (four buttons while Install shows; the search is a box under it, js/search.js): the small words "booking deck" go under 680px (where they would squeeze the buttons with large buttons, Install showing and the labels Install and Backup from 560px), TOURBOOK shows whole and no longer gives way, and the buttons share the rest of the row, 4px apart. Each keeps its height and narrows only where four do not fit (a 320px phone with extra-large text and large buttons); under 400px TOURBOOK is never larger than with normal text (as from 400px, where it is 16px whatever the text size), and at 340px and under the dot before it goes too, for room. */
@media (max-width: 679px) { .brand small { display: none; } }
@media (max-width: 560px) { .top .brand { flex: 0 0 auto; overflow: visible; } .top-actions { flex: 0 1 auto; min-width: 0; } .top .cloud { flex: 0 1 var(--hit); min-width: 0; } }
@media (max-width: 470px) { .top-actions { gap: 4px; } }
@media (max-width: 340px) { .top .brand .dot { display: none; } }
button, .btn, a.btn, .chip, .check, .day, summary { touch-action: manipulation; }
.btn, .chip, .icon-btn, .day, .card.tap, .seg button { transition: transform .12s ease, background-color .15s ease, border-color .15s ease, box-shadow .15s ease, opacity .15s ease, filter .15s ease; }
.btn:active, .chip:active, .icon-btn:active, .day:active, .card.tap:active, .seg button:active { transform: scale(.96); }
@media (hover: hover) { .card.tap:hover { transform: translateY(-1px); box-shadow: 0 4px 14px #0002; } .btn.primary:hover { filter: brightness(1.06); } .day:not(.blank):hover { transform: scale(1.03); } .icon-btn:hover { transform: scale(1.08); } }
.card.tap { min-height: var(--hit); }
.req { color: var(--danger); }
.actions .btn, .card-row .btn { flex: none; }
.actions { gap: 10px; }
.card .actions .btn { flex: 1 1 auto; justify-content: center; }
@media (min-width: 560px) { .card .actions .btn { flex: 0 0 auto; } }
.seg.wide { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); width: 100%; margin: 0; } .seg.wide button { min-width: 0; overflow-wrap: anywhere; padding-inline: 8px; }
/* The display choices on a narrow phone with large text: equal thirds would break "Standard" or "Record" inside the word. There each choice is as wide as its words, and a row that cannot hold all of them puts the last on a line of its own. */
@media (max-width: 380px) {
  html[data-text=large] .pref:not(.ac-ask-pref) > .seg.wide, html[data-text=xlarge] .pref:not(.ac-ask-pref) > .seg.wide { display: flex; flex-wrap: wrap; }
  html[data-text=large] .pref:not(.ac-ask-pref) > .seg.wide button, html[data-text=xlarge] .pref:not(.ac-ask-pref) > .seg.wide button { flex: 1 1 auto; overflow-wrap: normal; }
} .pref-label { font-weight: 700; margin-bottom: 6px; } .pref { margin-bottom: 4px; }
.stack .btn { width: 100%; }
.help summary { min-height: var(--hit); display: flex; align-items: center; }
.form-actions .btn { min-width: 96px; }
/* On the narrowest phones Delete, Cancel and Save at that width are wider than the form (312px in 302), and every Edit form would scroll sideways: there they share the row. */
@media (max-width: 340px) { .form-actions .btn { min-width: 0; flex: 1 1 auto; padding-inline: 10px; } }
.page-head .btn { min-width: 88px; }
:root[data-contrast=high], :root[data-contrast=high][data-palette][data-scheme] { --muted: color-mix(in srgb, var(--text) 82%, var(--bg)); --line: color-mix(in srgb, var(--text) 55%, var(--bg)); --focus: #ffd400; }
/* The focus ring in the light scheme: the light blue and the yellow above are for dark pages (under 2.3:1 and 1.2:1 on a light
   theme's page, panels and cards). A dark blue reads at 4.7:1 or better on every light theme, and with high contrast a navy at 10:1. */
:root[data-scheme=light] { --focus: #0b57d0; }
:root[data-contrast=high][data-palette][data-scheme=light] { --focus: #00256b; }
html[data-contrast=high] .btn.ghost, html[data-contrast=high] .chip, html[data-contrast=high] .card, html[data-contrast=high] input, html[data-contrast=high] select, html[data-contrast=high] textarea, html[data-contrast=high] .deck, html[data-contrast=high] .dk-btn, html[data-contrast=high] .dk-cassette, html[data-contrast=high] .dk-tab { border-width: 2px; }
html[data-contrast=high] .pill { border-width: 2px; color: var(--text); }
@media (forced-colors: none) { html[data-contrast=high] .dk-progress { background: color-mix(in srgb, var(--text) 25%, var(--bg2)); } html[data-contrast=high] .dk-fill { background: var(--text); } } /* the digital player's line: on the stronger --line the accent is almost the same grey (under 2:1 in most themes), so with high contrast it is drawn in the text colour on a quiet track */
/* Motion. Default ("soft"): the section menu moves (the record or the tape turns, the digital player's line slides), page
   content fades in, and small touches below run. "bar": only the section menu. "off": nothing. The device's reduce-motion
   setting wins over all of them. */
.fade-in { animation: softIn .35s ease-out both; }
@keyframes softIn { from { opacity: 0; } to { opacity: 1; } }
html[data-motion=bar] *:not(.dk-disc):not(.dk-arm):not(.dk-band):not(.dk-reel):not(.dk-pack):not(.dk-fill):not(.deckbar), html[data-motion=bar] *::before, html[data-motion=bar] *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
html[data-motion=off] *, html[data-motion=off] *::before, html[data-motion=off] *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; } }
@media (forced-colors: active) { .btn, .chip, .card, .dk-btn, .dk-track, .dk-tab { border: 1px solid CanvasText; } .dk-track.on, .dk-tab.on { outline: 2px solid Highlight; } .dk-track.on:focus-visible, .dk-tab.on:focus-visible { outline-width: 4px; outline-offset: 2px; } .dk-art { border: 1px solid CanvasText; } .dk-fill { forced-color-adjust: none; } .dk-platter, .dk-disc, .dk-sheen, .dk-arm, .dk-arm-cap, .dk-arm-base, .dk-record > .dk-label, .dk-window { forced-color-adjust: none; } } /* the record and the tape window are pictures with their own colours */
.cloud, .chip { min-width: var(--hit); justify-content: center; }
.seg button { min-height: var(--hit); }
.kv a { min-height: var(--hit); display: inline-flex; align-items: center; }
.card.kv > div { align-items: center; }

.check-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.check-row .check { flex: 1; min-width: 0; }
.stepper { display: flex; align-items: center; flex: none; }
.stepper input { width: 3.2rem; text-align: center; padding-left: 4px; padding-right: 4px; -moz-appearance: textfield; appearance: textfield; }
.stepper input::-webkit-outer-spin-button, .stepper input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.stepper .icon-btn { border: 1px solid var(--line); color: var(--text); font-size: 1.3rem; }
.qty { color: var(--accent); }

/* venues & maps */
 

  
.stale { color: var(--danger); }
.matrix { display: grid; gap: 8px; } .matrix-row { display: grid; grid-template-columns: 1fr minmax(9rem, 11rem); gap: 10px; align-items: center; } .matrix-row label { color: var(--text); font-size: .95rem; }
.place { display: grid; gap: 8px; }
.minimap { display: block; position: relative; height: 190px; border-radius: var(--radius); overflow: hidden; background: var(--bg2); border: 1px solid var(--line); margin-bottom: 4px; }
.map-inner { position: absolute; left: 50%; top: 50%; width: 0; height: 0; } .map-inner img { position: absolute; width: 256px; height: 256px; max-width: none; user-select: none; -webkit-user-drag: none; }
.pin { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -100%); font-size: 2rem; filter: drop-shadow(0 2px 2px #0006); }
.attrib { position: absolute; right: 0; bottom: 0; font-size: .65rem; background: #ffffffcc; color: #333; padding: 1px 5px; }
.v { margin-left: 8px; text-align: right; }

/* install */
.install-steps { padding-left: 1.3rem; display: grid; gap: 10px; margin: 0; }

/* desktop / tablet layout: same app, more room */
@media (min-width: 760px) {
  .list { grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 0 12px; }
  .stats { max-width: 560px; }
}
@media (min-width: 1000px) {
  #app { max-width: 1120px; }
  .page-card { max-width: 1120px; margin: 0 auto; }
  .page-head h1 { font-size: 1.7rem; }
  /* bookings month: calendar left, what's next right */
  
  
   
  
  /* booking detail: two columns of sections under the header */
  
  
  
  /* timecode notes: script beside notes */
  
  
  
  
  
  /* field tools and forms get a sensible width instead of stretching */
  
  .cam-wrap { max-height: 56vh; }
  .sheet { width: min(760px, 100%); }
}

/* small touches */
.pop-in { animation: popIn .25s cubic-bezier(.2, .8, .3, 1.25) both; }
@keyframes popIn { from { opacity: 0; scale: .94; } to { opacity: 1; scale: 1; } } /* `scale`, not `transform`, so centred elements keep their translate */
.pill.rec { animation: recBlink 1.3s ease-in-out infinite; }
@keyframes recBlink { 50% { opacity: .45; } }
.check input { transition: transform .12s ease; } .check input:active { transform: scale(.9); }
.stat b { display: inline-block; animation: popIn .3s ease-out both; }
.toast { animation: rise .25s cubic-bezier(.2, .9, .3, 1); }

/* tour */
.tour { position: fixed; inset: 0; z-index: 150; }
.tour-spot { position: fixed; border-radius: 14px; box-shadow: 0 0 0 9999px #000a; transition: top .4s cubic-bezier(.2, .8, .2, 1), left .4s cubic-bezier(.2, .8, .2, 1), width .4s cubic-bezier(.2, .8, .2, 1), height .4s cubic-bezier(.2, .8, .2, 1); pointer-events: none; }
.tour-spot.center { top: 50%; left: 50%; width: 0; height: 0; border-radius: 50%; }
.tour-spot.tour-pulse::after { content: ''; position: absolute; inset: -4px; border-radius: inherit; border: 2px solid var(--accent); animation: tourPulse 1.4s ease-out 2; }
@keyframes tourPulse { 0% { opacity: .9; transform: scale(1); } 100% { opacity: 0; transform: scale(1.12); } }
.tour-card { position: fixed; left: 50%; transform: translateX(-50%); width: min(420px, calc(100% - 32px)); background: var(--card); color: var(--text); border: 1px solid var(--line); border-radius: 16px; padding: 14px 16px; box-shadow: 0 12px 40px #0006; animation: popIn .25s ease-out both; }
.tour-card.center { top: 50%; transform: translate(-50%, -50%); }
.tour-card h2 { font-size: 1.15rem; margin: 2px 0 6px; } .tour-card p { margin: 0 0 12px; line-height: 1.45; }
.tour-actions { display: flex; gap: 8px; align-items: center; }

/* settings: sections, and the two groups (General, Work & billing) that hold sections of their own */

 /* a mark only for the eye: the open state is already spoken */

 

 

/* twirl-downs (settings lists) */
.twirl { border: 1px solid var(--line); border-radius: 12px; background: var(--bg2); margin-bottom: 8px; }
.twirl > summary { list-style: none; cursor: pointer; display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; gap: 10px; align-items: center; padding: 10px 12px; min-height: var(--hit); }
.twirl > summary > span:nth-child(3) { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.twirl > summary::-webkit-details-marker { display: none; }
.twirl > summary::after { content: '›'; color: var(--muted); font-size: 1.2rem; transition: transform .15s ease; }
.twirl[open] > summary::after { transform: rotate(90deg); }
.twirl > summary:focus-visible { outline: 3px solid var(--focus); border-radius: 12px; }
.twirl-ico { font-size: 1.3rem; width: 1.8rem; text-align: center; }
.twirl-name { font-weight: 700; } .twirl-sub { display: block; font-weight: 400; font-size: .8rem; color: var(--muted); }
.twirl-body { padding: 0 12px 12px; display: grid; gap: 8px; }
.twirl .tag { display: inline-block; font-size: .7rem; padding: 1px 7px; border-radius: 999px; border: 1px solid var(--line); color: var(--muted); white-space: nowrap; }
.twirl .tag.ok { color: var(--ok); border-color: var(--ok); } .twirl .tag.no { color: var(--danger); border-color: var(--danger); }
.swatches { display: inline-flex; gap: 3px; } .swatches i { width: 14px; height: 14px; border-radius: 50%; border: 1px solid #0003; display: inline-block; }
.theme-row { display: grid; grid-template-columns: auto 1fr auto; gap: 12px; align-items: center; width: 100%; padding: 8px 10px; border: 1px solid var(--line); border-radius: 10px; background: var(--card); color: var(--text); font: inherit; cursor: pointer; min-height: var(--hit); text-align: left; }
.theme-row[aria-checked=true] { border-color: var(--accent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 35%, transparent); }
.theme-row .check { font-weight: 800; color: var(--accent); }
/* roles: the first-run question and Settings → Your role (js/role-pick.js) */
.rp-intro { margin: 0; }
.rp-list { display: grid; gap: 8px; }
.rp-card { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 12px; align-items: center; margin: 0; }
.rp-card[aria-checked=true], .rp-card.on { border-color: var(--accent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 35%, transparent); }
.rp-icon { font-size: 1.7rem; width: 2.2rem; text-align: center; }
.rp-text { display: grid; gap: 2px; min-width: 0; }
.rp-name { font-size: 1.05rem; }
.rp-sub { font-size: .85rem; font-weight: 600; font-style: italic; color: var(--muted); margin-top: -2px; } /* Jack of Trades' Master of None */
.rp-blurb, .rp-menu { overflow-wrap: anywhere; }
.rp-check { font-weight: 800; color: var(--accent); min-width: 1ch; }
.rp-nudge { margin: 8px 0 4px; display: grid; gap: 8px; border-left: 4px solid var(--accent); } .rp-nudge-text { margin: 0; overflow-wrap: anywhere; }
.theme-list { display: grid; gap: 6px; }

/* the clock: a slim strip under the Rolodex while it runs, and the card in a booking's Hours box */
.clockbar { margin: 6px 0 12px; }
.clock { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 10px 12px; display: grid; gap: 8px; }
.clock.strip { padding: 8px 12px; gap: 6px; } .clock.strip .clock-title { font-size: .95rem; }
.clock.card-clock { background: transparent; border: 0; padding: 0; margin-bottom: 4px; }
.clock.working { border-color: var(--ok); } .clock.on-break { border-color: var(--accent); }

.clock-title { font-weight: 700; display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.clock .dot { width: 10px; height: 10px; border-radius: 50%; background: var(--muted); flex: none; }
.clock.working .dot { background: var(--ok); animation: recBlink 1.3s ease-in-out infinite; } .clock.on-break .dot { background: var(--accent); }

.clock-btns { display: flex; gap: 8px; align-items: center; } .clock-btns .btn { flex: 1 1 auto; justify-content: center; }
.clock-btns .btn.over { border-color: var(--danger); color: var(--danger); }

.clock select { width: auto; max-width: 60%; }

/* hours */
.hours .stats { grid-template-columns: repeat(3, 1fr); }
.hours .stat small { font-size: .7rem; }

 

  

 

.subactions { display: flex; gap: 8px; flex-wrap: wrap; margin: -4px 0 10px; }

/* workflow */
.pill.st-quoted { color: var(--accent); border-color: var(--accent); } .pill.st-prepped { color: var(--ok); border-color: var(--ok); } .pill.st-in-post { color: var(--blue); border-color: var(--blue); } .pill.st-archived { color: var(--muted); }
.mini.st-quoted { border-color: var(--accent); } .mini.st-prepped { border-color: var(--ok); } .mini.st-in-post { border-color: var(--blue); } .dots i.st-quoted { background: var(--accent); } .dots i.st-prepped { background: var(--ok); } .dots i.st-in-post { background: var(--blue); }

.stage { flex: none; display: inline-flex; align-items: center; gap: 6px; padding: 6px 10px; border-radius: 999px; border: 1px solid var(--line); background: var(--bg2); color: var(--muted); font: inherit; font-size: .85rem; cursor: pointer; min-height: 36px; }
.stage.past { color: var(--text); } .stage.now { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); font-weight: 700; }

.progress { height: 6px; background: var(--bg2); border-radius: 3px; overflow: hidden; margin: 8px 0 10px; } .progress i { display: block; height: 100%; background: var(--accent); border-radius: 3px; }
.checklist { display: grid; gap: 2px; }
.check-item { display: flex; align-items: center; gap: 6px; } .check-item .check { flex: 1; min-width: 0; } .check-item.done .check span { color: var(--muted); text-decoration: line-through; }

.sub { margin-top: 12px; display: grid; gap: 6px; } .sub h4 { margin: 4px 0 2px; }
  

 
 

.overdue { color: var(--danger); font-weight: 700; }
 

.hours .tag { font-size: .7rem; border: 1px solid var(--line); border-radius: 999px; padding: 0 6px; color: var(--muted); font-weight: 500; }

/* ------------------------------ call sheet ------------------------------ */
.cs-paper { background: var(--paper); color: var(--paper-ink); border-radius: 10px; padding: 14px; font-size: .84rem; line-height: 1.4; overflow: auto; max-height: 60vh; border: 1px solid var(--line); }
.cs-paper .cs-head { display: flex; justify-content: space-between; gap: 12px; border-bottom: 2px solid currentColor; padding-bottom: 6px; }
.cs-paper .cs-brand { font-weight: 700; } .cs-paper .cs-kicker { font-size: .68rem; letter-spacing: .2em; opacity: .7; }
.cs-paper .cs-when { text-align: right; font-size: .78rem; opacity: .8; } .cs-paper .cs-when b { display: block; font-size: .9rem; opacity: 1; }
.cs-paper h2 { margin: 10px 0 2px; font-size: 1.2rem; } .cs-paper .cs-sub { opacity: .8; margin-bottom: 6px; }
.cs-paper .cs-times { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: 6px; margin: 8px 0; }
.cs-paper .cs-time { border: 1px solid #0003; border-radius: 8px; padding: 6px 8px; } .cs-paper .cs-time span { display: block; font-size: .66rem; text-transform: uppercase; letter-spacing: .08em; opacity: .7; } .cs-paper .cs-time b { font-size: 1.05rem; }
.cs-paper .cs-sec { margin-top: 12px; } .cs-paper .cs-sec h4 { margin: 0 0 4px; font-size: .68rem; letter-spacing: .14em; text-transform: uppercase; opacity: .7; border-bottom: 1px solid #0002; padding-bottom: 2px; }
.cs-paper .cs-kv { display: grid; grid-template-columns: 110px 1fr; gap: 8px; padding: 2px 0; } .cs-paper .cs-kv span { opacity: .7; } .cs-paper .cs-kv a { color: inherit; word-break: break-all; }
.cs-paper table { width: 100%; border-collapse: collapse; margin: 2px 0 6px; } .cs-paper th, .cs-paper td { text-align: left; vertical-align: top; padding: 4px 5px; border-bottom: 1px solid #0002; font-size: .8rem; } .cs-paper th { font-size: .66rem; text-transform: uppercase; letter-spacing: .06em; opacity: .7; }
.cs-paper .cs-day { font-weight: 700; margin: 6px 0 2px; } .cs-paper .cs-pre { white-space: pre-wrap; margin: 3px 0; } .cs-paper .cs-foot { margin-top: 14px; padding-top: 6px; border-top: 1px solid #0002; font-size: .72rem; opacity: .75; }

.cs-paper.editing { border: 2px dashed var(--accent); }

@media print { #print-root { display: block; } }

/* ------------------------------ update bar ------------------------------ */
.update-bar { position: fixed; left: 50%; transform: translateX(-50%); bottom: max(16px, env(safe-area-inset-bottom, 0px)); z-index: 250; display: flex; gap: 10px; align-items: center; background: var(--card); color: var(--text); border: 1px solid var(--accent); border-radius: 999px; padding: 8px 8px 8px 16px; box-shadow: 0 8px 30px #0005; max-width: calc(100% - 32px); font-size: .9rem; }
.update-bar .btn { white-space: nowrap; }
body.has-update-bar #page { padding-bottom: 110px; }
@media (max-width: 480px) { .update-bar { flex-wrap: wrap; justify-content: center; border-radius: 16px; } }
/* The desktop app's licence (js/licence.js): its bar sits above the update bar when both show. */

 /* never over a sheet's buttons, or the script's Mark */

body.has-licence-bar .toast { z-index: 320; pointer-events: none; } /* messages show above the bar, and never block its buttons */

body.has-licence-bar #page { padding-bottom: 110px; }
body.has-licence-bar.has-update-bar #page { padding-bottom: 180px; }

.theme-group { font-size: .72rem; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); margin: 10px 0 4px; display: flex; flex-direction: column; gap: 2px; } .theme-group .twirl-sub { text-transform: none; letter-spacing: 0; }

.cs-paper .money-parties { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin: 10px 0; }
.cs-paper .money-parties h4 { margin: 0 0 4px; font-size: .66rem; letter-spacing: .14em; text-transform: uppercase; opacity: .7; }
.cs-paper .money-totals { margin: 8px 0 0 auto; max-width: 320px; } .cs-paper .money-totals .cs-kv { grid-template-columns: 1fr auto; text-align: right; } .cs-paper .money-totals .total b { font-size: 1rem; }
.cs-paper th.num, .cs-paper td.num { text-align: right; white-space: nowrap; }

/* The money overview on a phone: the four totals two by two, and a booking's quote and invoice under its name when they do not fit beside it. */

  
.stat.bad b { color: var(--danger); }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 12px; } @media (max-width: 480px) { .grid2 { grid-template-columns: 1fr; } }

#helpBtn .cloud-ico { font-weight: 800; }
.tour-actions .spacer { flex: 1; }

.sheet-tools { display: flex; gap: 4px; align-items: center; }
.sheet-help { font-weight: 800; }
.sheet:focus { outline: none; } /* the sheet itself takes the focus when it opens (util.js sheet()): its heading says where you are */

/* Getting paid: Pay buttons, bank QR and payments on the Money page and inside the document */
.cs-paper .pay-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0; }
.cs-paper .pay-btn { display: inline-block; padding: 9px 14px; border: 1.5px solid #1a4e8a; border-radius: 10px; color: #1a4e8a; font-weight: 700; text-decoration: none; font-size: 13px; }
.cs-paper .pay-qr { display: flex; gap: 14px; align-items: center; margin: 8px 0; }
.cs-paper .pay-qr svg { width: 112px; height: 112px; flex: none; background: #fff; border: 1px solid #ddd; border-radius: 6px; padding: 3px; }
.cs-paper .pay-ref { margin: 6px 0 0; font-size: 12px; color: #444; }
.cs-paper .paid-stamp { display: inline-block; margin: 8px 0; padding: 6px 12px; border: 2px solid #2a8a4a; border-radius: 8px; color: #2a8a4a; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }

.share-link { width: 100%; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; word-break: break-all; }
.share-qr svg { width: 180px; height: 180px; background: #fff; padding: 6px; border-radius: 10px; display: block; margin: 0 auto; }

/* Where an item is */

/* Budget on a booking */

#bk-budget .card.stack { grid-template-columns: minmax(0, 1fr); }
#bk-budget .stats { grid-template-columns: repeat(3, minmax(0, 1fr)); }
#bk-budget .stat b { font-size: clamp(.9rem, 3.8vw, 1.15rem); overflow-wrap: anywhere; }
 /* name and chevron: the chevron turns in place */

/* Price list: the editor's lines and the picker's tick rows (the price under the name, never squeezed) */
.price-item { display: grid; gap: 2px; text-align: left; min-width: 0; overflow-wrap: break-word; } .price-item strong { font-size: 1rem; }
.price-group { gap: 0; } .price-group h4 { margin: 10px 0 2px; }
.price-pick { align-items: flex-start; } .price-pick input { margin-top: 2px; }
.price-pick-text { flex: 1; display: grid; gap: 1px; min-width: 0; overflow-wrap: break-word; } .price-pick-text > span { font-size: 1rem; }
/* A box or button of a form reached with Tab is scrolled clear of the Save bar, which stays at the foot of the sheet and would cover it: the bar is one button and its padding tall, and the focus ring needs its own room. */
.sheet-body:has(.form-actions) { scroll-padding-bottom: calc(var(--hit) + 30px); }
.sheet-body:has(.price-picker) { scroll-padding-bottom: 84px; } /* a ticked row reached with Tab is never under the Add bar */
/* Rows in a form (quote lines, contacts, deliverables): the first text box on a line of its own, the rest below it */
.field .rows .row-edit { flex-wrap: wrap; } .field .rows .row-edit > input { flex: 1 1 0; min-width: 0; } .field .rows .row-edit > input[type=text]:first-child { flex: 1 1 100%; }
/* Booking page: darker outlined boxes for the tools, the hours and the day's weather; the folded workflow box; edit
   days in their own colour; people and equipment lists that fold after five; the shot list grouped by scene. */
.box-dark { background: var(--bg2); border: 2px solid color-mix(in srgb, var(--line) 55%, var(--muted)); border-radius: 12px; }

 
#bk-hours { margin-top: 0; } 

 
 

.pill.edit { color: var(--edit); border-color: var(--edit); } 
.mini.edit { border-color: var(--edit); } .dots i.edit { background: var(--edit); }

  /* the stage strip scrolls inside, never widens the box */
 

 

/* The button that goes back up a level: a ringed return mark, a shine as it appears, a pulse under the pointer */
.back-btn { position: relative; overflow: hidden; border-color: var(--accent); color: var(--accent); font-weight: 700; gap: 8px; padding-left: 8px; }
.back-arrow { display: inline-grid; place-items: center; width: 1.55em; height: 1.55em; border-radius: 50%; border: 2px solid currentColor; font-weight: 900; font-size: 1.05em; line-height: 1; padding-right: .1em; }
.back-btn::after { content: ''; position: absolute; inset: -2px; background: linear-gradient(110deg, transparent 35%, color-mix(in srgb, var(--accent) 38%, transparent) 50%, transparent 65%); transform: translateX(-130%); pointer-events: none; }
.back-btn.shine::after { animation: back-shine 1.1s .3s ease-out 1 both; }
@keyframes back-shine { to { transform: translateX(130%); } }
.back-btn:hover, .back-btn:focus-visible { animation: back-pulse 1.3s ease-in-out infinite; background: color-mix(in srgb, var(--accent) 10%, transparent); }
@keyframes back-pulse { 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 45%, transparent); } 60% { box-shadow: 0 0 0 7px transparent; } }
.back-btn:active { transform: scale(.96); }
html[data-motion=off] .back-btn::after, html[data-motion=bar] .back-btn::after { animation: none; transform: none; opacity: 0; }

/* Bookings month: the tools as a grid of even tiles, and the calendar in a frame of its own */

.cal-panel { padding: 10px 10px 12px; margin-bottom: 18px; border-radius: var(--radius); }
.cal-panel .cal-nav { margin-bottom: 6px; } .cal-panel .cal-title { font-size: 1.05rem; }

/* the PIN set-up screen (first start, or an existing user's next one), and forms inside a tutorial card */

.tour-card { max-height: calc(100% - 32px); overflow: auto; display: flex; flex-direction: column; }
/* a card cut short (docked at the screen's edge beside a tall spotlight) scrolls its words; the buttons stay in view */
.tour-body { min-height: 0; overflow: auto; overscroll-behavior: contain; }
.tour-body.tour-more { -webkit-mask-image: linear-gradient(#000 calc(100% - 2.2em), transparent); mask-image: linear-gradient(#000 calc(100% - 2.2em), transparent); }
.tour-card > .tour-actions { flex: none; }
.tour-form { margin: 0 0 12px; }
.tour-fields { display: grid; gap: 8px; }
.tour-field { display: grid; gap: 3px; font-size: .85rem; color: var(--muted); }
.tour-field input { font: inherit; font-size: 1rem; color: var(--text); background: var(--bg2); border: 1px solid var(--line); border-radius: 10px; padding: 8px 10px; min-height: var(--hit); width: 100%; box-sizing: border-box; }
.tour-field input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
  

/* press and hold a booking: a fill creeps across the bottom while the hold lasts, then the delete sheet opens */
.holding { position: relative; overflow: hidden; -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
.holding::after { content: ''; position: absolute; left: 0; bottom: 0; height: 4px; width: 0; background: var(--danger); animation: hold-fill 3s linear forwards; pointer-events: none; }
@keyframes hold-fill { to { width: 100%; } }
.card.tap, .card.hero { touch-action: pan-y; }

/* Tourbook booking statuses (js/model.js STATUSES): the pill, the calendar's mini line and the day dots. */
.pill.st-hold { color: var(--muted); border-color: var(--muted); border-style: dashed; } .pill.st-offer { color: var(--accent); border-color: var(--accent); }
.pill.st-confirmed { color: var(--ok); border-color: var(--ok); } .pill.st-advanced { color: var(--blue); border-color: var(--blue); }
.pill.st-done { color: var(--text); border-color: var(--line); } .pill.st-settled { color: var(--ok); border-color: var(--ok); background: color-mix(in srgb, var(--ok) 14%, transparent); }
.pill.st-cancelled { color: var(--danger); border-color: var(--danger); text-decoration: line-through; }
.mini.st-hold { border-color: var(--muted); border-style: dashed; } .mini.st-offer { border-color: var(--accent); } .mini.st-advanced { border-color: var(--blue); } .mini.st-done, .mini.st-settled { border-color: var(--line); opacity: .8; } .mini.st-cancelled { opacity: .5; text-decoration: line-through; }
.dots i.st-hold { background: var(--muted); } .dots i.st-offer { background: var(--accent); } .dots i.st-confirmed { background: var(--ok); } .dots i.st-advanced { background: var(--blue); } .dots i.st-done, .dots i.st-settled { background: var(--line); } .dots i.st-cancelled { background: var(--danger); opacity: .5; }

/* Section headings on the white paper previews (day sheet, press kit, documents) read in paper ink, not the accent. */
.cs-paper h4, .cs-doc h4 { color: var(--paper-ink); }
