/* ==========================================================================
   WE ARE ONE VOICE — shared stylesheet
   Visual direction: AURORA COMMAND GLASS
   Structural DNA locked from CSS-LOCK.md — do not redecide layout skeleton
   here, only the visual execution (glass, aurora light, glow-rings, elevation)
   ========================================================================== */

/* ---------- reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }
img { max-width: 100%; display: block; }
img, video, canvas, svg { max-width: 100%; height: auto; }
h1, h2, h3, h4, p { margin: 0; }

/* ---------- mobile/touch device baseline (site-wide, all 19 live pages) ----------
   Centralized here so every page inherits it from the one shared stylesheet,
   instead of each page re-declaring its own copy. */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
* { -webkit-tap-highlight-color: transparent; }

/* ---------- registered custom properties (needed for animatable --angle) ---------- */
@property --angle {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}

/* ---------- design tokens ---------- */
:root {
  /* palette — VRChat-matched charcoal + electric cyan-teal, locked in CSS-LOCK.md */
  --bg-void: #07090d;
  --bg-void-rgb: 7, 9, 13;
  --bg-panel: #171d27;
  --bg-panel-rgb: 23, 29, 39;
  --bg-panel-raised: #1e2632;
  --bg-panel-raised-rgb: 30, 38, 50;
  --line-hair: #2c3644;
  --teal-mid: #1c92c9;
  --teal-mid-rgb: 28, 146, 201;
  --teal-accent: #38e8ff;
  --teal-accent-rgb: 56, 232, 255;
  --teal-accent-soft: rgba(56, 232, 255, 0.25);
  --teal-dim: #163544;
  --text-body: #eef1f5;
  --text-dim: #8f97a3;
  --status-green: #3ecf6a;
  --status-live: #e8395c;
  --status-live-rgb: 232, 57, 92;

  /* geometry / motion */
  --radius-lg: 22px;
  --radius-md: 14px;
  --radius-sm: 9px;
  --ease: cubic-bezier(.16, 1, .3, 1);

  /* elevation tier system — stack tight+diffuse dark shadows, cyan rim-light at top tier */
  --elev-1: 0 1px 2px rgba(0, 0, 0, .45);
  --elev-2: 0 1px 2px rgba(0, 0, 0, .45), 0 6px 16px rgba(0, 0, 0, .4);
  --elev-3: 0 2px 4px rgba(0, 0, 0, .5), 0 14px 30px rgba(0, 0, 0, .45), 0 0 0 1px rgba(56, 232, 255, .08);
  --elev-4: 0 2px 6px rgba(0, 0, 0, .55), 0 24px 48px rgba(0, 0, 0, .5), 0 0 38px rgba(56, 232, 255, .28), inset 0 1px 0 rgba(56, 232, 255, .22);
}

/* ---------- base / typography ---------- */
html { color-scheme: dark; }

body {
  background: var(--bg-void);
  color: var(--text-body);
  font-family: 'Rajdhani', 'Segoe UI', sans-serif;
  font-weight: 500;
  font-size: 16px;
  line-height: 1.55;
  min-height: 100vh;   /* fallback for browsers without dvh */
  min-height: 100dvh;  /* iOS/Android address-bar-safe viewport height */
  position: relative;
  overflow-x: hidden;
  overscroll-behavior-y: none;
}

/* ---------- AURORA AMBIENT LIGHT — signature motif ----------
   Large blurred, screen-blended radial blobs drifting slowly behind
   every page. Same two tint weights of the single accent hue everywhere,
   so ambient light reads as depth/temperature, never a second brand color. */
