/* Generated from the app theme by components/app/test/tool/
 * web_theme_test.dart. Do not edit; run `just web-theme`. */
:root {
  color-scheme: dark;

  /* Material colour roles */
  --md-primary: #FFFFFF;
  --md-on-primary: #000000;
  --md-primary-container: #FFFFFF33;
  --md-on-primary-container: #FFFFFF;
  --md-secondary: #8E929E;
  --md-secondary-container: #1E212B;
  --md-on-secondary-container: #FFFFFF;
  --md-error: #FF453A;
  --md-on-error: #FFFFFF;
  --md-surface-dim: #000000;
  --md-surface: #101216;
  --md-surface-bright: #262A36;
  --md-surface-container-lowest: #0A0B0E;
  --md-surface-container-low: #101216;
  --md-surface-container: #16181F;
  --md-surface-container-high: #1E212B;
  --md-surface-container-highest: #262A36;
  --md-on-surface: #FFFFFF;
  --md-on-surface-variant: #8E929E;
  --md-outline: #262A36;
  --md-outline-variant: #1F222C;
  --md-scrim: #000000;

  /* Stage surfaces and text */
  --stagely-bg: #000000;
  --stagely-studio-card: #14161D;
  --stagely-studio-rack: #181B24;
  --stagely-studio-border: #262B3A;
  --stagely-text-primary: #FFFFFF;
  --stagely-text-secondary: #8E929E;
  --stagely-text-muted: #636A79;
  --stagely-focus: #FFFFFF;

  /* Semantic meanings */
  --stagely-overridden: #F71899;
  --stagely-error-red: #FF453A;
  --stagely-success: #30D158;
  --stagely-warning: #FFD60A;
  --stagely-metronome-active: #FF453A;
  --stagely-chord-base-key: #FDE016;
  --stagely-cue-dynamic: #FF9F0A;
  --stagely-transpose-up: #FF453A;
  --stagely-transpose-down: #38B6FF;
  --stagely-accidental-sharp: #FFB340;
  --stagely-accidental-flat: #38B6FF;
  --stagely-accidental-natural: #FFFFFF;

  /* Chord harmonic function (scale degree) */
  --stagely-chord-degree-1: #FFD60A;
  --stagely-chord-degree-2: #FF9F0A;
  --stagely-chord-degree-3: #BF5AF2;
  --stagely-chord-degree-4: #38B6FF;
  --stagely-chord-degree-5: #FF453A;
  --stagely-chord-degree-6: #30D158;
  --stagely-chord-degree-7: #FF375F;
  --stagely-chord-out-of-key: #8E929E;

  /* Song sections */
  --stagely-section-intro: #FF3B30;
  --stagely-section-verse: #30D158;
  --stagely-section-prechorus: #00D2FF;
  --stagely-section-chorus: #00D2D3;
  --stagely-section-postchorus: #00D2A7;
  --stagely-section-bridge: #AF52DE;
  --stagely-section-interlude: #FF9500;
  --stagely-section-instrumental: #FF9500;
  --stagely-section-solo: #FF9500;
  --stagely-section-turnaround: #FFC107;
  --stagely-section-vamp: #BF5AF2;
  --stagely-section-tag: #FF2D55;
  --stagely-section-outro: #FF2D55;

  /* Persona wayfinding (persona artwork only) */
  --stagely-persona-prepare: #D86BFF;
  --stagely-persona-practice: #FFD60A;
  --stagely-persona-perform: #3FD8FF;
  --stagely-persona-prepare-0: #F6C2FF;
  --stagely-persona-prepare-1: #D86BFF;
  --stagely-persona-prepare-2: #A54DFF;
  --stagely-persona-prepare-3: #6A3DF0;
  --stagely-persona-prepare-4: #26105A;
  --stagely-persona-prepare-5: #0D0526;
  --stagely-persona-practice-0: #FFF39A;
  --stagely-persona-practice-1: #FFD60A;
  --stagely-persona-practice-2: #FF9F0A;
  --stagely-persona-practice-3: #FF5F2E;
  --stagely-persona-practice-4: #4D1C00;
  --stagely-persona-practice-5: #1F0A00;
  --stagely-persona-perform-0: #C4F8FF;
  --stagely-persona-perform-1: #3FD8FF;
  --stagely-persona-perform-2: #1A8CFF;
  --stagely-persona-perform-3: #1F4FD8;
  --stagely-persona-perform-4: #0A1E66;
  --stagely-persona-perform-5: #020820;

  /* Shape, glass and type */
  --stagely-radius-studio: 20px;
  --stagely-radius-card: 24px;
  --stagely-persona-corner: 0.234375;
  --stagely-glass-blur: 5px;
  --stagely-glass-panel-blur: 20px;
  --stagely-glass-tint: 0.2;
  --stagely-glass-panel-tint: 0.82;
  --stagely-glass-saturation: 1.5;
  --stagely-font: 'Inter', system-ui, sans-serif;
  --stagely-font-mono: 'JetBrains Mono', 'Roboto Mono', ui-monospace, monospace;

  /* pointer input density */
  --stagely-pointer-target: 40px;
  --stagely-pointer-inline-target: 36px;
  --stagely-pointer-row-inset: 8px;
  --stagely-pointer-row-height: 40px;
  --stagely-pointer-field-height: 44px;

  /* touch input density */
  --stagely-touch-target: 48px;
  --stagely-touch-inline-target: 44px;
  --stagely-touch-row-inset: 12px;
  --stagely-touch-row-height: 56px;
  --stagely-touch-field-height: 56px;
}

