/* Glass 2.0 — the material layer (theme/THEMING-PLAN.md, canon in
   theme/GLASS-2.0-IMPLEMENTATION-GUIDE.md).
   Loads after screens.css and re-materializes the existing component classes
   as milky glass on a soft white stage; color arrives as light, poured by
   js/glassfx.js. Deleting this file + js/glassfx.js restores the flat skin.

   Discipline carried over from the flat skin:
   - values come from tokens.css (the glass block), no importance overrides;
   - every animated selector here is mirrored in the reduced-motion block at
     the END of this file (this is the last stylesheet, so it wins ties);
   - specular sheen is painted as a background layer, never a pseudo-element,
     so it can't fight existing ::before/::after or cover content.

   Documented exceptions to "color is light, never paint":
   - one solid light-bringer per view (.btn primary, sent bubble, seg thumb,
     PAIR orb, selected gender chip) — canon §6.3;
   - safety/urgency keeps paint (.urgent, danger tags, destructive confirm). */

/* ---------- the stage ---------- */
body { background: var(--stage); }
.screen { background: var(--stage); }
/* overlay screens (landing/auth/onboarding) carry their own ambient light —
   they live outside the tab panes, so the wash engine never reaches them,
   and milky glass needs something behind it to read as glass */
.landing, .onb {
  background:
    radial-gradient(120% 70% at 82% -12%, rgba(var(--t), .13) 0%, rgba(var(--t), 0) 58%),
    radial-gradient(130% 80% at -14% 96%, rgba(14, 165, 233, .1) 0%, rgba(14, 165, 233, 0) 60%),
    var(--stage);
}

/* settings is a utility surface — it must not inherit the tab's mood (opened
   from the gold Ask tab it tinted yellow). Pin it neutral: brand-blue accents
   on a near-white ground for maximum legibility. */
.screen[data-screen="settings"] {
  --t: 61, 123, 255;
  --deep: #1D4ED8;
  background: var(--stage-settings);
}
/* settings profile header: centered column — photo on top, action and
   caption beneath. Scoped to settings so the onboarding picker keeps its
   side-by-side layout. */
.screen[data-screen="settings"] .photo-picker {
  flex-direction: column;
  align-items: center;
  gap: var(--s-3);
  margin: var(--s-2) 0 var(--s-5);
}
.screen[data-screen="settings"] .photo-picker .preview {
  width: 96px;
  height: 96px;
  box-shadow: 0 10px 26px -12px rgba(var(--shade), .35);
}
.screen[data-screen="settings"] .photo-picker > div {
  display: grid;
  justify-items: center;
  gap: var(--s-1);
  text-align: center;
}

/* ambient wash → spill receiver: the light engine anchors the mood radial
   at the last interaction (--spill-x/y) and recolors it via --t. Gradient
   recolors are discrete (gradients don't interpolate); the opacity fade
   carries the transition. */
.screen.root::before {
  bottom: 0;
  background:
    radial-gradient(80% 62% at var(--spill-x, 50%) var(--spill-y, 30%),
      rgba(var(--t), var(--amb-a1, .1)) 0%, rgba(var(--t), 0) 62%),
    radial-gradient(150% 120% at var(--spill-x, 50%) var(--spill-y, 30%),
      rgba(var(--t), var(--amb-a2, .045)) 0%, rgba(var(--t), 0) 72%);
}

/* the gold Ask tab gets a much lighter ambient hand — yellow light over
   dense content read as a film sitting ON the page and hurt legibility.
   Gold stays in the accents; the ambience goes to a whisper. */
.tab-pane[data-tab="ask"] { --amb-a1: .05; --amb-a2: .02; }
.tab-pane[data-tab="ask"] .gwash { opacity: .045; }
.tab-pane[data-tab="ask"] .gwash.b { opacity: .03; }
.tab-pane[data-tab="ask"] .gwash.c { opacity: .02; }

/* drifting pastel blobs — js/glassfx.js parents the three .gwash nodes into
   the ACTIVE root screen only (blur budget). */
.gwash {
  position: fixed;
  width: 440px;
  height: 440px;
  border-radius: var(--r-pill);
  filter: blur(90px);
  pointer-events: none;
  z-index: 0;
  opacity: .11;
  background: rgb(var(--t));
  will-change: transform;
  animation: gdrift 26s ease-in-out infinite;
}
.gwash.b { animation-delay: -9s; opacity: .07; }
.gwash.c { animation-delay: -18s; opacity: .05; }
@keyframes gdrift {
  0%, 100% { transform: translate3d(-4%, -3%, 0) scale(1); }
  50% { transform: translate3d(5%, 4%, 0) scale(1.08); }
}

/* ---------- the glass material ---------- */
/* Surfaces: sheen streak stacked over the milky gradient. Blur is spent on
   containers only (budget ≤8 per screen): cards, lists, sheets, chrome. */
.card,
.list,
.banner,
.seg,
.course-mini,
.heartcheck,
.segment,
.cal-grid {
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, 0) 26%,
      rgba(255, 255, 255, 0) 72%, rgba(255, 255, 255, .18) 100%),
    linear-gradient(150deg, var(--glass-hi), var(--glass-lo));
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.35);
  backdrop-filter: blur(var(--glass-blur)) saturate(1.35);
  border: 1px solid var(--glass-rim);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .95),
    0 16px 38px -16px rgba(var(--shade), .22);
}
.card, .list, .course-mini, .room-card, .story-card { border-radius: var(--r-lg); }

/* blur budget (≤8 backdrop-filter surfaces per screen): small tiles and cards
   on the opaque stage keep the milky gradients but spend no blur of their own
   — visually near-identical at this size */
.stat,
.options .opt,
.auth-role-tiles .opt,
.room-card,
.story-card {
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, 0) 26%,
      rgba(255, 255, 255, 0) 72%, rgba(255, 255, 255, .18) 100%),
    linear-gradient(150deg, var(--glass-hi), var(--glass-lo));
  border: 1px solid var(--glass-rim);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .95),
    0 16px 38px -16px rgba(var(--shade), .22);
}

/* lit — light only: inner glow + colored halo (state carried by glassfx or
   an .on/.lit class), never a repaint */
.lit,
.card.lit {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .95),
    inset 0 0 26px rgba(var(--t), .14),
    0 16px 38px -16px rgba(var(--shade), .22),
    0 10px 28px -8px rgba(var(--t), .45);
  transition: box-shadow var(--lit-ms) var(--ease);
}

/* the poured tint layer glassfx creates inside stateful elements */
.tintfx {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 0;
  opacity: 0;
  clip-path: circle(0px at 50% 50%);
  will-change: clip-path, opacity;
}

/* pour hosts: .tintfx is absolutely positioned, so the elements glassfx pours
   into need their own positioning context, and their labels must paint above
   the tint layer (the app's equivalent of canon's .glass > * guard) */
.tag-chips .chip, .hc-mood, .cal-day, .sc-actions .act, .rf-btn,
.inv-chip, .remind, .qz-opt, .avatar-pick .av, .row[data-assign] {
  position: relative;
}
.tag-chips .chip > *, .hc-mood > *, .cal-day > *, .sc-actions .act > *,
.rf-btn > *, .inv-chip > *, .remind > *, .qz-opt > *, .avatar-pick .av > *,
.row[data-assign] > * {
  position: relative;
  z-index: 1;
}

/* press — a clean squash, nothing carves */
.pressing { transform: scale(.96); transition: transform 80ms ease-out; }

/* press grammar: .pressing owns the squash, so the flat skin's :active rules
   must neither repaint the material nor double up the transform */