body::before,
body::after {
  content: "";
  position: fixed;
  inset: -25%;
  z-index: 0;
  pointer-events: none;
  filter: blur(75px);
  mix-blend-mode: screen;
  will-change: transform;
}
body::before {
  background:
    radial-gradient(38% 32% at 18% 20%, rgba(56, 232, 255, .20), transparent 70%),
    radial-gradient(30% 26% at 82% 12%, rgba(20, 120, 140, .30), transparent 70%);
  animation: aurora-drift-a 34s ease-in-out infinite alternate;
}
body::after {
  background:
    radial-gradient(34% 30% at 75% 82%, rgba(56, 232, 255, .14), transparent 70%),
    radial-gradient(28% 24% at 15% 78%, rgba(20, 120, 140, .26), transparent 70%);
  animation: aurora-drift-b 26s ease-in-out infinite alternate;
}
@keyframes aurora-drift-a {
  0%   { transform: translate(0, 0) scale(1); }
  100% { transform: translate(4%, 6%) scale(1.08); }
}
@keyframes aurora-drift-b {
  0%   { transform: translate(0, 0) scale(1.05); }
  100% { transform: translate(-5%, -4%) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  body::before, body::after { animation: none; }
}

.page { position: relative; z-index: 1; }

h1, h2, h3, h4 {
  font-family: 'Chakra Petch', 'Orbitron', 'Segoe UI', sans-serif;
  font-weight: 800;
  letter-spacing: .04em;
}

/* restrained glow — reserved for hero/active headings, not every heading */
.title-glow {
  letter-spacing: .07em;
  text-transform: uppercase;
  background: linear-gradient(90deg, #eafcff, var(--teal-accent) 45%, var(--teal-mid));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  text-shadow: 0 0 6px rgba(56, 232, 255, .32), 0 0 22px rgba(56, 232, 255, .16);
}

/* HUD-style small-caps status readouts — "NOW SINGING", "QUEUE", etc */
.hud-label {
  font-family: 'Rajdhani', sans-serif;
  font-weight: 700;
  font-size: .68rem;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--teal-accent);
  opacity: .85;
}
.kicker {
  font-family: 'Rajdhani', sans-serif;
  font-weight: 600;
  font-size: .78rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.text-dim { color: var(--text-dim); }
.container {
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 1.5rem;
}
.prose-narrow { max-width: 700px; margin: 0 auto; }

/* ---------- ornament / crest block (top of every page) ---------- */
.ornament-top {
  padding: 2.6rem 0 1.4rem;
  text-align: center;
}
.hairline {
  display: block;
  width: 120px;
  height: 1px;
  margin: 0 auto 1.4rem;
  background: linear-gradient(90deg, transparent, var(--line-hair) 20%, var(--teal-accent-soft) 50%, var(--line-hair) 80%, transparent);
}
.crest {
  position: relative;
  width: 58px;
  height: 58px;
  margin: 0 auto;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.crest::before {
  content: "";
  position: absolute;
  inset: -2px;
  border-radius: inherit;
  background: conic-gradient(from var(--angle), var(--teal-mid), var(--teal-accent), #a6faff, var(--teal-accent), var(--teal-mid));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  padding: 2px;
  animation: spin-ring 9s linear infinite;
}
.crest span {
  position: relative;
  z-index: 1;
  width: 100%; height: 100%;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 25%, var(--bg-panel-raised), var(--bg-void) 75%);
  display: flex; align-items: center; justify-content: center;
  font-family: 'Chakra Petch', 'Orbitron', sans-serif;
  font-weight: 900;
  font-size: .82rem;
  letter-spacing: .03em;
  color: var(--teal-accent);
  text-shadow: 0 0 8px rgba(56, 232, 255, .5);
}
.crest.small { width: 40px; height: 40px; }
.crest.small span { font-size: .62rem; }
@keyframes spin-ring { to { --angle: 360deg; } }
@media (prefers-reduced-motion: reduce) { .crest::before { animation: none; } }

.back-link {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font-family: 'Rajdhani', sans-serif;
  font-weight: 600;
  font-size: .82rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-dim);
  transition: color .25s var(--ease);
}
.back-link:hover { color: var(--teal-accent); }
.back-link-row { text-align: center; padding-top: .6rem; }

/* ---------- title / subtitle / mission / motto ---------- */
.hero-title {
  text-align: center;
  font-size: clamp(2.1rem, 6vw, 3.6rem);
  margin: .6rem 0 1rem;
}
.page-title {
  text-align: center;
  font-size: clamp(1.5rem, 3.4vw, 2.1rem);
  margin: .4rem 0 1rem;
  color: var(--text-body);
}
.subtitle {
  text-align: center;
  font-family: 'Rajdhani', sans-serif;
  font-weight: 600;
  letter-spacing: .2em;
  text-transform: uppercase;
  font-size: .82rem;
  color: var(--text-dim);
  margin-bottom: 1.8rem;
}
.divider-dot {
  width: 6px; height: 6px;
  margin: 0 auto 1.8rem;
  border-radius: 50%;
  background: var(--teal-accent);
  box-shadow: 0 0 10px 2px rgba(56, 232, 255, .6);
}
.mission {
  text-align: center;
  color: var(--text-body);
  font-size: 1.05rem;
  margin-bottom: 1.6rem;
}
.mission p + p { margin-top: .9rem; }
.motto {
  text-align: center;
  font-family: 'Rajdhani', sans-serif;
  font-weight: 700;
  letter-spacing: .28em;
  text-transform: uppercase;
  font-size: .82rem;
  color: var(--teal-accent);
  text-shadow: 0 0 12px rgba(56, 232, 255, .3);
  margin-bottom: 3rem;
}

.lede {
  text-align: center;
  color: var(--text-dim);
  max-width: 560px;
  margin: 0 auto 2.2rem;
}

/* ==========================================================================
   GLASS PANELS + ROTATING GLOW-RING — the card/tile system
   ========================================================================== */

/* the rotating conic glow-ring wrapper */
.ring-card {
  position: relative;
  isolation: isolate;
  border-radius: var(--radius-lg);
}
.ring-card::before {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  padding: 1.5px;
  background: conic-gradient(from var(--angle), var(--teal-mid), var(--teal-accent), #a6faff 50%, var(--teal-accent), var(--teal-mid));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  opacity: .45;
  z-index: 0;
  animation: spin-ring 16s linear infinite;
  transition: opacity .35s var(--ease);
}
.ring-card:hover::before,
.ring-card:focus-within::before { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .ring-card::before { animation: none; } }

/* ---- CTA spin-glow — reused verbatim from index.html's "ENTER NOW" button
   (.v3-hero-cta): same rainbow conic gradient, same waov-cta-spin /
   waov-cta-pulse keyframes, always-on rather than hover-gated. Opt-in
   modifier — add class "cta-spin-glow" to a .ring-card to get it. Does not
   change index.html's own button; index.html keeps its own inline copy of
   these keyframes (identical values, so no visual change there). Currently
   used only by the "Meet the Teachers" tile on services-hub.html. */
@keyframes waov-cta-spin { to { --angle: 360deg; } }
@keyframes waov-cta-pulse {
  0%, 100% { filter: saturate(1) brightness(1) drop-shadow(0 0 5px rgba(56,232,255,0.35)); }
  50%      { filter: saturate(1.5) brightness(1.18) drop-shadow(0 0 18px rgba(56,232,255,0.75)); }
}
.ring-card.cta-spin-glow::before {
  background: conic-gradient(from var(--angle),
    #ff0040, #ff8000, #ffe000, #00d040,
    #00e0ff, #0060ff, #a000ff, #ff0040);
  opacity: 1;
  animation: waov-cta-spin 4s linear infinite, waov-cta-pulse 2.6s ease-in-out infinite;
}
.ring-card.cta-spin-glow:hover::before,
.ring-card.cta-spin-glow:focus-within::before { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .ring-card.cta-spin-glow::before { animation: none; } }

/* slow-glimmer variant — dashboard's Decide Your Schedule + Services tiles.
   Same thin conic ring, just brighter at rest and lazier spin. */
.ring-card.glimmer-slow::before {
  opacity: .65;
  animation-duration: 28s;
}
@media (prefers-reduced-motion: reduce) { .ring-card.glimmer-slow::before { animation: none; } }

/* the glass panel itself — sits inside the ring, holds a contrast "film" layer */
.glass {
  position: relative;
  z-index: 1;
  border-radius: var(--radius-lg);
  background-color: rgba(var(--bg-panel-rgb), .55);
  background-image: linear-gradient(rgba(var(--bg-void-rgb), .28), rgba(var(--bg-void-rgb), .28));
  backdrop-filter: blur(17px) saturate(145%);
  -webkit-backdrop-filter: blur(17px) saturate(145%);
  border: 1px solid rgba(var(--teal-accent-rgb), .16);
  box-shadow: var(--elev-2);
  transition: transform .35s var(--ease), box-shadow .35s var(--ease), border-color .35s var(--ease);
}

/* generic tile: ring + glass combined, used for chambers/order-tiles/roster tiles */
.tile {
  display: block;
  padding: 1.6rem 1.5rem;
  border-radius: var(--radius-lg);
}
.tile .glass,
a.tile.glass,
.tile.glass {
  height: 100%;
}
.tile-link { display: block; height: 100%; }

.ring-card:hover .glass,
.ring-card:focus-within .glass {
  transform: translateY(-4px);
  box-shadow: var(--elev-4);
  border-color: rgba(var(--teal-accent-rgb), .38);
}

.tile-kicker {
  font-family: 'Rajdhani', sans-serif;
  font-weight: 700;
  font-size: .68rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--teal-accent);
  margin-bottom: .55rem;
  display: block;
}
.tile-title {
  font-family: 'Chakra Petch', 'Orbitron', sans-serif;
  font-weight: 800;
  font-size: 1.05rem;
  color: var(--text-body);
  margin-bottom: .4rem;
}
.tile-desc {
  font-size: .88rem;
  color: var(--text-dim);
}

/* tile-row: landing page 5-across chamber row */
.tile-row {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 1.1rem;
  margin: 0 0 2.6rem;
}
@media (max-width: 980px) { .tile-row { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .tile-row { grid-template-columns: 1fr; } }

/* order tiles: dashboard — auto-fit so remaining tiles stretch to fill the
   row (tile count varies by role: 1 for customer, 2 for teacher/both) */
.order-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1.1rem;
  margin-bottom: 2rem;
}
@media (max-width: 520px) { .order-tiles { grid-template-columns: 1fr; } }

/* single feature card — dashboard's Order Tiles, collapsed from a grid of
   tiles into 1 expanded vertical card with itemized rows inside */
.feature-card { margin-bottom: 2rem; }
.feature-card-inner { position: relative; overflow: hidden; padding: 2.2rem 2rem 1.4rem; }

/* sweep glow — soft neon-teal band that turns on, travels top-to-bottom
   through the whole card, and fades out. Fires twice per page load, then
   stays still. Colors pulled from the site's existing tokens (--teal-accent,
   the #a6faff bright accent already used in the ring's conic-gradient) —
   no new hues introduced, just leaned brighter/softer for a neon feel. */
.feature-glow-sweep {
  position: absolute;
  left: 0; right: 0;
  height: 46%;
  top: -46%;
  background: linear-gradient(180deg,
    transparent,
    rgba(166, 250, 255, .16) 20%,
    rgba(var(--teal-accent-rgb), .5) 50%,
    rgba(166, 250, 255, .16) 80%,
    transparent);
  filter: blur(26px);
  opacity: 0;
  pointer-events: none;
  z-index: 0;
  animation: feature-glow-travel 3.4s ease-in-out 2;
}
@keyframes feature-glow-travel {
  0%   { top: -46%; opacity: 0; }
  15%  { opacity: 1; }
  85%  { opacity: 1; }
  100% { top: 100%; opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .feature-glow-sweep { display: none; } }

.feature-list { position: relative; z-index: 1; margin-top: 1.2rem; }
.feature-row {
  display: block;
  padding: 1.1rem .4rem;
  border-top: 1px solid rgba(var(--teal-accent-rgb), .14);
  transition: background .25s var(--ease), padding-left .25s var(--ease);
}
.feature-list a.feature-row:first-child { border-top: none; }
.feature-row:hover,
.feature-row:focus-visible {
  background: rgba(var(--teal-accent-rgb), .06);
  padding-left: .8rem;
}
.feature-row-title {
  font-family: 'Chakra Petch', 'Orbitron', sans-serif;
  font-weight: 800;
  font-size: 1rem;
  color: var(--text-body);
  margin-bottom: .3rem;
}
.feature-row-desc {
  font-size: .88rem;
  color: var(--text-dim);
}

/* roster grid: vocal lessons hub */
.roster-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 1.1rem;
  margin-bottom: 2rem;
}

/* ==========================================================================
   SERVICES HUB — teacher-type tile upgrade (services-hub.html only)
   Slims the hierarchy: the tile itself carries category identity via a
   color-coded glow ring + tiny corner banner, instead of a separate
   classification step. .people-tile adds a near-1:1 avatar photo that
   overlaps the card's top edge for a "popping out" dimensional look.
   ========================================================================== */

.people-tile .glass.tile {
  height: auto;
  aspect-ratio: 3 / 4;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  overflow: visible;
}

.tile-banner {
  position: absolute;
  top: .5rem;
  right: .5rem;
  z-index: 3;
  font-family: 'Rajdhani', sans-serif;
  font-weight: 700;
  font-size: .6rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  padding: .18rem .5rem;
  border-radius: 999px;
  color: inherit;
  background: rgba(var(--bg-void-rgb), .6);
  backdrop-filter: blur(6px);
  border: 1px solid currentColor;
}

.tile-avatar {
  position: absolute;
  top: -20%;
  left: 50%;
  transform: translateX(-50%);
  width: 76%;
  aspect-ratio: 1 / 1;
  border-radius: var(--radius-md);
  background-color: rgba(var(--bg-panel-raised-rgb), .85);
  background-size: cover;
  background-position: center top;
  z-index: 2;
  filter: drop-shadow(0 10px 22px rgba(0, 0, 0, .55));
  transition: transform .35s var(--ease);
}
.ring-card:hover .tile-avatar,
.ring-card:focus-within .tile-avatar { transform: translateX(-50%) translateY(-6px); }

.tile-body {
  position: relative;
  z-index: 1;
  padding-top: 2.4rem;
}

/* ---- color identity per category, same palette family, new accent per type ---- */
.ring-card.tile-claude { color: #ff9d47; }
.ring-card.tile-claude::before { background: conic-gradient(from var(--angle), #ff9d47, #ffcf8a 50%, #ff9d47); }
.tile-claude .tile-avatar { box-shadow: 0 0 0 2px rgba(255, 157, 71, .35), 0 0 34px rgba(255, 157, 71, .5); }

.ring-card.tile-vocal { color: #f4f7fb; }
.ring-card.tile-vocal::before { background: conic-gradient(from var(--angle), #f4f7fb, #b9c4d1 50%, #f4f7fb); }
.tile-vocal .tile-avatar { box-shadow: 0 0 0 2px rgba(244, 247, 251, .35), 0 0 34px rgba(244, 247, 251, .45); }

.ring-card.tile-dj { color: #e8395c; }
.ring-card.tile-dj::before { background: conic-gradient(from var(--angle), #e8395c, #14090c 50%, #e8395c); }
.tile-dj .tile-avatar { box-shadow: 0 0 0 2px rgba(232, 57, 92, .4), 0 0 34px rgba(232, 57, 92, .5); }
.tile-dj .tile-avatar::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(180deg, rgba(232, 57, 92, .2), rgba(7, 9, 13, .9));
  pointer-events: none;
}


.ring-card.tile-teachers { color: #3ecf6a; }
.ring-card.tile-teachers::before { background: conic-gradient(from var(--angle), #3ecf6a, #1c92c9 50%, #3ecf6a); }

/* per-subject framing. Source art is mixed 3:4 / 16:9 / 1:1 and every
   character sits horizontally centred, so only the vertical slice varies. */
.tile-avatar { background-position: var(--tp-pos, center 18%); }

/* ==========================================================================
   ENTRANCE — shared staggered rise.
   Ported out of index.html's inline <style>, where it was .v3-root-scoped and
   therefore unreachable from any other page. index.html's .v3-root rules still
   reference it; the inline duplicate was deleted so there is ONE definition.
   House timing: 700ms, cubic-bezier(.2,.8,.2,1), 120ms step, first item .50s.
   fill-mode `backwards` is load-bearing — it leaves the element's own
   transform alone once done, so :hover still works.
   ========================================================================== */
@keyframes waov-rise {
  from { opacity: 0; transform: translateY(24px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ==========================================================================
   TEACHER PROFILE HERO — the "trusty & robust" stage (tp-*)
   The photo NEVER enters .glass: it sits BEHIND the panel as a sibling stage.
   That one move dissolves every blocker at once — .glass keeps its contrast
   film (it owns background-image), .photo-placeholder stays untouched for the
   4 other pages that share it, and full-bleed stops fighting .ring-card's
   max-width/isolation.
   ========================================================================== */

.tp-shell {
  --tp-glow: var(--teal-accent);
  --tp-glow-rgb: var(--teal-accent-rgb);
  --tp-stage-h: clamp(380px, 48vh, 560px);
  position: relative;
  isolation: isolate;
}
/* lane identity carried over from the services-hub tiles — the thing you
   clicked and the page you land on are visibly the same object */
.tp-shell.tp-dj     { --tp-glow: #e8395c; --tp-glow-rgb: 232, 57, 92; }
.tp-shell.tp-vocal  { --tp-glow: #f4f7fb; --tp-glow-rgb: 244, 247, 251; }
.tp-shell.tp-claude { --tp-glow: #ff9d47; --tp-glow-rgb: 255, 157, 71; }

.tp-stage {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: var(--tp-stage-h);
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  animation: waov-rise .9s cubic-bezier(.2, .8, .2, 1) backwards;
}
/* full-bleed escape from .container's 1120px. Safe because body sets
   overflow-x:hidden. Omitted on trainer-profile.html, whose 3-column
   .dash-shell must not be spanned.

   Centred with margin-left, NOT transform: translateX(-50%). This is not a
   style preference — .tp-stage carries `animation: waov-rise`, which animates
   `transform`, and an animation overrides normal declarations. A translateX
   here would be WIPED OUT for the animation's whole 900ms (the stage renders
   half a viewport to the right) and then snap into place as it ends.
   left:50% + margin-left:-50vw lands the same centring using properties the
   animation never touches. */
.tp-shell.tp-bleed .tp-stage {
  left: 50%; right: auto;
  width: 100vw;
  margin-left: -50vw;
}

/* layer 1 — texture. Always present; it IS both the loading state and the
   no-photo state. Reuses .photo-placeholder's 45deg hatch so an empty stage
   still speaks this site's language, plus .v3-hero's grid + top-vignette mask
   so it reads as a designed hero rather than a gap. */
.tp-stage-texture {
  position: absolute;
  inset: 0;
  background-color: rgba(var(--bg-panel-rgb), .35);
  background-image:
    linear-gradient(155deg, rgba(var(--tp-glow-rgb), .10), rgba(var(--teal-mid-rgb), .06)),
    repeating-linear-gradient(45deg, rgba(255,255,255,.03) 0 10px, transparent 10px 20px),
    linear-gradient(rgba(var(--tp-glow-rgb), .05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(var(--tp-glow-rgb), .05) 1px, transparent 1px);
  background-size: auto, auto, 34px 34px, 34px 34px;
  mask-image: radial-gradient(ellipse 80% 100% at 50% 0%, black, transparent 75%);
  -webkit-mask-image: radial-gradient(ellipse 80% 100% at 50% 0%, black, transparent 75%);
}

/* layer 2 — the photo. --tp-photo is set by JS ONLY after the bitmap has
   decoded, so a missing/404 asset never flashes; the texture just stays.
   The mask dissolves the photo's own edges so there is no rectangle. */
.tp-stage-photo {
  position: absolute;
  inset: 0;
  background-image: var(--tp-photo, none);
  background-size: cover;
  background-position: var(--tp-pos, center 18%);
  background-repeat: no-repeat;
  opacity: 0;
  transform: scale(1.04);
  transition: opacity .9s var(--ease), transform .9s var(--ease);
  mask-image: radial-gradient(ellipse 92% 108% at 50% 8%, black 38%, transparent 84%);
  -webkit-mask-image: radial-gradient(ellipse 92% 108% at 50% 8%, black 38%, transparent 84%);
}
.tp-shell.is-loaded .tp-stage-photo { opacity: 1; transform: scale(1); }

/* layer 3 — scrim. Same recipe as .tile-dj .tile-avatar::after, scaled to a
   hero. The bottom stop is SOLID var(--bg-void) — that stop is the seam: the
   photo's bottom edge and the page background are literally the same colour,
   so the photo has no bottom. */
.tp-stage-scrim {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 70% 90% at 50% 18%, rgba(var(--tp-glow-rgb), .18), transparent 65%),
    linear-gradient(90deg, var(--bg-void), transparent 16%, transparent 84%, var(--bg-void)),
    linear-gradient(180deg,
      rgba(var(--bg-void-rgb), .30) 0%,
      rgba(var(--bg-void-rgb), .48) 44%,
      rgba(var(--bg-void-rgb), .90) 76%,
      var(--bg-void) 100%);
}
/* no side feather at full width — the radial already carries the edges and
   feathering 100vw just wastes the photo */
.tp-shell.tp-bleed .tp-stage-scrim {
  background:
    radial-gradient(ellipse 70% 90% at 50% 18%, rgba(var(--tp-glow-rgb), .18), transparent 65%),
    linear-gradient(180deg,
      rgba(var(--bg-void-rgb), .30) 0%,
      rgba(var(--bg-void-rgb), .48) 44%,
      rgba(var(--bg-void-rgb), .90) 76%,
      var(--bg-void) 100%);
}

/* content rides the stage's lower third — one knob drives both */
.tp-shell-body {
  position: relative;
  z-index: 1;
  padding-top: calc(var(--tp-stage-h) * .62);
}

/* .ring-card.tile-* also sets `color` (for .tile-banner's currentColor border).
   Every child in .glass sets its own colour today, but this keeps an unstyled
   future child from inheriting a lane accent as body text. */
.tp-panel > .glass { color: var(--text-body); }

/* stagger: the photo settles FIRST, then the info panel arrives on top.
   Stage 0->900ms un-delayed; panel starts at .74s, ~80% into the stage. */
.tp-shell-body > .kicker,
.tp-shell-body > .page-title,
.tp-panel,
.tp-shell ~ .order-tiles > .ring-card {
  animation: waov-rise .7s cubic-bezier(.2, .8, .2, 1) backwards;
}
.tp-shell-body > .kicker     { animation-delay: .50s; }
.tp-shell-body > .page-title { animation-delay: .62s; }
.tp-panel                    { animation-delay: .74s; }
.tp-shell ~ .order-tiles > .ring-card:nth-child(1) { animation-delay: .86s; }
.tp-shell ~ .order-tiles > .ring-card:nth-child(2) { animation-delay: .98s; }
.tp-shell ~ .order-tiles > .ring-card:nth-child(3) { animation-delay: 1.10s; }
.tp-shell ~ .order-tiles > .ring-card:nth-child(4) { animation-delay: 1.22s; }

/* House convention: kill `animation`, leave `transition`. The photo's reveal
   is a transition, so it survives — a 900ms cross-fade with no movement is
   not a vestibular trigger. Does not touch .ring-card::before's spin-ring,
   which is already handled at its own rule. */
@media (prefers-reduced-motion: reduce) {
  .tp-stage,
  .tp-shell-body > .kicker,
  .tp-shell-body > .page-title,
  .tp-panel,
  .tp-shell ~ .order-tiles > .ring-card { animation: none; }
}

@media (max-width: 620px) {
  .tp-shell { --tp-stage-h: clamp(280px, 40vh, 380px); }
}

/* ==========================================================================
   TP RACE — the "racing video-game" hero reveal.
   Opt in with .tp-race on .tp-shell. Layers snap into place like a race-game
   wipe, then the photo lands with a BAM. Nothing in .tp-* above is replaced.

   HARD RULE: this NEVER touches .tp-stage's own transform. .tp-bleed puts
   translateX(-50%) there to centre the full-bleed stage — animating it would
   fight the centring. So the whole choreography lives on .tp-stage's
   inset:0 children, which is exactly why it behaves identically on the
   bleed (dj-teacher, miles) and non-bleed (trainer-profile) pages.

   Easing is waov-rise's cubic-bezier(.2,.8,.2,1) throughout — same motion
   vocabulary as the rest of the site. Total 780ms to BAM; the .tp-panel
   stagger at .74s is untouched and still lands on top.
   ========================================================================== */

/* the three shutter bars — "the layers sliding into place" */
.tp-race-bars {
  position: absolute;
  inset: 0;
  z-index: 2;              /* above texture(0)/photo(1), below scrim */
  pointer-events: none;
  overflow: hidden;
}
.tp-race-bars i {
  position: absolute;
  left: -2%;
  width: 104%;
  height: 14%;
  display: block;
  transform: scaleX(0);
  background-color: rgba(var(--tp-glow-rgb), .30);
  background-image: repeating-linear-gradient(45deg, rgba(255,255,255,.05) 0 10px, transparent 10px 20px);
  box-shadow: 0 0 24px rgba(var(--tp-glow-rgb), .45);
}
.tp-race-bars i:nth-child(1) { top: 22%; transform-origin: left center; }
.tp-race-bars i:nth-child(2) { top: 48%; transform-origin: right center; }
.tp-race-bars i:nth-child(3) { top: 71%; transform-origin: left center; }

/* the BAM — one light streak crossing as the photo lands */
.tp-race-flash {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  opacity: 0;
  background: linear-gradient(90deg, transparent, rgba(var(--tp-glow-rgb), .9), transparent);
  mix-blend-mode: screen;
}

/* The race OWNS the photo reveal for racing shells only.
   .tp-stage-photo already carries `transition: opacity .9s, transform .9s`
   which .is-loaded flips. Left alone, that 900ms transition outlives the
   420ms animation and the two fight over the same properties. Killing the
   transition here is scoped to .tp-race, so the 4 non-racing usages keep
   their crossfade untouched. */
.tp-shell.tp-race .tp-stage-photo { transition: none; }

.tp-shell.tp-race.is-racing .tp-stage-texture {
  animation: tp-race-texture .26s cubic-bezier(.2, .8, .2, 1) backwards;
}
.tp-shell.tp-race.is-racing .tp-race-bars i {
  animation: tp-race-bar .34s cubic-bezier(.2, .8, .2, 1) backwards;
}
.tp-shell.tp-race.is-racing .tp-race-bars i:nth-child(1) { animation-delay: .08s; }
.tp-shell.tp-race.is-racing .tp-race-bars i:nth-child(2) { animation-delay: .14s; }
.tp-shell.tp-race.is-racing .tp-race-bars i:nth-child(3) { animation-delay: .20s; }

/* `backwards` is load-bearing (same reason as waov-rise): the photo sits at
   the `from` state through the .30s delay with no extra rule, and hands its
   own transform back afterwards so :hover still works. */
.tp-shell.tp-race.is-racing .tp-stage-photo {
  animation: tp-race-photo .42s cubic-bezier(.2, .8, .2, 1) .30s backwards;
}
.tp-shell.tp-race.is-racing .tp-race-flash {
  animation: tp-race-flash .22s cubic-bezier(.2, .8, .2, 1) .60s backwards;
}

@keyframes tp-race-texture {
  from { opacity: 0; transform: translateX(-14%) skewX(-8deg); }
  to   { opacity: 1; transform: translateX(0) skewX(0); }
}
/* wipe in from one edge, then straight out to the other — a shutter.
   All three are gone by ~560ms and the photo arrives through the gap. */
@keyframes tp-race-bar {
  0%   { transform: scaleX(0); opacity: 1; }
  52%  { transform: scaleX(1); opacity: 1; }
  53%  { transform-origin: right center; }
  100% { transform: scaleX(0); opacity: .9; transform-origin: right center; }
}
@keyframes tp-race-photo {
  from { opacity: 0; transform: translateX(8%) scale(1.14); }
  to   { opacity: 1; transform: translateX(0) scale(1); }
}
@keyframes tp-race-flash {
  0%   { opacity: 0;   transform: scaleX(.2); }
  50%  { opacity: .55; }
  100% { opacity: 0;   transform: scaleX(1.3); }
}

/* Miles has no photo, so the bars part onto his texture instead — that IS
   his hero (the texture is declared the no-photo state above). Retime so the
   flash lands with the NAME rather than a picture: "the layers slid in and
   the name landed" is the honest reveal for a teacher with no photo yet. */
.tp-shell.tp-race:not([data-photo]).is-racing .tp-race-bars i { animation-duration: .30s; }
.tp-shell.tp-race:not([data-photo]).is-racing .tp-race-flash { animation-delay: .48s; }

/* House convention: kill `animation`, keep `transition`. The bars and flash
   exist only to move, so they are removed outright rather than frozen
   mid-wipe across the photo. .tp-race killed the photo's transition above —
   hand it back, per this file's own ruling that a 900ms crossfade with no
   movement is not a vestibular trigger. */
@media (prefers-reduced-motion: reduce) {
  .tp-shell.tp-race .tp-stage-texture,
  .tp-shell.tp-race .tp-stage-photo,
  .tp-shell.tp-race .tp-race-bars i,
  .tp-shell.tp-race .tp-race-flash { animation: none; }

  .tp-shell.tp-race .tp-race-bars,
  .tp-shell.tp-race .tp-race-flash { display: none; }

  .tp-shell.tp-race .tp-stage-photo { transition: opacity .9s var(--ease); }
}

/* ==========================================================================
   ROSTER MATCH FILTER — search a song/keyword + filter trainers by genre.
   Mock/localStorage roster only; pure client-side, no backend. */
.match-bar {
  display: flex;
  flex-direction: column;
  gap: .85rem;
  margin: .4rem 0 1.4rem;
}
.match-search { position: relative; }
.match-search .form-input { padding-left: 2.4rem; }
.match-search::before {
  content: "\1F50D";
  position: absolute;
  left: .85rem;
  top: 50%;
  transform: translateY(-50%);
  font-size: .85rem;
  opacity: .55;
  pointer-events: none;
}
.genre-pills { display: flex; flex-wrap: wrap; gap: .5rem; }
.genre-pill {
  font-family: 'Rajdhani', sans-serif;
  font-weight: 700;
  font-size: .74rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-dim);
  background: rgba(var(--bg-panel-rgb), .5);
  border: 1px solid var(--line-hair);
  border-radius: 999px;
  padding: .42rem .9rem;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  transition: color .2s var(--ease), border-color .2s var(--ease), background .2s var(--ease);
}
.genre-pill:hover { color: var(--text-body); border-color: rgba(var(--teal-accent-rgb), .4); }
.genre-pill.active {
  color: #071016;
  background: var(--teal-accent);
  border-color: var(--teal-accent);
  box-shadow: 0 0 12px rgba(var(--teal-accent-rgb), .35);
}
.match-count {
  font-family: 'Rajdhani', sans-serif;
  font-size: .78rem;
  letter-spacing: .04em;
  color: var(--text-dim);
}
.match-count b { color: var(--teal-accent); font-weight: 700; }
.roster-empty {
  grid-column: 1 / -1;
  text-align: center;
  color: var(--text-dim);
  font-family: 'Rajdhani', sans-serif;
  padding: 2rem 1rem;
  border: 1px dashed var(--line-hair);
  border-radius: var(--radius-md);
}

/* create-your-own tile — visually distinct: dashed border, no ring, "+" icon */
.tile-create {
  border: 2px dashed rgba(var(--teal-accent-rgb), .4);
  border-radius: var(--radius-lg);
  background: rgba(var(--bg-panel-rgb), .3);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 1.6rem 1.2rem;
  min-height: 100%;
  transition: border-color .3s var(--ease), background .3s var(--ease), transform .3s var(--ease);
}
.tile-create:hover {
  border-color: var(--teal-accent);
  background: rgba(var(--bg-panel-rgb), .5);
  transform: translateY(-4px);
}
.tile-create .plus-icon {
  width: 46px; height: 46px;
  border-radius: 50%;
  border: 2px dashed rgba(var(--teal-accent-rgb), .55);
  display: flex; align-items: center; justify-content: center;
  font-family: 'Chakra Petch', 'Orbitron', sans-serif;
  font-size: 1.4rem;
  color: var(--teal-accent);
  margin-bottom: .8rem;
}
.plus-icon-spin {
  position: relative;
}
.plus-icon-spin::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  padding: 2px;
  animation: plus-icon-spin 16s linear infinite;
  background: conic-gradient(
    rgba(var(--teal-accent-rgb), 0) 0deg,
    rgba(var(--teal-accent-rgb), .8) 40deg,
    rgba(var(--teal-accent-rgb), 0) 80deg,
    rgba(120, 150, 255, .35) 150deg,
    rgba(190, 130, 255, .3) 190deg,
    rgba(255, 140, 190, .28) 230deg,
    rgba(255, 205, 140, .28) 270deg,
    rgba(var(--teal-accent-rgb), 0) 320deg,
    rgba(var(--teal-accent-rgb), .8) 360deg
  );
  -webkit-mask: repeating-conic-gradient(#000 0deg 8deg, transparent 8deg 20deg);
          mask: repeating-conic-gradient(#000 0deg 8deg, transparent 8deg 20deg);
  pointer-events: none;
  z-index: -1;
}
@keyframes plus-icon-spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .plus-icon-spin { animation: none; }
}

/* photo placeholder */
.photo-placeholder {
  width: 100%;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-md);
  background:
    linear-gradient(155deg, rgba(56,232,255,.10), rgba(28,146,201,.06)),
    repeating-linear-gradient(45deg, rgba(255,255,255,.03) 0 10px, transparent 10px 20px);
  border: 1px solid var(--line-hair);
  display: flex; align-items: center; justify-content: center;
  color: var(--text-dim);
  font-size: .72rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  margin-bottom: 1rem;
}

/* ==========================================================================
   BUTTONS — shimmer sheen sweep on primary CTAs
   ========================================================================== */
.btn {
  position: relative;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  padding: .85rem 1.6rem;
  border-radius: var(--radius-sm);
  font-family: 'Rajdhani', sans-serif;
  font-weight: 700;
  font-size: .92rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  border: 1px solid var(--line-hair);
  background: rgba(var(--bg-panel-raised-rgb), .7);
  color: var(--text-body);
  cursor: pointer;
  transition: transform .3s var(--ease), box-shadow .3s var(--ease), border-color .3s var(--ease), background .3s var(--ease);
}
.btn:hover {
  transform: translateY(-2px);
  border-color: rgba(var(--teal-accent-rgb), .5);
  box-shadow: var(--elev-3);
}

.btn-primary {
  background: linear-gradient(155deg, var(--teal-mid), #12617f);
  border-color: rgba(var(--teal-accent-rgb), .5);
  color: #04141a;
  font-weight: 800;
}
.btn-primary:hover {
  box-shadow: var(--elev-4);
}
.btn-primary::before {
  content: "";
  position: absolute;
  top: 0; left: -60%;
  width: 40%; height: 100%;
  background: linear-gradient(120deg, transparent, rgba(255, 255, 255, .55), transparent);
  transform: skewX(-20deg);
  pointer-events: none;
}
.btn-primary:hover::before {
  animation: sheen-sweep .9s var(--ease) forwards;
}
@keyframes sheen-sweep {
  from { left: -60%; }
  to   { left: 140%; }
}
.btn-block { width: 100%; }
.btn-ghost {
  background: transparent;
  border-color: var(--line-hair);
  color: var(--text-dim);
}
.btn-ghost:hover { color: var(--teal-accent); }

/* ==========================================================================
   FOOTER BAND + LINK ROW
   ========================================================================== */
.footer-band {
  margin: 2.6rem auto 1.6rem;
  max-width: 900px;
  padding: 1.3rem 1.6rem;
  border-radius: var(--radius-lg);
  background: rgba(var(--bg-panel-rgb), .5);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  border: 1px solid var(--line-hair);
  text-align: center;
  color: var(--text-dim);
  font-size: .88rem;
  box-shadow: var(--elev-1);
}
.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 1.6rem;
  justify-content: center;
  padding: 1.6rem 0 2.4rem;
  font-family: 'Rajdhani', sans-serif;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  font-size: .78rem;
  color: var(--text-dim);
}
.footer-links a:hover { color: var(--teal-accent); }

/* struck-through footer entries — destination doesn't exist yet, so they are
   shown as pending rather than as links that silently no-op when clicked */
.footer-links .fl-struck {
  text-decoration: line-through;
  text-decoration-thickness: 1px;
  opacity: .45;
  cursor: default;
  user-select: none;
}
.site-footer {
  text-align: center;
  padding-bottom: 2.4rem;
  color: var(--text-dim);
  font-size: .78rem;
  letter-spacing: .05em;
}

/* ==========================================================================
   LOGIN / GATE TILES — equal weight, dashboard-gate visual language reused
   ========================================================================== */
.gate-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.1rem;
  margin: 1.6rem 0;
}
@media (max-width: 560px) { .gate-row { grid-template-columns: 1fr; } }

.gate-tile {
  padding: 1.7rem 1.2rem;
  text-align: center;
  cursor: pointer;
  border: none;
  width: 100%;
  font: inherit;
}
.gate-icon {
  width: 52px; height: 52px;
  margin: 0 auto .9rem;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-family: 'Chakra Petch', 'Orbitron', sans-serif;
  font-weight: 900;
  font-size: 1.15rem;
  background: rgba(var(--bg-panel-raised-rgb), .8);
  border: 1px solid rgba(var(--teal-accent-rgb), .3);
  color: var(--teal-accent);
  box-shadow: inset 0 0 14px rgba(56, 232, 255, .08);
}
.gate-label {
  font-family: 'Chakra Petch', 'Orbitron', sans-serif;
  font-weight: 700;
  font-size: .95rem;
  color: var(--text-body);
  margin-bottom: .3rem;
}
.gate-sub {
  font-size: .78rem;
  color: var(--text-dim);
  letter-spacing: .05em;
}
.gate-tile.locked { opacity: .55; cursor: not-allowed; }

.auth-card {
  max-width: 480px;
  margin: 0 auto;
  padding: 2rem 1.8rem;
}
.helper-line {
  text-align: center;
  font-size: .82rem;
  color: var(--text-dim);
  margin-top: 1rem;
}
.helper-line a { color: var(--teal-accent); }
.helper-line a:hover { text-decoration: underline; }

.status-banner {
  margin: 1.2rem auto 0;
  max-width: 480px;
  padding: .85rem 1.1rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line-hair);
  background: rgba(var(--bg-panel-raised-rgb), .6);
  font-size: .85rem;
  color: var(--text-dim);
  text-align: center;
}
.status-banner.warn { border-color: rgba(232, 57, 92, .35); color: #f2b9c4; }
.status-banner.ok { border-color: rgba(62, 207, 106, .4); color: #a9f0c1; }

/* status pill (verified / not verified) */
.status-pill {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .3rem .7rem;
  border-radius: 999px;
  font-size: .7rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  font-weight: 700;
  border: 1px solid var(--line-hair);
  background: rgba(var(--bg-panel-raised-rgb), .6);
  color: var(--text-dim);
}
.status-pill .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--text-dim); }
.status-pill.verified { color: var(--status-green); border-color: rgba(62,207,106,.4); }
.status-pill.verified .dot { background: var(--status-green); box-shadow: 0 0 6px rgba(62,207,106,.7); }
.status-pill.not-verified { color: #f2b9c4; border-color: rgba(232,57,92,.35); }
.status-pill.not-verified .dot { background: var(--status-live); }

/* ==========================================================================
   GLOW-MORPHISM "LIVE" PULSE — stacked triple ring, glow-morphism state
   ========================================================================== */
.live-badge {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .28rem .65rem;
  border-radius: 999px;
  background: rgba(var(--status-live-rgb), .16);
  border: 1px solid rgba(var(--status-live-rgb), .5);
  color: #ffd3dd;
  font-family: 'Rajdhani', sans-serif;
  font-weight: 700;
  font-size: .66rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  animation: live-pulse-ring 2.4s ease-out infinite;
}
@keyframes live-pulse-ring {
  0%   { box-shadow: 0 0 0 0 rgba(var(--status-live-rgb), .55), 0 0 0 0 rgba(var(--status-live-rgb), .35), 0 0 0 0 rgba(var(--status-live-rgb), .18); }
  70%  { box-shadow: 0 0 0 6px rgba(var(--status-live-rgb), 0), 0 0 0 14px rgba(var(--status-live-rgb), 0), 0 0 0 24px rgba(var(--status-live-rgb), 0); }
  100% { box-shadow: 0 0 0 0 rgba(var(--status-live-rgb), 0), 0 0 0 0 rgba(var(--status-live-rgb), 0), 0 0 0 0 rgba(var(--status-live-rgb), 0); }
}
@media (prefers-reduced-motion: reduce) { .live-badge { animation: none; } }

/* ==========================================================================
   DASHBOARD SHELL — 3 column (sidebar / center / right rail)
   ========================================================================== */
.dash-shell {
  display: grid;
  grid-template-columns: 250px 1fr 260px;
  gap: 1.4rem;
  align-items: start;
  padding: 1.8rem 0 2.6rem;
}
@media (max-width: 1000px) {
  .dash-shell { grid-template-columns: 1fr; }
}

/* Mobile-only identity/nav drawer (2026-08-28): the sidebar aside is left
   completely untouched above 640px. Below that it becomes an off-canvas
   panel triggered by a fixed toggle button instead of stacking as the
   first tall block on the page. Desktop rules above are never modified. */
@media (max-width: 640px) {
  .dash-shell .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    width: min(82vw, 300px);
    max-width: 300px;
    z-index: 900;
    overflow-y: auto;
    border-radius: 0;
    transform: translateX(-105%);
    transition: transform .28s ease;
    box-shadow: var(--elev-2);
  }
  .dash-shell .sidebar.mobile-open { transform: translateX(0); }

  .mobile-nav-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    position: fixed;
    top: max(14px, env(safe-area-inset-top));
    left: max(16px, env(safe-area-inset-left));
    width: 44px;
    height: 44px;
    z-index: 950;
    border-radius: 50%;
    /* fallback opaque-enough values first so the button stays visible even if
       the --teal-accent-rgb / --bg-panel-rgb custom properties don't resolve;
       the rgba() rules win afterward wherever those vars ARE set */
    border: 1px solid rgba(60, 180, 170, .55);
    border: 1px solid rgba(var(--teal-accent-rgb), .3);
    background-color: rgba(20, 30, 34, .9);
    background-color: rgba(var(--bg-panel-rgb), .9);
    color: var(--text-dim);
    font-size: 1.2rem;
    line-height: 1;
    box-shadow: 0 0 10px 2px rgba(60, 180, 170, .35), 0 0 10px 2px rgba(var(--teal-accent-rgb), .35);
    animation: mobile-nav-toggle-glow 2.6s ease-in-out infinite;
  }
  @keyframes mobile-nav-toggle-glow {
    0%, 100% { box-shadow: 0 0 8px 1px rgba(60, 180, 170, .3), 0 0 8px 1px rgba(var(--teal-accent-rgb), .3); }
    50%      { box-shadow: 0 0 18px 5px rgba(60, 180, 170, .65), 0 0 18px 5px rgba(var(--teal-accent-rgb), .65); }
  }
  @media (prefers-reduced-motion: reduce) {
    .mobile-nav-toggle { animation: none; }
  }

  .mobile-nav-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,.45);
    z-index: 890;
  }
  .mobile-nav-overlay.mobile-open { display: block; }

  .dash-shell .sidebar .nav-list a,
  .dash-shell .sidebar .nav-list .nav-item {
    min-height: 44px;
    display: flex;
    align-items: center;
  }
}
@media (min-width: 641px) {
  .mobile-nav-toggle, .mobile-nav-overlay { display: none; }
}

.dash-panel {
  border-radius: var(--radius-lg);
  background-color: rgba(var(--bg-panel-rgb), .55);
  background-image: linear-gradient(rgba(var(--bg-void-rgb), .28), rgba(var(--bg-void-rgb), .28));
  backdrop-filter: blur(16px) saturate(145%);
  -webkit-backdrop-filter: blur(16px) saturate(145%);
  border: 1px solid rgba(var(--teal-accent-rgb), .14);
  box-shadow: var(--elev-2);
  padding: 1.5rem 1.3rem;
}

.sidebar { position: sticky; top: 1.4rem; text-align: center; }
.avatar-circle {
  width: 84px; height: 84px;
  margin: 0 auto .9rem;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 25%, var(--bg-panel-raised), var(--bg-void) 75%);
  border: 1px solid var(--line-hair);
  display: flex; align-items: center; justify-content: center;
  color: var(--text-dim);
  font-size: .68rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  position: relative;
}
.avatar-circle::before {
  content: "";
  position: absolute; inset: -3px;
  border-radius: 50%;
  background: conic-gradient(from var(--angle), var(--teal-mid), var(--teal-accent), #a6faff, var(--teal-accent), var(--teal-mid));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  padding: 3px;
  animation: spin-ring 7s linear infinite;
}
@media (prefers-reduced-motion: reduce) { .avatar-circle::before { animation: none; } }

.member-name { font-family: 'Chakra Petch', 'Orbitron', sans-serif; font-weight: 700; font-size: 1.05rem; margin-bottom: .3rem; }
.rank-tag {
  display: inline-block;
  font-size: .68rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--teal-accent);
  background: var(--teal-dim);
  border-radius: 999px;
  padding: .2rem .6rem;
  margin-bottom: .7rem;
}
.registry-no { font-size: .74rem; color: var(--text-dim); margin: .7rem 0 1.1rem; letter-spacing: .05em; }

.nav-list { text-align: left; margin-top: 1.2rem; }
.nav-list li + li { margin-top: .15rem; }
.nav-list a, .nav-list .nav-item {
  display: block;
  padding: .6rem .7rem;
  border-radius: var(--radius-sm);
  font-size: .88rem;
  color: var(--text-dim);
  transition: background .25s var(--ease), color .25s var(--ease);
}
.nav-list a:hover, .nav-list .nav-item:hover {
  background: rgba(var(--teal-accent-rgb), .08);
  color: var(--teal-accent);
}
/* gold-shine cross-links — Student Dashboard <-> Teacher Dashboard.
   Gold (#f2c94c) already used site-wide as the "optional field" accent
   (login.html, role-gate.html) — reused here as the shared gold token. */
.nav-list a.nav-gold,
.feature-row-title.nav-gold {
  position: relative;
  overflow: hidden;
  background: linear-gradient(100deg, #b8860b 0%, #f2c94c 25%, #fff3c4 50%, #f2c94c 75%, #b8860b 100%);
  background-size: 220% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: #f2c94c;
  font-weight: 600;
  animation: nav-gold-shine 5s ease-in-out infinite;
}
.nav-list a.nav-gold:hover {
  background-color: rgba(242, 201, 76, .1);
  animation-duration: 1.6s;
}
@keyframes nav-gold-shine {
  0%   { background-position: 200% 0; }
  100% { background-position: -20% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .nav-list a.nav-gold { animation: none; background-position: 0 0; }
}
.sidebar-footer-line {
  margin-top: 1.4rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line-hair);
  font-size: .74rem;
  font-style: italic;
  color: var(--text-dim);
}

.dash-center-header { margin-bottom: 1.6rem; }
.welcome-title { font-size: clamp(1.4rem, 3vw, 1.9rem); margin-bottom: .5rem; }
.welcome-tag { color: var(--text-dim); font-size: .92rem; }
.provider-badge {
  display: inline-flex; align-items: center; gap: .3rem;
  font-size: .68rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--teal-accent); background: var(--teal-dim);
  border-radius: 999px; padding: .15rem .55rem; margin-left: .5rem;
  vertical-align: middle;
}

.section-heading {
  font-family: 'Chakra Petch', 'Orbitron', sans-serif;
  font-weight: 700;
  font-size: 1.05rem;
  margin: 2rem 0 1rem;
  color: var(--text-body);
}
.section-heading:first-child { margin-top: 0; }

/* scheduled sessions list */
.sessions-list { display: flex; flex-direction: column; gap: .8rem; }
.session-row {
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  gap: 1rem;
  align-items: center;
  padding: .9rem 1.1rem;
  border-radius: var(--radius-md);
  position: relative;   /* anchors the absolutely-placed .row-expand-cue */
  cursor: pointer;      /* whole row body opens the detail overlay (Plan 2) */
}
/* row-body hover / focus glow — reuses the .glass transition already on the row */
.session-row:hover,
.session-row:focus-visible {
  border-color: rgba(var(--teal-accent-rgb), .38);
  box-shadow: var(--elev-3);
  transform: translateY(-2px);
  outline: none;
}
@media (max-width: 700px) { .session-row { grid-template-columns: 1fr; text-align: left; } }
.session-date { font-family: 'Chakra Petch', 'Orbitron', sans-serif; font-size: .82rem; color: var(--teal-accent); white-space: nowrap; }
.session-with { font-size: .85rem; color: var(--text-dim); }
.session-type { font-size: .78rem; color: var(--text-body); }

/* discoverability glyph — top-right, out of grid flow (position:absolute),
   pointer-events:none so clicks fall through to the row body */
.row-expand-cue {
  position: absolute;
  top: .5rem;
  right: .7rem;
  font-size: .85rem;
  line-height: 1;
  color: var(--text-dim);
  opacity: .4;
  pointer-events: none;
  transition: opacity .25s var(--ease), color .25s var(--ease), transform .25s var(--ease);
}
.session-row:hover .row-expand-cue,
.session-row:focus-visible .row-expand-cue {
  opacity: .95;
  color: var(--teal-accent);
  transform: translate(1px, -1px);
}

/* two-party confirmation cell — replaces the single status pill.
   Uses a .status-pill as the combined verdict, plus two clickable
   confirm chips (student + teacher). Mock/localStorage only. */
.session-confirms {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: .4rem;
  white-space: nowrap;
}
@media (max-width: 700px) { .session-confirms { align-items: flex-start; } }

.confirm-verdict { align-self: flex-end; }
@media (max-width: 700px) { .confirm-verdict { align-self: flex-start; } }

.confirm-chip-row { display: flex; gap: .4rem; flex-wrap: wrap; }

.confirm-chip {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .28rem .6rem;
  border-radius: 999px;
  font-family: 'Rajdhani', sans-serif;
  font-size: .66rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  font-weight: 700;
  border: 1px solid var(--line-hair);
  background: rgba(var(--bg-panel-raised-rgb), .8);
  color: var(--text-dim);
  cursor: pointer;
  white-space: nowrap;
  transition: border-color .25s var(--ease), background .25s var(--ease),
              color .25s var(--ease), transform .2s var(--ease), box-shadow .25s var(--ease);
}
.confirm-chip .chip-dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  border: 1px solid var(--text-dim);
  background: transparent;
  flex-shrink: 0;
  transition: background .25s var(--ease), border-color .25s var(--ease), box-shadow .25s var(--ease);
}
.confirm-chip:hover { transform: translateY(-1px); border-color: rgba(var(--teal-accent-rgb), .5); }

/* pending = hollow / dim */
.confirm-chip.pending { color: var(--text-dim); }
.confirm-chip.pending .chip-dot { background: transparent; border-color: var(--text-dim); }

/* confirmed = filled / green */
.confirm-chip.confirmed {
  color: var(--status-green);
  border-color: rgba(62, 207, 106, .5);
  background: rgba(62, 207, 106, .12);
}
.confirm-chip.confirmed .chip-dot {
  background: var(--status-green);
  border-color: var(--status-green);
  box-shadow: 0 0 6px rgba(62, 207, 106, .7);
}

/* read-only mirror — the other party's slot on a given dashboard */
.confirm-chip.readonly {
  cursor: default;
  opacity: .78;
}
.confirm-chip.readonly:hover { transform: none; border-color: var(--line-hair); }
.confirm-chip.readonly.confirmed:hover { border-color: rgba(62, 207, 106, .5); }

.empty-state {
  text-align: center;
  color: var(--text-dim);
  font-size: .9rem;
  padding: 1.6rem;
  border: 1px dashed var(--line-hair);
  border-radius: var(--radius-md);
}

/* ==========================================================================
   PLAN 2 — SCHEDULED-SESSION DETAIL OVERLAY
   Centered dark-glass modal. Row body opens it; confirm chips never do.
   Shared shell injected once by renderSessions on BOTH dashboards.
   Mock/localStorage only — no backend.
   ========================================================================== */
.session-modal {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.2rem;
  background: rgba(var(--bg-void-rgb), .72);
  backdrop-filter: blur(4px) saturate(120%);
  -webkit-backdrop-filter: blur(4px) saturate(120%);
  opacity: 0;
  visibility: hidden;
  transition: opacity .32s var(--ease), visibility .32s var(--ease);
}
.session-modal.open { opacity: 1; visibility: visible; }

/* floating card reuses .glass (bg-panel .55 + blur + teal border + radius-lg) */
.session-modal-card {
  position: relative;
  width: min(92vw, 460px);
  max-height: 88vh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 1.6rem;
  box-shadow: var(--elev-4);
  transform: translateY(12px) scale(.98);
  opacity: 0;
  transition: transform .32s var(--ease), opacity .32s var(--ease);
}
.session-modal.open .session-modal-card {
  transform: translateY(0) scale(1);
  opacity: 1;
}

/* round close X — .btn-ghost feel: hair border, dim -> teal on hover */
.session-modal-close {
  position: absolute;
  top: .9rem;
  right: .9rem;
  width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px solid var(--line-hair);
  background: transparent;
  color: var(--text-dim);
  font-size: 1.15rem;
  line-height: 1;
  cursor: pointer;
  transition: color .25s var(--ease), border-color .25s var(--ease), background .25s var(--ease);
}
.session-modal-close:hover {
  color: var(--teal-accent);
  border-color: rgba(var(--teal-accent-rgb), .5);
  background: rgba(var(--teal-accent-rgb), .08);
}

.modal-head {
  display: flex;
  align-items: center;
  gap: .8rem;
  flex-wrap: wrap;
  padding-right: 2.2rem;   /* clear the close button */
  margin-bottom: 1.1rem;
}
.modal-title {
  font-family: 'Chakra Petch', 'Orbitron', sans-serif;
  font-weight: 800;
  font-size: 1.15rem;
  color: var(--text-body);
  margin: 0;
}

.modal-detail-list { display: flex; flex-direction: column; gap: 0; }
.modal-detail-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: .5rem 0;
  border-bottom: 1px solid rgba(var(--bg-panel-raised-rgb), .7);
}
.modal-detail-row:last-child { border-bottom: 0; }
.modal-detail-label {
  font-family: 'Rajdhani', sans-serif;
  font-size: .68rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-dim);
  flex-shrink: 0;
}
.modal-detail-value {
  font-size: .9rem;
  color: var(--text-body);
  text-align: right;
}
.modal-ph { font-style: italic; color: var(--text-dim); font-size: .82rem; }

/* MOCK flag — reuses the .tile-kicker look (Rajdhani caps, teal, tracked) */
.modal-mock-tag {
  display: inline-block;
  font-family: 'Rajdhani', sans-serif;
  font-weight: 700;
  font-size: .56rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--teal-accent);
  border: 1px solid rgba(var(--teal-accent-rgb), .35);
  border-radius: 999px;
  padding: .05rem .4rem;
  margin-left: .35rem;
  vertical-align: middle;
}

/* in-modal confirm controls reuse .session-confirms / .confirm-chip / .status-pill;
   only realign them left inside the card */
.modal-confirm-block {
  margin-top: 1.2rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--line-hair);
  display: flex;
  flex-direction: column;
  gap: .6rem;
}
.modal-confirm-block .session-confirms { align-items: flex-start; white-space: normal; }
.modal-confirm-block .confirm-verdict { align-self: flex-start; }

body.modal-open { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  .session-modal,
  .session-modal-card { transition: opacity .2s linear; }
  .session-modal-card,
  .session-modal.open .session-modal-card { transform: none; }
}

/* first-fire tour — 5-step Back/Next walkthrough, dashboard.html only.
   Reuses the site's glass card + btn system, matches the modal's fixed
   dark backdrop pattern. */
.tour-backdrop {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  background: rgba(var(--bg-void-rgb), .72);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.tour-backdrop[hidden] { display: none; }
.tour-card {
  width: 100%;
  max-width: 420px;
  padding: 2rem 1.8rem 1.6rem;
  text-align: center;
}
.tour-dots {
  display: flex;
  justify-content: center;
  gap: .4rem;
  margin-bottom: 1.1rem;
}
.tour-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: rgba(var(--teal-accent-rgb), .3);
  transition: background .25s var(--ease), transform .25s var(--ease);
}
.tour-dot.active {
  background: var(--teal-accent);
  transform: scale(1.3);
}
.tour-title {
  font-family: 'Chakra Petch', 'Orbitron', sans-serif;
  font-weight: 800;
  font-size: 1.2rem;
  color: var(--text-body);
  margin-bottom: .6rem;
}
.tour-desc {
  font-size: .92rem;
  color: var(--text-dim);
  line-height: 1.5;
  margin-bottom: 1.6rem;
}
.tour-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}
.tour-nav { display: flex; gap: .6rem; }
@media (prefers-reduced-motion: reduce) {
  .tour-dot { transition: none; }
}

/* lessons log — Session History overlay riding the tour-backdrop shell.
   Read-only list of the user's real bookings; active rows tinted accent. */
.lessons-log-card {
  max-width: 520px;
  text-align: left;
}
.lessons-log-list {
  display: flex;
  flex-direction: column;
  margin: 1rem 0 1.4rem;
  max-height: 340px;
  overflow-y: auto;
}
.lessons-log-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: .85rem .2rem;
  border-top: 1px solid rgba(var(--teal-accent-rgb), .14);
}
.lessons-log-row:first-child { border-top: none; }
.lessons-log-row .status-pill { flex-shrink: 0; }
.lessons-log-title {
  font-family: 'Chakra Petch', 'Orbitron', sans-serif;
  font-weight: 800;
  font-size: .92rem;
  color: var(--text-body);
  margin-bottom: .2rem;
}
.lessons-log-row.active .lessons-log-title { color: var(--teal-accent); }
.lessons-log-meta {
  font-size: .8rem;
  color: var(--text-dim);
}

/* inquiry tiles row */
.inquiry-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.1rem;
  margin-bottom: 2rem;
}
@media (max-width: 700px) { .inquiry-row { grid-template-columns: 1fr; } }

/* access gates row on dashboard */
.access-gates {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
  margin-bottom: 2rem;
}

/* gate hero — Trainer Verification promoted to a full-width rectangle,
   weighted like the Featured Trainer Spot tile. Payout + VRChat sit
   centered beneath it in .gate-pair. */
.gate-hero { margin-bottom: 1rem; }
/* Plain centered stack — matches .gate-pair--stacked .tile's layout below
   (kicker -> title -> desc -> button), so all 3 Teacher Gates tiles share
   one visual pattern. No photo, no split grid. */
.gate-hero-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 1.8rem 1.6rem;
}
.gate-hero-btn { margin-top: .9rem; }

.gate-pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
  max-width: 640px;
  margin: 0 auto 2rem;
}

/* --stacked modifier — Payout Setup + VRChat Gate rendered as a vertical
   stack of full-width tiles matching .gate-hero, instead of the 2-up
   .gate-pair row. Scoped modifier class (same pattern as dashboard.html's
   .lesson-lane-tile/.tile-span-3 stack change) so the base .gate-pair rule
   above stays untouched. */
.gate-pair.gate-pair--stacked {
  grid-template-columns: 1fr;
  max-width: none;
  margin: 0 0 1rem;
}
.gate-pair--stacked .tile {
  padding: 1.8rem 1.6rem;
  min-height: 168px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.gate-hero-inner { min-height: 168px; }

@media (max-width: 700px) {
  .gate-pair { grid-template-columns: 1fr; }
}
@media (max-width: 760px) { .access-gates { grid-template-columns: 1fr; } }

/* right rail */
.rail-block + .rail-block { margin-top: 1.2rem; }
.seal-slot { text-align: center; }
.seal-ring {
  position: relative;
  width: 78px; height: 78px;
  margin: 0 auto .8rem;
  border-radius: 50%;
}
.seal-ring::before {
  content: "";
  position: absolute; inset: -3px;
  border-radius: 50%;
  background: conic-gradient(from var(--angle), var(--teal-mid), var(--teal-accent), #a6faff, var(--teal-accent), var(--teal-mid));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  padding: 3px;
  animation: spin-ring 6s linear infinite;
}
@media (prefers-reduced-motion: reduce) { .seal-ring::before { animation: none; } }
.seal-ring span {
  position: relative; z-index: 1;
  width: 100%; height: 100%; border-radius: 50%;
  background: radial-gradient(circle at 35% 25%, var(--bg-panel-raised), var(--bg-void) 75%);
  display: flex; align-items: center; justify-content: center;
  color: var(--text-dim); font-size: .62rem; text-align: center; letter-spacing: .05em; text-transform: uppercase; padding: .3rem;
}
.identity-tier { text-align: center; font-family: 'Chakra Petch', 'Orbitron', sans-serif; font-size: .82rem; color: var(--teal-accent); margin-bottom: .3rem; }
.activity-feed { display: flex; flex-direction: column; gap: .6rem; margin-top: .6rem; }
.activity-item { font-size: .8rem; color: var(--text-dim); border-left: 2px solid var(--line-hair); padding-left: .7rem; }
.activity-item strong { color: var(--text-body); }

/* ---------- membership card (bottom, flagship spotlight card) ---------- */
.membership-card {
  position: relative;
  isolation: isolate;
  margin-top: .8rem;
  border-radius: var(--radius-lg);
  padding: 1rem 1.25rem;
  background-color: rgba(var(--bg-panel-rgb), .6);
  background-image:
    linear-gradient(155deg, rgba(56,232,255,.07), transparent 60%),
    linear-gradient(rgba(var(--bg-void-rgb), .3), rgba(var(--bg-void-rgb), .3));
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  border: 1px solid rgba(var(--teal-accent-rgb), .22);
  box-shadow: var(--elev-3);
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 1rem;
  align-items: center;
  text-align: left;
}
.membership-card::after {
  content: "";
  position: absolute; inset: 0; border-radius: inherit;
  background: radial-gradient(220px circle at var(--x, 50%) var(--y, 50%), rgba(56,232,255,.14), transparent 65%);
  opacity: 0; transition: opacity .3s ease; pointer-events: none;
}
.membership-card:hover::after { opacity: 1; }
.card-avatar {
  width: 44px; height: 44px; border-radius: 50%;
  background: radial-gradient(circle at 35% 25%, var(--bg-panel-raised), var(--bg-void) 75%);
  border: 1px solid var(--line-hair);
}
.card-name { font-family: 'Chakra Petch', 'Orbitron', sans-serif; font-size: 1rem; margin-bottom: .2rem; text-align: left; }
.card-meta { font-size: .76rem; color: var(--text-dim); text-align: left; }
.card-flourish {
  display: block;
  margin-top: .3rem;
  font-family: 'Chakra Petch', 'Orbitron', sans-serif;
  font-size: .68rem;
  letter-spacing: .1em;
  color: var(--teal-accent);
  text-align: left;
}

/* dashboard footer bar */
.dash-footer-bar {
  margin-top: 1.6rem;
  text-align: center;
  color: var(--text-dim);
  font-size: .82rem;
}
.dash-footer-bar .rights { margin-top: .4rem; font-size: .74rem; }

/* ==========================================================================
   FORMS — glass inputs, used on create-profile.html
   ========================================================================== */
.form-group { margin-bottom: 1.2rem; text-align: left; }
.form-label {
  display: block;
  font-size: .78rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: .4rem;
}
.form-input, .form-textarea, .form-select {
  width: 100%;
  padding: .75rem .9rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line-hair);
  background: rgba(var(--bg-void-rgb), .5);
  color: var(--text-body);
  font-family: 'Rajdhani', sans-serif;
  font-size: 1rem; /* 16px minimum — prevents iOS Safari auto-zoom on focus */
  transition: border-color .25s var(--ease), box-shadow .25s var(--ease);
}
.form-input:focus, .form-textarea:focus, .form-select:focus {
  outline: none;
  border-color: var(--teal-accent);
  box-shadow: 0 0 0 3px rgba(56, 232, 255, .12);
}
.form-textarea { resize: vertical; min-height: 100px; }

/* table type / input tile pickers — checkbox/radio driven .tile look */
.picker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: .9rem;
  margin-bottom: 1.6rem;
}
.picker-tile {
  position: relative;
  cursor: pointer;
  border-radius: var(--radius-md);
  border: 1px solid var(--line-hair);
  background: rgba(var(--bg-panel-raised-rgb), .5);
  padding: 1.1rem .9rem;
  text-align: center;
  transition: border-color .25s var(--ease), transform .25s var(--ease), background .25s var(--ease);
}
.picker-tile input { position: absolute; opacity: 0; inset: 0; cursor: pointer; margin: 0; }
.picker-tile .picker-icon { font-size: 1.4rem; margin-bottom: .4rem; }
.picker-tile .picker-label { font-size: .82rem; font-weight: 600; color: var(--text-body); }
.picker-tile .picker-sub { font-size: .7rem; color: var(--text-dim); margin-top: .2rem; }
.picker-tile:hover { transform: translateY(-2px); border-color: rgba(var(--teal-accent-rgb), .4); }
.picker-tile.selected {
  border-color: var(--teal-accent);
  background: rgba(var(--teal-accent-rgb), .1);
  box-shadow: 0 0 0 1px rgba(var(--teal-accent-rgb), .4), var(--elev-3);
}
.picker-tile[data-disabled="true"] { opacity: .35; pointer-events: none; }

.step-heading {
  display: flex;
  align-items: center;
  gap: .6rem;
  margin: 1.8rem 0 1rem;
}
.step-num {
  width: 26px; height: 26px;
  border-radius: 50%;
  background: var(--teal-dim);
  color: var(--teal-accent);
  display: flex; align-items: center; justify-content: center;
  font-family: 'Chakra Petch', 'Orbitron', sans-serif;
  font-size: .78rem;
  flex-shrink: 0;
}
.step-title {
  font-family: 'Rajdhani', sans-serif;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  font-size: .85rem;
  color: var(--text-body);
}

/* ==========================================================================
   NEUMORPHIC RECESSED CONTROLS — mic / volume style widgets ONLY
   (sparing use, matched-hue dual box-shadow, never full cards)
   ========================================================================== */
.neu-control {
  background: var(--bg-panel);
  border-radius: var(--radius-md);
  box-shadow:
    inset 4px 4px 10px rgba(0, 0, 0, .55),
    inset -4px -4px 10px rgba(45, 55, 70, .18);
  padding: 1.1rem 1.2rem;
}
.neu-control-label {
  display: flex;
  justify-content: space-between;
  font-size: .74rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: .7rem;
}
.neu-control-label span:last-child { color: var(--teal-accent); }

input[type="range"].neu-slider {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 8px;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--teal-accent) var(--val, 50%), rgba(255, 255, 255, .06) 0);
  box-shadow:
    inset 2px 2px 5px rgba(0, 0, 0, .6),
    inset -2px -2px 5px rgba(45, 55, 70, .18);
  outline: none;
  cursor: pointer;
}
input[type="range"].neu-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 20px; height: 20px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #eafcff, var(--teal-accent) 60%, var(--teal-mid));
  box-shadow: 0 0 10px rgba(56, 232, 255, .65), 2px 2px 5px rgba(0, 0, 0, .5);
  cursor: pointer;
  border: none;
  margin-top: -6px;
}
input[type="range"].neu-slider::-moz-range-thumb {
  width: 20px; height: 20px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #eafcff, var(--teal-accent) 60%, var(--teal-mid));
  box-shadow: 0 0 10px rgba(56, 232, 255, .65), 2px 2px 5px rgba(0, 0, 0, .5);
  cursor: pointer;
  border: none;
}
input[type="range"].neu-slider::-moz-range-track {
  height: 8px; border-radius: 999px;
  background: rgba(255,255,255,.06);
  box-shadow: inset 2px 2px 5px rgba(0,0,0,.6), inset -2px -2px 5px rgba(45,55,70,.18);
}

