/*
 * Stock & Flow — Web Edition interface and presentation
 * Future Curiosity Lab · 2026
 *
 * Defines the application shell, HUD, public controls, tooltip surfaces,
 * responsive participation layer, and screen-level design-system tokens.
 * Canvas artwork geometry remains controlled by the JavaScript renderer.
 */
@import url("fonts.css");

:root {
  color-scheme: light;

  /* Colour */
  --background: #fcfcfa;
  --foreground: #202026;
  --muted: #7b7a7e;
  --grid: #e6e5e2;
  --online: #79b59c;
  --warning: #e1b43d;
  --error: #d46253;
  --data-change: #2592eb;
  --live: #16A765;
  --memory-lane-accent: #D32F2F;
  /* Shared callout-caret geometry: About, Memory Lane, participant tooltip, portrait legend. */
  --callout-caret-half: 11px;
  --callout-caret-depth: 14px;
  --callout-caret-inner-half: 10px;
  --callout-caret-inner-depth: 13px;

  /* Type */
  --font-interface: "Inter", "Noto Sans Thai", Arial, sans-serif;

  /* Shared HUD geometry — one value keeps both screen edges equal */
  --hud-side-margin: 28px;
  --hud-top: 24px;
  --hud-identity-height: 74px;
  --hud-section-gap: 22px;
  --hud-line: 14px;
  --hud-row-gap: 7px;
  --hud-value-gap: 72px;

  /* Participation / QR */
  --participation-width: 200px;
  --participation-font-size: 14px;
  --participation-line-height: 18px;
  --participation-title-gap: 5px;
  --participation-instruction-gap: 5px;
  --qr-size: 140px;
  --qr-align-offset: 14.44px;
  --qr-motion-x: 0px;
  --qr-motion-y: 0px;
  --qr-motion-scale: 1;
  /* 4-module quiet zone of 41-module QR */
}

* {
  box-sizing: border-box;
}

html,
body {
  width: 100%;
  height: 100%;
  margin: 0;
  overflow: hidden;
  background: var(--background);
  color: var(--foreground);
  font-family: var(--font-interface);
  font-optical-sizing: auto;
}

#app-shell {
  --web-control-height: 64px;
  width: 100%;
  height: 100vh;
  height: 100dvh;
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto;
  overflow: hidden;
  background: var(--background);
}

#screen {
  position: relative;
  width: 100%;
  height: auto;
  min-height: 0;
  overflow: hidden;
}

#stage {
  display: block;
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  background: var(--background);
}

.hud {
  position: absolute;
  top: var(--hud-top);
  display: grid;
  gap: var(--hud-section-gap);
  margin: 0;
  padding: 0;
  font-size: 12px;
  line-height: var(--hud-line);
  letter-spacing: .06em;
  pointer-events: none;
}

.hud-left {
  left: var(--hud-side-margin);
  min-width: 190px;
}

.work-identity {
  height: var(--hud-identity-height);
}

.work-title {
  margin-bottom: 7px;
  font-size: 28px;
  font-weight: 800;
  line-height: 28px;
  letter-spacing: .04em;
}

.work-context,
.work-credit,
.work-version {
  font-size: 10px;
  font-weight: 400;
  line-height: 12px;
  letter-spacing: .045em;
  white-space: nowrap;
  text-transform: uppercase;
}

.work-context {
  color: var(--memory-lane-accent);
  font-weight: 600;
}

.work-credit {
  margin-top: 2px;
  color: var(--muted);
}

.work-version-row {
  display: flex;
  align-items: baseline;
  gap: 4px;
  margin-top: 1px;
  white-space: nowrap;
  pointer-events: auto;
}

.work-version {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.work-version-separator {
  color: var(--muted);
}

.work-about-button {
  appearance: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--data-change);
  font: inherit;
  font-size: 10px;
  line-height: 12px;
  font-weight: 600;
  letter-spacing: inherit;
  text-transform: uppercase;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.work-about-button:hover,
.work-about-button[aria-expanded="true"] {
  text-decoration: underline;
}

.work-about-button:focus-visible,
.about-close:focus-visible {
  outline: 2px solid var(--data-change);
  outline-offset: 2px;
}

.about-panel {
  position: fixed;
  z-index: 82;
  left: var(--hud-side-margin);
  top: calc(var(--hud-top) + var(--hud-identity-height) + 10px);
  box-sizing: border-box;
  width: min(430px, calc(100vw - (var(--hud-side-margin) * 2)));
  max-height: calc(100dvh - var(--web-control-height) - var(--hud-top) - var(--hud-identity-height) - 30px);
  display: grid;
  grid-template-rows: 42px minmax(0, 1fr);
  border: 1px solid var(--grid);
  background: #FFFFFF;
  box-shadow:
    0 2px 7px rgba(33, 32, 38, .20),
    0 20px 52px rgba(33, 32, 38, .20);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(-10px);
  transition:
    opacity 240ms cubic-bezier(.22,.61,.36,1),
    transform 280ms cubic-bezier(.22,.61,.36,1),
    visibility 0s linear 280ms;
}

.about-panel.is-open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateY(0);
  transition-delay: 0s;
}