.btn:active {
  background:
    linear-gradient(rgba(4, 16, 56, .25), rgba(4, 16, 56, .25)),
    var(--grad-brand);
  transform: none;
}
.dock-fab .fab:active {
  background:
    linear-gradient(rgba(4, 16, 56, .25), rgba(4, 16, 56, .25)),
    var(--grad-brand);
  transform: none;
}
button.chip:active, a.chip:active {
  background: rgba(255, 255, 255, .6);
  transform: none;
}

/* ---------- solid light-bringer: keep the accent card painted ---------- */
.card.accent {
  background:
    linear-gradient(rgba(4, 16, 56, .25), rgba(4, 16, 56, .25)),
    var(--grad-brand);
  border-color: var(--glass-rim);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .35),
    0 12px 30px -10px rgba(var(--t), .5);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

/* ---------- chrome: topbar, pushed header, dock ---------- */
.topbar.scrolled {
  background: linear-gradient(150deg, var(--glass-hi), var(--glass-lo));
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.35);
  backdrop-filter: blur(var(--glass-blur)) saturate(1.35);
  box-shadow: 0 1px 0 rgba(var(--shade), .1);
}
.screen-header {
  background: linear-gradient(150deg, rgba(255, 255, 255, .82), rgba(255, 255, 255, .62));
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.35);
  backdrop-filter: blur(var(--glass-blur)) saturate(1.35);
  box-shadow: 0 1px 0 rgba(var(--shade), .08);
}
.screen-header .back-btn { color: var(--deep); }

/* floating glass dock — the signature surface. The pour layers live inside
   .dclip (glassfx-injected) so the protruding PAIR orb is never clipped.
   --dock-lift lives in tokens.css. */
.dock {
  left: var(--s-3);
  right: var(--s-3);
  bottom: calc(var(--safe-bottom) + var(--dock-lift));
  height: var(--dock-h);
  padding-bottom: 0;
  border-radius: 30px;
  background: linear-gradient(150deg, var(--glass-hi), var(--glass-lo));
  -webkit-backdrop-filter: blur(24px) saturate(1.5);
  backdrop-filter: blur(24px) saturate(1.5);
  border: 1px solid var(--glass-rim);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .95),
    0 18px 40px -14px rgba(var(--shade), .35);
  transition: box-shadow var(--lit-ms) var(--ease);
}
.dock[data-lit] {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .95),
    inset 0 0 32px rgba(var(--t), .13),
    0 18px 40px -14px rgba(var(--shade), .35),
    0 12px 40px -10px rgba(var(--t), .5),
    0 22px 70px -14px rgba(var(--t), .42);
}
.dclip {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  overflow: hidden;
  pointer-events: none;
}
.dpour {
  position: absolute;
  inset: 0;
  opacity: 0;
  will-change: clip-path, opacity;
}
.dspark {
  position: absolute;
  width: 150px;
  height: 150px;
  margin: -75px 0 0 -75px;
  border-radius: var(--r-pill);
  pointer-events: none;
  background: radial-gradient(circle, rgba(var(--t), .55) 0%, rgba(var(--t), 0) 70%);
  filter: blur(6px);
  animation: dspark 700ms var(--ease) forwards;
}
@keyframes dspark {
  0% { opacity: 0; transform: scale(.4); }
  30% { opacity: 1; }
  100% { opacity: 0; transform: scale(1.5); }
}
.dock-item, .dock-fab { position: relative; z-index: 1; }
.dock-item.active { color: var(--deep); }
.dock-item.active .ico { background: none; }
.dock-item.active .ico svg {
  transform: translateY(-1px) scale(1.12);
  filter: drop-shadow(0 0 9px rgba(var(--t), .85));
}
.dock-item.active span { text-shadow: 0 0 12px rgba(var(--t), .45); }
/* the PAIR orb — the dock's solid. Seated INTO the glass bar (only a small
   crown rises above it, so it never blocks screen content), sized up to 66px
   with the label inside the orb, and breathing slow gold light — the
   pairHalo / goldGlow recipe from theme/glass-docks.html. */
.dock-fab { justify-content: center; gap: 0; }
.dock-fab .fab {
  position: relative;
  width: 66px;
  height: 66px;
  margin-top: 0; /* justify-content centers the orb dead-on the bar */
  overflow: hidden;
  padding-bottom: 14px; /* lifts the glyph so the in-orb label fits below it */
  border: 0;
  animation: pair-halo 4.6s ease-in-out infinite;
}
.dock-fab .fab::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--r-pill);
  pointer-events: none;
  animation: pair-gold-in 4.6s ease-in-out infinite;
}
.dock-fab .fab svg { width: 24px; height: 24px; }
/* the label moves inside the orb, like the sample. Must NOT match the orb
   itself (also a span): on the relatively-positioned .fab these left/bottom
   offsets acted as a relative shove that knocked the orb off-center. */
.dock-fab > span:not(.fab) {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: 11px;
  z-index: 2;
  color: var(--surface);
  font-size: 9px;
  line-height: 1;
  letter-spacing: .08em;
  text-shadow: 0 1px 3px rgba(8, 14, 44, .35);
  pointer-events: none;
}
@keyframes pair-halo {
  0%, 100% {
    box-shadow:
      inset 0 0 0 1.5px rgba(255, 255, 255, .42),
      inset 0 2px 6px rgba(255, 255, 255, .35),
      0 10px 22px -6px rgba(var(--shade), .55),
      0 0 0 0 color-mix(in srgb, var(--glow) 0%, transparent);
  }
  50% {
    box-shadow:
      inset 0 0 0 1.5px rgba(255, 255, 255, .55),
      inset 0 2px 6px rgba(255, 255, 255, .35),
      0 10px 22px -6px rgba(var(--shade), .55),
      0 0 30px 5px color-mix(in srgb, var(--glow) 55%, transparent);
  }
}
@keyframes pair-gold-in {
  0%, 100% { box-shadow: inset 0 0 10px 2px color-mix(in srgb, var(--glow) 10%, transparent); }
  50% { box-shadow: inset 0 0 22px 8px color-mix(in srgb, var(--glow) 40%, transparent); }
}

/* chat composer clears the floating dock */
.screen.chat .composer {
  margin-bottom: calc(var(--dock-h) + var(--safe-bottom) + var(--dock-lift) + var(--s-2));
}
.toast-root { bottom: calc(var(--dock-h) + var(--safe-bottom) + var(--dock-lift) + var(--s-4)); }

/* ---------- lists & rows: the list is the glass, rows are light ---------- */
.list { border-radius: var(--r-lg); }
.row { background: transparent; }
.row + .row { border-top: 1px solid rgba(var(--shade), .08); }
.row:active { background: transparent; transform: none; }
.row .avatar { background: rgba(255, 255, 255, .6); color: var(--deep); box-shadow: 0 4px 12px -6px rgba(var(--shade), .3); }

.section-label {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  font-weight: 600;
}

/* ---------- buttons ---------- */
.btn {
  border: 1px solid rgba(255, 255, 255, .35);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .3),
    0 12px 26px -10px rgba(var(--t), .5);
}
.btn.secondary {
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, 0) 100%),
    rgba(255, 255, 255, .6);
  border: 1px solid var(--glass-rim);
  color: var(--deep);
  box-shadow:
    inset 0 0 18px rgba(var(--t), .08),
    0 10px 24px -12px rgba(var(--shade), .25);
}
.btn.secondary:active {
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, 0) 100%),
    rgba(255, 255, 255, .6);
  transform: none;
}
.btn:disabled { opacity: .55; box-shadow: none; }
.icon-btn {
  background: rgba(255, 255, 255, .6);
  border: 1px solid var(--glass-rim);
  color: var(--deep);
  box-shadow: 0 4px 12px -6px rgba(var(--shade), .25);
}
.icon-btn:active { background: rgba(255, 255, 255, .6); transform: none; }