.neu-mic-btn {
  width: 54px; height: 54px;
  border-radius: 50%;
  background: var(--bg-panel);
  box-shadow:
    6px 6px 12px rgba(0, 0, 0, .55),
    -6px -6px 12px rgba(45, 55, 70, .16);
  border: none;
  color: var(--teal-accent);
  font-size: 1.2rem;
  cursor: pointer;
  transition: box-shadow .25s var(--ease);
}
.neu-mic-btn:active {
  box-shadow:
    inset 4px 4px 8px rgba(0, 0, 0, .6),
    inset -4px -4px 8px rgba(45, 55, 70, .18);
}

/* ==========================================================================
   MISC UTILITIES
   ========================================================================== */
.center { text-align: center; }
.mt-0 { margin-top: 0; }
.mb-0 { margin-bottom: 0; }
.stack { display: flex; flex-direction: column; gap: 1rem; }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }

.badge-outline {
  display: inline-block;
  font-size: .68rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-dim);
  border: 1px solid var(--line-hair);
  border-radius: 999px;
  padding: .2rem .6rem;
}

.specialty-tag {
  display: inline-block;
  font-size: .74rem;
  color: var(--teal-accent);
  background: var(--teal-dim);
  border-radius: 999px;
  padding: .2rem .6rem;
  margin-bottom: .5rem;
}