/* Blueprints: the app's reusable surfaces, drawn with the tokens above.
 * Source: components/app/test/tool/web_blueprints.css. Use these classes on
 * every web surface instead of restyling the same thing locally. */

/* Base: true-black stage, Inter, white as the only accent. */
html {
  background: var(--stagely-bg);
  color: var(--stagely-text-primary);
  font-family: var(--stagely-font);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--stagely-bg);
}

::selection {
  background: var(--md-primary);
  color: var(--md-on-primary);
}

:focus-visible {
  outline: 2px solid var(--stagely-focus);
  outline-offset: 2px;
}

/* Input density follows the pointer, like StagelyMetrics. */
:root {
  --st-target: var(--stagely-pointer-target);
  --st-field-height: var(--stagely-pointer-field-height);
  --st-row-inset: var(--stagely-pointer-row-inset);
}

@media (pointer: coarse) {
  :root {
    --st-target: var(--stagely-touch-target);
    --st-field-height: var(--stagely-touch-field-height);
    --st-row-inset: var(--stagely-touch-row-inset);
  }
}

/* Concentric corners: a rounded shape inside another shares the centre of its
 * arcs, so its radius is the container's less the gap between them. Every
 * container sets --st-radius and --st-pad (its padding); .st-nested takes the
 * difference, and siblings share one height and one radius. */
.st-panel,
.st-glass--panel,
.st-glass-card {
  --st-radius: var(--stagely-radius-card);
  --st-pad: 24px;
}

.st-pad {
  padding: var(--st-pad);
}

.st-nested {
  border-radius: max(0px, calc(var(--st-radius) - var(--st-pad)));
}

/* Panel: the in-page container (library table, cards). Plain fill, no glass. */
.st-panel {
  background: var(--md-surface-container-lowest);
  border: 1px solid var(--md-outline);
  border-radius: var(--st-radius);
}