/* solid budget (§7): in-card / in-list buttons go quiet glass so each view
   keeps ONE solid light-bringer; the budgeted solids are re-asserted below
   at higher specificity */
.card .btn, .list .btn {
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, 0) 100%),
    rgba(255, 255, 255, .65);
  border: 1px solid var(--glass-rim);
  color: var(--deep);
  box-shadow:
    inset 0 0 14px rgba(var(--t), .08),
    0 8px 20px -10px rgba(var(--shade), .3);
}
.heartcheck .hc-cta,
.match-card:first-of-type .btn,
.card .btn[data-a=ask],
.onb .btn[data-a=next],
.onb .btn[data-a=finish],
.btn[data-a=submit] {
  background:
    linear-gradient(rgba(4, 16, 56, .25), rgba(4, 16, 56, .25)),
    var(--grad-brand);
  border: 1px solid rgba(255, 255, 255, .35);
  color: var(--surface);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .3),
    0 12px 26px -10px rgba(var(--t), .5);
}
/* floating actions (Start a lounge / Write a story / Add) — glass pills that
   float over the scroll, lit by their tab's mood, never painted */
.fab-float {
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .55) 0%, rgba(255, 255, 255, 0) 40%, rgba(255, 255, 255, 0) 100%),
    linear-gradient(150deg, rgba(255, 255, 255, .88), rgba(255, 255, 255, .7));
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.35);
  backdrop-filter: blur(var(--glass-blur)) saturate(1.35);
  border: 1px solid var(--glass-rim);
  color: var(--deep);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .95),
    inset 0 0 18px rgba(var(--t), .1),
    0 14px 30px -10px rgba(var(--shade), .35),
    0 10px 26px -12px rgba(var(--t), .45);
  bottom: calc(var(--dock-h) + var(--safe-bottom) + var(--dock-lift) + var(--s-4));
}
.fab-float:active {
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .55) 0%, rgba(255, 255, 255, 0) 40%, rgba(255, 255, 255, 0) 100%),
    linear-gradient(150deg, rgba(255, 255, 255, .88), rgba(255, 255, 255, .7));
  transform: none;
}

/* ---------- segmented controls ----------
   Exactly the dock's language: the selected option is not a surface at all —
   it is LIGHT. A soft mood glow blooms behind the label, and the label goes
   deep and bold with a faint halo, just like the lit dock tab. */
.seg { padding: var(--s-1); border-radius: var(--r-pill); }
.seg button {
  transition:
    background 300ms var(--ease), color 300ms var(--ease),
    text-shadow 300ms var(--ease), transform 120ms var(--ease);
}
.seg button.active {
  background: radial-gradient(85% 100% at 50% 50%,
    rgba(var(--t), .2) 0%, rgba(var(--t), .06) 62%, rgba(var(--t), 0) 100%);
  color: var(--deep);
  font-weight: 800;
  text-shadow: 0 0 12px rgba(var(--t), .4);
  box-shadow: none;
}
/* the community slider: its gliding thumb becomes the same bloom of light */
.segment .thumb {
  background: radial-gradient(85% 100% at 50% 50%,
    rgba(var(--t), .2) 0%, rgba(var(--t), .06) 62%, rgba(var(--t), 0) 100%);
  border: 0;
  box-shadow: none;
}
.segment button { transition: color 300ms var(--ease), text-shadow 300ms var(--ease); }
.segment button.on { color: var(--deep); font-weight: 800; text-shadow: 0 0 12px rgba(var(--t), .4); }

/* ---------- chips & badges ---------- */
.chip {
  background: rgba(255, 255, 255, .6);
  border: 1px solid var(--glass-rim);
  color: var(--deep);
  box-shadow: 0 4px 12px -6px rgba(var(--shade), .25);
}
.chip.gold, .badge.gold {
  background: var(--grad-gold);
  border-color: rgba(255, 255, 255, .5);
  color: #5F3D00;
  box-shadow: 0 6px 14px -6px color-mix(in srgb, var(--gold) 60%, transparent);
}
.badge {
  background: var(--grad-gold);
  color: #5F3D00;
  box-shadow: 0 4px 10px -4px color-mix(in srgb, var(--gold) 70%, transparent);
}
.tag-chips .chip { background: rgba(255, 255, 255, .55); border: 1px solid var(--glass-rim); color: var(--muted); }
.tag-chips .chip.on {
  position: relative;
  background: rgba(var(--t), .12);
  border-color: rgba(var(--t), .4);
  color: var(--deep);
  box-shadow: 0 6px 16px -8px rgba(var(--t), .5);
}
.phase-chip { border-color: rgba(var(--t), .5); color: var(--deep); background: rgba(255, 255, 255, .4); }

/* mentor match score — the same milky-pill idiom as .chip */
.match-score {
  background: rgba(255, 255, 255, .6);
  border: 1px solid var(--glass-rim);
  color: var(--deep);
  box-shadow: 0 4px 12px -6px rgba(var(--shade), .25);
}

/* call status chips — tinted glass pills, never paint */
.chip.st-pending { background: rgba(241, 178, 43, .12); border-color: rgba(241, 178, 43, .35); color: #B45309; }
.chip.st-confirmed { background: rgba(var(--t), .1); border-color: rgba(var(--t), .3); color: var(--deep); }
.chip.st-declined { background: color-mix(in srgb, var(--danger) 8%, rgba(255, 255, 255, .6)); border-color: color-mix(in srgb, var(--danger) 25%, transparent); color: var(--danger); }
.chip.st-done { background: rgba(var(--shade), .06); color: var(--muted); }

/* ---------- stat tiles ---------- */
.stat { border-radius: var(--r-lg); }
.stat strong { font-variant-numeric: tabular-nums; color: var(--deep); }
.stat span {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .2em;
}
button.stat:active { border-color: rgba(var(--t), .5); }
.stat.on { border-color: rgba(var(--t), .5); box-shadow: inset 0 0 22px rgba(var(--t), .12), 0 16px 38px -16px rgba(var(--shade), .22); }
.stat.on::before { content: none; } /* the inner glow replaces the gradient bar */

/* ---------- banners ---------- */
.banner { border-radius: var(--r-lg); }
.banner p { color: var(--deep); }
/* in-banner actions go quiet glass — the view keeps ONE solid light-bringer */
.banner .btn {
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, 0) 100%),
    rgba(255, 255, 255, .65);
  border: 1px solid var(--glass-rim);
  color: var(--deep);
  box-shadow:
    inset 0 0 14px rgba(var(--t), .08),
    0 8px 20px -10px rgba(var(--shade), .3);
}
.banner.urgent .btn { color: var(--danger); box-shadow: inset 0 0 14px color-mix(in srgb, var(--danger) 8%, transparent), 0 8px 20px -10px rgba(var(--shade), .3); }

/* Fatihah prompt: gold paint is not a sanctioned solid — demoted to glass
   that runs the gold mood (amber-deep text via .banner p) */
.banner.fatihah-prompt {
  --t: 241, 178, 43;
  --deep: #B45309;
  border-color: color-mix(in srgb, var(--gold) 35%, transparent);
}

/* blank avatar reads as an avatar everywhere (was a dashed square) */
.avatar-blank { border-radius: var(--r-pill); }
/* urgent keeps paint (safety exception) — the breathe moves to light so it
   reads on glass. Same keyframe name: this later definition wins. */