/* Bubble tail: About is the top-left sibling of the Memory Lane popup.
   The tail points back toward MORE DETAILS so the panel's origin is explicit. */
.about-panel::before,
.about-panel::after {
  content: "";
  position: absolute;
  pointer-events: none;
  width: 0;
  height: 0;
}

.about-panel::before {
  left: 186px;
  top: -14px;
  border-left: var(--callout-caret-half) solid transparent;
  border-right: var(--callout-caret-half) solid transparent;
  border-bottom: var(--callout-caret-depth) solid var(--grid);
  filter: drop-shadow(0 -3px 2px rgba(33, 32, 38, .12));
}

.about-panel::after {
  left: 187px;
  top: -12px;
  border-left: var(--callout-caret-inner-half) solid transparent;
  border-right: var(--callout-caret-inner-half) solid transparent;
  border-bottom: var(--callout-caret-inner-depth) solid #FFFFFF;
}

.about-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 0 12px 0 14px;
  border-bottom: 1px solid var(--grid);
  background: #FFFFFF;
}

.about-panel-title,
.about-close {
  font-family: 'Inter', sans-serif;
  font-size: 10px;
  line-height: 1;
  font-weight: 600;
  letter-spacing: .06em;
}

.about-panel-title {
  color: var(--foreground);
}

.about-close {
  appearance: none;
  min-height: 30px;
  padding: 0 4px;
  border: 0;
  background: transparent;
  color: var(--foreground);
  cursor: pointer;
}

.about-close:hover {
  color: var(--muted);
}

.about-panel-content {
  min-height: 0;
  overflow: auto;
  padding: 16px 18px 18px;
  background: #FFFFFF;
  font-family: 'Noto Sans Thai', 'Inter', sans-serif;
}

.about-panel-content p {
  margin: 0;
  font-size: 14px;
  line-height: 1.65;
  font-weight: 400;
  letter-spacing: 0;
}

.about-panel-content p + p {
  margin-top: 16px;
}

.about-panel-content strong {
  font-weight: 600;
}

.about-signature {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  margin-top: 20px;
  padding-top: 14px;
  border-top: 1px solid var(--grid);
}

.about-logo {
  display: block;
  width: auto;
  height: 24px;
  margin: 0;
}

.about-panel-content .about-credit {
  display: inline;
  margin: 0;
  color: inherit;
  font: inherit;
  font-weight: 500;
  letter-spacing: inherit;
  text-decoration: none;
}

.about-panel-content .about-credit:hover {
  color: var(--foreground);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.about-panel-content .about-credit:focus-visible {
  outline: 2px solid var(--data-change);
  outline-offset: 3px;
}

.about-meta {
  margin-top: 2px;
  color: var(--muted);
  font-family: 'Inter', sans-serif;
  font-size: 10px;
  line-height: 14px;
  font-weight: 400;
  letter-spacing: .035em;
}

@media (max-width: 640px) {
  .about-panel {
    left: 14px;
    top: calc(var(--hud-top) + var(--hud-identity-height) + 8px);
    width: calc(100vw - 28px);
    max-height: calc(100dvh - var(--web-control-height) - var(--hud-top) - var(--hud-identity-height) - 24px);
  }
}

.hud-group {
  display: grid;
  gap: var(--hud-row-gap);
}

.hud-heading {
  margin-bottom: 2px;
  font-weight: 700;
}

.hud-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  column-gap: var(--hud-value-gap);
}

