  /* ============================================================
     RESET SESSION — Portal-anchored control
     Sits at the Portal's lower-left bracket, horizontally aligned
     with the 'portal' label at the lower-right bracket. Architectural
     symmetry: entry-affordance on one corner, session-reset on the other.
  ============================================================ */
  .reset-session {
    position: fixed;
    left: 14px;
    top: 38%;
    transform: translateY(-50%) rotate(180deg);
    writing-mode: vertical-rl;
    display: flex; align-items: center; gap: 7px;
    padding: 0;
    background: transparent;
    border: none;
    font-family: 'IBM Plex Mono', monospace;
    font-size: 9.5px;
    letter-spacing: 0.42em;
    text-transform: uppercase;
    color: rgba(232, 144, 128, 0.55);
    cursor: pointer;
    z-index: 51;
    transition: color 0.3s ease, opacity 0.3s ease;
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
  }
  .reset-session svg { display: none; }
  body.revealed[data-state="idle"] .reset-session,
  body.revealed[data-state="live"] .reset-session {
    opacity: 1;
    pointer-events: auto;
  }
  .reset-session:hover {
    color: #ffb09c;
  }
  .reset-session:hover svg {
    transform: rotate(-30deg);
  }
  .reset-session svg {
    width: 11px; height: 11px;
    flex-shrink: 0;
    transition: transform 0.4s cubic-bezier(0.2, 0, 0.2, 1);
  }
  /* Confirmation state — armed and waiting for second tap */
  .reset-session.confirming {
    color: #ffb09c;
    text-shadow: 0 0 10px rgba(232, 144, 128, 0.45);
    animation: reset-pulse-soft 1.4s ease-in-out infinite;
  }
  .reset-session.confirming svg {
    transform: rotate(-30deg);
  }
  @keyframes reset-pulse-soft {
    0%, 100% { opacity: 0.7; }
    50%      { opacity: 1; }
  }
  @media (max-width: 720px) {
    .reset-session {
      left: 18px;
      font-size: 8px;
      letter-spacing: 0.28em;
      gap: 5px;
    }
    .reset-session svg { width: 10px; height: 10px; }
  }

  /* ============================================================
     PORTAL — affordance-only entry threshold
     Two L-corner brackets mark the zone. No border, no fill, no
     permanent text. Discoverable through use, not instruction.
  ============================================================ */
  .portal {
    position: absolute;
    top: 80px;
    left: 50%;
    transform: translateX(-50%);
    width: min(720px, 86vw);
    height: 140px;
    z-index: 12;
    transition: height 0.5s cubic-bezier(0.2, 0, 0.2, 1);
    opacity: 0;
    pointer-events: auto;
    cursor: pointer;
  }
  body.revealed[data-state="idle"] .portal,
  body.revealed[data-state="live"] .portal {
    opacity: 1;
    transition: opacity 1.4s ease 0.7s,
                height 0.5s cubic-bezier(0.2, 0, 0.2, 1);
  }
  .portal.dragover {
    height: 30vh;
  }
  /* Two diagonal L-brackets — top-left + bottom-right. Inverted L pair. */
  .portal-bracket {
    position: absolute;
    width: 18px; height: 18px;
    border: 1px solid rgba(220, 170, 100, 0.32);
    pointer-events: none;
    transition: border-color 0.3s ease, width 0.4s ease, height 0.4s ease;
  }
  .portal-bracket.tl {
    top: 0; left: 0;
    border-right: none; border-bottom: none;
  }
  .portal-bracket.br {
    bottom: 0; right: 0;
    border-left: none; border-top: none;
  }
  .portal.dragover .portal-bracket {
    border-color: rgba(232, 196, 120, 0.85);
    width: 26px; height: 26px;
  }
  /* Portal label — permanent, anchored at the lower-right L-bracket.
     Same typography family as the call-button sub-labels. The label
     itself is the affordance — small, curious, inviting a tap. */
  .portal-label {
    position: absolute;
    bottom: -4px;
    right: 22px;
    display: flex; align-items: center; gap: 7px;
    padding: 4px 2px 4px 6px;
    font-family: 'IBM Plex Mono', monospace;
    font-size: 9px;
    letter-spacing: 0.32em;
    text-transform: uppercase;
    color: rgba(220, 170, 100, 0.62);
    pointer-events: none;
    transition: color 0.3s ease, transform 0.3s ease;
    white-space: nowrap;
  }
  .portal-label svg {
    width: 11px; height: 13px;
    transition: transform 0.3s ease, color 0.3s ease;
    color: inherit;
  }
  .portal:hover .portal-label,
  .portal.dragover .portal-label {
    color: var(--gold-icon);
  }
  .portal:hover .portal-label svg,
  .portal.dragover .portal-label svg {
    transform: translateY(-2px);
  }
  /* Hint surfaces ONLY during drag — no permanent label */
  .portal-hint {
    position: absolute;
    left: 50%; top: 50%;
    transform: translate(-50%, -50%);
    font-family: 'Fraunces', serif;
    font-style: italic;
    font-size: 14px;
    color: var(--gold-icon);
    text-shadow: 0 0 12px rgba(232, 196, 120, 0.45);
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.3s ease;
    white-space: nowrap;
  }
  .portal.dragover .portal-hint { opacity: 1; }
  .portal.received .portal-bracket {
    border-color: rgba(232, 196, 120, 0.65);
  }

  /* Coach mark — shows ONCE on first idle, then never again.
     A breath of soft gold light from the brackets, with a brief
     italic whisper of intent. Self-dismisses after 4 seconds. */
  .portal.coach .portal-bracket {
    animation: coach-breathe 2.4s ease-in-out 2;
  }
  .portal.coach .portal-hint {
    opacity: 1;
    animation: coach-fade 4s ease-in-out forwards;
  }
  @keyframes coach-breathe {
    0%, 100% { border-color: rgba(220, 170, 100, 0.32); }
    50%      { border-color: rgba(232, 196, 120, 0.75); }
  }
  @keyframes coach-fade {
    0%   { opacity: 0; }
    20%  { opacity: 1; }
    75%  { opacity: 1; }
    100% { opacity: 0; }
  }