.banner.urgent, .row.urgent {
  background: color-mix(in srgb, var(--danger) 7%, var(--surface));
  animation: urgent-breathe 2.6s ease-in-out infinite;
}
.row.urgent { border-radius: var(--r-lg); }
@keyframes urgent-breathe {
  0%, 100% { box-shadow: inset 0 1px 0 rgba(255, 255, 255, .95), 0 10px 26px -12px color-mix(in srgb, var(--danger) 20%, transparent); }
  50% { box-shadow: inset 0 1px 0 rgba(255, 255, 255, .95), 0 12px 32px -10px color-mix(in srgb, var(--danger) 55%, transparent); }
}

/* ---------- forms: shallow wells ---------- */
.field input, .field select, .field textarea, .composer input, .plain-input {
  background: rgba(255, 255, 255, .55);
  /* a faint shade rim — wells often sit directly on the stage, where a
     white-on-white rim would leave the field invisible */
  border: 1px solid rgba(var(--shade), .16);
  box-shadow:
    inset 0 1px 3px rgba(var(--shade), .1),
    0 1px 0 rgba(255, 255, 255, .6);
  border-radius: var(--r-md);
  transition: border-color var(--fade-ms) var(--ease), box-shadow var(--fade-ms) var(--ease);
}
.field input:focus-visible, .field select:focus-visible, .field textarea:focus-visible,
.composer input:focus-visible, .plain-input:focus-visible {
  outline: none;
  border-color: rgba(var(--t), .55);
  box-shadow:
    inset 0 1px 3px rgba(var(--shade), .1),
    0 0 0 3px rgba(var(--t), .18),
    0 8px 22px -10px rgba(var(--t), .45);
}
input:disabled { opacity: .55; }
.field > span {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .18em;
  text-transform: uppercase;
}
.composer {
  background: transparent;
  box-shadow: none;
}
.composer input { border-radius: var(--r-pill); }

/* switch: the visible track is a ::before covering the padding box exactly —
   the button's 44px hit-box (transparent borders) paints NOTHING itself.
   Shadows drawn on the button box rendered as a stray oval halo around the
   pill and warped its shape; on the pseudo they hug the real track. */
.switch, .switch.on {
  background: none;
  box-shadow: none;
}
.switch::before {
  content: "";
  position: absolute;
  inset: 0; /* the padding box IS the 52x32 track (borders excluded) */
  border-radius: var(--r-pill);
  background: rgba(4, 16, 56, .08);
  box-shadow: inset 0 1px 3px rgba(var(--shade), .12);
  transition: background 200ms var(--ease), box-shadow 300ms var(--ease);
}
/* the on-state gradient can't transition (gradients don't interpolate), so it
   lives on an ::after that crossfades in by opacity over the grey track */
.switch::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--r-pill);
  background:
    linear-gradient(rgba(255, 255, 255, .12), rgba(255, 255, 255, 0)),
    var(--grad-brand);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .25),
    0 4px 12px -4px rgba(var(--t), .5);
  opacity: 0;
  transition: opacity 200ms var(--ease);
  pointer-events: none;
}
.switch.on::after { opacity: 1; }
.switch span { z-index: 1; }

/* ---------- sheets & toasts ---------- */
.sheet-wrap .scrim {
  background: rgba(15, 23, 42, .32);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}
.sheet {
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, 0) 26%, rgba(255, 255, 255, 0) 100%),
    linear-gradient(165deg, rgba(255, 255, 255, .86), rgba(255, 255, 255, .72));
  -webkit-backdrop-filter: blur(30px) saturate(1.35);
  backdrop-filter: blur(30px) saturate(1.35);
  border: 1px solid var(--glass-rim);
  border-bottom: 0;
  border-radius: 30px 30px 0 0;
  box-shadow: 0 -18px 50px -18px rgba(var(--shade), .4);
}
.sheet .grabber { background: rgba(var(--shade), .18); }
.toast {
  background: rgba(20, 29, 61, .85);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border: 1px solid rgba(255, 255, 255, .12);
  box-shadow: 0 14px 34px -12px rgba(var(--shade), .5);
}

/* ---------- chat ---------- */
.bubble {
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, 0) 40%, rgba(255, 255, 255, 0) 100%),
    rgba(255, 255, 255, .72);
  border: 1px solid var(--glass-rim);
  border-radius: 18px 18px 18px 6px;
  box-shadow: 0 10px 24px -14px rgba(var(--shade), .25);
}
/* sent bubble — the thread's solid light-bringer. The flat skin's dark
   overlay stack is kept: it is what holds white text at the 4.5:1 floor
   (canon's #6FA0FF top edge alone does not). */
.bubble.me {
  background:
    linear-gradient(rgba(4, 16, 56, .22), rgba(4, 16, 56, .22)),
    linear-gradient(135deg, var(--lumen), var(--brand));
  border: 1px solid rgba(255, 255, 255, .35);
  border-radius: 18px 18px 6px 18px;
  box-shadow: 0 12px 28px -12px rgba(var(--t), .55);
}
.bubble .ticks.read { color: var(--glow); text-shadow: 0 0 8px color-mix(in srgb, var(--glow) 60%, transparent); }
.bubble.sys { background: none; border: 0; box-shadow: none; }
.bubble.typing { border-radius: 18px 18px 18px 6px; }
/* moderation/question state lives on the tag pills (.mq-tag / .flag-tag keep
   their token paint) — the bubbles themselves stay plain glass */
.bubble.marked-q:not(.me), .bubble.flagged:not(.me), .bubble.noted:not(.me) {
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, 0) 40%, rgba(255, 255, 255, 0) 100%),
    rgba(255, 255, 255, .72);
  border-color: var(--glass-rim);
  box-shadow: 0 10px 24px -14px rgba(var(--shade), .25);
}
.bubble.me.marked-q, .bubble.me.flagged, .bubble.me.noted {
  color: var(--surface);
  box-shadow: 0 12px 28px -12px rgba(var(--t), .55);
}
.bubble.me.marked-q time, .bubble.me.flagged time, .bubble.me.noted time { color: var(--surface); }
/* the own-question sky ring becomes the lit recipe: inner glow + mood halo */
.bubble.me.question {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .3),
    0 12px 28px -12px rgba(var(--t), .55),
    0 10px 28px -8px rgba(var(--t), .45);
}
/* call bubbles stay card-style on both sides — milky glass, ink text */
.bubble.call.me {
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, 0) 40%, rgba(255, 255, 255, 0) 100%),
    rgba(255, 255, 255, .72);
  border: 1px solid var(--glass-rim);
  color: var(--ink);
  box-shadow: 0 10px 24px -14px rgba(var(--shade), .25);
}

/* ---------- progress ---------- */
.cm-bar {
  background: rgba(var(--shade), .07);
  box-shadow: inset 0 1px 3px rgba(var(--shade), .1);
  height: 8px;
}
.cm-bar i {
  box-shadow: 0 0 10px rgba(var(--t), .5);
  transition: width 800ms var(--ease);
}
.cm-icon { background: rgba(var(--t), .1); color: var(--deep); }

/* ---------- calendar ---------- */
.cal-grid { border-radius: var(--r-lg); }
.cal-day[data-day]:active { background: none; transform: none; }
.cal-day.today { box-shadow: inset 0 0 0 2px rgba(var(--t), .65), inset 0 0 14px rgba(var(--t), .12); }
.cal-day.sel {
  background: rgba(var(--t), .14);
  color: var(--deep);
  box-shadow: inset 0 0 0 1px rgba(var(--t), .35), inset 0 0 16px rgba(var(--t), .12);
  font-weight: 800;
}
.cal-day.sel:active { background: rgba(var(--t), .14); transform: none; }
.cal-day.sel .cal-dot.on, .cal-day.sel .cal-dot.pend { background: var(--deep); }