.hud-row strong {
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.hud-right {
  top: calc(var(--hud-top) + var(--hud-identity-height) + var(--hud-section-gap));
  right: var(--hud-side-margin);
  width: min(var(--participation-width),
      calc(100vw - var(--hud-side-margin) - var(--hud-side-margin)));
  min-width: 0;
  text-align: right;
}

/*
  All three elements share the same right-hand reference box.
  Changing the Thai font size therefore never changes the screen margin.
*/
.participation-input {
  justify-items: stretch;
  gap: 0;
  margin: 0;
  padding: 0;
  text-align: right;
}


.participation-title,
.participation-subtitle,
.participation-instruction {
  display: block;
  width: 100%;
  margin: 0;
  padding: 0;
  color: var(--foreground);
  font-size: var(--participation-font-size);
  line-height: var(--participation-line-height);
  text-align: right;
  white-space: nowrap;
}

.participation-title {
  font-family: "Inter", "Noto Sans Thai", sans-serif;
  font-weight: 700;
  letter-spacing: .06em;
}

.participation-subtitle {
  margin-top: var(--participation-subtitle-gap);
  font-family: "Noto Sans Thai", sans-serif;
  font-weight: 400;
  letter-spacing: 0;
}

.participation-instruction {
  margin-top: var(--participation-instruction-gap);
  font-family: "Noto Sans Thai", sans-serif;
  font-weight: 400;
  letter-spacing: 0;
}

.qr-placeholder {
  display: block;
  width: var(--qr-size);
  height: auto;
  margin: 0 0 0 auto;
  padding: 0;
  justify-self: end;
  transform-origin: center;
  transform:
    translate3d(calc(var(--qr-align-offset) + var(--qr-motion-x)), var(--qr-motion-y), 0)
    scale(var(--qr-motion-scale));
}

.qr-placeholder.is-recomposition-moving {
  position: relative;
  z-index: 4;
  will-change: transform;
}

.qr-placeholder.is-recomposition-source-hidden {
  opacity: 0;
}

.qr-recomposition-proxy {
  position: fixed;
  z-index: 4;
  display: block;
  margin: 0;
  padding: 0;
  pointer-events: none;
  transform-origin: center;
  will-change: left, top, width, height, transform;
}

.recomposition-cta {
  position: absolute;
  left: 50%;
  z-index: 4;
  width: min(420px, calc(100vw - 80px));
  margin: 0;
  padding: 0;
  color: var(--foreground);
  font-family: "Noto Sans Thai", sans-serif;
  font-size: 18px;
  font-weight: 450;
  line-height: 24px;
  text-align: center;
  pointer-events: none;
  opacity: 0;
  transform: translateX(-50%);
}

.credit {
  font-size: 10px;
  letter-spacing: .025em;
}

.hud-value {
  color: var(--foreground);
  white-space: nowrap;
  transition: color var(--data-change-return, 1300ms) ease;
}

.hud-value.is-updated {
  color: var(--data-change);
  transition-duration: var(--data-change-in, 260ms);
}

.status-dot {
  display: block;
  align-self: center;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--warning);
  transform: translateY(-1px);
}

.status-dot.online {
  background: var(--online);
}

.status-dot.error {
  background: var(--error);
}

.hud-arriving {
  min-height: 38px;
  opacity: var(--arriving-idle-opacity, .34);
  transition: opacity var(--arriving-transition, 1100ms) ease;
}

.hud-arriving.is-active {
  opacity: var(--arriving-active-opacity, 1);
}

.operator {
  position: absolute;
  left: 24px;
  bottom: 24px;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  background: rgba(255, 255, 255, .94);
  border: 1px solid var(--grid);
  font-size: 12px;
}

.operator:not([hidden]) {
  display: flex;
}

.operator button {
  padding: 5px 9px;
  font: inherit;
  white-space: nowrap;
}

@media (max-width: 640px) {
  :root {
    --hud-side-margin: 14px;
    --hud-top: 14px;
    --hud-identity-height: 62px;
    --hud-section-gap: 18px;
    --hud-line: 12px;
    --hud-row-gap: 6px;
    --participation-width: 180px;
    --participation-font-size: 11px;
    --participation-line-height: 15px;
    --qr-size: 120px;
    --qr-align-offset: 11.71px;
  }

  .hud {
    font-size: 10px;
  }

  .work-title {
    font-size: 15px;
  }
}

/* Blink signals: reconnecting status and queued-arrival count. */
@keyframes ml-blink {

  0%,
  100% {
    opacity: 1;
  }

  50% {
    opacity: .18;
  }
}

.status-dot.reconnecting {
  background: var(--warning);
  animation: ml-blink 1s ease-in-out infinite;
}

#connection-label.reconnecting {
  color: var(--warning);
  animation: ml-blink 1s ease-in-out infinite;
}

#waiting-count.is-waiting {
  animation: ml-blink 1s ease-in-out infinite;
}

/* Fixed left-HUD width keeps right-aligned values stable when status labels change length. */
:root {
  --hud-left-width: 250px;
}

.hud-left {
  width: var(--hud-left-width);
  min-width: 0;
}