.rate-line { font-family: 'Chakra Petch', 'Orbitron', sans-serif; font-size: .95rem; color: var(--text-body); margin: .4rem 0; }

.field-block { margin-bottom: 1.1rem; }
.field-block .field-label {
  font-size: .72rem; letter-spacing: .12em; text-transform: uppercase; color: var(--text-dim); margin-bottom: .3rem; display: block;
}
.field-block .field-value { color: var(--text-body); font-size: .92rem; }

.not-found-block {
  max-width: 480px;
  margin: 2rem auto;
  text-align: center;
  padding: 2.2rem 1.6rem;
}

/* ---------- footer nav (the site's 13-link nav, split across two rows on
   index.html and a shorter set on inner pages) — mobile tap-target pass.
   Kept as a wrapping flex list rather than a hamburger: it already lives at
   the page bottom (not a sticky top bar), so collapsing it behind a toggle
   would hide it further, not simplify it. Instead each link gets a real
   44px-tall tap target and breathing room once it stacks on phones. ---------- */
@media (max-width: 700px) {
  .footer-links {
    gap: .9rem 1.4rem;
    padding: 1.2rem 1rem 1.8rem;
  }
  .footer-links a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    min-width: 44px;
    padding: .5rem .3rem;
  }
}

/* Global: the hidden attribute must win over any display rule (teacher-only tiles etc.) */
[hidden] { display: none !important; }