/* ---------- onboarding & auth ---------- */
.options .opt, .auth-role-tiles .opt { border-radius: var(--r-lg); }
.opt.on {
  border-color: rgba(var(--t), .45);
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, 0) 100%),
    rgba(var(--t), .1);
  box-shadow:
    inset 0 0 22px rgba(var(--t), .1),
    0 12px 30px -12px rgba(var(--t), .4);
}
/* press is only a faint tint — the squash belongs to .pressing, the full
   treatment to .on */
.opt:active {
  background: rgba(var(--t), .06);
  transform: none;
}
.auth-role-tiles .opt.primary { border-color: rgba(var(--t), .35); }
.auth-role-tiles .opt .avatar { border-radius: var(--r-pill); }
/* selected role tile: glass + --deep, not solid brand */
.auth-role-tiles .opt.on .avatar {
  background: rgba(var(--t), .12);
  color: var(--deep);
  box-shadow: inset 0 0 12px rgba(var(--t), .15);
}
.auth-role-tiles .opt.on .tick {
  background: rgba(var(--t), .15);
  border-color: rgba(var(--t), .5);
  color: var(--deep);
}
.auth-role-tiles .opt .opt-flag {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: .18em;
  text-transform: uppercase;
}
.gender-pick .chip {
  background: rgba(255, 255, 255, .6);
  border: 1px solid var(--glass-rim);
  color: var(--deep);
  box-shadow: 0 4px 12px -6px rgba(var(--shade), .25);
}
.gender-pick .chip.on {
  /* the selected gender pill is a canonical solid (counts to the budget) —
     per-gender gradients, keyed off the data-g attribute */
  background: linear-gradient(135deg, #4E8CFF, #0161F7);
  border-color: rgba(255, 255, 255, .4);
  color: var(--surface);
  box-shadow: 0 8px 18px -8px rgba(1, 97, 247, .5);
}
.gender-pick .chip.on[data-g="woman"] {
  background: linear-gradient(135deg, #F472B6, #DB2777);
  box-shadow: 0 8px 18px -8px rgba(219, 39, 119, .5);
}
.avatar-pick .av.on { border-color: rgba(var(--t), .7); box-shadow: 0 0 0 3px rgba(var(--t), .2), 0 6px 16px -8px rgba(var(--t), .5); }
.tos-row a { color: var(--deep); }

/* ---------- community moments ---------- */
/* the breathing gold rim belongs to LIVE rooms (community.js tags them
   .room-card.live); a pinned card carries no paint of its own */
.room-card.live {
  animation: live-rim 3s ease-in-out infinite;
}
.room-card.pinned {
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, 0) 26%,
      rgba(255, 255, 255, 0) 72%, rgba(255, 255, 255, .18) 100%),
    linear-gradient(150deg, var(--glass-hi), var(--glass-lo));
  border-color: var(--glass-rim);
}
@keyframes live-rim {
  0%, 100% { box-shadow: inset 0 1px 0 rgba(255, 255, 255, .95), 0 16px 38px -16px rgba(var(--shade), .22), 0 0 0 0 color-mix(in srgb, var(--gold) 35%, transparent); }
  50% { box-shadow: inset 0 1px 0 rgba(255, 255, 255, .95), 0 16px 38px -16px rgba(var(--shade), .22), 0 0 22px -2px color-mix(in srgb, var(--gold) 45%, transparent); }
}

/* community runs all-light — zero solids (seg thumb is a bloom, FAB is
   glass): every active state below is tint + glow on milky material */
.compose-teaser {
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, 0) 100%),
    linear-gradient(150deg, var(--glass-hi), var(--glass-lo));
  border: 1px solid var(--glass-rim);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .95), 0 10px 26px -12px rgba(var(--shade), .25);
}
.sc-actions .act.liked {
  background: rgba(var(--t), .12);
  color: var(--deep);
  box-shadow: 0 6px 16px -8px rgba(var(--t), .5);
}
.inv-chip.on {
  background: rgba(var(--t), .12);
  border-color: rgba(var(--t), .4);
  color: var(--deep);
  box-shadow: 0 6px 16px -8px rgba(var(--t), .5);
}
.remind.on {
  background: rgba(241, 178, 43, .12);
  border-color: rgba(241, 178, 43, .4);
  color: #B45309;
  box-shadow: inset 0 0 12px rgba(241, 178, 43, .18), 0 6px 16px -8px rgba(241, 178, 43, .5);
}
/* old :active transforms retired — .pressing scale(.96) is the single press
   grammar */
.room-card:active, .remind:active, .inv-chip:active,
.compose-teaser:active, .sc-actions .act:active {
  transform: none;
}
.comment .cb {
  background: rgba(255, 255, 255, .6);
  border: 1px solid var(--glass-rim);
  box-shadow: 0 4px 12px -6px rgba(var(--shade), .2);
}
.comment-row input {
  background: rgba(255, 255, 255, .55);
  border: 1px solid rgba(var(--shade), .16);
  box-shadow: inset 0 1px 3px rgba(var(--shade), .1), 0 1px 0 rgba(255, 255, 255, .6);
}
.comment-row input:focus-visible {
  outline: none;
  border-color: rgba(var(--t), .55);
  box-shadow: inset 0 1px 3px rgba(var(--shade), .1), 0 0 0 3px rgba(var(--t), .18), 0 8px 22px -10px rgba(var(--t), .45);
}
.comment-row button {
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, 0) 100%),
    rgba(255, 255, 255, .65);
  border: 1px solid var(--glass-rim);
  color: var(--deep);
  box-shadow: inset 0 0 14px rgba(var(--t), .08), 0 8px 20px -10px rgba(var(--shade), .3);
}
.familiar, .date-chip {
  background: rgba(255, 255, 255, .6);
  border: 1px solid var(--glass-rim);
  color: var(--deep);
  box-shadow: 0 4px 12px -6px rgba(var(--shade), .25);
}
.mod-tag, .leave-btn {
  background: rgba(255, 255, 255, .7);
  border: 1px solid var(--glass-rim);
  color: var(--deep);
  box-shadow: 0 4px 10px -4px rgba(var(--shade), .3);
}
.mp-acts .chip { min-height: 44px; }
.mp-acts .chip[data-no] { min-width: 44px; }

/* live-room screen */
.room-foot {
  background: linear-gradient(150deg, var(--glass-hi), var(--glass-lo));
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.35);
  backdrop-filter: blur(var(--glass-blur)) saturate(1.35);
  border-top: 0;
  box-shadow: 0 -1px 0 rgba(var(--shade), .1);
  margin-bottom: calc(var(--dock-h) + var(--safe-bottom) + var(--dock-lift));
}
.rf-btn .ric {
  background: rgba(255, 255, 255, .6);
  border: 1px solid var(--glass-rim);
  box-shadow: 0 4px 12px -6px rgba(var(--shade), .25);
}
.rf-btn:active .ric { transform: none; }
/* the raised hand / live mic lights gold THROUGH the glass, never a disc */
.rf-btn.on .ric {
  background: rgba(241, 178, 43, .16);
  border-color: rgba(241, 178, 43, .4);
  color: #B45309;
  box-shadow: inset 0 0 14px rgba(241, 178, 43, .22), 0 6px 16px -8px rgba(241, 178, 43, .5);
}
/* speaker / listener avatars demoted from gradient discs to ringed glass */
.spk .sav, .lis .lav {
  background: rgba(255, 255, 255, .55);
  color: var(--deep);
  box-shadow: 0 0 0 2.5px rgba(255, 255, 255, .9), 0 8px 20px -8px rgba(var(--shade), .35);
}
.mic {
  background: rgba(255, 255, 255, .6);
  border: 1px solid var(--glass-rim);
  box-shadow: 0 4px 10px -4px rgba(var(--shade), .3);
}
.hand-toast {
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, 0) 100%),
    linear-gradient(150deg, var(--glass-hi), var(--glass-lo));
  border: 1px solid var(--glass-rim);
  color: var(--deep);
  box-shadow: 0 10px 24px -12px rgba(var(--shade), .25);
}
/* .host-tag keeps its gold (host convention); the flags/badges go milky */
.hand-flag {
  background: rgba(255, 255, 255, .75);
  color: #B45309;
  box-shadow: 0 4px 10px -4px rgba(var(--shade), .35);
}
.rf-badge {
  background: rgba(255, 255, 255, .75);
  color: var(--deep);
  box-shadow: 0 4px 10px -4px rgba(var(--shade), .3);
}

