/* TiltLab start-up loader. Each machine sets the --tl-* colours on .tl-boot.
   While the machine builds itself the main thread is busy, so the playfield loop
   animates only transform and opacity and keeps running on the compositor. */
.tl-boot {
  --tl-bg: #080b19; --tl-bg-2: #10183a; --tl-ink: #edf1ff; --tl-muted: #8995b0; --tl-line: #283044;
  --tl-accent: #8aeaff; --tl-accent-2: #ef438d; --tl-lamp: #ffa53a; --tl-bad: #ff5b4d;
  position: fixed; inset: 0; z-index: 40; overflow-y: auto; color: var(--tl-ink);
  background: radial-gradient(ellipse 70% 60% at 72% 38%, color-mix(in srgb, var(--tl-bg-2) 92%, transparent), var(--tl-bg) 72%);
  font-family: Arial, Helvetica, sans-serif; padding: calc(env(safe-area-inset-top, 0px) + 32px) 16px 28px;
  transition: opacity .8s ease, visibility 0s .8s;
}
.tl-boot.is-gone { opacity: 0; visibility: hidden; pointer-events: none; }
.tl-boot [hidden] { display: none !important; }
.tl-boot-card { width: min(980px, 100%); margin: 0 auto; display: grid; grid-template-columns: minmax(0, 1fr) minmax(220px, 300px); gap: clamp(20px, 5vw, 64px); align-items: start; }
.tl-boot-kicker { margin: 0 0 14px; font-size: 10px; font-weight: 700; letter-spacing: 2.4px; color: var(--tl-muted); text-transform: uppercase; }
.tl-boot-kicker b { color: var(--tl-accent); font-weight: 700; }
.tl-boot h1 { margin: 0 0 22px; font-size: clamp(48px, 7vw, 80px); line-height: 1.02; letter-spacing: -3px; font-weight: 900; font-stretch: condensed; }
.tl-boot h1 em { font-style: italic; color: var(--tl-accent); letter-spacing: -4px; }