.hud-row {
  grid-template-columns: minmax(0, 1fr) auto;
}

@media (max-width: 640px) {
  :root {
    --hud-left-width: 230px;
  }
}

/* Fixed-size avatar tooltip rendered as a DOM overlay independent of canvas zoom. */
.avatar-tooltip {
  position: fixed;
  z-index: 50;
  max-width: 280px;
  padding: 10px 14px;
  border-radius: 12px;
  background: #ffffff;
  color: #1c1b1f;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .10), 0 4px 14px rgba(0, 0, 0, .14);
  border: 1px solid rgba(0, 0, 0, .04);
  font-family: 'Noto Sans Thai', 'Inter', sans-serif;

  /* Portrait geometry is built on one 8px module. The card itself has no
     independent width/height constant: JS derives its bounds from these
     component dimensions, so artwork, legend, and outer padding stay related. */
  --portrait-unit: 8px;
  --portrait-pad: 16px;            /* 2u */
  --portrait-art-size: 208px;      /* 26u */
  --portrait-gap: 16px;            /* 2u */
  --portrait-legend-width: 320px;  /* 40u */
  --portrait-row-height: 48px;     /* 6u */

  pointer-events: none;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 300ms ease, transform 300ms ease;
}

.avatar-tooltip.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.avatar-tooltip.is-leaving {
  opacity: 0;
  transform: translateY(-3px);
  transition-duration: 500ms;
}

.avatar-tooltip.is-ceremony {
  transform: translateY(0);
  transition: none;
}

.avatar-tooltip[hidden] {
  display: none;
}

.avatar-tooltip .tt-text {
  margin: 0;
  font-size: 16px;
  line-height: 22px;
  font-weight: 400;
  color: #1c1b1f;
  white-space: pre-wrap;
  word-break: break-word;
}

.avatar-tooltip .tt-district {
  margin: 4px 0 0;
  font-size: 12px;
  line-height: 16px;
  letter-spacing: .04em;
  color: #1c1b1f;
}

.avatar-tooltip .tt-district:empty {
  display: none;
}

/* Speech-bubble caret and submission-time metadata. */
.avatar-tooltip .tt-time {
  margin: 3px 0 0;
  font-size: 12px;
  /* Same size as district metadata; differentiated by tone */
  line-height: 16px;
  letter-spacing: .03em;
  color: #9a9aa0;
}

.avatar-tooltip .tt-time:empty {
  display: none;
}

.avatar-tooltip .tt-caret {
  position: absolute;
  bottom: calc(-1 * var(--callout-caret-depth));
  left: var(--tt-caret-pos, 50%);
  width: 0;
  height: 0;
  transform: translateX(-50%);
  border-left: var(--callout-caret-half) solid transparent;
  border-right: var(--callout-caret-half) solid transparent;
  border-top: var(--callout-caret-depth) solid #ffffff;
  /* Default / legacy direction: card above, caret points down to the avatar. */
  filter: drop-shadow(0 3px 2px rgba(0, 0, 0, .10));
}

.avatar-tooltip.flip .tt-caret,
.avatar-tooltip.place-bottom .tt-caret {
  bottom: auto;
  top: calc(-1 * var(--callout-caret-depth));
  left: var(--tt-caret-pos, 50%);
  right: auto;
  transform: translateX(-50%);
  border-left: var(--callout-caret-half) solid transparent;
  border-right: var(--callout-caret-half) solid transparent;
  border-top: none;
  border-bottom: var(--callout-caret-depth) solid #ffffff;
  filter: drop-shadow(0 -3px 2px rgba(0, 0, 0, .10));
}

.avatar-tooltip.place-top .tt-caret {
  top: auto;
  bottom: calc(-1 * var(--callout-caret-depth));
  left: var(--tt-caret-pos, 50%);
  right: auto;
  transform: translateX(-50%);
  border-left: var(--callout-caret-half) solid transparent;
  border-right: var(--callout-caret-half) solid transparent;
  border-top: var(--callout-caret-depth) solid #ffffff;
  border-bottom: none;
  filter: drop-shadow(0 3px 2px rgba(0, 0, 0, .10));
}

.avatar-tooltip.place-left .tt-caret {
  left: auto;
  right: calc(-1 * var(--callout-caret-depth));
  top: var(--tt-caret-pos, 50%);
  bottom: auto;
  transform: translateY(-50%);
  border-top: var(--callout-caret-half) solid transparent;
  border-bottom: var(--callout-caret-half) solid transparent;
  border-left: var(--callout-caret-depth) solid #ffffff;
  border-right: none;
  filter: drop-shadow(3px 0 2px rgba(0, 0, 0, .10));
}