/* ---------- the guide check-in ---------- */
.heartcheck { border-radius: var(--r-lg); }
.hc-eyebrow {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .2em;
  text-transform: uppercase;
}
/* guide speech bubble — the .tut-bubble recipe, guide-side tail radius */
.hc-speech {
  border-radius: 6px 20px 20px 20px;
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, 0) 100%),
    linear-gradient(150deg, var(--glass-hi), var(--glass-lo));
  border: 1px solid var(--glass-rim);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .95), 0 14px 32px -14px rgba(var(--shade), .25);
}
/* gold name labels fail contrast on glass — amber-deep instead */
.hc-speech .hc-who, .tut-who { color: #B45309; }
.hc-moods { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.hc-mood {
  background: rgba(255, 255, 255, .55);
  border: 1px solid var(--glass-rim);
  box-shadow: 0 4px 12px -6px rgba(var(--shade), .2);
}
.hc-mood:active { transform: none; }
/* checked mood — the .tag-chips .chip.on idiom: tint, inner glow, no border */
.hc-mood[aria-checked="true"] {
  background: rgba(var(--t), .12);
  border-color: transparent;
  box-shadow: inset 0 0 16px rgba(var(--t), .14), 0 6px 16px -8px rgba(var(--t), .5);
}
.hc-mood[aria-checked="true"] .label { color: var(--deep); }
/* streak chip — gold glass pill (its --t/--deep are pinned gold below) */
.hc-streak {
  background: rgba(255, 255, 255, .6);
  border: 1px solid var(--glass-rim);
  color: var(--deep);
  box-shadow: inset 0 0 14px rgba(var(--t), .16), 0 6px 16px -8px rgba(var(--t), .45);
}

/* ---------- UI improvement pass (theme/UI-IMPROVEMENT-PLAN.md) ---------- */

/* 2.3 · missed-consent nudge: rim ignition instead of a background blink */
.tos-row.flash { animation: tos-ignite 900ms var(--ease) 2; border-radius: var(--r-md); }
@keyframes tos-ignite {
  0%, 100% { box-shadow: 0 0 0 0 rgba(var(--t), 0); }
  40% { box-shadow: 0 0 0 3px rgba(var(--t), .28), 0 8px 24px -8px rgba(var(--t), .5); }
}

/* 3.1 / 4.1 · onboarding progress: well track, glowing mood fill */
.onb-top .progress {
  background: rgba(var(--shade), .08);
  box-shadow: inset 0 1px 3px rgba(var(--shade), .1);
}
.onb-top .progress i { box-shadow: 0 0 10px rgba(var(--t), .55); }

/* 3.4 · tutorial: guide-side speech tail + per-slide mood on the feature chip */
.tut-bubble {
  border-radius: 6px 20px 20px 20px;
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, 0) 100%),
    linear-gradient(150deg, var(--glass-hi), var(--glass-lo));
  border: 1px solid var(--glass-rim);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .95), 0 14px 32px -14px rgba(var(--shade), .25);
}
.tut-feature .avatar { background: rgba(var(--t), .12); color: var(--deep); }
.tut-feature strong { color: var(--deep); }

/* 3.5 · tutorial send-off: miniature dock preview, each tab in its mood */
.tut-dockprev {
  display: flex;
  gap: var(--s-2);
  justify-content: center;
  margin-top: var(--s-4);
  padding: var(--s-2) var(--s-3);
  border-radius: var(--r-pill);
  background: linear-gradient(150deg, var(--glass-hi), var(--glass-lo));
  border: 1px solid var(--glass-rim);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .95), 0 10px 26px -12px rgba(var(--shade), .3);
}
.tut-dockprev span {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: var(--r-pill);
  color: var(--deep);
  background: rgba(var(--t), .1);
}

/* 3.4 · in-footer skip (thumb-reachable twin of the top-right button) */
.tut-skip-inline {
  min-height: 44px;
  padding: 0 var(--s-3);
  font-size: var(--t-sub);
  font-weight: 700;
  color: var(--muted);
  background: none;
  border: 0;
}

/* 3.3 · multi-select help: the first pick is marked as the first step */
.opt { position: relative; }
.opt .first-tag {
  position: absolute;
  top: calc(-1 * var(--s-2));
  right: var(--s-3);
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: #5F3D00;
  background: var(--grad-gold);
  border-radius: var(--r-pill);
  padding: 2px var(--s-2);
  box-shadow: 0 4px 10px -4px color-mix(in srgb, var(--gold) 70%, transparent);
}

/* PAIR sheet: the da'ee's own code box is a glass well (no sheen, shade rim) */
.qr-box {
  background: rgba(255, 255, 255, .55);
  border: 1px solid rgba(var(--shade), .16);
  box-shadow: inset 0 1px 3px rgba(var(--shade), .1), 0 1px 0 rgba(255, 255, 255, .6);
}
/* 3.6 · QR scanner: the mock camera's navy canvas becomes a well frame; the
   corner brackets mute to soft shade/gold and the gold scan line (below)
   keeps sweeping */
.qr-scan {
  position: relative;
  overflow: hidden;
  background: rgba(255, 255, 255, .55);
  border: 1px solid rgba(var(--shade), .16);
  box-shadow: inset 0 1px 3px rgba(var(--shade), .1);
}
.qr-scan .c { border-color: color-mix(in srgb, var(--gold) 45%, rgba(var(--shade), .3)); }
.qr-scan::after {
  content: "";
  position: absolute;
  left: 10%;
  right: 10%;
  top: 12%;
  height: 2px;
  border-radius: var(--r-pill);
  background: var(--glow);
  box-shadow: 0 0 12px 2px color-mix(in srgb, var(--glow) 60%, transparent);
  animation: qr-sweep 2.6s ease-in-out infinite;
}
@keyframes qr-sweep {
  0%, 100% { top: 12%; opacity: .4; }
  50% { top: 84%; opacity: .95; }
}

/* 1.2 · mono utility voice: live markers */
.live-chip, .live-dot {
  font-family: var(--font-mono);
  letter-spacing: .14em;
}

/* 1.3 · touch targets: story actions reach the 44px floor */
.sc-actions .act { min-height: 44px; min-width: 44px; }

/* 6.4 / 6.3 · gold moments pour gold, not blue */
.sc-actions .act, .rf-btn[data-a="hand"], .hc-streak { --t: 241, 178, 43; --deep: #B45309; }

/* 5.3 · composer: the send button floods with the gradient once there is
   text. Gradients can't transition, so the flood lives on an ::after that
   fades in by opacity (the button's own background clears when ready) */
.composer .btn {
  position: relative;
  z-index: 0; /* stacking context: the ::after flood can't slip behind the
     composer's pinned-footer fade */
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, 0) 100%),
    rgba(255, 255, 255, .6);
  border: 1px solid var(--glass-rim);
  color: var(--deep);
  box-shadow: inset 0 0 14px rgba(var(--t), .08), 0 8px 20px -10px rgba(var(--shade), .25);
  transition: color var(--fade-ms) var(--ease),
              box-shadow var(--fade-ms) var(--ease), transform 120ms var(--ease);
}
.composer .btn::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1; /* below the label, above the button's own background */
  border-radius: inherit;
  background:
    linear-gradient(rgba(4, 16, 56, .25), rgba(4, 16, 56, .25)),
    var(--grad-brand);
  opacity: 0;
  transition: opacity var(--fade-ms) var(--ease);
  pointer-events: none;
}
.composer .btn.ready {
  background: none;
  border-color: rgba(255, 255, 255, .35);
  color: var(--surface);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .3), 0 12px 26px -10px rgba(var(--t), .5);
}
.composer .btn.ready::after { opacity: 1; }
/* 1.6 · pinned-footer fade: content dissolves under the composer */
.screen.chat .composer {
  background: linear-gradient(180deg, rgba(246, 248, 255, 0) 0%, rgba(246, 248, 255, .92) 34%);
  box-shadow: none;
}

