/* Cursorless display material. Loaded last; every rule is glasses-scoped.
   Source: design/references/meta-app-panels/panel-detail.png.
   These are emitted colours, not a blur/darkening of the physical scene. */
[data-host="glasses"] {
  --ink: #000;
  --text: #f4f4fa;
  --dim: #d1d4e5;
  --accent: #e2dbff;
  --focus: #fff;
  --glow: none;
  --display: var(--ui);
  --live: #ff9696;
  --live-bar: #ff9696;
  --work: #ffd496;
  --panel: radial-gradient(ellipse at 0% 0%, rgba(214,153,229,.38), transparent 64%),
    linear-gradient(115deg, rgba(83,65,148,.70), rgba(29,74,99,.50));
  --panel-edge: rgba(212,212,255,.34);
  --panel-rim: inset 0 1px 0 rgba(255,228,255,.48);
  --fs-phonetic: 26px;
  --fs-gloss: 22px;
  --fs-mine: 15px;
  --fs-theirs: 14px;
  --fs-intent: 14px;
}

[data-host="glasses"] body { background: #000; }
[data-host="glasses"] #stage { padding: 20px; }
[data-host="glasses"] #bar {
  font-size: 14px; letter-spacing: 0; gap: 8px; margin-bottom: 12px;
  min-height: 28px;
}
[data-host="glasses"] #bar .pair { flex-shrink: 0; }
[data-host="glasses"] #bar .lang { padding: 4px 6px; border-radius: 9px; }
[data-host="glasses"] #bar .mode,
[data-host="glasses"] #status { font-size: 12px; letter-spacing: .03em; }

/* One material across content, feedback, and actions. Insets keep each panel
   visibly detached from the canvas. No outer shadow and no real-world blur. */
[data-host="glasses"] :is(.card, .said, #heard, .idle-hero, .stage-note,
  #out > .hint:not(.idle-hero), #out > .err, #mic, #scene-btn) {
  background: var(--panel);
  border: 1px solid var(--panel-edge);
  border-radius: 22px;
  box-shadow: var(--panel-rim);
  color: var(--text);
}
[data-host="glasses"] #out { gap: 10px; overflow: hidden; }
[data-host="glasses"] .said {
  padding: 12px 18px; margin: 0; flex: none;
}
/* Same attribution treatment as #heard .who-tag — the two labels name the same
   thing and had drifted into two different looks. */
[data-host="glasses"] .said .eyebrow {
  font-size: 12px; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; margin-bottom: 5px; color: var(--dim);
}
[data-host="glasses"] .gloss {
  font-weight: 500; line-height: 1.25; letter-spacing: 0;
  text-wrap: pretty;
}
[data-host="glasses"] .card,
[data-host="glasses"] .card.matched {
  align-self: stretch; padding: 10px 18px; border-width: 1px;
  position: relative; flex: none;
}
[data-host="glasses"] .card .intent {
  font-size: var(--fs-intent); font-weight: 500; letter-spacing: 0;
  text-transform: none; line-height: 1.2;
}
[data-host="glasses"] .card .mine { margin-top: 3px; line-height: 1.2; }
[data-host="glasses"] .card .phonetic {
  font-weight: 600; letter-spacing: 0; line-height: 1.16; margin-top: 5px;
}
[data-host="glasses"] .card .theirs { margin-top: 3px; line-height: 1.2; }
[data-host="glasses"] .card .phonetic .tone { color: var(--text); }

/* "It heard me and it picked this one" is the single most important moment in
   a turn, and it was carried by five small words on the intent line — the same
   weight as a label. It is a recognition event, so the whole panel answers:
   the card lights up, the other two drop back, and a filled check sits where
   the eye already is. Brightness and a solid mark, not hue alone, because an
   additive display has no dark and the wearer may be in sunlight. */
[data-host="glasses"] #out:has(.card.matched) .card:not(.matched) {
  opacity: .55;
}
[data-host="glasses"] .card.matched {
  background:
    radial-gradient(ellipse at 0% 0%, rgba(236,206,255,.52), transparent 66%),
    linear-gradient(115deg, rgba(126,102,214,.86), rgba(48,116,152,.66));
  border-color: rgba(238,232,255,.80);
  box-shadow: inset 0 1px 0 rgba(255,240,255,.62), 0 0 0 1px rgba(210,196,255,.34);
  padding-right: 52px;
}
[data-host="glasses"] .card.matched :is(.intent, .mine, .theirs) { color: var(--text); }
/* app.css puts ' ✓ SAID' on .intent::after for the phone. That is a DIFFERENT
   pseudo-element from the badge below, so on glass both rendered — the text
   mark and the badge, two copies of one fact. The phone keeps its version. */
