/*
 * Page-specific styles for /products/bam.
 *
 * Port of the design's inline <style> block in `Imaginando BAM.html`,
 * plus the shared product-page chrome the React handoff pulled from
 * `product-sections.css` (tutorials, testimonials, edu/mobile split,
 * pricing helpers) — sourced from the already-shipped GRFX /
 * product-template ports so it stays consistent with the rest of the
 * redesign. Same convention as the DLYM / K7D / GRFX / TKFX product
 * pages: the product-detail chrome (.product-nav, .hero, .sec-head,
 * .req-grid, .help-grid, .press …) is duplicated here intentionally —
 * hoist into /style.css once a cross-page commit consolidates it.
 *
 * Already in /style.css (intentionally NOT duplicated):
 *   :root tokens, html/body/a/button resets, ::selection, .mono, .wrap,
 *   .btn / .btn.primary / .btn.ghost / .btn .arrow, .section base,
 *   .reveal, the global nav + footer chrome, .yt-poster.
 *
 * PALETTE — BAM keeps the GLOBAL lime --accent (the deliberate
 * site-wide convention every shipped product page follows; the GRFX
 * handoff was turquoise yet shipped lime). The handoff's warm amber is
 * carried as a scoped secondary (--accent-2) for the percussive touches
 * — the snare lane, mixer meter gradient, send rows. Flip the two
 * declarations below to adopt the handoff's full warm-orange palette.
 *
 * BAM-only chrome (animated panels — JS in /pages/bam.js, all
 * reduced-motion aware and IntersectionObserver-gated):
 *   .matrix-vis  — clip-launcher matrix (scene cycle)
 *   .plock-vis   — parameter automation lane + target rail (playhead sweep)
 *   .proll-vis   — piano-roll composer (velocity-shaded notes, static)
 *   .mixer-vis   — 16-channel mixer (green→yellow→red VU meters)
 *   .fxr-vis     — FX insert chain (static)
 *   .hybrid-vis  — hybrid audio + MIDI clip with shared playhead
 */

:root {
  --accent-2: #ffd166; /* amber — BAM's percussive secondary */
}
html[data-theme="light"],
:root[data-theme="light"] {
  --accent-2: #c89030;
}

/* ============================================================
 * Section heading — product-detail scale (matches GRFX/DRC/…).
 * ============================================================ */
/* Base `.section` padding + border live in style.css; bam only adds a
 * positioning context for its absolutely-placed animated panels. */
.section { position: relative; }
.sec-head { display: flex; justify-content: space-between; align-items: end; gap: 24px; margin-bottom: 48px; flex-wrap: wrap; }
.sec-head h2 {
  font-family: var(--display);
  font-weight: 500;
  font-size: clamp(38px, 5vw, 72px);
  line-height: 0.95;
  letter-spacing: -0.025em;
  margin: 8px 0 0;
  max-width: none;
  text-wrap: balance;
}
.sec-head h2 em { font-family: var(--serif); font-style: italic; font-weight: 400; color: var(--accent); }
.sec-head .meta {
  display: block;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--fg-faint);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-align: right;
  max-width: 30ch;
}
/* On mobile the section header stacks (flex-direction:column comes from the
   shared style.css @media). This local .sec-head redefinition carries
   align-items:end, which — being declared after style.css — also wins the
   stacked layout and shoves the eyebrow + heading to the right edge. Restore
   left alignment (mirrors the shared @media 700 rule). */
@media (max-width: 700px) {
  .sec-head { flex-direction: column; align-items: start; }
  .sec-head .meta { text-align: left; }
}

/* ============================================================
 * HERO
 * ============================================================ */
/* ============================================================
 * HERO — BAM tint + visual only. Chrome is shared (`.phero-*` in
 * public/style.css, via +productHero — refs #444). BAM keeps its
 * deeper padding, two-tone gradient, 1.05fr split, 1100px collapse and
 * wider copy; the visual is the clip-matrix screenshot.
 * ============================================================ */