.avatar-tooltip.place-right .tt-caret {
  right: auto;
  left: calc(-1 * var(--callout-caret-depth));
  top: var(--tt-caret-pos, 50%);
  bottom: auto;
  transform: translateY(-50%);
  border-top: var(--callout-caret-half) solid transparent;
  border-bottom: var(--callout-caret-half) solid transparent;
  border-left: none;
  border-right: var(--callout-caret-depth) solid #ffffff;
  filter: drop-shadow(-3px 0 2px rgba(0, 0, 0, .10));
}
/* ============================================================
   WEB EDITION · DESKTOP CONTROL BAR
   The browser viewport is one composition: the artwork stage occupies the
   remaining space and the controls form a separate row below it. Controls do
   not overlay or reduce the legibility of the visualization.
   ============================================================ */
html,
body {
  min-height: 100%;
  min-height: 100dvh;
}

.web-control-bar {
  position: relative;
  z-index: 20;
  flex-shrink: 0;
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 24px;
  box-sizing: border-box;
  height: var(--web-control-height);
  min-height: 0;
  padding: 13px var(--hud-side-margin);
  border-top: 1px solid var(--grid);
  background: #FFFFFF;
  overflow: hidden;
  pointer-events: auto;
  opacity: 0;
  transform: translateY(10px);
  transition:
    height 820ms cubic-bezier(.22,.61,.36,1),
    padding 820ms cubic-bezier(.22,.61,.36,1),
    border-color 820ms cubic-bezier(.22,.61,.36,1),
    opacity 860ms cubic-bezier(.22,.61,.36,1),
    transform 860ms cubic-bezier(.22,.61,.36,1);
}

#app-shell.controls-collapsed .web-control-bar {
  height: 0;
  padding-top: 0;
  padding-bottom: 0;
  border-top-color: transparent;
  border-top-width: 0;
}

.web-control-bar:not(.is-revealed) {
  pointer-events: none;
}

.web-control-bar.is-revealed {
  opacity: 1;
  transform: translateY(0);
}

.web-control-left {
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 18px;
}

.web-control-right {
  display: flex;
  justify-content: flex-end;
}

.web-view-buttons {
  display: flex;
  align-items: center;
  gap: 5px;
}

.web-view-button {
  appearance: none;
  min-width: 116px;
  min-height: 36px;
  margin: 0;
  padding: 0 12px;
  border: 0;
  border-radius: 0;
  background: #F3F2F0;
  color: #212026;
  font: inherit;
  font-size: 11px;
  line-height: 1;
  font-weight: 600;
  letter-spacing: .04em;
  text-align: center;
  cursor: pointer;
  transition:
    background-color 180ms cubic-bezier(.22,.61,.36,1),
    color 180ms cubic-bezier(.22,.61,.36,1),
    opacity 180ms cubic-bezier(.22,.61,.36,1);
}

.web-view-button:hover {
  background: #212026;
  color: #B3B2B1;
}

.web-view-button:focus-visible {
  outline: 2px solid #2592EB;
  outline-offset: 2px;
}

.web-view-button.is-active {
  background: #212026;
  color: #F3F2F0;
}

.web-auto-button {
  min-width: 116px;
}

.web-auto-button.is-active {
  background: var(--live);
  color: #FFFFFF;
}


/* ============================================================
   WEB EDITION · MEMORY LANE PARTICIPATION LAYER
   Desktop: portrait popup above the participation CTA, without recomposing
   the Stock & Flow field. Narrow screens: the same iframe fills the viewport,
   preserving continuity with the current Stock & Flow page and state.
   ============================================================ */
.web-control-divider {
  width: 1px;
  height: 18px;
  margin: 0 5px;
  flex: 0 0 auto;
  background: var(--grid);
}

.web-memory-button {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 196px;
  min-height: 36px;
  padding: 0 16px;
  border: 1px solid var(--memory-lane-accent);
  border-radius: 999px;
  background: var(--memory-lane-accent);
  color: #FFFFFF;
  font-family: 'Noto Sans Thai', 'Inter', sans-serif;
  font-size: 12px;
  line-height: 1;
  font-weight: 600;
  letter-spacing: .01em;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background-color 180ms cubic-bezier(.22,.61,.36,1),
    border-color 180ms cubic-bezier(.22,.61,.36,1),
    color 180ms cubic-bezier(.22,.61,.36,1),
    opacity 180ms cubic-bezier(.22,.61,.36,1);
}