[data-host="glasses"] .card.matched .intent::after { content: none; }
/* Replaces the old ' · ✓ Said' text run. A mark in the corner survives the
   fit- steps that hide .intent entirely, which the text version did not. */
[data-host="glasses"] .card.matched::after {
  content: '✓';
  position: absolute; top: 50%; right: 16px; transform: translateY(-50%);
  width: 30px; height: 30px; border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(255,255,255,.94); color: #2b2350;
  font-size: 17px; font-weight: 700; line-height: 1;
}

/* The host browser paints its own focus ring — an orange one on this device —
   the moment the app calls .focus(). It lands on whatever DOM focus is seated,
   which on boot is a reply card nobody has moved to yet, so it reads as a
   pre-selected answer in a colour this UI never uses. Every focus signal here
   is drawn deliberately below, so the UA ring is removed on everything, not
   just the .focusable set: #sayText, #sayGo and the scene chips are focusable
   too and were each showing it. Both :focus and :focus-visible, because the
   programmatic .focus() call trips the first without the second. */
[data-host="glasses"] :is(*, :focus, :focus-visible) { outline: none; }

/* D-pad selection surrounds the complete target. Already-spoken remains a
   labelled checkmark, so a spoken reply and a different focused reply coexist. */
[data-host="glasses"] :is(.focusable, #picker .opt) {
  outline: 2px solid transparent; outline-offset: -3px;
}
/* Only .focused paints, and 07-shell.js sets that class only after the wearer
   actually moves (globalThis.focusShown). DOM focus alone must never draw, or
   card one looks chosen before anyone chose it. */
[data-host="glasses"] :is(.focusable.focused, #picker .opt.focused) {
  outline-color: var(--focus); color: var(--text);
}
[data-host="glasses"] .card.focused,
[data-host="glasses"] .card.matched.focused { border-color: var(--panel-edge); }
[data-host="glasses"] .card.focused .intent { color: var(--text); }
[data-host="glasses"] :is(.focusable, #picker .opt).panel-pressed {
  box-shadow: inset 0 0 0 3px var(--focus);
  filter: brightness(1.15);
}

[data-host="glasses"] #heard {
  font-size: 16px; padding: 10px 18px; margin: 0 0 10px;
  line-height: 1.3; flex: none;
}
/* Who is talking was an inline run at the head of the sentence, in the same
   size and colour as the sentence, so "you said"/"them" read as the first two
   words of the quote rather than as its attribution. It becomes its own line
   above the text: smaller, tracked, and on its own row, so the eye gets the
   speaker before it starts reading. */
[data-host="glasses"] #heard .who-tag {
  display: block; margin: 0 0 4px; vertical-align: baseline;
  font-size: 12px; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--dim);
}
/* Their line is what the reply answers, so it is the bright one; yours is the
   sentence the app is not answering and stays quiet. */
[data-host="glasses"] #heard.who-them .who-tag { color: var(--accent); }
[data-host="glasses"] #heard.who-me .who-tag,
[data-host="glasses"] #heard.self-echo .who-tag { color: var(--dim); }
[data-host="glasses"] #heard.self-pending {
  /* Retain the existing progress underline above the new panel material. */
  background-image: linear-gradient(90deg, transparent, var(--work), transparent), var(--panel);
  background-size: 40% 2px, 100% 100%, 100% 100%;
  background-repeat: no-repeat;
}
[data-host="glasses"] .idle-hero {
  flex: 0 1 auto; align-self: stretch; padding: 28px; margin: auto 0;
  text-align: left; align-items: flex-start;
}
[data-host="glasses"] .hint.idle-hero .big {
  font-size: 28px; font-weight: 500; letter-spacing: 0; line-height: 1.2;
}
[data-host="glasses"] .hint.idle-hero .sub {
  font-size: 18px; line-height: 1.4; max-width: 100%; margin-top: 12px;
}
[data-host="glasses"] .hint.idle-hero .scene-set,
[data-host="glasses"] .pair-link { font-size: 16px; }
[data-host="glasses"] .pair-link { margin-top: 16px; }
[data-host="glasses"] :is(.stage-note, #out > .hint:not(.idle-hero), #out > .err) {
  padding: 14px 18px; font-size: 16px; margin: 0;
}
[data-host="glasses"] :is(.stage-note.err, #out > .err) { border-color: var(--hot); }
[data-host="glasses"] footer { gap: 10px; padding-top: 12px; }
[data-host="glasses"] #mic,
[data-host="glasses"] #scene-btn {
  min-height: 48px; padding: 12px 18px; font-size: 16px; font-weight: 500;
  letter-spacing: 0; text-transform: none;
}
[data-host="glasses"] #mic.focused { background: var(--panel); color: var(--text); }
[data-host="glasses"] #mic.on { border-color: var(--live); color: var(--text); }