/* 5.2 · Learn portal: glass course cards; the next step carries the light */
.learn-card {
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, 0) 26%, rgba(255, 255, 255, 0) 72%, rgba(255, 255, 255, .18) 100%),
    linear-gradient(150deg, var(--glass-hi), var(--glass-lo));
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.35);
  backdrop-filter: blur(var(--glass-blur)) saturate(1.35);
  border: 1px solid var(--glass-rim);
  border-radius: var(--r-lg);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .95), 0 16px 38px -16px rgba(var(--shade), .22);
}
.learn-card.next {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .95),
    inset 0 0 26px rgba(var(--t), .12),
    0 16px 38px -16px rgba(var(--shade), .22),
    0 10px 28px -8px rgba(var(--t), .4);
}
.lc-bar { background: rgba(var(--shade), .07); box-shadow: inset 0 1px 3px rgba(var(--shade), .1); }
.lc-bar i { box-shadow: 0 0 8px rgba(var(--t), .45); }
/* course icon chips go mood-tint (the .cm-icon idiom), never gradient */
.learn-card .lc-icon, .learn-card.gold .lc-icon { background: rgba(var(--t), .1); color: var(--deep); }

/* shared .prog bars (pipeline / learner / mentee / compliance): well + glow */
.prog {
  background: rgba(var(--shade), .07);
  box-shadow: inset 0 1px 3px rgba(var(--shade), .1);
}
.prog i { box-shadow: 0 0 10px rgba(var(--t), .5); transition: width 800ms var(--ease); }
.prog.gold i { box-shadow: 0 0 10px color-mix(in srgb, var(--gold) 55%, transparent); }

/* 5.2 · Fatihah progress dots light in the (indigo) mood */
.fat-dots i.on { background: rgb(var(--t)); box-shadow: 0 0 8px rgba(var(--t), .45); }

/* 5.2 · certificate: the gold ring stack (Fatihah + compliance sheets) */
.cert-glass {
  border: 1px solid color-mix(in srgb, var(--gold) 55%, transparent);
  box-shadow:
    inset 0 0 0 3px color-mix(in srgb, var(--gold) 18%, transparent),
    inset 0 0 0 6px rgba(255, 255, 255, .8),
    inset 0 0 0 7px color-mix(in srgb, var(--gold) 35%, transparent),
    0 14px 34px -14px color-mix(in srgb, var(--gold) 45%, transparent);
}

/* 1.5 · academy iframe: no chrome blur while the cross-document surface is
   topmost (§11) — the dock never overlaps (the frame stops above it) */
.screen.academy .screen-header {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
/* the frame clears the FLOATING dock, so its inset pays the lift too */
.screen.academy { inset: 0 0 calc(var(--dock-h) + var(--safe-bottom) + var(--dock-lift)) 0; }
/* academy iframe placeholder: shimmer skeleton, not a text label */
.screen.academy .academy-loading {
  display: grid;
  place-items: center;
  align-content: center;
  gap: var(--s-3);
}
.academy-loading .skeleton { width: min(70vw, 320px); }
.academy-loading .skeleton.block { min-height: 120px; width: min(84vw, 380px); }

/* 7.3 · assignment sheet: at-capacity rows dim, never grey out */
.row.cap { opacity: .55; }

/* 7.4 · bulk bar: floating glass pill above the floating dock */
.bulk-bar {
  bottom: calc(var(--dock-h) + var(--safe-bottom) + var(--dock-lift) + var(--s-3));
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, 0) 100%),
    linear-gradient(150deg, var(--glass-hi), var(--glass-lo));
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.35);
  backdrop-filter: blur(var(--glass-blur)) saturate(1.35);
  border: 1px solid var(--glass-rim);
  border-radius: var(--r-pill);
  color: var(--ink);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .95), 0 14px 34px -12px rgba(var(--shade), .35);
}
.bulk-bar button { color: var(--deep); background: rgba(var(--t), .1); }
.bulk-bar button:active { transform: none; }
/* bulk Assign is the d-learners view's one solid (§7) */
.bulk-bar [data-b=assign] {
  background:
    linear-gradient(rgba(4, 16, 56, .25), rgba(4, 16, 56, .25)),
    var(--grad-brand);
  color: var(--surface);
  box-shadow: 0 8px 18px -8px rgba(var(--t), .5);
}
.checkbox {
  background: rgba(255, 255, 255, .55);
  border: 1px solid rgba(var(--shade), .16);
  box-shadow: inset 0 1px 3px rgba(var(--shade), .1);
}
/* checked — the well lights in the mood and the check draws in, never a
   solid gradient */
.checkbox.on {
  background: rgba(var(--t), .14);
  border-color: rgba(var(--t), .5);
  color: var(--deep);
  box-shadow: inset 0 0 12px rgba(var(--t), .15);
}
.checkbox.on svg * {
  stroke-dasharray: 24;
  stroke-dashoffset: 24;
  animation: check-draw 300ms var(--ease) forwards;
}

/* 5.3 · chat day dividers: quiet well pills between days */
.day-divider {
  align-self: center;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--muted);
  background: rgba(var(--shade), .06);
  box-shadow: inset 0 1px 2px rgba(var(--shade), .08);
  border-radius: var(--r-pill);
  padding: var(--s-1) var(--s-3);
  margin: var(--s-2) auto;
}

/* 1.4 · empty states: soft icon chip, one line, one action */
.empty-state {
  display: grid;
  justify-items: center;
  gap: var(--s-3);
  text-align: center;
  padding: var(--s-6) var(--s-4);
}
.empty-state .avatar {
  width: 56px;
  height: 56px;
  border-radius: var(--r-pill);
  background: rgba(var(--t), .1);
  color: var(--deep);
  display: grid;
  place-items: center;
}
.empty-state p { max-width: 30ch; }

/* ---------- consistency pass: remaining surfaces ---------- */

/* compliance course — quiz options are pour hosts (positioning set up top):
   milky rows, no own backdrop-filter inside the blurred card */
.qz-opt {
  background: rgba(255, 255, 255, .6);
  border: 1px solid var(--glass-rim);
  box-shadow: 0 4px 12px -6px rgba(var(--shade), .2);
}
.qz-opt:active { transform: none; }
.qz-opt.right {
  background: rgba(var(--t), .14);
  border-color: rgba(var(--t), .4);
  color: var(--deep);
  box-shadow: inset 0 0 14px rgba(var(--t), .12);
}
.qz-opt.wrong {
  background: rgba(241, 178, 43, .1);
  border-color: rgba(241, 178, 43, .35);
  color: #B45309;
}
.qz-opts.answered .qz-opt:not(.right) { opacity: .55; }
.qz-pm {
  background: rgba(var(--t), .1);
  border: 1px solid rgba(var(--t), .25);
  color: var(--deep);
}
.comp-verb {
  background: rgba(255, 255, 255, .6);
  border: 1px solid var(--glass-rim);
  color: var(--deep);
  box-shadow: 0 4px 12px -6px rgba(var(--shade), .25);
}
.sig-canvas {
  background: rgba(255, 255, 255, .55);
  border: 1px solid rgba(var(--shade), .16);
  box-shadow: inset 0 1px 3px rgba(var(--shade), .1);
}
/* current module — the lit inner-glow replaces the inset gold ring */
.comp-mod.current {
  box-shadow:
    inset 0 0 22px rgba(241, 178, 43, .18),
    0 10px 28px -8px rgba(241, 178, 43, .4);
}
/* near-miss: the painted left border becomes a thin gold inner-glow edge */
.card.comp-nearmiss {
  border-left: 0;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .95),
    inset 2px 0 0 rgba(241, 178, 43, .55),
    0 16px 38px -16px rgba(var(--shade), .22);
}