/* ================================================================
   MOBILE PERFORMANCE LAYER — added 2026-08-27 (mobile optimize pass)
   Phones (<768px) get the same look with the expensive parts off:
   · the two fixed aurora layers stop drifting and blur less (a 75px
     blur on a 150%-viewport layer repainting every frame is the #1
     jank source on phones)
   · every INFINITE decorative loop (spin rings, gold nav shine, live
     pulse, plus-icon spin) stops. One-shot entrance animations
     (waov-rise, tp-race, sheen-sweep) are kept — they are short.
   Desktop is untouched.
   ================================================================ */
@media (max-width: 767px) {
  body::before, body::after {
    animation: none;
    filter: blur(40px);
    will-change: auto;
    inset: -10%;
  }
  .crest::before,
  .ring-card::before,
  .avatar-circle::before,
  .seal-ring::before,
  .plus-icon-spin,
  .live-badge,
  .nav-list a.nav-gold { animation: none; }
  .nav-list a.nav-gold { background-position: 0 0; }
}

/* ================================================================
   PERF PASS 2026-08-27 (shared, mobile only). Backdrop blur is the
   single most expensive paint on phones, so ≤640px panels go solid;
   fixed / inline utility links reach the 44px tap minimum; and the
   .waov-offscreen helper lets a page pause animations that an
   IntersectionObserver has scrolled out of view. Desktop untouched.
   ================================================================ */