.phero { padding: 48px 0 96px; }
.phero-bg {
  background:
    radial-gradient(ellipse 80% 60% at 70% 35%, color-mix(in oklab, var(--accent) 14%, transparent), transparent 60%),
    radial-gradient(ellipse 60% 50% at 12% 85%, color-mix(in oklab, var(--accent-2) 8%, transparent), transparent 60%);
}
.phero-grid { grid-template-columns: 1fr 1.05fr; }
.phero h2 { max-width: 22ch; }
.phero .lede { max-width: 50ch; }
@media (max-width: 1100px) {
  .phero-grid { grid-template-columns: 1fr; gap: 40px; align-items: start; }
}
/* Hero shot — clip-matrix screenshot in the right column. The `img`
   MUST be width-constrained or it renders at its natural pixel size. */
.hero-shot { position: relative; align-self: start; margin-top: 44px; border-radius: 6px; border: 0.5px solid var(--line-strong); overflow: hidden; background: #0c0807; box-shadow: 0 30px 80px rgba(0, 0, 0, 0.65), inset 0 1px 0 rgba(255, 255, 255, 0.04); }
.hero-shot img { display: block; width: 100%; height: auto; }

/* ============================================================
 * FEATURE-PANEL VISUALS (inside .feat .visual)
 * ============================================================ */
/* CLIP MATRIX — mirrors BAM's real clip launcher rather than the global
 * lime accent (deliberate, scoped exception to the site-wide convention:
 * this panel depicts an actual product surface). Each column owns a hue
 * from the app's 17-colour track palette (bam/common/DSSequencer.h), set
 * via --tc in bam.pug. Behaviour follows DSMatrixViewSlotNode.cpp: empty
 * cells near-black, resting clips dim (~50%), the live scene ignites to
 * full brightness with a white edge + glow. Committed dark in both
 * themes — the app canvas is always black, matching the hero shot. */
.matrix-vis { position: absolute; inset: 0; padding: 18px; display: flex; flex-direction: column; gap: 5px; font-family: var(--mono); font-size: 9px; letter-spacing: 0.06em; text-transform: uppercase; z-index: 1; background: #0a0a0b; }
.matrix-vis .m-foot, .matrix-vis .m-row { display: grid; grid-template-columns: repeat(8, 1fr) 42px; gap: 4px; align-items: center; }
.matrix-vis .m-foot { color: rgba(244, 241, 234, 0.4); padding-top: 6px; border-top: 0.5px solid rgba(244, 241, 234, 0.12); }
.matrix-vis .m-foot span { padding: 0 4px; }
.matrix-vis .m-row { flex: 1; transition: opacity 0.25s ease; }
.matrix-vis .m-scene { color: rgba(244, 241, 234, 0.85); font-weight: 500; letter-spacing: 0.18em; text-align: right; }
.matrix-vis .m-foot span:last-child { text-align: right; }
.matrix-vis .m-clip { position: relative; height: 100%; border: 0.5px solid rgba(255, 255, 255, 0.05); border-radius: 5px; background: #141414; display: grid; place-items: center; color: rgba(244, 241, 234, 0.38); font-size: 9px; transition: border-color 0.25s ease, background 0.25s ease, color 0.25s ease, box-shadow 0.25s ease; }
/* active-row crosshair on EMPTY cells only (app: rgb(50,50,50)).
 * :not(.filled) keeps this off filled/live cells, which otherwise win
 * on specificity here and would lose their hue. */
.matrix-vis .m-row.playing .m-clip:not(.filled) { background: #232326; }
/* resting clip — track hue darkened ~50% */
.matrix-vis .m-clip.filled { background: color-mix(in srgb, var(--tc) 34%, #0c0c0f); border-color: color-mix(in srgb, var(--tc) 42%, transparent); color: color-mix(in srgb, var(--tc) 78%, #ffffff); }
.matrix-vis .m-row.playing .m-scene { color: #ffffff; }
/* live clip — the launched clip is the brightest state: full-brightness
 * hue + white edge + glow. The scene cycle (JS toggles .playing/.live per
 * row) carries the motion; matches the app's lit clips. */
.matrix-vis .m-clip.live { background: var(--tc); color: #08080a; font-weight: 600; border-color: rgba(255, 255, 255, 0.85); box-shadow: 0 0 18px color-mix(in srgb, var(--tc) 55%, transparent), inset 0 0 0 1px rgba(255, 255, 255, 0.5); }

/* PARAM LOCK — mirrors BAM's real automation lane
 * (bam/common/qml/PanelAutomations.qml). Left rail = the parameter-target
 * list (selected row highlighted, LEARN + delete beneath, as in the app's
 * Pane); right lane = 16 step columns where the inherited value rides DIM
 * and per-step LOCKS ignite to full --accent at their explicit value (the
 * app draws unlocked steps at 0.5 opacity, locked at 1.0). Committed dark
 * in both themes — like the clip-matrix panel this depicts an actual
 * product surface and the app canvas is always black. The playhead sweep
 * (JS toggles .play across the columns) carries the motion; bar heights
 * are fixed, since locked/inherited values don't move. */
.plock-vis { position: absolute; inset: 0; padding: 16px 18px; display: flex; flex-direction: column; gap: 8px; z-index: 1; background: #0a0a0b; font-family: var(--mono); }
.plock-vis .pl-head, .plock-vis .pl-foot { display: flex; justify-content: space-between; font-size: 9px; letter-spacing: 0.14em; text-transform: uppercase; color: rgba(244, 241, 234, 0.4); }
.plock-vis .pl-head { color: rgba(244, 241, 234, 0.75); }
.plock-vis .pl-foot span:first-child { color: var(--accent); }
.pl-body { flex: 1; display: grid; grid-template-columns: 108px 1fr; gap: 10px; min-height: 0; }
/* left rail — parameter targets + LEARN / delete */
.pl-params { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.pl-plist { flex: 1; display: flex; flex-direction: column; gap: 2px; overflow: hidden; }
.pl-param { display: flex; align-items: center; gap: 6px; padding: 3px 6px; border-radius: 4px; min-width: 0; }
.pl-param.sel { background: #e8e6df; }
.pl-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 5px color-mix(in oklab, var(--accent) 55%, transparent); flex-shrink: 0; }
.pl-param.byp .pl-dot { background: #2c2c30; box-shadow: none; }
.pl-param.sel .pl-dot { box-shadow: 0 0 6px var(--accent); }
.pl-pname { font-size: 8.5px; letter-spacing: 0.05em; text-transform: uppercase; color: rgba(244, 241, 234, 0.5); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pl-param.byp .pl-pname { color: rgba(244, 241, 234, 0.28); }
.pl-param.sel .pl-pname { color: #0a0a0b; font-weight: 600; }
.pl-tools { display: flex; gap: 6px; }
.pl-learn { flex: 1; display: grid; place-items: center; height: 22px; border: 0.5px solid rgba(244, 241, 234, 0.28); border-radius: 4px; font-size: 8.5px; letter-spacing: 0.18em; color: rgba(244, 241, 234, 0.6); }
.pl-trash { width: 22px; height: 22px; display: grid; place-items: center; border: 0.5px solid rgba(244, 241, 234, 0.14); border-radius: 4px; color: rgba(244, 241, 234, 0.4); }
.pl-trash svg { width: 12px; height: 12px; }
/* right lane — 16 step columns; the playhead brightens the active column */
.pl-lane { display: grid; grid-template-columns: repeat(16, 1fr); gap: 2px; align-items: stretch; min-height: 0; }
.pl-step { position: relative; display: flex; align-items: flex-end; background: #101012; border-radius: 2px; overflow: hidden; transition: background 0.1s linear; }
.pl-step.play { background: #33333a; }
.pl-bar { width: 100%; background: color-mix(in oklab, var(--accent) 46%, #101012); transition: filter 0.1s linear; }
.pl-bar.lock { background: var(--accent); box-shadow: 0 0 10px color-mix(in oklab, var(--accent) 45%, transparent); }
.pl-step.play .pl-bar { filter: brightness(1.2); }

/* PIANO ROLL — mirrors BAM's Composer (shared IComposerEditor): every
 * note is the CLIP colour (one hue per clip, no per-note hue variation)
 * with OPACITY driven by velocity (the app paints each note at
 * alpha = velocity), plus a darker right-edge length handle and a thin
 * black outline — no glow. The clip hue (--pr-note) is a real entry from
 * BAM's track-colour palette (bam/common/DSSequencer.h) — indigo #5C5CE5,
 * the same palette the clip-launcher/matrix draws from — a deliberate,
 * scoped exception to the site-wide lime accent, exactly like the matrix
 * panel: both depict an actual product surface. Committed dark in both
 * themes: the composer canvas is always black. */
.proll-vis { --pr-note: #5c5ce5; position: absolute; inset: 0; padding: 18px; display: flex; flex-direction: column; gap: 8px; z-index: 1; background: #0a0a0b; font-family: var(--mono); }
.pr-head { display: flex; justify-content: space-between; font-size: 9px; letter-spacing: 0.14em; text-transform: uppercase; color: rgba(244, 241, 234, 0.4); }
.pr-grid { flex: 1; position: relative; border: 0.5px solid rgba(244, 241, 234, 0.1); border-radius: 6px; overflow: hidden; background: #0c0c0e; }
.pr-row { display: grid; grid-template-columns: repeat(16, 1fr); height: calc(100% / 14); background: rgba(255, 255, 255, 0.03); }
.pr-row.black { background: transparent; }
.pr-cell { border-right: 0.5px solid rgba(255, 255, 255, 0.04); border-bottom: 0.5px solid rgba(255, 255, 255, 0.03); }
.pr-cell.beat { border-right-color: rgba(255, 255, 255, 0.10); }
.pr-note { position: absolute; background: var(--pr-note); border-radius: 3px; border: 0.5px solid rgba(0, 0, 0, 0.6); overflow: hidden; }
/* darker right-edge = the app's note "length handle" (clipColor.darker()) */
.pr-note::after { content: ""; position: absolute; top: 0; bottom: 0; right: 0; width: 5px; background: color-mix(in oklab, var(--pr-note) 48%, #0a0a0b); }

/* MIXER — mirrors BAM's mixer (PanelMixer / DSMeterItem): neutral-grey
 * channel strips with fixed green→yellow→red level meters. The app's
 * meter is a VU scale — green ≤ -6 dB, yellow -6..0, red 0..+6 (+6 = full
 * scale) — lit bottom-up by the signal; here the full scale lives in
 * .mx-bar::before at meter height (100cqh) and the bar's height clips it,
 * so a quiet channel reads all-green and a hot one tips into red. Faders
 * and labels are neutral white/grey — the real mixer carries NO track
 * colour (verified: PanelMixerTrack is entirely neutral). Committed dark
 * like the other product-surface panels. */
.mixer-vis { --vu-green: #2fcc4f; --vu-yellow: #ffd23b; --vu-red: #ff453a; position: absolute; inset: 0; padding: 14px 18px; display: flex; flex-direction: column; gap: 10px; z-index: 1; background: #0a0a0b; font-family: var(--mono); }
.mx-head { display: flex; justify-content: space-between; font-size: 9px; letter-spacing: 0.14em; text-transform: uppercase; color: rgba(244, 241, 234, 0.4); }
.mx-bpm { color: rgba(244, 241, 234, 0.6); }
.mx-strips { flex: 1; display: flex; align-items: flex-end; gap: 6px; padding: 6px 0; }
.mx-strip { flex: 1; display: flex; flex-direction: column; align-items: stretch; gap: 6px; height: 100%; justify-content: flex-end; position: relative; min-width: 0; }
.mx-meter { flex: 1; position: relative; overflow: hidden; container-type: size; border: 0.5px solid rgba(244, 241, 234, 0.1); border-radius: 3px; background: linear-gradient(180deg, #222126, #191719); min-height: 60px; }
/* the lit portion clips a full-height VU scale, so colour tracks level */
.mx-bar { position: absolute; left: 0; right: 0; bottom: 0; overflow: hidden; transition: height 0.08s linear; }
.mx-bar::before { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 100cqh; background: linear-gradient(to top, var(--vu-green) 0 63%, var(--vu-yellow) 63% 79%, var(--vu-red) 79% 100%); }
.mx-fader { position: relative; height: 30px; background: rgba(255, 255, 255, 0.03); border: 0.5px solid rgba(244, 241, 234, 0.1); border-radius: 3px; }
.mx-cap { position: absolute; left: -2px; right: -2px; height: 4px; background: #e8e6df; border-radius: 2px; }
.mx-lbl { font-size: 7.5px; letter-spacing: 0.06em; color: rgba(244, 241, 234, 0.4); text-align: center; }
.mx-divider { width: 0.5px; background: rgba(244, 241, 234, 0.14); align-self: stretch; margin: 0 4px; }
.mx-master { flex: 1.6; display: flex; flex-direction: row; gap: 3px; align-items: flex-end; }
.mx-master .mx-meter { flex: 1; min-height: 0; height: 100%; }
.mx-mlbl { position: absolute; bottom: -2px; left: 0; right: 0; color: rgba(244, 241, 234, 0.6); font-weight: 500; }

/* FX RACK */
.fxr-vis { position: absolute; inset: 0; padding: 18px; display: flex; flex-direction: column; gap: 10px; z-index: 1; }
.fxr-head { display: flex; justify-content: space-between; font-family: var(--mono); font-size: 9px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--fg-faint); }
.fxr-rows { flex: 1; display: flex; flex-direction: column; gap: 8px; }
.fxr-row { flex: 1; display: flex; align-items: center; gap: 8px; padding: 10px 14px; border: 0.5px solid var(--line); border-radius: 9px; background: rgba(255, 255, 255, 0.02); font-family: var(--mono); font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--fg-dim); position: relative; overflow: hidden; flex-wrap: wrap; }
.fxr-lbl { flex-shrink: 0; color: var(--fg); font-weight: 500; }
.fxr-lbl.out { color: var(--accent); }
.fxr-arrow { color: var(--fg-faint); flex-shrink: 0; }
.fxr-chip { padding: 6px 10px; border: 0.5px solid var(--line-strong); border-radius: 6px; background: rgba(0, 0, 0, 0.3); font-size: 9.5px; letter-spacing: 0.12em; color: var(--fg-dim); white-space: nowrap; }
.fxr-chip.on { border-color: var(--accent); background: color-mix(in oklab, var(--accent) 12%, transparent); color: var(--accent); box-shadow: 0 0 12px color-mix(in oklab, var(--accent) 30%, transparent); }
.fxr-chip.alt { border-color: color-mix(in oklab, var(--accent-2) 60%, var(--line-strong)); background: color-mix(in oklab, var(--accent-2) 10%, transparent); color: var(--accent-2); }
.fxr-pct { margin-left: auto; color: var(--accent); font-size: 10px; }
.fxr-row.send { background: color-mix(in oklab, var(--accent-2) 4%, transparent); }
.fxr-row.send .fxr-lbl { color: var(--accent-2); }

/* ============================================================
 * TRAILER — 21:9 frame wrapping the +ytPoster click-to-play.
 * ============================================================ */
.trailer { position: relative; border: 0.5px solid var(--line); border-radius: 18px; background: var(--card); overflow: hidden; }

/* ============================================================
 * WORKFLOW — feature mosaic
 * ============================================================ */
.feats { display: grid; grid-template-columns: repeat(12, 1fr); gap: 18px; }
@media (max-width: 1000px) { .feats { grid-template-columns: 1fr; } }
.feat { position: relative; border: 0.5px solid var(--line); border-radius: 18px; background: var(--card); overflow: hidden; display: flex; flex-direction: column; transition: border-color 0.25s ease, transform 0.25s ease; }
.feat:hover { border-color: var(--line-strong); }
.feat .visual { position: relative; aspect-ratio: 5 / 3; border-bottom: 0.5px solid var(--line); overflow: hidden; background: radial-gradient(circle at 50% 50%, var(--card-2), var(--bg) 75%); }
/* Real screenshot (opt-in via `image`): drop the fixed ratio and follow the
   image's own proportions so nothing is cropped. */
.feat .visual.has-img { aspect-ratio: auto; }
.feat .visual .feat-img { display: block; width: 100%; height: auto; }
.feat .body { padding: 28px 32px 32px; display: flex; flex-direction: column; gap: 12px; flex: 1; }
.feat .ovr { font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--fg-faint); }
.feat h3 { font-family: var(--display); font-weight: 500; font-size: 30px; letter-spacing: -0.02em; line-height: 1.05; margin: 0; text-wrap: balance; }
.feat h3 em { font-family: var(--serif); font-style: italic; font-weight: 400; color: var(--accent); }
.feat p { margin: 0; color: var(--fg-dim); font-size: 14.5px; line-height: 1.55; text-wrap: pretty; max-width: 48ch; }
.feat .tagrow { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.feat .tagrow span { font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em; color: var(--fg-dim); padding: 3px 8px; border: 0.5px solid var(--line); border-radius: 999px; }
.span-7 { grid-column: span 7; }
.span-5 { grid-column: span 5; }
.span-12 { grid-column: span 12; }
.span-6 { grid-column: span 6; }
@media (max-width: 1000px) { .span-7, .span-5, .span-12, .span-6 { grid-column: span 1; } }
/* The fxchain tile forces an ultra-wide 24/7 visual (inline style in bam.pug).
   Once the mosaic is single-column that box gets far too short (~96px at phone
   width) for the insert chain, whose chips wrap to ~250px — the content spills
   out (and on iOS Safari an aspect-ratio box doesn't clip absolute children, so
   it overlaps the next section). Drop the fixed ratio here and let the visual
   grow to its content: un-absolute the demo so it contributes height. */
@media (max-width: 1000px) {
  .feat .visual[style*="24/7"] { aspect-ratio: auto !important; }
  .feat .visual[style*="24/7"] .fxr-vis { position: static; }
}

/* Full feature list — migrated to the shared #features section
 * (.specs-list in public/style.css); the old .feat-list is gone. */

/* ============================================================
 * SOUND
 * ============================================================ */
.sound-shell { display: grid; grid-template-columns: 1.5fr 1fr; gap: 24px; align-items: stretch; }
@media (max-width: 1000px) { .sound-shell { grid-template-columns: 1fr; } }
.eng-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
@media (max-width: 560px) { .eng-grid { grid-template-columns: repeat(2, 1fr); } }
.eng-card { border: 0.5px solid var(--line); border-radius: 12px; background: var(--card); padding: 18px 16px; display: flex; flex-direction: column; gap: 5px; transition: border-color 0.2s ease, transform 0.2s ease; }
.eng-card:hover { border-color: var(--accent); transform: translateY(-2px); }
.eng-name { font-family: var(--display); font-weight: 500; font-size: 16px; letter-spacing: -0.01em; color: var(--fg); }
.eng-note { font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--fg-faint); line-height: 1.4; }
.sound-side { border: 0.5px solid var(--line); border-radius: 18px; background: linear-gradient(135deg, color-mix(in oklab, var(--accent) 7%, var(--card)), var(--card)); padding: 32px; display: flex; flex-direction: column; gap: 18px; }
.sound-stat { display: flex; flex-direction: column; gap: 6px; }
.sound-stat .num { font-family: var(--display); font-weight: 500; font-size: 64px; line-height: 0.9; letter-spacing: -0.03em; color: var(--fg); }
.sound-stat .num em { font-family: var(--serif); font-style: italic; font-weight: 400; color: var(--accent); }
.sound-stat .lbl { font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--fg-faint); max-width: 24ch; }
.sound-side p { margin: 0; color: var(--fg-dim); font-size: 14px; line-height: 1.55; text-wrap: pretty; flex: 1; }
.sound-side .btn { align-self: flex-start; }
.sound-side .btn.ghost { padding: 0; height: auto; color: var(--fg-dim); font-size: 13px; }
.sound-side .btn.ghost:hover { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }

/* ============================================================
 * AUDIO + MIDI — hybrid clip
 * ============================================================ */
.hybrid-shell { display: grid; grid-template-columns: 1.15fr 1fr; gap: 32px; align-items: center; }
@media (max-width: 1000px) { .hybrid-shell { grid-template-columns: 1fr; gap: 28px; } }
.hybrid-vis-wrap { position: relative; aspect-ratio: 16 / 10; border-radius: 18px; border: 0.5px solid var(--line-strong); overflow: hidden; background: radial-gradient(circle at 50% 20%, #1d140e 0%, #0c0807 75%); box-shadow: 0 30px 80px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.04); }
.hybrid-copy h3 { font-family: var(--display); font-weight: 500; font-size: clamp(30px, 3.4vw, 46px); line-height: 1.02; letter-spacing: -0.025em; margin: 0 0 16px; text-wrap: balance; }
.hybrid-copy h3 em { font-family: var(--serif); font-style: italic; font-weight: 400; color: var(--accent); }
.hybrid-copy p { margin: 0 0 14px; color: var(--fg-dim); font-size: 15px; line-height: 1.6; text-wrap: pretty; max-width: 46ch; }
.hybrid-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 18px; }
.hybrid-tags span { font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em; color: var(--fg-dim); padding: 4px 9px; border: 0.5px solid var(--line); border-radius: 999px; }
.hybrid-vis { position: absolute; inset: 0; padding: 18px; display: flex; flex-direction: column; gap: 10px; z-index: 1; }
.hy-head, .hy-foot { display: flex; justify-content: space-between; font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--fg-faint); }
.hy-head { color: var(--fg); }
.hy-bpm { color: var(--accent); }
.hy-foot span:first-child { color: var(--accent); }
.hy-lanes { flex: 1; position: relative; display: flex; flex-direction: column; gap: 10px; }
.hy-lane { flex: 1; position: relative; border: 0.5px solid var(--line); border-radius: 9px; background: rgba(0, 0, 0, 0.25); padding: 10px 12px; overflow: hidden; }
.hy-tag { position: absolute; top: 8px; left: 10px; font-family: var(--mono); font-size: 8px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--fg-faint); z-index: 2; }
.hy-audio .hy-tag { color: var(--accent-2); }
.hy-midi .hy-tag { color: var(--accent); }
.hy-wave { position: absolute; inset: 18px 12px 10px; display: flex; align-items: center; gap: 2px; }
.hy-bar { flex: 1; background: color-mix(in oklab, var(--accent-2) 45%, transparent); border-radius: 1px; min-height: 2px; transition: background 0.12s linear; }
.hy-bar.live { background: var(--accent-2); box-shadow: 0 0 8px color-mix(in oklab, var(--accent-2) 60%, transparent); }
.hy-roll { position: absolute; inset: 18px 12px 8px; }
.hy-note { position: absolute; background: var(--accent); border-radius: 3px; box-shadow: 0 0 10px color-mix(in oklab, var(--accent) 40%, transparent); border: 0.5px solid color-mix(in oklab, var(--accent) 80%, white); }
.hy-playhead { position: absolute; top: 0; bottom: 0; width: 1.5px; background: var(--fg); box-shadow: 0 0 12px var(--fg); opacity: 0.7; z-index: 3; }

/* ============================================================
 * PLAY & PERFORM — controllers
 * ============================================================ */
.ctrl-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 8px; }
.ctrl-pill { display: flex; align-items: center; gap: 10px; padding: 14px 18px; border: 0.5px solid var(--line); border-radius: 12px; background: var(--card); font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em; color: var(--fg-dim); transition: border-color 0.2s ease, color 0.2s ease, transform 0.2s ease; }
.ctrl-pill:hover { border-color: var(--accent); color: var(--fg); transform: translateY(-2px); }
.ctrl-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 8px var(--accent); flex-shrink: 0; }
.ctrl-strip { margin-top: 18px; padding: 18px 24px; border: 0.5px dashed var(--line); border-radius: 12px; font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em; color: var(--fg-faint); display: flex; gap: 18px; flex-wrap: wrap; justify-content: space-between; }

/* ============================================================
 * RUNS EVERYWHERE — platform matrix
 * ============================================================ */
.plat-matrix { border: 0.5px solid var(--line); border-radius: 16px; background: var(--card); overflow: hidden; }
.pm-head, .pm-row { display: grid; grid-template-columns: 1.1fr 0.9fr 1.7fr 0.9fr 0.8fr; align-items: center; gap: 12px; padding: 16px 24px; }
.pm-head { font-family: var(--mono); font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--fg-faint); border-bottom: 0.5px solid var(--line); background: color-mix(in oklab, var(--fg) 3%, transparent); }
.pm-row { border-bottom: 0.5px solid var(--line); transition: background 0.2s ease; }
.pm-row:last-child { border-bottom: 0; }
.pm-row:hover { background: color-mix(in oklab, var(--accent) 5%, transparent); }
.pm-row.new { background: color-mix(in oklab, var(--accent) 7%, transparent); }
.pm-os { font-family: var(--display); font-weight: 500; font-size: 19px; letter-spacing: -0.01em; color: var(--fg); display: flex; align-items: center; gap: 8px; }
.pm-new { font-style: normal; font-family: var(--mono); font-size: 8.5px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent-ink); background: var(--accent); padding: 2px 6px; border-radius: 999px; }
.pm-yes { font-family: var(--display); color: var(--accent); font-size: 16px; }
.pm-fmt { font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em; color: var(--fg-dim); text-transform: uppercase; }
.pm-min, .pm-disk { font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em; color: var(--fg-faint); text-transform: uppercase; }
@media (max-width: 760px) {
  .pm-head { display: none; }
  .pm-row { grid-template-columns: 1fr 1fr; gap: 6px 12px; padding: 18px 20px; }
  .pm-os { grid-column: 1 / -1; font-size: 22px; margin-bottom: 4px; }
  .pm-fmt { grid-column: 1 / -1; }
}
.plat-notes { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-top: 18px; }
@media (max-width: 900px) { .plat-notes { grid-template-columns: 1fr; } }
.pn-note { border: 0.5px solid var(--line); border-radius: 14px; background: var(--card); padding: 24px; display: flex; flex-direction: column; gap: 10px; }
.pn-note .mono { font-family: var(--mono); font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent); }
.pn-note p { margin: 0; color: var(--fg-dim); font-size: 13.5px; line-height: 1.55; text-wrap: pretty; }
.pn-note p b { color: var(--fg); font-weight: 500; }

/* ============================================================
 * AUDIO DEMOS — the `.audio-*` / `.sc-frame` shell is now the shared
 * canonical block in public/style.css (Product "Audio demos"
 * section); BAM uses it unchanged via +productAudioDemos. Only the
 * BAM-specific `.artist-quote` panel below the embed stays here.
 * ============================================================ */
.artist-quote { margin-top: 48px; padding: 36px 40px; border: 0.5px solid var(--line); border-radius: 18px; background: linear-gradient(135deg, color-mix(in oklab, var(--accent) 6%, var(--card)), var(--card)); }
.artist-quote .aq-mark { font-family: var(--serif); font-size: 64px; line-height: 0; color: var(--accent); display: block; height: 30px; }
.artist-quote .aq-body { font-family: var(--serif); font-style: italic; font-size: clamp(22px, 2.4vw, 30px); line-height: 1.3; margin: 0 0 14px; color: var(--fg); text-wrap: balance; max-width: 60ch; }
.artist-quote .aq-by { font-family: var(--mono); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--fg-faint); }
.artist-quote .aq-by b { color: var(--accent); font-weight: 500; }
@media (max-width: 900px) { .tut-grid { grid-template-columns: 1fr; } }

/* Expansion packs section is now the shared +productExpansions mixin —
 * styles live in public/style.css (.exp / .exp-grid / .exp-see-all). */

/* ============================================================
 * REQUIREMENTS
 * ============================================================ */
.req-grid { gap: 0; }
.req-grid .req { padding: 28px; }
.req-grid .req:last-child { border-right: 0; }
.req-grid .req h5 { font-size: 18px; }
.req-grid .req p { font-size: 13.5px; }
@media (max-width: 520px) {
  .req-grid .req { border-right: 0; }
}

/* HELP section (.help-grid / .hcard) is now shared — see /style.css. */