/* recorder — live state runs the gold ramp (the plan retired red for live) */
.rec-btn.live { background: var(--grad-gold); color: var(--ink); }
.rec-btn.live::after { border-color: var(--gold); }
.rec-time { color: #B45309; }

/* karaoke highlight on glass */
.fat-arabic span.lit { color: var(--deep); }
/* completion medal — gold conic ring + inner sphere + breathing halo
   (guide §6.7 medals) */
.fat-medal {
  position: relative;
  background: conic-gradient(from 210deg,
    var(--gold), var(--glow) 32%, var(--gold) 55%, var(--glow) 82%, var(--gold));
  color: var(--surface);
  box-shadow: 0 12px 30px -10px color-mix(in srgb, var(--gold) 60%, transparent);
  animation: medal-halo 3.2s ease-in-out infinite;
}
.fat-medal::before {
  content: "";
  position: absolute;
  inset: 6px;
  border-radius: var(--r-pill);
  background: radial-gradient(circle at 35% 28%, var(--lumen), var(--brand) 70%);
  box-shadow: inset 0 2px 5px rgba(255, 255, 255, .45), inset 0 -4px 8px rgba(4, 16, 56, .3);
}
.fat-medal svg { position: relative; z-index: 1; }
@keyframes medal-halo {
  0%, 100% { box-shadow: 0 12px 30px -10px color-mix(in srgb, var(--gold) 60%, transparent), 0 0 0 0 color-mix(in srgb, var(--glow) 0%, transparent); }
  50% { box-shadow: 0 12px 30px -10px color-mix(in srgb, var(--gold) 60%, transparent), 0 0 26px 4px color-mix(in srgb, var(--glow) 45%, transparent); }
}

/* landing feature rows */
.l-feat {
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, 0) 100%),
    linear-gradient(150deg, var(--glass-hi), var(--glass-lo));
  border: 1px solid var(--glass-rim);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .95), 0 10px 24px -12px rgba(var(--shade), .22);
}
.l-feat .fic { background: rgba(var(--t), .1); color: var(--deep); }

/* SSO buttons — milky glass rows, no :active tint repaint */
.sso-btn {
  background: rgba(255, 255, 255, .6);
  border: 1px solid var(--glass-rim);
  box-shadow: 0 4px 12px -6px rgba(var(--shade), .25);
}
.sso-btn:active { background: rgba(255, 255, 255, .6); transform: none; }

/* accordions — milky glass, quiet press */
details.acc {
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, 0) 100%),
    linear-gradient(150deg, var(--glass-hi), var(--glass-lo));
  border: 1px solid var(--glass-rim);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .95), 0 10px 26px -12px rgba(var(--shade), .22);
}
details.acc summary:active { background: transparent; }

/* da'ee team tag strip — a glass well */
.tag-strip {
  background: rgba(255, 255, 255, .55);
  border: 1px dashed rgba(var(--shade), .25);
  box-shadow: inset 0 1px 3px rgba(var(--shade), .1);
}

/* contact profile action tiles */
.cp-tile {
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, 0) 100%),
    rgba(255, 255, 255, .6);
  border: 1px solid var(--glass-rim);
  box-shadow: 0 4px 12px -6px rgba(var(--shade), .25);
}
.cp-tile:active {
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, 0) 100%),
    rgba(255, 255, 255, .6);
  transform: none;
}
.cp-tile .ic { color: var(--deep); }

/* profile photo preview — a shallow well */
.photo-picker .preview {
  background: rgba(255, 255, 255, .55);
  border: 1px solid rgba(var(--shade), .16);
  box-shadow: inset 0 1px 3px rgba(var(--shade), .1);
}

/* tutorial feature card + dots */
.tut-feature {
  background:
    linear-gradient(115deg, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, 0) 100%),
    linear-gradient(150deg, var(--glass-hi), var(--glass-lo));
  border: 1px solid var(--glass-rim);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .95), 0 10px 26px -12px rgba(var(--shade), .25);
}
.tut-dots i.on { background: rgb(var(--t)); box-shadow: 0 0 8px rgba(var(--t), .5); }

/* onboarding progress fill breathes softly (well track is set above) */
.onb-top .progress i { animation: onb-fill-breathe 3s ease-in-out infinite; }
@keyframes onb-fill-breathe {
  0%, 100% { box-shadow: 0 0 6px rgba(var(--t), .35); }
  50% { box-shadow: 0 0 12px rgba(var(--t), .65); }
}

/* ---------- small screens & hit areas ---------- */
.onb-footer { flex-wrap: wrap; } /* 3-button footers overflowed 320px */
/* five learner dock labels collided at ≤400px ('ConnectionsCommunity') —
   shrink the label voice so all five fit */
@media (max-width: 400px) {
  .dock-item span { font-size: 10px; letter-spacing: -.02em; }
}
@media (max-width: 340px) {
  .dock-item { padding-left: 2px; padding-right: 2px; }
  .dock-item span { font-size: 9px; letter-spacing: -.03em; }
}
.chip[data-role], .chip[data-rm] { min-height: 44px; }
.rp-bar { min-height: 44px; } /* flex centering keeps the 6px track centered */
.rp-btn {
  width: 44px;
  height: 44px;
  border: 5px solid transparent; /* 44px hit box, 34px visible disc (.switch idiom) */
  background-color: var(--brand);
  background-clip: padding-box;
}
.bubble.call { min-width: min(220px, 100%); }

/* ---------- reduced-motion mirrors (must stay LAST in the cascade) ---------- */
@media (prefers-reduced-motion: reduce) {
  .gwash, .dock-fab .fab, .dock-fab .fab::after, .room-card.live, .banner.urgent, .row.urgent,
  .fat-medal, .onb-top .progress i, .checkbox.on svg * { animation: none; }
  .dock-fab .fab {
    box-shadow:
      inset 0 0 0 1.5px rgba(255, 255, 255, .45),
      0 10px 22px -6px rgba(var(--shade), .55),
      0 0 18px 3px color-mix(in srgb, var(--glow) 30%, transparent);
  }
  .banner.urgent, .row.urgent { background: color-mix(in srgb, var(--danger) 10%, var(--surface)); }
  .dspark { animation: none; opacity: 0; }
  .pressing { transition: none; }
  .dock, .lit, .card.lit, .cm-bar i, .prog i,
  .seg button, .segment button, .switch::before, .switch::after, .fab-float,
  .field input, .field select, .field textarea, .composer input, .composer .btn,
  .composer .btn::after, .tut-dots i { transition: none; }
  .tos-row.flash { animation: none; background: transparent; box-shadow: 0 0 0 3px rgba(var(--t), .28); }
  .qr-scan::after { animation: none; top: 48%; opacity: .8; }
  /* static end-states for the effects introduced above */
  .checkbox.on svg * { stroke-dashoffset: 0; }
  .onb-top .progress i { box-shadow: 0 0 10px rgba(var(--t), .55); }
}