.web-memory-button:hover:not([aria-expanded="true"]) {
  background: #C62828;
  border-color: #C62828;
  color: #FFFFFF;
}

.web-memory-button[aria-expanded="true"] {
  background: rgba(211, 47, 47, .10);
  border-color: rgba(211, 47, 47, .28);
  color: var(--memory-lane-accent);
}

.web-memory-button[aria-expanded="true"]:hover {
  background: rgba(211, 47, 47, .14);
  border-color: rgba(211, 47, 47, .34);
  color: var(--memory-lane-accent);
}

.web-memory-button:focus-visible,
.memory-lane-close:focus-visible {
  outline: 2px solid var(--data-change);
  outline-offset: 2px;
}

.memory-lane-panel {
  position: fixed;
  z-index: 80;
  right: var(--hud-side-margin);
  bottom: calc(var(--web-control-height) + 16px);
  box-sizing: border-box;
  width: min(410px, calc(100vw - var(--hud-side-margin) - var(--hud-side-margin)));
  height: calc(100dvh - var(--web-control-height) - 32px);
  max-height: none;
  display: grid;
  grid-template-rows: 42px minmax(0, 1fr);
  border: 1px solid var(--grid);
  background: #FFFFFF;
  box-shadow:
    0 2px 7px rgba(33, 32, 38, .20),
    0 20px 52px rgba(33, 32, 38, .20);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(10px);
  transition:
    opacity 240ms cubic-bezier(.22,.61,.36,1),
    transform 280ms cubic-bezier(.22,.61,.36,1),
    visibility 0s linear 280ms;
}

.memory-lane-panel.is-open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateY(0);
  transition-delay: 0s;
}

/* Bubble tail: the panel extends visually toward the participation CTA,
   using the same white-surface language as Stock & Flow tooltips. */
.memory-lane-panel::before,
.memory-lane-panel::after {
  content: "";
  position: absolute;
  pointer-events: none;
  width: 0;
  height: 0;
}

.memory-lane-panel::before {
  right: 87px;
  bottom: -14px;
  border-left: var(--callout-caret-half) solid transparent;
  border-right: var(--callout-caret-half) solid transparent;
  border-top: var(--callout-caret-depth) solid var(--grid);
  filter: drop-shadow(0 4px 3px rgba(33, 32, 38, .16));
}

.memory-lane-panel::after {
  right: 88px;
  bottom: -12px;
  border-left: var(--callout-caret-inner-half) solid transparent;
  border-right: var(--callout-caret-inner-half) solid transparent;
  border-top: var(--callout-caret-inner-depth) solid #FFFFFF;
}

.memory-lane-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 0 12px 0 14px;
  border-bottom: 1px solid var(--grid);
  background: #FFFFFF;
}

.memory-lane-panel-title,
.memory-lane-close {
  font-family: 'Inter', sans-serif;
  font-size: 10px;
  line-height: 1;
  font-weight: 600;
  letter-spacing: .06em;
}

.memory-lane-panel-title {
  color: var(--memory-lane-accent);
}

.memory-lane-close {
  appearance: none;
  min-height: 30px;
  padding: 0 4px;
  border: 0;
  background: transparent;
  color: var(--foreground);
  cursor: pointer;
}

.memory-lane-close:hover {
  color: var(--muted);
}

.memory-lane-frame {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  background: #FFFFFF;
}