/* the dot-matrix display: amber dots behind a dark grid */
.tl-dmd { position: relative; display: grid; gap: 4px; padding: 14px 16px; border-radius: 6px; background: #120802; border: 1px solid #3a210c; box-shadow: inset 0 0 24px #000, 0 0 30px color-mix(in srgb, var(--tl-lamp) 12%, transparent); overflow: hidden; max-width: 460px; }
.tl-dmd span, .tl-dmd strong { position: relative; z-index: 0; font-family: 'Courier New', Courier, monospace; font-weight: 700; color: var(--tl-lamp); text-shadow: 0 0 6px color-mix(in srgb, var(--tl-lamp) 80%, transparent), 0 0 16px color-mix(in srgb, var(--tl-lamp) 40%, transparent); white-space: nowrap; overflow: hidden; text-overflow: clip; }
.tl-dmd span { font-size: 13px; letter-spacing: 3px; }
.tl-dmd strong { font-size: clamp(26px, 4.4vw, 36px); letter-spacing: 4px; font-variant-numeric: tabular-nums; }
.tl-dmd::after { content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: radial-gradient(circle, transparent 0 1.15px, #120802 1.6px) 0 0 / 3.2px 3.2px; opacity: .78; }
.tl-boot.is-tilted .tl-dmd span { color: var(--tl-bad); text-shadow: 0 0 8px var(--tl-bad); animation: tl-tilt .5s steps(1, end) infinite; }

.tl-line { margin: 18px 0 8px; min-height: 1.4em; font-size: 15px; color: #c9d3e6; overflow-wrap: anywhere; }
.tl-bar { position: relative; height: 4px; border-radius: 2px; background: #1b2338; overflow: hidden; max-width: 460px; }
.tl-bar i { position: absolute; inset: 0 auto 0 0; width: 0; background: linear-gradient(90deg, var(--tl-accent-2), var(--tl-accent)); box-shadow: 0 0 12px color-mix(in srgb, var(--tl-accent) 60%, transparent); }
.tl-boot.is-building .tl-bar::after { content: ""; position: absolute; inset: 0 auto 0 0; width: 22%; background: linear-gradient(90deg, transparent, rgba(255,255,255,.45), transparent); animation: tl-run 1.2s linear infinite; will-change: transform; }
.tl-count { margin: 8px 0 18px; font-size: 11px; color: var(--tl-muted); font-variant-numeric: tabular-nums; letter-spacing: .4px; }

/* insert lamps: one per file */
.tl-inserts { display: grid; gap: 12px; margin: 0 0 18px; max-width: 460px; transition: opacity .5s, max-height .6s; max-height: 600px; overflow: hidden; }
.tl-boot.is-building .tl-inserts, .tl-boot.is-built .tl-inserts { opacity: 0; max-height: 0; margin: 0; }
.tl-insert-name { margin: 0 0 6px; font-size: 9px; letter-spacing: 2px; color: var(--tl-muted); text-transform: uppercase; }
.tl-insert-row { display: flex; flex-wrap: wrap; gap: 6px; }
.tl-insert { position: relative; display: block; width: 13px; height: 13px; border-radius: 50%; background: radial-gradient(circle at 38% 32%, #2a3550, #151c2e 70%); border: 1px solid #2b3550; animation: tl-idle 1.6s ease-in-out infinite; }
.tl-insert.is-big { width: 120px; height: 13px; border-radius: 7px; overflow: hidden; }
.tl-insert.is-big b { position: absolute; inset: 0; transform: scaleX(0); transform-origin: 0 50%; background: linear-gradient(90deg, var(--tl-accent-2), var(--tl-accent)); }
.tl-insert.is-hot { background: radial-gradient(circle at 38% 32%, #fff3d6, var(--tl-lamp) 55%, #8a4a12); border-color: var(--tl-lamp); animation: tl-blink .45s steps(1, end) infinite; }
.tl-insert.is-big.is-hot { animation: none; background: #1b2338; }
.tl-insert.is-ok { background: radial-gradient(circle at 38% 32%, #ffffff, var(--tl-accent) 50%, color-mix(in srgb, var(--tl-accent) 40%, #000)); border-color: var(--tl-accent); box-shadow: 0 0 10px color-mix(in srgb, var(--tl-accent) 70%, transparent); animation: tl-pop .45s ease-out; }
.tl-g-kit .tl-insert.is-ok, .tl-g-data .tl-insert.is-ok, .tl-g-font .tl-insert.is-ok { background: radial-gradient(circle at 38% 32%, #fff, var(--tl-accent-2) 50%, color-mix(in srgb, var(--tl-accent-2) 40%, #000)); border-color: var(--tl-accent-2); box-shadow: 0 0 10px color-mix(in srgb, var(--tl-accent-2) 70%, transparent); }
.tl-insert.is-big.is-ok { animation: none; background: #1b2338; box-shadow: 0 0 12px color-mix(in srgb, var(--tl-accent) 50%, transparent); }
.tl-insert.is-bad { background: var(--tl-bad); border-color: var(--tl-bad); animation: tl-shake .3s; }

/* build steps */
.tl-steps { margin: 0 0 6px; padding: 0; list-style: none; display: grid; gap: 4px; font-size: 13px; color: #5d6a85; max-width: 460px; }
.tl-steps li { position: relative; padding-left: 22px; line-height: 1.4; }
.tl-steps li::before { content: ""; position: absolute; left: 2px; top: .3em; width: 10px; height: 10px; border-radius: 50%; border: 1px solid #3a4560; background: #121a2c; }
.tl-steps li.is-done { color: #a9b5cc; }
.tl-steps li.is-done::before { background: var(--tl-accent); border-color: var(--tl-accent); box-shadow: 0 0 8px var(--tl-accent); }
.tl-steps li.is-now { color: var(--tl-ink); }
.tl-steps li.is-now::before { background: var(--tl-lamp); border-color: var(--tl-lamp); animation: tl-blink .5s steps(1, end) infinite; }
.tl-detail { margin: 0 0 14px; min-height: 1.2em; font-size: 11px; color: var(--tl-muted); max-width: 460px; }

/* failure, report, meta */
.tl-fail { margin: 0 0 16px; padding: 14px 16px; border-radius: 6px; border: 1px solid color-mix(in srgb, var(--tl-bad) 60%, transparent); background: color-mix(in srgb, var(--tl-bad) 10%, transparent); font-size: 14px; line-height: 1.5; max-width: 460px; }
.tl-fail p { margin: 0 0 10px; overflow-wrap: anywhere; }
.tl-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.tl-actions button { min-height: 44px; padding: 0 16px; border-radius: 3px; border: 1px solid #3a4560; background: #121a2c; color: var(--tl-ink); font: 700 11px Arial, sans-serif; letter-spacing: 1.2px; cursor: pointer; }
.tl-actions button.is-primary { background: var(--tl-accent); color: #0b1725; border-color: transparent; }
.tl-actions button[disabled] { opacity: .5; }
.tl-note { margin: 10px 0 0 !important; font-size: 12px; color: var(--tl-muted); }
.tl-report { margin: 0 0 12px; max-width: 460px; }
.tl-report summary { cursor: pointer; font-size: 10px; letter-spacing: 1.6px; color: var(--tl-muted); text-transform: uppercase; min-height: 32px; display: flex; align-items: center; }
.tl-report table { width: 100%; margin-top: 6px; border-collapse: collapse; font: 11px ui-monospace, Menlo, Consolas, monospace; }
.tl-report td { padding: 3px 6px 3px 0; border-bottom: 1px dashed #232b40; white-space: nowrap; color: #a9b5cc; }
.tl-report td:first-child { white-space: normal; overflow-wrap: anywhere; }
.tl-report tr.bad td { color: var(--tl-bad); }
.tl-meta { margin: 6px 0 0; font-size: 10px; color: #56627b; letter-spacing: .4px; }
.tl-back { margin: 14px 0 0; font-size: 12px; color: var(--tl-muted); }
.tl-back a { color: var(--tl-accent); text-decoration: none; display: inline-flex; min-height: 44px; align-items: center; }
.tl-back a:hover { text-decoration: underline; }

/* the little playfield */
.tl-field { width: 100%; height: auto; display: block; overflow: visible; }
.tl-field .cab { fill: #0c1226; stroke: #dde6f2; stroke-width: 2.5; }
.tl-field .glass { fill: url(#tl-glass); }
.tl-field .rail { fill: none; stroke: #33405e; stroke-width: 2; stroke-linecap: round; }
.tl-field .route { fill: none; stroke: #1e2a46; stroke-width: 3; stroke-linecap: round; stroke-dasharray: 2 6; }
.tl-field .trail { fill: none; stroke: var(--tl-accent); stroke-width: 3; stroke-linecap: round; filter: drop-shadow(0 0 4px var(--tl-accent)); }
.tl-field .bumper circle { fill: #141c36; stroke: var(--tl-accent-2); stroke-width: 3; }
.tl-field .bumper .cap { fill: var(--tl-accent-2); opacity: .15; }
.tl-field .sling { fill: color-mix(in srgb, var(--tl-accent) 18%, transparent); stroke: var(--tl-accent); stroke-width: 1.5; stroke-linejoin: round; }
.tl-field .lamp { fill: #24304e; }
.tl-field .flipper { fill: #dde6f2; }
.tl-field .flip-l { transform-origin: 62px 286px; }
.tl-field .flip-r { transform-origin: 138px 286px; }
.tl-field .ball { fill: url(#tl-steel); filter: drop-shadow(0 2px 2px rgba(0,0,0,.6)); transform: translate(182px, 312px); }
.tl-field .plunger { fill: #dde6f2; }

.tl-boot.is-building .tl-field .ball, .tl-boot.is-built .tl-field .ball { animation: tl-ball 2.6s infinite; }
.tl-boot.is-building .tl-field .flip-l, .tl-boot.is-built .tl-field .flip-l { animation: tl-flip-l 2.6s infinite; }
.tl-boot.is-building .tl-field .flip-r, .tl-boot.is-built .tl-field .flip-r { animation: tl-flip-r 2.6s infinite; }
.tl-boot.is-building .tl-field .b0 .cap, .tl-boot.is-built .tl-field .b0 .cap { animation: tl-hit 2.6s infinite; animation-delay: -1.95s; }
.tl-boot.is-building .tl-field .b1 .cap, .tl-boot.is-built .tl-field .b1 .cap { animation: tl-hit 2.6s infinite; animation-delay: -1.64s; }
.tl-boot.is-building .tl-field .b2 .cap, .tl-boot.is-built .tl-field .b2 .cap { animation: tl-hit 2.6s infinite; animation-delay: -2.24s; }
.tl-boot.is-building .tl-field .lamp, .tl-boot.is-built .tl-field .lamp { animation: tl-chase 1.3s steps(1, end) infinite; }
.tl-field .lamp:nth-of-type(2) { animation-delay: -.33s !important; } .tl-field .lamp:nth-of-type(3) { animation-delay: -.66s !important; } .tl-field .lamp:nth-of-type(4) { animation-delay: -.99s !important; }

@keyframes tl-ball {
  0%   { transform: translate(92px, 274px); animation-timing-function: cubic-bezier(.2,.7,.4,1); }
  14%  { transform: translate(100px, 169px); animation-timing-function: ease-out; }
  26%  { transform: translate(82px, 128px); animation-timing-function: ease-out; }
  38%  { transform: translate(121px, 120px); animation-timing-function: ease-in-out; }
  50%  { transform: translate(104px, 168px); animation-timing-function: cubic-bezier(.5,0,.8,.6); }
  68%  { transform: translate(140px, 238px); animation-timing-function: ease-in; }
  84%  { transform: translate(110px, 274px); animation-timing-function: cubic-bezier(.3,.6,.5,1); }
  100% { transform: translate(92px, 274px); }
}
@keyframes tl-flip-l { 0%, 7%, 100% { transform: rotate(0deg); } 2% { transform: rotate(-30deg); } }
@keyframes tl-flip-r { 0%, 83%, 92%, 100% { transform: rotate(0deg); } 86% { transform: rotate(30deg); } }
@keyframes tl-hit { 0%, 8%, 100% { opacity: .15; } 1% { opacity: 1; } }
@keyframes tl-chase { 0%, 25% { fill: var(--tl-lamp); } 26%, 100% { fill: #24304e; } }
@keyframes tl-idle { 50% { opacity: .55; } }
@keyframes tl-blink { 50% { opacity: .35; } }
@keyframes tl-pop { from { transform: scale(1.5); } }
@keyframes tl-shake { 33% { transform: translateX(-3px); } 66% { transform: translateX(3px); } }
@keyframes tl-run { from { transform: translateX(-100%); } to { transform: translateX(460%); } }
@keyframes tl-tilt { 50% { opacity: .2; } }

@media (max-width: 760px) {
  .tl-boot { padding-top: calc(env(safe-area-inset-top, 0px) + 20px); }
  .tl-boot-card { grid-template-columns: minmax(0, 1fr) 96px; gap: 14px; }
  .tl-boot-copy { display: contents; }
  .tl-boot-head { grid-column: 1; }
  .tl-field-wrap { grid-column: 2; grid-row: 1; align-self: center; }
  .tl-boot-body { grid-column: 1 / -1; }
  .tl-boot h1 { font-size: 46px; letter-spacing: -2px; margin-bottom: 0; }
  .tl-boot h1 em { letter-spacing: -2.5px; }
}
@media (prefers-reduced-motion: reduce) {
  .tl-boot *, .tl-boot *::before, .tl-boot *::after { animation: none !important; transition: none !important; }
}