.st-panel-header {
  color: var(--stagely-text-secondary);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* Glass: only for layers floating above other content (islands, sticky bars). */
.st-glass {
  background: color-mix(
    in srgb,
    var(--md-surface-container-high) calc(var(--stagely-glass-tint) * 100%),
    transparent
  );
  backdrop-filter: blur(var(--stagely-glass-blur))
    saturate(var(--stagely-glass-saturation));
  -webkit-backdrop-filter: blur(var(--stagely-glass-blur))
    saturate(var(--stagely-glass-saturation));
  border: 1px solid color-mix(in srgb, var(--md-primary) 12%, transparent);
  border-radius: 999px;
}

.st-glass--panel {
  background: color-mix(
    in srgb,
    var(--md-surface-container) calc(var(--stagely-glass-panel-tint) * 100%),
    transparent
  );
  backdrop-filter: blur(var(--stagely-glass-panel-blur))
    saturate(var(--stagely-glass-saturation));
  -webkit-backdrop-filter: blur(var(--stagely-glass-panel-blur))
    saturate(var(--stagely-glass-saturation));
  border-radius: var(--st-radius);
}

@media (prefers-reduced-transparency: reduce) {
  .st-glass,
  .st-glass--panel {
    background: var(--md-surface-container-high);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
}

/* Buttons: white pill for the one primary action, tonal for the rest. */
.st-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: var(--st-target);
  padding: 0 20px;
  border: 0;
  border-radius: 999px;
  background: var(--md-primary);
  color: var(--md-on-primary);
  font: 500 14px/1 var(--stagely-font);
  text-decoration: none;
  cursor: pointer;
  transition: opacity 0.15s ease;
}

.st-button:hover {
  opacity: 0.9;
}

.st-button:disabled {
  opacity: 0.5;
  cursor: default;
}

.st-button--tonal {
  background: var(--md-surface-container-high);
  color: var(--md-on-surface);
}

.st-button--text {
  background: transparent;
  color: var(--stagely-text-secondary);
}

.st-button--text:hover {
  color: var(--md-on-surface);
}

/* Field: outlined like the app's text fields; white outline when focused. A
 * pill, like the buttons it sits beside. */
.st-field {
  min-height: var(--st-field-height);
  padding: 0 16px;
  border: 1px solid var(--md-outline);
  border-radius: calc(var(--st-field-height) / 2);
  background: var(--md-surface-container-lowest);
  color: var(--md-on-surface);
  font: 400 16px var(--stagely-font);
  outline: none;
}

.st-field::placeholder {
  color: var(--stagely-text-muted);
}

.st-field:focus {
  border-color: var(--stagely-focus);
}

/* Chip: a choice among several (filters, roles). */
.st-chip {
  min-height: calc(var(--st-target) - 8px);
  padding: 0 14px;
  border: 1px solid var(--md-outline);
  border-radius: 999px;
  background: transparent;
  color: var(--stagely-text-secondary);
  font: 500 13px var(--stagely-font);
  cursor: pointer;
}

.st-chip[aria-pressed='true'] {
  border-color: var(--md-primary);
  background: var(--md-primary);
  color: var(--md-on-primary);
}

/* Song section card: outline and glow in the section's colour. */
.st-section {
  --section: var(--stagely-text-muted);
  position: relative;
  border: 1.5px solid var(--section);
  border-radius: var(--stagely-radius-studio);
  background: var(--stagely-bg);
  box-shadow: 0 0 14px color-mix(in srgb, var(--section) 35%, transparent);
}

.st-section-badge {
  --section: var(--stagely-text-muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border: 1.5px solid var(--section);
  border-radius: 50%;
  background: var(--stagely-bg);
  color: var(--stagely-text-primary);
  font: 700 11px var(--stagely-font);
}

.st-section--intro { --section: var(--stagely-section-intro); }
.st-section--verse { --section: var(--stagely-section-verse); }
.st-section--prechorus { --section: var(--stagely-section-prechorus); }
.st-section--chorus { --section: var(--stagely-section-chorus); }
.st-section--bridge { --section: var(--stagely-section-bridge); }
.st-section--interlude { --section: var(--stagely-section-interlude); }
.st-section--outro { --section: var(--stagely-section-outro); }

/* Chord: bold, coloured by its harmonic function in the song's key. */
.st-chord {
  font: 700 1em var(--stagely-font);
  color: var(--chord, var(--stagely-chord-out-of-key));
}

.st-chord--1 { --chord: var(--stagely-chord-degree-1); }
.st-chord--2 { --chord: var(--stagely-chord-degree-2); }
.st-chord--3 { --chord: var(--stagely-chord-degree-3); }
.st-chord--4 { --chord: var(--stagely-chord-degree-4); }
.st-chord--5 { --chord: var(--stagely-chord-degree-5); }
.st-chord--6 { --chord: var(--stagely-chord-degree-6); }
.st-chord--7 { --chord: var(--stagely-chord-degree-7); }

/* Persona wayfinding: colours only the persona artwork, like the app. */
.st-persona--prepare { --persona: var(--stagely-persona-prepare); }
.st-persona--practice { --persona: var(--stagely-persona-practice); }
.st-persona--perform { --persona: var(--stagely-persona-perform); }

/* Text roles. */
.st-eyebrow {
  color: var(--stagely-text-secondary);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.st-muted {
  color: var(--stagely-text-secondary);
}

.st-mono {
  font-family: var(--stagely-font-mono);
}

/* Status messages. */
.st-status {
  padding: 12px 16px;
  border: 1px solid var(--status, var(--md-outline));
  border-radius: 12px;
  color: var(--md-on-surface);
  font-size: 14px;
}

.st-status--success { --status: var(--stagely-success); }
.st-status--error { --status: var(--stagely-error-red); }

/* Stage lights: the page is lit like a venue, and a light's colour says where
 * you are. Persona colours (wayfinding) light only the area of that persona;
 * everything else is white light on the black stage. */

/* Film grain on the stage, behind the content so text keeps its contrast. */
.st-grain {
  isolation: isolate;
}

.st-grain::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.07;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* A white spotlight from above: the calm stage for reading and working. */
.st-spotlight {
  background:
    radial-gradient(
      ellipse 70% 45% at 50% -10%,
      color-mix(in srgb, var(--md-primary) 9%, transparent),
      transparent 70%
    ),
    var(--stagely-bg);
  background-attachment: fixed;
}

/* The hero rig: three persona beams crossing over the stage (the 3P line). */
.st-rig {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
}

.st-beam {
  position: absolute;
  top: -20%;
  width: 24%;
  height: 130%;
  opacity: 0.9;
  filter: blur(36px) saturate(1.6);
  mix-blend-mode: screen;
  background:
    radial-gradient(
      ellipse 45% 22% at 50% 12%,
      var(--persona),
      transparent 70%
    ),
    linear-gradient(
      180deg,
      var(--persona),
      color-mix(in srgb, var(--persona) 45%, transparent) 35%,
      color-mix(in srgb, var(--persona) 10%, transparent) 60%,
      transparent 80%
    );
  transform-origin: 50% 0;
  animation: st-sway 14s ease-in-out infinite alternate;
}

.st-beam.st-persona--prepare {
  left: 2%;
  --st-tilt: -30deg;
}

.st-beam.st-persona--practice {
  left: 38%;
  --st-tilt: 0deg;
  opacity: 0.6;
  animation-delay: -5s;
}

.st-beam.st-persona--perform {
  right: 2%;
  --st-tilt: 30deg;
  animation-delay: -9s;
}

/* Where the beams land: a soft pool of white light on the floor. */
.st-rig::after {
  content: '';
  position: absolute;
  left: 15%;
  right: 15%;
  bottom: 0;
  height: 40%;
  background: radial-gradient(
    ellipse 50% 40% at 50% 55%,
    color-mix(in srgb, var(--md-primary) 12%, transparent),
    transparent 70%
  );
}

@keyframes st-sway {
  from {
    transform: rotate(calc(var(--st-tilt) - 5deg));
  }
  to {
    transform: rotate(calc(var(--st-tilt) + 5deg));
  }
}

/* A persona's area: washed from below in its light. */
.st-wash {
  position: relative;
  isolation: isolate;
}

.st-wash::before {
  content: '';
  position: absolute;
  inset: -10% -5% auto;
  height: 120%;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(
    ellipse 55% 45% at 50% 60%,
    color-mix(in srgb, var(--persona) 28%, transparent),
    transparent 70%
  );
}

/* Glass card: an in-page panel that lets the stage light through. */
.st-glass-card {
  background: color-mix(in srgb, var(--md-surface-container-lowest) 62%, transparent);
  backdrop-filter: blur(var(--stagely-glass-panel-blur))
    saturate(var(--stagely-glass-saturation));
  -webkit-backdrop-filter: blur(var(--stagely-glass-panel-blur))
    saturate(var(--stagely-glass-saturation));
  border: 1px solid color-mix(in srgb, var(--md-primary) 10%, transparent);
  border-radius: var(--st-radius);
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--md-primary) 8%, transparent);
}

/* Active sweep: a light running round the border in the card's colour, like
 * the app's rotating border on the active element. Shown on hover/focus. */
@property --st-angle {
  syntax: '<angle>';
  initial-value: 0deg;
  inherits: false;
}

.st-sweep {
  position: relative;
}

.st-sweep::after {
  content: '';
  position: absolute;
  inset: 0;
  padding: 1.5px;
  border-radius: inherit;
  pointer-events: none;
  background: conic-gradient(
    from var(--st-angle),
    color-mix(in srgb, var(--persona, var(--md-primary)) 30%, transparent),
    var(--persona, var(--md-primary)),
    color-mix(in srgb, var(--persona, var(--md-primary)) 30%, transparent) 50%,
    transparent 75%,
    color-mix(in srgb, var(--persona, var(--md-primary)) 30%, transparent)
  );
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  opacity: 0;
  transition: opacity 0.3s ease;
  animation: st-spin 4s linear infinite;
}

.st-sweep:is(:hover, :focus-within)::after {
  opacity: 1;
}

@keyframes st-spin {
  to {
    --st-angle: 360deg;
  }
}

/* Meaningful colours glow in their own light, like activeGlowShadow. */
.st-glow {
  text-shadow: 0 0 18px color-mix(in srgb, currentColor 45%, transparent);
}

.st-section-badge.st-glow {
  box-shadow: 0 0 12px color-mix(in srgb, var(--section) 40%, transparent);
}

@media (prefers-reduced-motion: reduce) {
  .st-beam,
  .st-sweep::after {
    animation: none;
  }
}

/* Scroll story: anchors glide, and blocks rise into view once. The hidden
 * start state applies only when a script has marked the page (.st-js), so
 * nothing is lost without JavaScript. */
html {
  scroll-behavior: smooth;
  scroll-padding-top: 96px;
}

.st-js .st-reveal {
  opacity: 0;
  transform: translateY(24px);
  transition:
    opacity 0.7s ease,
    transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
  transition-delay: var(--st-delay, 0s);
}

.st-js .st-reveal.is-visible {
  opacity: 1;
  transform: none;
}

/* Roadmap spine: steps threaded on a line, like a song's sections in the app.
 * Each step hangs on the line by its node (usually its persona's .st-glyph),
 * and the line runs through the nodes' centres in the personas' light. */
.st-spine {
  --st-node: 48px;
  --st-node-gap: 20px;
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 48px;
  padding-left: calc(var(--st-node) + var(--st-node-gap));
}

.st-spine::before {
  content: '';
  position: absolute;
  top: calc(var(--st-node) / 2);
  bottom: calc(var(--st-node) / 2);
  left: calc(var(--st-node) / 2 - 1px);
  width: 2px;
  background: linear-gradient(
    180deg,
    var(--stagely-persona-prepare),
    var(--stagely-persona-practice),
    var(--stagely-persona-perform)
  );
  opacity: 0.5;
}

.st-spine-node {
  --st-glyph-size: var(--st-node);
  position: absolute;
  top: 0;
  left: calc(-1 * (var(--st-node) + var(--st-node-gap)));
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  .st-js .st-reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* Product bar: the one navigation every Stagely Pro page shares (site, guide,
 * app, console). A glass pill whose padding equals the gap to its controls,
 * so the logo and the buttons sit concentric in its ends. */
.st-nav {
  --st-pad: 8px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: var(--st-pad);
  border-radius: calc(var(--st-target) / 2 + var(--st-pad));
}

.st-nav-brand {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding-right: 12px;
  border-radius: 999px;
  color: var(--stagely-text-primary);
  font: 700 16px var(--stagely-font);
  text-decoration: none;
}

.st-nav-brand img {
  width: var(--st-target);
  height: var(--st-target);
  border-radius: 50%;
}

.st-nav-links {
  display: flex;
  align-items: center;
  gap: 4px;
}

/* Field bar: a field and its button in one glass capsule, all concentric. */
.st-bar {
  --st-pad: 6px;
  display: flex;
  flex-wrap: wrap;
  gap: var(--st-pad);
  padding: var(--st-pad);
  border-radius: calc(var(--st-field-height) / 2 + var(--st-pad));
}

.st-bar > .st-field {
  flex: 1 1 14rem;
  min-width: 0;
  border-color: transparent;
  background: transparent;
}

.st-bar > .st-field:focus {
  border-color: var(--stagely-focus);
}

.st-bar > .st-button {
  flex: 1 0 auto;
}

/* A button that sits beside a field takes the field's height. */
.st-button--field,
.st-bar > .st-button {
  min-height: var(--st-field-height);
}

/* Persona artwork: the app's own PersonaGlyph, rendered frame by frame into
 * one sprite per persona (`just persona-art`, 24 frames, first empty, last at
 * rest). It plays its entrance once, when its block comes into view, and
 * rests on the last frame; under reduced motion it starts at rest. It stands
 * on glass, as the app's PersonaTile does, on the same rounded square. */
.st-glyph {
  --st-size: var(--st-glyph-size, 64px);
  display: inline-block;
  flex: none;
  width: var(--st-size);
  height: var(--st-size);
  border-radius: calc(var(--st-size) * var(--stagely-persona-corner));
  background-color: color-mix(
    in srgb,
    var(--md-surface-container) calc(var(--stagely-glass-panel-tint) * 100%),
    transparent
  );
  background-repeat: no-repeat;
  background-size: 100% 2400%;
  background-position: 0 100%;
  box-shadow:
    0 calc(var(--st-size) * 0.04) calc(var(--st-size) * 0.08)
      rgb(0 0 0 / 0.55),
    0 calc(var(--st-size) * 0.18) calc(var(--st-size) * 0.45)
      rgb(0 0 0 / 0.6);
  animation: st-glyph-in 0.7s steps(24, jump-none) both;
}

.st-glyph--prepare { background-image: url('/persona/persona-prepare.webp'); }
.st-glyph--practice { background-image: url('/persona/persona-practice.webp'); }
.st-glyph--perform { background-image: url('/persona/persona-perform.webp'); }

.st-js .st-reveal:not(.is-visible) .st-glyph {
  animation-play-state: paused;
}

@keyframes st-glyph-in {
  from {
    background-position: 0 0;
  }
  to {
    background-position: 0 100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .st-glyph {
    animation: none;
  }
}