/* An open mode hides the underlying UI: additive dark surfaces cannot occlude
   previously drawn text. This prevents two screens shining through each other. */
[data-host="glasses"] #stage:has(#picker.open) > :not(#picker),
[data-host="glasses"] #stage:has(#sceneModal.open) > :not(#sceneModal) { visibility: hidden; }
[data-host="glasses"] #stage:has(#sceneModal.open) #picker { visibility: hidden; }
[data-host="glasses"] #picker,
[data-host="glasses"] #sceneModal {
  inset: 20px; padding: 24px; background: var(--panel);
  border: 1px solid var(--panel-edge); border-radius: 28px;
  box-shadow: var(--panel-rim);
}
[data-host="glasses"] #picker .ptitle,
[data-host="glasses"] #sceneModal .sm-title {
  font-size: 24px; font-weight: 500; text-transform: none; letter-spacing: 0;
  color: var(--text);
}
[data-host="glasses"] #picker .plist { gap: 6px 10px; padding: 3px; }
[data-host="glasses"] #picker .opt {
  border: 0; border-radius: 12px; min-height: 42px; padding: 8px 12px;
  color: var(--text); font-size: 18px;
}
[data-host="glasses"] #picker .opt.current::after { color: var(--text); }
[data-host="glasses"] #picker .pfoot,
[data-host="glasses"] #sceneModal .sm-foot { font-size: 14px; }
[data-host="glasses"] #sceneModal .sm-sub { font-size: 20px; }
[data-host="glasses"] #sceneModal .sm-rec {
  min-height: 54px; border: 1px solid var(--panel-edge); border-radius: 16px;
  background: rgba(152,154,227,.18); color: var(--text); font-weight: 500;
}
[data-host="glasses"] #sceneModal .sm-heard { font-size: 16px; }
[data-host="glasses"] #sceneModal :is(#sceneWave, .sm-prog) { background-color: rgba(128,146,216,.12); }

/* Fit the real content, in priority order. Do not make pronunciation tiny to
   retain the native-script helper that is available on the paired phone. */
[data-host="glasses"] #out:is(.fit-1, .fit-2, .fit-3, .fit-4) {
  --fs-intent: 14px; --fs-mine: 14px; --fs-theirs: 14px;
  --fs-phonetic: 24px; --fs-gloss: 20px; gap: 8px;
}
[data-host="glasses"] #out:is(.fit-1, .fit-2, .fit-3, .fit-4) .theirs { display: none; }
[data-host="glasses"] #out:is(.fit-2, .fit-3, .fit-4) .card { padding: 8px 16px; }
/* Keep the badge's gutter through every fit step, or the tightened padding
   runs the reply text under the checkmark. */
[data-host="glasses"] #out:is(.fit-2, .fit-3, .fit-4) .card.matched { padding-right: 52px; }
[data-host="glasses"] #out:is(.fit-2, .fit-3, .fit-4) .said { padding: 10px 16px; margin: 0; }
[data-host="glasses"] #out:is(.fit-3, .fit-4) { --fs-phonetic: 22px; --fs-gloss: 18px; }
/* fit-4 hides .intent, which is why the mark cannot live on that line. The
   badge above is positioned on the card itself, so it survives here unchanged
   — this step used to redeclare ::after and produced a second, different mark. */
[data-host="glasses"] #out.fit-4 .intent { display: none; }
/* The emoji is INSIDE .intent, which the rule above hides at fit-4 - so without
   this the cue would disappear at exactly the step where the display is most
   cramped and a one-glyph label does the most work. Show the line again and
   blank the text, leaving the emoji alone on it: three cards still tell apart
   at a glance, at the cost of one glyph of height rather than a whole label. */
[data-host="glasses"] #out.fit-4 .intent:has(.emoji) {
  display: block;
  font-size: 0;        /* kills the intent text; .emoji re-declares its own size */
  line-height: 1;
}
[data-host="glasses"] #out.fit-4 .intent .emoji {
  font-size: var(--fs-intent); margin-right: 0;
}

[data-host="glasses"] .card.ghost {
  opacity: 1; min-height: 78px; animation: none;
}
[data-host="glasses"] .card.ghost::after {
  content: 'Preparing reply…'; font-size: 16px; color: var(--dim);
}

/* The photograph is a texture stress test, never optical calibration. Black
   text shadows are disabled above and the scene stays sharp here. */
[data-host="glasses"] body.has-bg #scene { filter: none; transform: none; }
[data-host="glasses"] body.has-bg #stage { background: transparent; }

@media (prefers-reduced-motion: no-preference) {
  [data-host="glasses"] :is(.focusable, #picker .opt) {
    transition: outline-color 160ms ease-out, filter 120ms ease-out;
  }
}