@media (max-width: 820px) {
  #app-shell {
    --web-control-height: 104px;
  }

  .web-control-bar {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-rows: 36px 40px;
    align-content: center;
    align-items: center;
    column-gap: 12px;
    row-gap: 8px;
    height: var(--web-control-height);
    padding: 10px 14px;
  }

  /* Let the mode group and AUTO participate directly in the two-row control grid. */
  .web-control-left {
    display: contents;
  }

  .web-view-buttons {
    grid-column: 1 / -1;
    grid-row: 1;
    width: 100%;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1px;
    padding: 1px;
    overflow: hidden;
    border-radius: 10px;
    background: var(--grid);
  }

  .web-view-buttons .web-view-button {
    width: 100%;
    min-width: 0;
    min-height: 34px;
    padding: 0 6px;
    border-radius: 0;
    font-size: 10px;
  }

  .web-control-divider {
    display: none;
  }

  .web-auto-button {
    grid-column: 1;
    grid-row: 2;
    justify-self: start;
    min-width: 72px;
    min-height: 40px;
    padding: 0 14px;
    border-radius: 20px;
    background: var(--soft, #F3F2F0);
    font-size: 10px;
  }

  .web-auto-button.is-active {
    background: var(--live);
    color: #FFFFFF;
  }

  .web-control-right {
    grid-column: 2;
    grid-row: 2;
    justify-self: end;
  }

  .web-memory-button {
    width: auto;
    min-width: 0;
    min-height: 40px;
    padding: 0 18px;
    border: 1px solid var(--memory-lane-accent);
    border-radius: 999px;
    background: var(--memory-lane-accent);
    color: #FFFFFF;
    font-size: 12px;
    letter-spacing: 0;
  }

  .web-memory-button:hover,
  .web-memory-button[aria-expanded="true"] {
    background: var(--memory-lane-accent);
    border-color: var(--memory-lane-accent);
    color: #FFFFFF;
    opacity: .90;
  }

  /* Mobile participation stays inside this page as a full-screen layer. The
     browser Back gesture is handled in app.js and closes this layer first. */
  .memory-lane-panel {
    z-index: 120;
    inset: 0;
    right: 0;
    bottom: 0;
    width: 100vw;
    height: 100dvh;
    max-height: none;
    grid-template-rows: 48px minmax(0, 1fr);
    border: 0;
    box-shadow: none;
    transform: translateY(12px);
  }

  .memory-lane-panel.is-open {
    transform: translateY(0);
  }

  .memory-lane-panel::before,
  .memory-lane-panel::after {
    display: none;
  }

  .memory-lane-panel-header {
    padding-left: max(14px, env(safe-area-inset-left));
    padding-right: max(12px, env(safe-area-inset-right));
  }
}

/* ============================================================
   WEB EDITION · PORTRAIT TOOLTIP
   v0.2.43: the existing participant-voice tooltip is the source state.
   When the viewport supports the single-row control layout, a click/tap
   morphs that same anchored card into an avatar + legend portrait.
   The caret remains attached to the source avatar.
   ============================================================ */
.avatar-tooltip .tt-comment {
  opacity: 1;
  /* M3-style exit: the voice lingers for a beat after click, then clears
     quickly while the container is already expanding. */
  transition: opacity 170ms cubic-bezier(.3, 0, .8, .15);
}

/* Click phase 1: only the participant comment fades. The existing surface and
   caret remain in place, so the viewer never sees an empty replacement card. */
.avatar-tooltip.is-portrait-comment-out .tt-comment {
  opacity: 0;
}

/* Click phase 2: FLIP animates the same tooltip surface from its compact rect
   into the already-measured portrait rect. Material-style emphasized easing
   keeps the expansion decisive at the start and gentle at rest. */
.avatar-tooltip.is-portrait-flip {
  transition:
    transform 520ms cubic-bezier(.2, 0, 0, 1),
    opacity 300ms ease;
  will-change: transform;
}

.avatar-tooltip.is-portrait-flip .tt-caret {
  transition: none;
}

.avatar-tooltip .tt-portrait {
  position: absolute;
  top: var(--portrait-pad);
  right: var(--portrait-pad);
  bottom: auto;
  left: var(--portrait-pad);
  display: grid;
  grid-template-columns: var(--portrait-art-size) var(--portrait-legend-width);
  gap: var(--portrait-gap);
  align-items: center;
  opacity: 0;
  visibility: hidden;
  transform: translateY(6px) scale(.975);
  overflow: hidden;
  /* The portrait enters *inside* the expanding surface. The card's own overflow
     becomes a moving mask, so artwork and legend are gradually uncovered rather
     than appearing after the container has already changed size. */
  transition:
    opacity 280ms cubic-bezier(.2, 0, 0, 1),
    transform 440ms cubic-bezier(.05, .7, .1, 1);
}

.avatar-tooltip.is-geometry-animating {
  /* Material 3 emphasized deceleration: fast enough to feel responsive at
     click, long and soft enough at the end for the large portrait to settle.
     Bounds animate directly, so typography and artwork are never squashed by
     a non-uniform FLIP scale. */
  transition:
    opacity 300ms ease,
    left 600ms cubic-bezier(.05, .7, .1, 1),
    top 600ms cubic-bezier(.05, .7, .1, 1),
    width 600ms cubic-bezier(.05, .7, .1, 1),
    height 600ms cubic-bezier(.05, .7, .1, 1),
    padding 600ms cubic-bezier(.05, .7, .1, 1),
    border-radius 600ms cubic-bezier(.05, .7, .1, 1),
    box-shadow 600ms cubic-bezier(.05, .7, .1, 1);
  will-change: left, top, width, height, padding, border-radius;
}

.avatar-tooltip.is-geometry-animating .tt-caret {
  transition:
    left 600ms cubic-bezier(.05, .7, .1, 1),
    top 600ms cubic-bezier(.05, .7, .1, 1);
}