@media (max-width: 640px) {
  .glass, .footer-band, .dash-panel { backdrop-filter: none; -webkit-backdrop-filter: none; }
  .glass, .dash-panel { background-color: rgba(var(--bg-panel-rgb), .88); }
  .footer-band { background: rgba(var(--bg-panel-rgb), .88); }
  .back-link { min-height: 44px; }
  .nav-list a, .nav-list .nav-item { min-height: 44px; display: flex; align-items: center; }
}
.waov-offscreen, .waov-offscreen *, .waov-offscreen::before, .waov-offscreen::after { animation-play-state: paused !important; }

/* ==========================================================================
   INDEX.HTML-MATCHED VISUAL OVERLAY — preview pass, 2026-09-17
   Pulls the real font + tile tokens straight from the live index.html
   (Anton headline, .action-tile border/gradient/hover-glow) onto the
   dashboards. Purely additive: no existing id/class removed or renamed,
   so auth.js/bookings.js/profiles.js/ui.js selectors are untouched.
   ========================================================================== */
.welcome-title,
.crest span {
  font-family: 'Chakra Petch', 'Orbitron', sans-serif;
}

/* .nav-list--tiles: opt-in modifier, same visual language as index.html's
   .action-tile (2px solid #38e8ff border, dark diagonal gradient fill,
   cyan hover glow) — applied via markup class, not a blanket .nav-list
   override, so login.html and any other .nav-list page stay as-is. */
