/* ═══════════════════════════════════════════════════════════════════════════
   SONO XR — DESIGN SYSTEM v1 · THE SHOWCASE SURFACE
   Phase 1 (2026-08-04). Loads LAST. Everything the layers above assert about
   colour, type, elevation and motion is answered here.

   The interface is the darkened room. The space is the only lit thing in it.

   Four jobs:
     1. Retire the Tron base that css/style.css still ships to this page
     2. The grain layer
     3. The slate — the one permanent brand element
     4. Chrome on intent + the media frame
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 0. THE ONE TOKEN COLLISION ─────────────────────────────────────────────
   css/style.css declares `--accent: #ff0055` (Tron grid-red) at :root, and it
   loads AFTER css/sono-tokens.css — same specificity, later wins. Without this
   line the product accent silently becomes red. Re-asserted here rather than
   reordering the links, because the token file is meant to load first.
   Keep in sync with css/sono-tokens.css. */
:root { --accent: #B08D57; }

/* ── 1. THE TRON BASE STANDS DOWN ───────────────────────────────────────────
   style.css is shared with the marketing site, so it is not edited here — its
   design variables are re-pointed at the system instead. This is what keeps
   cyan, orange, neon-red and Orbitron/Rajdhani off the showcase even though
   hundreds of untouched style.css rules still reference them. */
body {
  --primary:                #B08D57;
  --primary-glow:           transparent;
  --secondary:              var(--accent);
  --secondary-glow:         transparent;
  --accent-glow:            transparent;
  --success-glow:           transparent;

  --bg-dark:                var(--ground-00);
  --bg-panel:               var(--ground-02);
  --bg-panel-solid:         var(--ground-01);
  --bg-panel-light:         var(--ground-01);

  --text-primary:           var(--ink-primary);
  --text-muted:             var(--ink-secondary);
  --text-dim:               var(--ink-tertiary);

  --border-glass:           transparent;
  --border-neon-primary:    transparent;
  --border-neon-secondary:  transparent;

  --font-title:             var(--font-display);
  --font-tech:              var(--font-screen);
  --font-body:              var(--font-screen);
  --font-mono:              var(--font-screen);

  --transition-fast:        var(--dur-press) var(--ease-out);
  --transition-normal:      var(--dur-tooltip) var(--ease-out);
  --transition-slow:        var(--dur-sheet) var(--ease-out);

  background: var(--ground-00);
  color: var(--ink-primary);
  font-family: var(--font-screen);
}

/* Nothing in this product glows, and no surface is pure black or pure white.
   These sweep up the literal values still sitting in untouched style.css
   rules that reach showcase elements. */
.showcase-container [class*="glow"],
.glow-cyan, .glow-text-cyan, .glow-text-orange { text-shadow: none; box-shadow: none; }

/* ── 2. TYPE ────────────────────────────────────────────────────────────────
   Six roles, one uppercase role (the slate). The display face carries the
   space's name; everything operational is the screen face. */
.splash-title,
.sxr-welcome h1,
.sxr-cine h1 {
  font-family: var(--font-display);
  font-weight: 300;
  letter-spacing: -0.03em;
  line-height: 0.92;
  text-transform: none;
  color: var(--ink-primary);
  /* the sheen gradient is gone — see .sxr-title-cine below */
  -webkit-text-fill-color: currentColor;
}
/* `display`, not `display-xl`. The entry title sits inside a card, not across
   the viewport — at 88px a four-word showcase name wraps to four lines in a
   650px box. display-xl is reserved for type that owns the full width. */
.splash-title { font-size: clamp(1.9rem, 4vw, 3.5rem); letter-spacing: -0.025em; line-height: 0.95; }
.splash-content { max-width: 760px !important; }
.sxr-welcome h1, .sxr-cine h1 { font-size: clamp(1.9rem, 4vw, 3.5rem); letter-spacing: -0.025em; line-height: 0.95; }

.sxr-overview h2, .sxr-local-panel h3, .sxa-head h3, .sxr-card h3, .sxr-rail-panel h5 {
  font-family: var(--font-screen);
  font-size: 1.75rem; font-weight: 400;
  letter-spacing: -0.015em; line-height: 1.10;
  text-transform: none; color: var(--ink-primary);
}
.sxr-pres-line {
  font-family: var(--font-display); font-weight: 300;
  letter-spacing: -0.025em; line-height: 0.95;
  font-size: clamp(1.9rem, 4vw, 3.5rem);
}

/* The living title sheen was a gradient on text. Both are on the kill list. */
.sxr-title-cine { background: none; animation: none; -webkit-text-fill-color: currentColor; }

/* Operational chrome — dock, rail, menus, buttons, labels — is sentence case
   at the caption size. Uppercase belongs to the slate alone. */
.sxr-mod, .sxr-rail-btn, .sxr-tm-item, .sxr-scene, .sxr-btn, .sxr-surface,
.sxr-frame-label, .sxr-gal-title, .sxr-back-pill, .sxr-fs-exit, .sxr-pres-next,
.sxr-pres-exit, .sxr-lead-pill, .rp-lbl, .rp-chip, .sxr-card label, .ov-badge,
.badge-tech, .sxa-act, .sxr-chip, .btn-cyber, #enter-experience-btn,
.sxr-billing .bb-line, .sxr-billing .bb-k, .splash-meta, .sxr-overview h4,
.sxr-cine .c-kicker, .sxa-kicker, .rp-sub, .sxr-brandrow .br-id b,
.hud-header-panel h1, .sxr-audio-pill .ap-txt b, .sxr-audio-pill .ap-state,
.sxr-poweredby, .sxr-brand-name, .sxr-cine .c-hll li, .sxr-cine .c-prod,
.sxr-cine .c-cred .c-nm, .sxr-local-panel h3, .sxr-welcome .w-sub {
  font-family: var(--font-screen);
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none !important;
}
.sxr-mod, .sxr-rail-btn { font-size: 0.8125rem; }

/* the price / sub-line is caption weight — it must not outrank the name */
.splash-price { font-size: 1rem !important; color: var(--ink-secondary) !important; }
.sxr-billing { color: var(--ink-tertiary); }
.sxr-billing .bb-line, .sxr-billing .bb-k { font-size: 0.8125rem; color: var(--ink-tertiary); }

/* ── 3. SURFACES ────────────────────────────────────────────────────────────
   Elevation is a luminance step. No borders, no shadows, no glass over media. */
.hud-header-panel, .sidebar-panel-interactive, .hud-controls-panel,
.splash-content-box, .sxr-dock, .sxr-rail, .sxr-rail-panel, .sxr-grp-menu,
.sxr-title-menu, .sxr-card, .sxr-settings-pop, .sxr-audio-pill,
.sxr-audio-panel, .sxr-local-panel, .sxr-step, .sxr-scenes {
  background: var(--ground-01) !important;
  border: 0 !important;
  border-radius: var(--radius) !important;
  box-shadow: none !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}
.sxr-grp-menu::after { display: none; }   /* connector notch — decoration */

/* the entry card is the one sheet that sits over moving media, so it steps up
   rather than going transparent */
.splash-content-box { background: var(--ground-02) !important; padding: var(--s-6) var(--s-7) !important; }

/* buttons: the primary action is a light field, everything else is a step */
.sxr-btn-primary, .sxr-lead-pill, .sxr-pres-next, #enter-experience-btn,
.btn-cyber.btn-solid, .rp-row button {
  background: var(--ink-primary) !important;
  color: var(--ground-00) !important;
  border: 0 !important;
  border-radius: var(--radius) !important;
  box-shadow: none !important;
  padding: 14px 28px !important;
  font-weight: 400;
}
.sxr-btn-ghost, .btn-cyber:not(.btn-solid), .sxr-surface, .rp-zoom button, .sxa-x {
  background: var(--ground-02) !important;
  color: var(--ink-primary) !important;
  border: 0 !important;
  border-radius: var(--radius) !important;
}
.sxr-btn-primary:hover, .sxr-lead-pill:hover, .sxr-pres-next:hover,
#enter-experience-btn:hover { transform: none !important; background: var(--ink-secondary) !important; }

/* form fields keep a boundary — a field with no edge is not a field. It is a
   luminance step, not a hairline. */
.sxr-card input, .sxr-card select, .sxr-card textarea, .rp-row input, .rp-row textarea {
  background: var(--ground-02) !important;
  border: 0 !important;
  border-radius: var(--radius) !important;
  color: var(--ink-primary);
}
.sxr-card input:focus, .sxr-card select:focus, .sxr-card textarea:focus,
.rp-row input:focus, .rp-row textarea:focus {
  outline: 1px solid var(--accent); outline-offset: 0;
}

/* avatars are 2px like everything else — there are no circles in this product */
.sxr-ov-broker .av, .rp-broker .av, .sxr-brandrow .br-av, .sxr-cine .c-cred .av {
  border-radius: var(--radius) !important; border: 0 !important;
}

/* chips, pills and badges are retired. What they carried was a label; a label
   is caption-sized ink on the ground it already sits on. */
.badge-tech, .ov-badge, .sxr-chip, .rp-chip, .sxa-chip, .sxr-frame-label,
.sxr-gal-title, .sxr-billing .bb-prod {
  background: transparent !important;
  border: 0 !important;
  border-radius: 0 !important;
  padding: 0 !important;
  color: var(--ink-secondary) !important;
  font-size: 0.8125rem; font-weight: 400; letter-spacing: 0; text-transform: none;
}
.badge-tech .dot, .sxr-tier-dot, .sxa-dot { display: none !important; }
.sxr-chip { margin-right: var(--s-4); }
.sxr-chip b { color: var(--ink-primary); font-weight: 400; }

/* ── 4. THE GRAIN LAYER ─────────────────────────────────────────────────────
   One static layer over media AND chrome, so the two read as one image. It
   kills banding in the near-blacks. If it is consciously visible, reduce it. */
.sono-grain {
  position: fixed; inset: 0; z-index: 99999; pointer-events: none;
  opacity: 0.025;
  filter: url(#sono-grain) contrast(170%) brightness(1000%);
}

/* ── 5. THE SLATE ───────────────────────────────────────────────────────────
   The one permanent brand element. Bottom-left, always visible, and the only
   thing on screen that never fades with the rest of the chrome.

   Because it never leaves, it gets a reserved band at the foot of the screen
   that no other chrome may enter. Everything in the bottom stack — the dock,
   the gallery strip, the white-label mark — is lifted clear of it here, from
   one variable, rather than by hand-tuned offsets that drift apart. */
:root { --sono-slate-band: 46px; }

.sxr-dock-wrap { padding-bottom: var(--sono-slate-band) !important; }
.sxr-gal-strip { bottom: var(--sono-slate-band) !important; }

/* On a phone the bottom stack (dock → rail → audio pill → brand) is positioned
   off --sxr-dock-band, so the slate's band is added THERE rather than as dock
   padding. Padding alone lifted the dock's buttons into the rail above it —
   the stack has one source of truth and this has to go through it. */
@media (max-width: 768px) {
  :root { --sxr-dock-band: calc(74px + var(--sono-slate-band)); }
  .sxr-dock-wrap { padding-bottom: calc(var(--sono-slate-band) + 10px) !important; }
}

/* The white-label brand mark and the slate both wanted the bottom-left corner.
   The slate is the permanent element, so the client's mark takes the opposite
   corner — where it still reads as the owner of the showcase. */
/* Desktop only. On a phone the brand mark already has a reserved slot in the
   bottom stack (showcase-stage.css, MOBILE LAYOUT PASS) well above the slate,
   and moving it into this corner would drop it on top of the rail. */
@media (min-width: 769px) {
  .sxr-brand-slot {
    left: auto !important; right: var(--s-4) !important;
    /* clears the exit control, which also lives in this corner */
    bottom: calc(var(--sono-slate-band) + var(--s-5)) !important;
  }
}
/* ⚠ assets/sxr-logo.png is still the cyan-violet gradient mark — an image, so
   CSS cannot fix it properly. Rendered monochrome here so the loudest thing on
   screen is not the logo. A real single-colour mark should replace the asset;
   this is a stopgap, not the answer. */
.sxr-brand-slot img, .sxr-brandrow .br-pow img {
  filter: grayscale(1) brightness(1.7) opacity(0.45);
}

.sono-slate {
  /* above every panel, sheet and overlay in the product — including the entry
     splash (9999) and the Audio Hub (10050). Only the grain sits over it.
     "Always visible" has to mean during the entry state too. */
  position: fixed; left: var(--s-4); bottom: var(--s-4); z-index: 10060;
  pointer-events: none; color: var(--ink-tertiary);
  /* It holds one line wherever one line fits and wraps where it does not.
     No breakpoint decides this — the slate's length is the showcase's, and a
     long title on a wide screen needs the same behaviour as a short one on a
     phone. Truncating was the wrong answer: the capture credit is the point
     of the thing, and it is last.

     Bounded by left AND right rather than a 100vw max-width: on a fixed
     element that constrains the box itself, so it cannot overrun the viewport
     no matter how the layout viewport is reported. */
  right: var(--s-4);
  overflow-wrap: break-word;
}
/* "Always visible" has to survive a white floor plan as well as a night
   exterior. The slate carries its own scrim — a soft wedge that fades up and
   to the right, so it reads on any media without putting a band across the
   bottom of the frame. Legibility, like the presenter scrim; not decoration. */
.sono-slate::before {
  content: ''; position: absolute; z-index: -1;
  left: calc(var(--s-4) * -1); right: 34%;
  top: calc(var(--s-4) * -1); bottom: calc(var(--s-4) * -1);
  background: linear-gradient(to top right, rgba(11,10,9,0.78), rgba(11,10,9,0) 72%);
}
.sono-slate .sl-sep { margin: 0 var(--s-2); opacity: 0.55; }
@media (max-width: 768px) {
  .sono-slate {
    left: var(--s-3); right: var(--s-3); bottom: var(--s-2);
    font-size: 0.625rem; letter-spacing: 0.12em;
  }
  .sono-slate .sl-sep { margin: 0 var(--s-1); }
}

/* ── 6. CHROME ON INTENT ────────────────────────────────────────────────────
   At rest the visitor sees the media, the slate, and nothing else.
   The slate is deliberately absent from this list. So is .sxr-pres — during a
   guided beat the line and its forward action ARE the content, and fading them
   would strand the viewer with no way on. */
.showcase-hud-header, .sxr-dock-wrap, .sxr-rail, .sxr-rail-panel,
.sxr-audio-pill, .sxr-settings-btn, .sxr-settings-pop, .sxr-lead-pill,
.sxr-brand-slot, .sxr-exit, .sxr-back-pill, .sxr-fs-exit, .sxr-frame-label,
.sxr-gal-strip, .sxr-gal-title, .sxr-scenes, .sxr-narr {
  transition: opacity var(--dur-chrome) var(--ease-out);
}
body.sono-idle .showcase-hud-header, body.sono-idle .sxr-dock-wrap,
body.sono-idle .sxr-rail, body.sono-idle .sxr-rail-panel,
body.sono-idle .sxr-audio-pill, body.sono-idle .sxr-settings-btn,
body.sono-idle .sxr-settings-pop, body.sono-idle .sxr-lead-pill,
body.sono-idle .sxr-brand-slot, body.sono-idle .sxr-exit,
body.sono-idle .sxr-back-pill, body.sono-idle .sxr-fs-exit,
body.sono-idle .sxr-frame-label, body.sono-idle .sxr-gal-strip,
body.sono-idle .sxr-gal-title, body.sono-idle .sxr-scenes, body.sono-idle .sxr-narr {
  opacity: 0; pointer-events: none;
}
/* returning is faster than leaving — intent should feel answered, not waited on */
body:not(.sono-idle) .showcase-hud-header, body:not(.sono-idle) .sxr-dock-wrap,
body:not(.sono-idle) .sxr-rail, body:not(.sono-idle) .sxr-audio-pill,
body:not(.sono-idle) .sxr-settings-btn, body:not(.sono-idle) .sxr-lead-pill,
body:not(.sono-idle) .sxr-brand-slot, body:not(.sono-idle) .sxr-exit {
  transition-duration: 200ms;
}

/* Kiosk exception: with no hover there is nothing to detect, so chrome stays. */
@media (hover: none) {
  body.sono-idle .showcase-hud-header, body.sono-idle .sxr-dock-wrap,
  body.sono-idle .sxr-rail, body.sono-idle .sxr-audio-pill,
  body.sono-idle .sxr-settings-btn, body.sono-idle .sxr-lead-pill,
  body.sono-idle .sxr-brand-slot, body.sono-idle .sxr-exit,
  body.sono-idle .sxr-gal-strip, body.sono-idle .sxr-gal-title,
  body.sono-idle .sxr-frame-label, body.sono-idle .sxr-scenes {
    opacity: 1; pointer-events: auto;
  }
}

/* every hover affordance is gated — a touch device must never inherit one */
@media (hover: hover) and (pointer: fine) {
  .sxr-mod:hover, .sxr-rail-btn:hover, .sxr-tm-item:hover, .sxr-scene:hover {
    background: var(--ground-02); color: var(--ink-primary);
  }
}

/* ── 7. THE FRAME ───────────────────────────────────────────────────────────
   Media fills the stage. Where a module's asset has its own aspect it is
   contained to the frame and the overflow is cropped — never letterboxed into
   a centre column with dead ground either side. */
#sxr-stage .sxr-stage-inner { left: 0; right: 0; top: 0; bottom: 0; }

.sxr-frame, .sxr-gal-main, .sxr-vgal-main, .sxr-pano-stage, .sxr-plan-stage {
  border-radius: 0 !important;
  border: 0 !important;
  box-shadow: none !important;
  background-color: var(--ground-00);
}
.sxr-frame video, .sxr-frame img, .sxr-frame .sxr-frame-img,
.sxr-vgal-main { object-fit: cover; width: 100%; height: 100%; }
.sxr-frame .sxr-frame-img { position: absolute; inset: 0; background-size: cover; background-position: center; }

/* The gallery and video stages used to stop 96px short so the thumbnail strip
   had a lane of its own. Now that the strip is chrome and fades on idle, that
   lane became a window onto whichever view is mounted behind — a band of the
   3D tour showing under the photograph. The media fills the stage and the
   strip floats over it, which is also what "media fills the stage" asks for. */
.sxr-gal-main, .sxr-vgal-main { inset: 0 !important; height: 100% !important; }
.sxr-gal-main { background-size: cover; background-position: center; }
.sxr-gal-strip { z-index: 2; padding: 0 var(--s-3) var(--s-3); box-sizing: border-box; }
/* the caption sits above the strip, not behind it */
.sxr-gal-title { bottom: calc(var(--sono-slate-band) + 96px) !important; left: var(--s-3) !important; }
.sxr-gal-thumb { border-radius: var(--radius); border: 0; }
.sxr-gal-thumb.active { opacity: 1; outline: 1px solid var(--accent); outline-offset: -1px; }

/* the entry visual and the ambient world both fill the viewport */
.splash-background-video, #splat-bg { object-fit: cover; width: 100%; height: 100%; }

/* HERO FRAME — the establishing visual sits in a 2.39:1 window with ground
   outside it, identically on every module. This is the shape the product is
   composed in; it is what makes a showcase read as one film rather than a
   sequence of differently-shaped boxes. */
.sono-hero-frame {
  position: absolute; left: 0; right: 0; top: 50%; transform: translateY(-50%);
  aspect-ratio: 2.39 / 1; max-height: 100%; overflow: hidden;
  background: var(--ground-00);
}

/* ── 8. MOTION ──────────────────────────────────────────────────────────────
   Nothing on a pointer-touched element runs longer than 300ms, and the
   uniform fade-in-on-scroll is gone entirely. */
.sxr-cine .k, .sxr-cine section.on .k { opacity: 1; transform: none; transition: none; }
.sxr-cine h1 .kw, .sxr-cine section.on h1 .kw, .sxr-welcome h1 .kw { opacity: 1; transform: none; animation: none; }
.sxr-billing, .sxr-brandrow, .sxr-step, .splash-content-box .badge-tech,
#enter-experience-btn, .sxr-welcome .w-sub, .sxr-welcome .sxr-cta-row { animation: none !important; }
.splash-background-video { animation: none !important; }   /* Ken Burns drift */
.sxr-cine .c-scroll { animation: none; }

@media (prefers-reduced-motion: reduce) {
  /* colour and opacity survive; transform motion does not */
  *, *::before, *::after {
    animation: none !important;
    transition-property: opacity, color, background-color, border-color, outline-color !important;
    transition-duration: var(--dur-chrome) !important;
  }
  .sono-grain { opacity: 0.02; }
}