/* Geometry state and content state are deliberately separate. The card first
   becomes the portrait surface; only later does the portrait content appear. */
.avatar-tooltip.is-portrait-shell {
  max-width: none;
  padding: var(--portrait-pad);
  border-radius: 14px;
}

.avatar-tooltip.is-portrait .tt-portrait {
  opacity: 1;
  visibility: visible;
  transform: translateY(0) scale(1);
}

.tt-portrait-art {
  display: grid;
  place-items: center;
  width: var(--portrait-art-size);
  height: var(--portrait-art-size);
}

.tt-portrait-avatar {
  display: block;
  width: var(--portrait-art-size);
  height: var(--portrait-art-size);
  opacity: 0;
  transform: scale(.94);
  transform-origin: 50% 50%;
  transition:
    opacity 240ms cubic-bezier(.2, 0, 0, 1),
    transform 420ms cubic-bezier(.05, .7, .1, 1);
}

.avatar-tooltip.is-portrait .tt-portrait-avatar {
  opacity: 1;
  transform: scale(1);
}

.avatar-tooltip.tt-portrait-ghost {
  z-index: 49;
  pointer-events: none;
}

.tt-portrait-legend {
  min-width: 0;
  align-self: start;
  display: grid;
  width: var(--portrait-legend-width);
  grid-auto-rows: var(--portrait-row-height);
}

.tt-legend-row {
  min-width: 0;
  display: grid;
  grid-template-columns: 38px minmax(0, 1fr);
  align-items: center;
  column-gap: 9px;
  border-bottom: 1px solid rgba(32, 32, 38, .12);
  opacity: 0;
  transform: translateY(5px);
  transition:
    opacity 230ms cubic-bezier(.2, 0, 0, 1),
    transform 340ms cubic-bezier(.05, .7, .1, 1);
}

.avatar-tooltip.is-portrait .tt-legend-row {
  opacity: 1;
  transform: translateY(0);
}

.avatar-tooltip.is-portrait .tt-legend-row:nth-child(1) { transition-delay: 34ms; }
.avatar-tooltip.is-portrait .tt-legend-row:nth-child(2) { transition-delay: 56ms; }
.avatar-tooltip.is-portrait .tt-legend-row:nth-child(3) { transition-delay: 78ms; }
.avatar-tooltip.is-portrait .tt-legend-row:nth-child(4) { transition-delay: 100ms; }
.avatar-tooltip.is-portrait .tt-legend-row:nth-child(5) { transition-delay: 122ms; }
.avatar-tooltip.is-portrait .tt-legend-row:nth-child(6) { transition-delay: 144ms; }

.tt-legend-row:last-child {
  border-bottom: 0;
}

.tt-legend-row > span:last-child {
  min-width: 0;
  display: grid;
  gap: 1px;
}

.tt-legend-row small,
.tt-legend-row strong {
  display: block;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: 'Noto Sans Thai', 'Inter', sans-serif;
}

.tt-legend-row small {
  font-size: 10px;
  line-height: 15px;
  font-weight: 400;
  color: #77777d;
}

.tt-legend-row strong {
  font-size: 13px;
  line-height: 19px;
  padding-top: 1px;
  font-weight: 600;
  color: #1c1b1f;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.tt-legend-mark {
  position: relative;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  color: #202026;
}

.tt-legend-mark .tt-shape {
  display: block;
  width: 22px;
  height: 22px;
}

.tt-legend-mark .tt-shape.circle {
  border-radius: 50%;
}

.tt-legend-mark .tt-shape.arch {
  border-radius: 11px 11px 0 0;
}

.tt-legend-mark .tt-shape.outline {
  border: 2px solid currentColor;
  background: transparent;
}

.tt-legend-mark .tt-shape.solid {
  background: currentColor;
}

.tt-dot-set {
  width: 28px;
  height: 28px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  place-items: center;
}

.tt-dot-set i {
  display: block;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: #202026;
}

.tt-time-set {
  width: 28px;
  display: grid;
  gap: 3px;
}

.tt-time-set i {
  display: block;
  width: 28px;
  height: 5px;
}

.tt-gender-dot {
  display: block;
  width: 19px;
  height: 19px;
  border-radius: 50%;
}

.tt-age-grid {
  width: 27px;
  height: 27px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  gap: 2px;
}

.tt-age-grid i {
  display: block;
  width: 7px;
  height: 7px;
  background: transparent;
}

.tt-age-grid i.on {
  background: #202026;
}