.nav-list--tiles li + li { margin-top: .6rem; }
.nav-list--tiles a,
.nav-list--tiles .nav-item {
  display: block;
  border: 2px solid transparent;
  background:
    linear-gradient(155deg, rgba(15, 15, 15, .9), rgba(0, 0, 0, .95)) padding-box,
    conic-gradient(from var(--angle), #001eff, #00c8ff, #7000ff, #001eff) border-box;
  animation: spin-ring 7s linear infinite;
  padding: .7rem 1rem;
  border-radius: 0;
  transition: filter .25s ease, box-shadow .25s ease;
}
.nav-list--tiles a:hover,
.nav-list--tiles .nav-item:hover {
  color: #6fa8ff;
  filter: saturate(1.4) brightness(1.2);
  box-shadow: 0 0 26px -3px rgba(26, 92, 255, .85);
}
@media (prefers-reduced-motion: reduce) {
  .nav-list--tiles a, .nav-list--tiles .nav-item { animation: none; }
}

/* Hide the dev-only TEST HARNESS bar for this design review — it's already
   gated off production by hostname, this just keeps it off the local
   preview too. Pure display:none, no markup/JS touched. */
#testHarness { display: none !important; }

/* dashboard.html only — Vocal/Claude/DJ Lessons tiles trimmed ~10% shorter
   (padding cut, not font-size, so text stays the same size). */
.lesson-lane-tile .tile { padding: 1.44rem 1.5rem; }

/* dashboard.html only — same border treatment as every other tile (1px at
   rest, brighter + glow on hover), just swapped to red (#ff0040, already
   used in the site's own conic-gradient palette) instead of teal. */
.lesson-lane-tile .glass {
  border: 2px solid transparent;
  background:
    linear-gradient(155deg, rgba(15, 15, 15, .92), rgba(0, 0, 0, .96)) padding-box,
    conic-gradient(from var(--angle), #ff0040, #ff6a00, #ff0090, #ff0040) border-box;
  animation: lesson-tile-sway 9s ease-in-out infinite alternate;
}
.lesson-lane-tile.ring-card:hover .glass,
.lesson-lane-tile.ring-card:focus-within .glass {
  filter: saturate(1.4) brightness(1.2);
  box-shadow: 0 0 32px -2px rgba(255, 0, 64, .85);
}
/* filled conic-gradient border — slow, small-amplitude drift back and forth,
   like a current, instead of a mechanical spin or a wide harsh swing. */
@keyframes lesson-tile-sway { to { --angle: 22deg; } }
@media (prefers-reduced-motion: reduce) { .lesson-lane-tile .glass { animation: none; } }

/* dashboard.html only — Services Hub tile, the My Schedule panel, and the
   Meet the Teachers tile all get the same border treatment as the sidebar
   nav tiles and the lesson lanes, just recolored neon yellow. Scoped via
   markup classes so the right-column Recent Activity/badge widgets (still
   cyan) are untouched. */
.services-hub-tile .glass,
.meet-teachers-tile .glass {
  border-width: 2px;
  border-color: rgba(242, 255, 0, .9);
}
.services-hub-tile.ring-card:hover .glass,
.services-hub-tile.ring-card:focus-within .glass,
.meet-teachers-tile.ring-card:hover .glass,
.meet-teachers-tile.ring-card:focus-within .glass {
  border-color: rgba(242, 255, 0, 1);
  box-shadow: 0 0 28px -2px rgba(242, 255, 0, .75);
}
.schedule-panel-yellow {
  border-width: 2px;
  border-color: rgba(242, 255, 0, .9);
  transition: border-color .25s ease, box-shadow .25s ease;
}
.schedule-panel-yellow:hover,
.schedule-panel-yellow:focus-within {
  border-color: rgba(242, 255, 0, 1);
  box-shadow: 0 0 28px -2px rgba(242, 255, 0, .75);
}

/* dashboard.html only — right-rail badge/Recent Activity widget, brought
   into the same neon scheme (blue sidebar, red lessons, yellow services)
   with a 4th hue, neon green, so it reads as part of the set instead of
   the odd cyan one out. */
.right-rail-tile {
  border: 2px solid transparent;
  background-image:
    linear-gradient(rgba(var(--bg-panel-rgb), .55), rgba(var(--bg-panel-rgb), .55)),
    linear-gradient(rgba(var(--bg-void-rgb), .28), rgba(var(--bg-void-rgb), .28)),
    conic-gradient(from var(--angle), #00ff66, #00fff2, #7cff00, #00ff66);
  background-origin: padding-box, padding-box, border-box;
  background-clip: padding-box, padding-box, border-box;
  animation: spin-ring 6s linear infinite;
}
.right-rail-tile:hover,
.right-rail-tile:focus-within {
  filter: saturate(1.4) brightness(1.2);
  box-shadow: 0 0 32px -2px rgba(0, 255, 102, .85);
}
@media (prefers-reduced-motion: reduce) { .right-rail-tile { animation: none; } }

/* dashboard.html only — a tiny divider line directly above the lesson-lane
   tile group (spans the full 3-col grid so it doesn't just sit in column 1). */
.lesson-lane-top-line {
  grid-column: 1 / -1;
  height: 1px;
  background: var(--line-hair);
  margin: .2rem 0 .4rem;
}

/* dashboard.html only — matching tiny line at the top of the left sidebar,
   above the avatar, so both columns open on the same thin divider. */
.sidebar-top-line {
  height: 1px;
  background: var(--line-hair);
  margin: 0 0 1rem;
}

/* dashboard.html + teacher-dashboard.html — hide the "No Avatar" placeholder
   box in the left sidebar. Not JS-referenced anywhere (grepped both auth.js
   and bookings.js, no getElementById('avatarCircle') calls), so display:none
   is safe — no functional dependency, purely a visual removal. */
#avatarCircle { display: none; }

/* dashboard.html + teacher-dashboard.html — Teacher Dashboard and Accounting
   left-panel nav links only. Overrides the shared .nav-list--tiles tile
   border/background with a borderless look: no box, no fill, just a thick
   soft-edged white paint-stripe down the left side. Scoped to
   .nav-list--tiles a.nav-gold so no other nav-list item or page is touched. */
.nav-list--tiles a.nav-gold {
  border: none;
  padding-left: 1.1rem;
  position: relative;
}
.nav-list--tiles a.nav-gold::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: 8%;
  bottom: 8%;
  left: 0;
  width: 6px;
  background: rgba(255, 255, 255, .8);
  filter: blur(1.5px);
  border-radius: 3px;
  animation: paint-stripe-sway 9s ease-in-out infinite alternate;
}
.nav-list--tiles a.nav-gold:hover {
  box-shadow: none;
}
.nav-list--tiles a.nav-gold:hover::before {
  background: rgba(255, 255, 255, 1);
  filter: blur(1px);
}
/* same slow, small-amplitude drift as the lesson tiles — a soft glow that
   breathes in and out, not a hard on/off flicker. */
@keyframes paint-stripe-sway {
  from { box-shadow: 0 0 2px rgba(255, 255, 255, .3); }
  to   { box-shadow: 0 0 10px rgba(255, 255, 255, .9); }
}
@media (prefers-reduced-motion: reduce) { .nav-list--tiles a.nav-gold::before { animation: none; } }

/* ============ FLAGSHIP SHARED BLOCK (canonical copy, appended 2026-09-19) ============ */
.cnm-root .tp-shell { --tp-stage-h: clamp(520px, 68vh, 780px); }
@media (max-width: 620px) {
  .cnm-root .tp-shell { --tp-stage-h: clamp(380px, 54vh, 480px); }
}
.cnm-root .tp-shell-body { padding-top: calc(var(--tp-stage-h) * .24); }
.cnm-root .tp-stage-texture {
  background-image:
    linear-gradient(155deg, rgba(var(--cnm-violet-rgb), .34), rgba(var(--cnm-magenta-rgb), .20)),
    repeating-linear-gradient(45deg, rgba(255, 255, 255, .03) 0 10px, transparent 10px 20px),
    linear-gradient(rgba(var(--cnm-magenta-rgb), .07) 1px, transparent 1px),
    linear-gradient(90deg, rgba(var(--cnm-magenta-rgb), .07) 1px, transparent 1px);
}
.cnm-root .tp-stage-photo { filter: blur(15px) saturate(1.45) brightness(.72) contrast(1.05); }
.cnm-root .tp-shell.tp-bleed .tp-stage-scrim {
  background:
    radial-gradient(ellipse 62% 78% at 50% 14%, rgba(var(--lane-glow-rgb,56,232,255), .18), transparent 62%),
    linear-gradient(180deg,
      rgba(42, 10, 82, .50) 0%,
      rgba(91, 26, 158, .52) 30%,
      rgba(184, 26, 125, .44) 54%,
      rgba(var(--bg-void-rgb), .88) 82%,
      var(--bg-void) 100%);
}
.cnm-root .tp-shell-body > .kicker,
.cnm-root .tp-shell-body .kicker { color: rgba(255,255,255,.72); letter-spacing: .32em; margin: 0 0 .4rem; }
.cnm-root .tp-shell-body .page-title { font-size: clamp(1.5rem, 4vw, 2.2rem); letter-spacing: .12em; margin-bottom: 1.6rem; text-shadow: 0 0 26px rgba(var(--cnm-magenta-rgb), .55), 0 2px 10px rgba(0,0,0,.7); text-align: center; }
.cnm-root .cnm-fan { position: relative; display: flex; justify-content: center; align-items: flex-end; max-width: 100%; margin: 0 auto 2.2rem; }
.cnm-root .cnm-poster { position: relative; flex: 0 0 auto; animation: waov-rise .7s cubic-bezier(.2,.8,.2,1) backwards; }
.cnm-root .cnm-poster.is-lead { z-index: 2; animation-delay: .46s; }
.cnm-root .cnm-poster.is-left { z-index: 1; animation-delay: .58s; margin-right: -46px; }
.cnm-root .cnm-poster.is-right { z-index: 1; animation-delay: .66s; margin-left: -46px; }
.cnm-root .cnm-poster-inner { position: relative; display: block; width: 100%; aspect-ratio: 776 / 1024; border-radius: var(--radius-md); overflow: hidden; background-color: rgba(var(--bg-panel-rgb), .9); background-size: cover; background-position: center 12%; background-repeat: no-repeat; transition: transform .6s var(--ease), filter .6s var(--ease); }
.cnm-root .cnm-poster.is-lead { width: clamp(212px, 29vw, 278px); }
.cnm-root .cnm-poster.is-lead .cnm-poster-inner { border: 1px solid rgba(var(--cnm-magenta-rgb), .5); box-shadow: 0 24px 60px rgba(0,0,0,.7), 0 0 46px rgba(var(--cnm-magenta-rgb), .32), inset 0 1px 0 rgba(255,255,255,.16); }
.cnm-root .cnm-poster.is-flank { width: clamp(172px, 23vw, 224px); }
.cnm-root .cnm-poster.is-flank .cnm-poster-inner { filter: saturate(.35) brightness(.5) contrast(1.05); border: 1px solid rgba(255,255,255,.1); box-shadow: 0 18px 44px rgba(0,0,0,.66); }
.cnm-root .cnm-poster.is-left .cnm-poster-inner { transform: rotate(-11deg) translateY(16px); }
.cnm-root .cnm-poster.is-right .cnm-poster-inner { transform: rotate(11deg) translateY(16px); }
.cnm-root .cnm-fan:hover .cnm-poster.is-left .cnm-poster-inner { transform: rotate(-16deg) translate(-16px, 8px); filter: saturate(.5) brightness(.62) contrast(1.05); }
.cnm-root .cnm-fan:hover .cnm-poster.is-right .cnm-poster-inner { transform: rotate(16deg) translate(16px, 8px); filter: saturate(.5) brightness(.62) contrast(1.05); }
@media (max-width: 820px) {
  .cnm-root .cnm-poster.is-flank { display: none; }
  .cnm-root .cnm-poster.is-lead { width: clamp(200px, 56vw, 260px); }
}
@media (prefers-reduced-motion: reduce) {
  .cnm-root .cnm-poster { animation: none; }
}
.cnm-root .cnm-now { position: absolute; left: 50%; bottom: -14px; transform: translateX(-50%); z-index: 4; display: inline-flex; align-items: center; gap: .5rem; padding: .42rem 1.1rem; border-radius: 999px; background: linear-gradient(100deg, var(--teal-mid), var(--teal-accent)); color: #04222b; font-family: 'Rajdhani', sans-serif; font-weight: 700; font-size: .74rem; letter-spacing: .22em; text-transform: uppercase; white-space: nowrap; box-shadow: 0 8px 26px rgba(0,0,0,.6), 0 0 26px var(--teal-accent-soft); animation: cnm-fade .5s ease-out 1.05s backwards; }
.cnm-root .cnm-now i { width: 7px; height: 7px; border-radius: 50%; background: #04222b; animation: cnm-blink 1.8s steps(1,end) infinite; }
@keyframes cnm-blink { 0%, 60% { opacity: 1; } 61%, 100% { opacity: .25; } }
@keyframes cnm-fade { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .cnm-root .cnm-now, .cnm-root .cnm-now i { animation: none; }
}
.cnm-root .cnm-sheet { position: relative; max-width: 660px; margin: 0 auto 2.6rem; padding: 2.4rem 1.9rem 2rem; border-radius: var(--radius-lg); border: 1px solid rgba(var(--cnm-magenta-rgb), .26); background: linear-gradient(168deg, rgba(var(--cnm-violet-rgb), .34) 0%, rgba(var(--cnm-magenta-rgb), .14) 46%, rgba(var(--bg-panel-rgb), .94) 100%), rgba(var(--bg-panel-rgb), .9); box-shadow: var(--elev-3), 0 0 70px rgba(var(--cnm-magenta-rgb), .18); backdrop-filter: blur(16px); }
.cnm-root .cnm-cert { position: absolute; top: -13px; left: 22px; display: inline-flex; align-items: center; gap: .3rem; padding: .26rem .74rem; border-radius: 7px; background: var(--cnm-magenta-hot); border: 1px solid rgba(255,255,255,.35); color: #fff; font-family: 'Orbitron', sans-serif; font-weight: 800; font-size: .68rem; letter-spacing: .16em; box-shadow: 0 6px 20px rgba(var(--cnm-magenta-rgb), .5); }
.cnm-root .cnm-sheet #teacherName { font-size: clamp(1.9rem, 5vw, 2.6rem); line-height: 1.05; text-align: left; margin: 0 0 .45rem; color: #fff; text-shadow: 0 2px 24px rgba(var(--cnm-magenta-rgb), .4); }
.cnm-root .cnm-metaline { display: flex; flex-wrap: wrap; align-items: center; gap: .55rem; font-family: 'Rajdhani', sans-serif; font-weight: 600; font-size: .84rem; letter-spacing: .08em; color: var(--text-dim); margin-bottom: 1.5rem; }
.cnm-root .cnm-metaline span:not(:last-child)::after { content: "\00b7"; margin-left: .55rem; color: rgba(var(--cnm-magenta-rgb), .8); }
.cnm-root .cnm-star { display: flex; align-items: center; gap: .85rem; padding: 1rem 1.1rem; border-radius: var(--radius-md); background: rgba(0,0,0,.26); border: 1px solid rgba(255,255,255,.07); border-left: 3px solid var(--cnm-gold); margin-bottom: 1.4rem; }
.cnm-root .cnm-star-glyph { font-size: 2.2rem; line-height: 1; color: var(--cnm-gold); text-shadow: 0 0 22px rgba(255,201,74,.6); }
.cnm-root .cnm-star-val { font-family: 'Orbitron', sans-serif; font-weight: 800; font-size: clamp(1.05rem, 3vw, 1.35rem); letter-spacing: .03em; color: #fff; line-height: 1.2; text-align: left; }
.cnm-root .cnm-star-cap { font-family: 'Rajdhani', sans-serif; font-weight: 600; font-size: .72rem; letter-spacing: .14em; text-transform: uppercase; color: var(--text-dim); margin-top: .18rem; }
.cnm-root .cnm-quote { position: relative; margin: 0 0 1.7rem; padding-left: 1.1rem; border-left: 2px solid rgba(var(--cnm-magenta-rgb), .55); font-family: 'Rajdhani', sans-serif; font-style: italic; font-weight: 500; font-size: 1.05rem; line-height: 1.6; color: rgba(238,241,245,.82); }
.cnm-root .cnm-head { display: flex; align-items: center; gap: .7rem; font-family: 'Orbitron', sans-serif; font-weight: 800; font-size: .78rem; letter-spacing: .2em; text-transform: uppercase; color: #fff; margin: 0 0 .7rem; }
.cnm-root .cnm-head::after { content: ""; flex: 1; height: 1px; background: linear-gradient(90deg, rgba(var(--cnm-magenta-rgb), .5), transparent); }
.cnm-root .cnm-synopsis { margin: 0 0 1.8rem; font-size: .98rem; line-height: 1.7; color: rgba(238,241,245,.78); }
.cnm-root .cnm-strip { display: grid; grid-template-columns: repeat(3, 1fr); align-items: start; gap: 1.2rem; padding: 1.3rem 0 1.5rem; border-top: 1px solid rgba(255,255,255,.09); border-bottom: 1px solid rgba(255,255,255,.09); margin-bottom: 1.6rem; }
.cnm-root .cnm-strip-label { display: block; font-family: 'Rajdhani', sans-serif; font-weight: 600; font-size: .68rem; letter-spacing: .16em; text-transform: uppercase; color: var(--text-dim); margin-bottom: .35rem; }
.cnm-root .cnm-strip-val { font-family: 'Rajdhani', sans-serif; font-weight: 700; font-size: .92rem; line-height: 1.45; color: #fff; }
.cnm-root .cnm-strip-val a { color: var(--teal-accent); }
@media (max-width: 560px) {
  .cnm-root .cnm-strip { grid-template-columns: 1fr; gap: 1rem; }
}
.cnm-root .cnm-lineup { text-align: center; font-family: 'Rajdhani', sans-serif; font-size: .72rem; letter-spacing: .18em; text-transform: uppercase; color: var(--text-dim); margin: -1rem 0 2.2rem; animation: cnm-fade .5s ease-out 1.15s backwards; }
@media (prefers-reduced-motion: reduce) {
  .cnm-root .cnm-lineup { animation: none; }
}
.cnm-root .wv-tile { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .9rem; width: 100%; max-width: 340px; aspect-ratio: 1.586 / 1; margin: 0 auto 1.6rem; padding: 1rem; border-radius: 14px; border: 1px solid rgba(var(--lane-glow-rgb,56,232,255),.34); background: linear-gradient(150deg, rgba(var(--cnm-violet-rgb), .40) 0%, rgba(var(--cnm-magenta-rgb), .16) 55%, rgba(var(--bg-panel-rgb), .92) 100%), rgba(0,0,0,.30); box-shadow: 0 14px 34px rgba(0,0,0,.55), 0 0 40px rgba(var(--cnm-magenta-rgb), .16); backdrop-filter: blur(12px); cursor: pointer; overflow: hidden; transition: transform .35s var(--ease), box-shadow .35s var(--ease), border-color .35s var(--ease); }
.cnm-root .wv-tile:hover, .cnm-root .wv-tile:focus-visible { transform: translateY(-4px); border-color: var(--cnm-magenta-hot); box-shadow: 0 20px 44px rgba(0,0,0,.6), 0 0 56px rgba(var(--cnm-magenta-rgb), .30); }
.cnm-root .wv-tile-cta { font-family: 'Orbitron', sans-serif; font-weight: 800; font-size: .8rem; letter-spacing: .14em; text-transform: uppercase; color: #fff; text-shadow: 0 2px 12px rgba(0,0,0,.7); }
.cnm-root .wv-tile-face { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .9rem; opacity: 1; transition: opacity .35s ease; }
.cnm-root .wv-tile-laptop { display: flex; align-items: center; justify-content: center; perspective: 420px; }
.cnm-root .wv-laptop-stub { width: 74px; height: 46px; border-radius: 6px; border: 1px solid rgba(255,255,255,.28); background: linear-gradient(160deg, rgba(var(--cnm-magenta-rgb), .45), rgba(var(--cnm-violet-rgb), .55)); box-shadow: 0 6px 18px rgba(0,0,0,.5); animation: wv-spin 6s linear infinite; }
@keyframes wv-spin { to { transform: rotateY(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .cnm-root .wv-laptop-stub { animation: none; }
}
.cnm-root .pay-pocket-flash { animation: pocketFlash 1s ease 2; }
@keyframes pocketFlash {
  0%, 100% { box-shadow: 0 0 0 0 rgba(var(--lane-glow-rgb,56,232,255),0); }
  50% { box-shadow: 0 0 0 16px rgba(var(--lane-glow-rgb,56,232,255),.38); }
}
@media (prefers-reduced-motion: reduce) {
  .cnm-root .pay-pocket-flash { animation: none; }
}

/* The editor (inputs, rate lock, save row, preview pills/overlay) moved to
   teacher.html on 2026-08-24 â€” its CSS was removed with it. Only the public
   profile + booking/checkout styles above remain in this file. */

/* ============ LANE-IDENTITY TILES (appended 2026-09-19) ============ */
/* ==========================================================================
   LANE-IDENTITY TILES (2026-09-19) â€” dashboard lesson tiles wear their lane:
   each category (vocal/claude/dj) gets the same glow ring the editor + profile
   use, so the three specialties read identically on the student home screen.
   Lane glow RGB values mirror profiles.js LANE_LOOK (280-color safe, matches
   the turquoise tail used elsewhere). Purely additive â€” existing tile layout
   untouched.
   ========================================================================== */
.lesson-lane-tile[data-lane='vocal']  { --tile-glow-rgb: 244,247,251; }
.lesson-lane-tile[data-lane='claude'] { --tile-glow-rgb: 255,157,71; }
.lesson-lane-tile[data-lane='dj']     { --tile-glow-rgb: 232,57,92; }
.lesson-lane-tile[data-lane] .glass   { border-color: rgba(var(--tile-glow-rgb), .42); }
.lesson-lane-tile[data-lane] .tile-kicker { color: rgb(var(--tile-glow-rgb)); }
.lesson-lane-tile[data-lane] .glass   { box-shadow: 0 0 22px rgba(var(--tile-glow-rgb), .12), inset 0 0 16px rgba(var(--tile-glow-rgb), .05); }
@media (prefers-reduced-motion: reduce) {
  .lesson-lane-tile[data-lane] .glass { box-shadow: none; }
}
/* canary guard: the karaoke-card tile must NOT exist â€” the left-panel
   "My Karaoke Card" nav item is the only perk-center entry point. */
.karaoke-card-tile { display: none !important; }
