/* Genie: the box, the palette, the conversation to the design (design/DESIGN_GUIDE.md; audit design/previews/visit-redesign/audit/app-gaps.json).
   Desktop and the web only: every rule is scoped :root:not(.android):not(.ios) or wrapped in @media (min-width:768px); the phones keep their tiers.
   Colours through tokens.css only (rule I-3).
   Decisions recorded here so a later pass does not re-litigate them:
   - Box height 44px (owner rule: inputs are 44-46px tall) at the design's own radius 9px (studio.css:41, freed of the
     studio.css generic input-override list that had lifted it to radius 8). The box's outer width/placement stay the
     shell agent's (shell.css .genie-wrap / .genie-bar).
   - Idle background stays var(--card) (= --panel): the Source, the README and the Visit file each say something
     different (transparent / --panel2 / --panel); the Visit file — the newest, and the one already shipped for this
     box — wins, so the build's existing var(--card) is correct as is. */

/* The design's own ring spread (Source 70: 13px, not studio.css's 11px); redeclaring the keyframe here (genie.css loads
   last) replaces it for the whole page. */
@keyframes genie-ring{0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--recording-red) 40%,transparent)}100%{box-shadow:0 0 0 13px transparent}}

@media (min-width:768px){
  /* Box: 44px (owner rule) at the design's own radius 9 (studio.css:41, once out from under the :533 override list
     below); the colour transition covers the background fill too, so listening/heard never snaps (Source 396). */
  :root:not(.android):not(.ios) .genie-bar{height:44px;transition:background-color 220ms var(--ease),border-color 220ms var(--ease),box-shadow 220ms var(--ease)}
  /* Mic glyphs at the design's 16px (Source 2684); the idle glyph reads --accent-text everywhere the box appears,
     including the visit page (Visit file line 265 and README §4 agree; only the Redesign file's plain --ink2 does not). */
  :root:not(.android):not(.ios) .genie-mic{color:var(--accent-text)}
  :root:not(.android):not(.ios) .genie-mic .icon{width:16px;height:16px}
  /* "Mic in use" stands in for the mic on the visit page while it records (Visit file 269-271): a real, titled span
     toggled from paintRecording(), not a pseudo-element, so it reaches the accessibility tree. */
  :root:not(.android):not(.ios) .genie-mic-busy{display:none}
  :root:not(.android):not(.ios) .genie-mic-busy:not([hidden]){display:inline-flex;align-items:center;flex:none;font-size:11px;color:var(--hint);padding-right:6px;white-space:nowrap}
  /* No second recording indicator once the header pill carries the timer, the label and "back to the visit" itself —
     but the chip still leads back to a visit transcribing or writing elsewhere (its own .working class, app.js), which
     the header pill does not draw a state for. */
  :root:not(.android):not(.ios) #recording-chip:not(.working){display:none}
}

@media (min-width:761px){
  /* Listening meter: the real microphone level (kept — better than the design's fake keyframe bars) drawn at the
     design's own geometry — 13px bars, bottom-anchored, a floor of .25 so a silent moment still reads as "listening"
     rather than flat (Source 427-431). LEVEL_BARS is 24 (genie-dock.js). */
  :root:not(.android):not(.ios) .genie-bar[data-state=listening] .genie-levels{align-items:flex-end;height:13px}
  :root:not(.android):not(.ios) .genie-levels i{height:13px;transform-origin:bottom;transform:scaleY(calc(.25 + var(--level,0) * .75))}
  /* The recording pill's own "back to the visit" control: the timer and the label are one button (Source 401-405);
     on the visit page itself (docked) it reads as plain text — going back to where you already are is a no-op. */
  :root:not(.android):not(.ios) .genie-rec-back{display:flex;align-items:center;gap:8px;flex:1;min-width:0;border:none;background:none;padding:0;text-align:left;font:inherit;color:inherit;cursor:pointer}
  :root:not(.android):not(.ios) .genie-bar.docked .genie-rec-back{cursor:default}
  /* Paused reads --warn (Source 2630), not the review queue's amber dot. */
  :root:not(.android):not(.ios) .genie-bar.paused .genie-rec-dot{background:var(--review-text)}
  /* The orb pulses in every open, non-idle phase (Source 2701: orbAnim runs whenever the conversation is "live"). */
  :root:not(.android):not(.ios) .genie-convo:not([data-state=idle]):not([data-state=recording]) .genie-orb{animation:genie-pulse 1.4s ease-in-out infinite}
  /* A neutral chip for a reply that found or heard nothing, instead of the green Done (the Source has no failure
     state to draw from; the build's own "Nothing was heard…" / "I could not find…" copy needs one). */
  :root:not(.android):not(.ios) .genie-chip.error{background:var(--review-bg);color:var(--review-text)}
  /* A streaming Genie turn shows Genie's own speaking bars under the text (Source 466-476); the caret stays only on
     the clinician's own turn (Source 2645). */
  :root:not(.android):not(.ios) .genie-turn.genie.streaming .genie-turn-body p::after{content:none}
  :root:not(.android):not(.ios) .genie-speak{display:none;align-items:flex-end;gap:2.5px;height:11px;margin-top:7px}
  :root:not(.android):not(.ios) .genie-turn.streaming .genie-speak{display:flex}
  :root:not(.android):not(.ios) .genie-speak i{width:2.5px;height:11px;border-radius:2px;background:var(--accent);transform-origin:bottom;animation:genie-level var(--sd,.5s) ease-in-out var(--sl,0s) infinite}
  /* Palette: at most 5 rows (Source 1878/1882, genie-dock.js), so the list never needs its own scroll region — the
     owner's no-scrolling-list rule is met by the count, not by a scrollbar. */
  :root:not(.android):not(.ios) .genie-palette-box{max-height:none;box-shadow:var(--shadow-popover)}
  :root:not(.android):not(.ios) .genie-palette-results{overflow:hidden}
  :root:not(.android):not(.ios) .genie-palette-empty strong{color:var(--ink);font-weight:550}
  /* The head's search glyph inherits --ink, unlike a dimmed --hint (Source 1745 has no colour override). */
  :root:not(.android):not(.ios) .genie-palette-head>.icon{color:var(--ink)}
  /* Messages are one line (owner rule): the footer status never wraps to a second. */
  :root:not(.android):not(.ios) .genie-convo-status{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
}

/* ---- What Genie changed, shown where it happened (genie-changes.js; design/GENIE_SPEC.md "The callout") -----------------------
   Every layout (desktop, the web at any width, the phone layouts), so these rules sit outside the desktop-only block above.
   - The row or section a change landed on is marked with --highlight (GENIE_SPEC: "the row it hangs from is highlighted"), which
     fades after about three seconds. The mark is drawn by genie-changes.js on the element itself (a script animation of
     background-color, so neither a row's own background rules nor a pane re-wrapping its content can hide or restart it). With
     reduced motion nothing moves or fades: the mark stays, still, while the callout shows. .genie-changed only names the element.
   - The callout hangs under the row, inside its card's edges (above the row when there is no room below or Genie's conversation
     is there): --accent-soft fill, --accent-line border, radius 10, the G mark, 14px/1.5 text with mono for dates and times, Undo,
     and a chevron to dismiss. It overlays the rows under it (MO-4: appearing content never shifts what is there; the table keeps
     its whole rows) at popover level (E-2: 60) with the popover shadow, and enters with the popover motion (MO-1: 140ms, rise).
   - While a visit records or the doctor types, nothing moves: the change's card in Genie's conversation (below) holds it. */
.genie-change{position:fixed;z-index:60;display:flex;align-items:flex-start;gap:12px;box-sizing:border-box;padding:15px;border:1px solid var(--accent-line);border-radius:10px;background:var(--accent-soft);box-shadow:var(--shadow-card);color:var(--ink);font-size:14px;line-height:1.5}
.genie-change.is-entering{animation:genie-change-in 140ms var(--ease)}
@keyframes genie-change-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
.genie-change__mark{display:flex;flex:none;align-items:center;justify-content:center;width:26px;height:26px;border-radius:var(--r-small);background:var(--accent);color:var(--accent-ink);font-size:11px;font-weight:650;line-height:1}
.genie-change__body{display:flex;flex:1;flex-direction:column;gap:2px;min-width:0;padding-top:2px}
.genie-change__line{margin:0;overflow-wrap:anywhere;text-wrap:pretty}
.genie-change__data{font-family:var(--font-mono);font-size:13px;white-space:nowrap}
.genie-change__error{margin:4px 0 0;color:var(--danger);font-size:12.5px;line-height:1.55}
.genie-change__undo,.genie-act__button{display:inline-flex;flex:none;align-items:center;justify-content:center;height:var(--h-compact);min-height:var(--h-compact);padding:0 12px;border:1px solid var(--accent-line);border-radius:var(--r-control);background:var(--panel);color:var(--accent-text);font:inherit;font-size:13px;font-weight:600;line-height:1;cursor:pointer;transition:border-color 160ms var(--ease),background-color 160ms var(--ease)}
.genie-act__button:is([data-action=cancel],[data-action=show]){border-color:var(--line);background:var(--panel2);color:var(--ink);font-weight:550}
.genie-act__button.is-primary{border-color:var(--accent);background:var(--accent);color:var(--accent-ink)}
.genie-change__undo:hover,.genie-act__button:hover{border-color:var(--ink3)}
.genie-act__button.is-primary:hover{border-color:var(--accent-hover);background:var(--accent-hover)}
:is(.genie-change__undo,.genie-act__button):disabled{border-color:var(--line);background:var(--panel2);color:var(--ink3);cursor:not-allowed}
.genie-change__close{display:inline-flex;flex:none;align-items:center;justify-content:center;width:var(--h-compact);height:var(--h-compact);min-height:var(--h-compact);padding:0;border:0;border-radius:var(--r-control);background:transparent;color:var(--ink3);cursor:pointer;transition:background-color 160ms var(--ease)}
.genie-change__close:hover{background:var(--panel)}
.genie-change__close .icon{width:18px;height:18px}

/* ---- Genie's action cards (genie-cards.js; owner, 1 Oct 2026) ------------------------------------------------------------------
   One card per action Genie takes, in Genie's conversation (the header conversation, the phone sheet or dock), kept there and
   updated in place: Going ahead (the countdown, Cancel) → Paused (Do it · Cancel) → Done (what changed, Show · Undo) → Undone;
   or Cancelled, or Expired. The card is the callout's material (--accent-soft, --accent-line, r10, the G mark, 14/1.5 lines with
   mono data); its status comes first in the badge shape (BD-1: 11/550, r5, 5px 8px, a 13px icon and the word — never colour
   alone) in the colour of what it means; the countdown is its seconds in mono and a 4px bar emptying (ST-3's bar; none with
   reduced motion, the seconds stay); a note (the server's own words when it cancelled or expired) is 12.5 --ink2. */
.genie-act{display:flex;flex:1;align-items:flex-start;gap:12px;box-sizing:border-box;min-width:0;padding:12px;border:1px solid var(--accent-line);border-radius:10px;background:var(--accent-soft);color:var(--ink);font-size:14px;line-height:1.5}
.genie-act__mark{display:flex;flex:none;align-items:center;justify-content:center;width:26px;height:26px;border-radius:var(--r-small);background:var(--accent);color:var(--accent-ink);font-size:11px;font-weight:650;line-height:1}
.genie-act__main{display:flex;flex:1;flex-direction:column;gap:7px;min-width:0}
.genie-act__head{display:flex;align-items:center;gap:8px;min-height:26px}
.genie-act__status{display:inline-flex;align-items:center;gap:5px;padding:5px 8px;border-radius:var(--r-badge);font-size:11px;font-weight:550;line-height:1;white-space:nowrap}
.genie-act__status .icon{width:13px;height:13px}
.genie-act__status.is-going{background:var(--panel);color:var(--accent-text)}
.genie-act__status:is(.is-paused,.is-expired,.is-partial){background:var(--warn-bg);color:var(--warn)}
.genie-act__status.is-done{background:var(--ok-bg);color:var(--ok)}
.genie-act__status:is(.is-cancelled,.is-undone,.is-discarded){background:var(--panel2);color:var(--ink2)}
/* Waiting for you (an approval: Add or Discard, nothing on its own): the accent on --panel, as Going ahead, with its own word and glyph */
.genie-act__status.is-waiting{background:var(--panel);color:var(--accent-text)}
.genie-act__seconds{margin-left:auto;font-family:var(--font-mono);font-size:12px;color:var(--ink2)}
.genie-act__bar{height:4px;overflow:hidden;border-radius:var(--r-pill);background:var(--line2)}
.genie-act__bar i{display:block;height:100%;background:var(--accent);transform-origin:left center}
.genie-act__body{display:flex;flex-direction:column;gap:2px}
.genie-act__line{margin:0;overflow-wrap:anywhere;text-wrap:pretty}
.genie-act__data{font-family:var(--font-mono);font-size:13px;white-space:nowrap}
.genie-act__note{margin:0;color:var(--ink2);font-size:12.5px;line-height:1.55}
.genie-act__error{margin:0;color:var(--danger);font-size:12.5px;line-height:1.55}
.genie-act__actions{display:flex;flex-wrap:wrap;gap:8px}
.genie-act-turn{align-items:stretch}
.genie-action-card{display:flex}
/* Phones: every tap target is at least 44×44 (H-2). */
:root:is(.android,.ios) :is(.genie-change__undo,.genie-change__close,.genie-act__button){min-width:44px;height:44px;min-height:44px}
@media (max-width:767px){
  :is(.genie-change__undo,.genie-change__close,.genie-act__button){min-width:44px;height:44px;min-height:44px}
}

/* ---- Genie's panel (owner, 1 Oct 2026: "floating genie is useless, let's go back to right side full height fixed genie widget.
   when genie is on collapse left menu"; genie-dock.js; design/DESIGN_GUIDE.md §5 App shell, §6 Genie panel) ------------------
   A full-height column at the right of the app shell, from the top of the window to its bottom, on --panel with a left --line.
   Docked from 1100px (the page narrows; nothing is covered): 320px wide to 1279px (L-9's side panel), 380px to 1439px, 400px
   from 1440px; from 768px to 1099px the same panel
   slides over the page with the scrim. The header keeps one Genie button (44px, the owner's control height) and, while a visit
   records away from its page, the visit's pill. Ids win over the older header-box rules in studio.css, shell.css and above. */
#genie-panel[hidden],#genie-panel-scrim[hidden]{display:none!important}
@media (min-width:768px){
  :root:not(.android):not(.ios){--genie-panel:320px}
  :root:not(.android):not(.ios) #genie-panel:not([hidden]){display:flex;flex-direction:column;flex:0 0 var(--genie-panel);width:var(--genie-panel);height:100dvh;min-width:0;background:var(--panel);border-left:1px solid var(--line);position:relative;z-index:30}
  :root:not(.android):not(.ios) #shell.genie-over #genie-panel:not([hidden]){position:fixed;top:0;right:0;bottom:0;z-index:70;width:min(400px,calc(100vw - 48px));box-shadow:var(--shadow-dialog);animation:genie-panel-in 200ms var(--ease)}
  :root:not(.android):not(.ios) #genie-panel-scrim:not([hidden]){position:fixed;inset:0;z-index:69;background:var(--scrim)}
  @keyframes genie-panel-in{from{transform:translateX(24px);opacity:.4}to{transform:none;opacity:1}}

  /* The header: the Genie button at the right end of the header row, level with the page's right edge (the old box's 180px
     minimum width left it 60px short of that edge), and the visit's pill only while a visit records away from its page */
  :root:not(.android):not(.ios) .workspace-header .genie-wrap{flex:0 0 auto;max-width:none;min-width:0;display:flex;justify-content:flex-end}
  :root:not(.android):not(.ios) #genie-bar{flex:0 0 auto;width:auto;min-width:0;max-width:none;height:44px;padding:0;gap:8px;border:0;background:none;box-shadow:none;animation:none}
  :root:not(.android):not(.ios) #genie-bar .genie-rec{display:none}
  :root:not(.android):not(.ios) #genie-bar.rec-away .genie-rec{display:flex;align-items:center;gap:8px;height:44px;max-width:320px;min-width:0;padding:0 6px 0 12px;border:1px solid var(--recording-red);border-radius:9px;background:var(--recording-bg)}
  :root:not(.android):not(.ios) #genie-bar #assistant-open{display:inline-flex;flex:none;align-items:center;gap:8px;width:auto;height:44px;min-height:44px;padding:0 11px 0 12px;border:1px solid var(--line);border-radius:9px;background:var(--panel);box-shadow:none;color:var(--accent-text);font:550 13.5px/1 var(--font-sans);cursor:pointer}
  :root:not(.android):not(.ios) #genie-bar #assistant-open:hover{border-color:var(--accent-line)}
  :root:not(.android):not(.ios) #genie-bar #assistant-open[aria-expanded=true]{background:var(--accent-soft);border-color:var(--accent-line)}
  :root:not(.android):not(.ios) #genie-bar #assistant-open .genie-helper{display:block;width:18px;height:18px;flex:none}
  :root:not(.android):not(.ios) #genie-bar #assistant-open :is(.genie-find,.genie-prompt){display:none}
  :root:not(.android):not(.ios) #genie-bar #assistant-open .genie-word{display:inline}
  :root:not(.android):not(.ios) #genie-bar #assistant-open .genie-keys{display:inline-block;padding:1px 5px;border:1px solid var(--line);border-radius:5px;background:none;font:400 11px/1.3 var(--font-mono);color:var(--ink3)}

  /* The panel: head · the conversation (scrolls on its own) · the chips that answer Genie · the voice row · the input · status */
  :root:not(.android):not(.ios) #genie-panel #genie-convo{position:static;display:flex;flex-direction:column;flex:1;min-height:0;width:auto;max-height:none;margin:0;border:0;border-radius:0;background:none;box-shadow:none;animation:none;overflow:hidden}
  :root:not(.android):not(.ios) #genie-panel .genie-convo-head{display:flex;align-items:center;gap:10px;flex:none;flex-wrap:nowrap;min-height:72px;padding:14px 16px 12px 18px;border-bottom:1px solid var(--line2)}
  :root:not(.android):not(.ios) #genie-panel .genie-panel-title{margin:0;font:650 15px/1.2 var(--font-sans);color:var(--ink)}
  :root:not(.android):not(.ios) #genie-panel .genie-chips{flex:1;min-width:0;flex-wrap:nowrap;overflow:hidden}
  :root:not(.android):not(.ios) #genie-panel .genie-convo-mic{margin-left:0}
  :root:not(.android):not(.ios) #genie-panel .genie-panel-close{display:inline-flex;align-items:center;gap:6px;flex:none;height:36px;min-height:36px;padding:0 10px;border:1px solid var(--line);border-radius:8px;background:var(--panel);color:var(--ink2);font-size:12.5px;font-weight:550}
  :root:not(.android):not(.ios) #genie-panel .genie-panel-close .icon{width:15px;height:15px}
  :root:not(.android):not(.ios) #genie-panel .genie-panel-close:hover{background:var(--panel2)}
  :root:not(.android):not(.ios) #genie-panel .genie-panel-empty{display:none;margin:0;padding:22px 20px;font-size:13.5px;line-height:1.55;color:var(--ink2)}
  :root:not(.android):not(.ios) #genie-panel .genie-panel-empty p{margin:0 0 6px}
  :root:not(.android):not(.ios) #genie-panel:has(#genie-turns:empty) .genie-panel-empty{display:block}
  :root:not(.android):not(.ios) #genie-panel .genie-turns{display:block;flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain}
  :root:not(.android):not(.ios) #genie-panel .genie-turns:empty{display:block}
  :root:not(.android):not(.ios) #genie-panel .genie-turn{padding:12px 16px}
  :root:not(.android):not(.ios) #genie-panel .genie-act-turn{display:block;padding:10px 14px;background:none}
  :root:not(.android):not(.ios) #genie-panel .genie-options:not([hidden]){padding:10px 14px;border-top:1px solid var(--line2)}
  :root:not(.android):not(.ios) #genie-panel .genie-option{max-width:100%}
  /* The voice row: what was heard and the live meter while listening, "Open …" once Genie offers to go somewhere */
  :root:not(.android):not(.ios) #genie-panel .genie-voice-row{display:none}
  :root:not(.android):not(.ios) #genie-panel[data-voice=on] .genie-voice-row{display:flex;align-items:center;gap:10px;flex:none;min-height:44px;padding:8px 14px;border-top:1px solid var(--line2);background:var(--accent-soft)}
  :root:not(.android):not(.ios) #genie-convo[data-state=listening] .genie-voice-row{background:var(--recording-bg)}
  :root:not(.android):not(.ios) #genie-panel .genie-levels{display:none}
  :root:not(.android):not(.ios) #genie-convo[data-state=listening] .genie-levels{display:flex;align-items:flex-end;gap:2.5px;height:13px;flex:none}
  :root:not(.android):not(.ios) #genie-panel .genie-levels i{display:block;width:2.5px;height:13px;border-radius:2px;background:var(--recording-red);transform-origin:bottom;transform:scaleY(calc(.25 + var(--level,0) * .75));transition:transform 90ms linear}
  :root:not(.android):not(.ios) #genie-panel .genie-heard{display:block;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px;color:var(--ink)}
  :root:not(.android):not(.ios) #genie-panel .genie-confirm:not([hidden]){display:inline-flex;align-items:center;gap:6px;flex:none;height:36px;min-height:36px;padding:0 12px;border:0;border-radius:8px;background:var(--accent);color:var(--on-accent);font-size:12.5px;font-weight:600}
  /* The input, at the bottom: 44px (H-1), the mic beside it, Send */
  :root:not(.android):not(.ios) #genie-panel .genie-convo-reply{display:flex;align-items:center;gap:8px;flex:none;padding:12px 14px 8px;border-top:1px solid var(--line2)}
  :root:not(.android):not(.ios) #genie-panel #genie-convo-reply-input{flex:1;min-width:0;height:44px;min-height:44px;padding:0 12px;border:1px solid var(--line);border-radius:9px;background:var(--panel);color:var(--ink);font:inherit;font-size:14px}
  :root:not(.android):not(.ios) #genie-panel .genie-mic:not([hidden]){display:inline-flex;align-items:center;justify-content:center;flex:none;width:44px;height:44px;min-height:44px;padding:0;border:1px solid var(--line);border-radius:9px;background:var(--panel);color:var(--accent-text)}
  :root:not(.android):not(.ios) #genie-panel .genie-mic[hidden]{display:none}
  :root:not(.android):not(.ios) #genie-panel .genie-mic:hover{background:var(--accent-soft)}
  :root:not(.android):not(.ios) #genie-panel .genie-mic .icon{width:18px;height:18px}
  :root:not(.android):not(.ios) #genie-convo[data-state=listening] .genie-mic:not([hidden]){border-color:var(--recording-red);background:var(--recording-red);color:var(--on-recording-red);animation:genie-ring 1.4s ease-out infinite}
  :root:not(.android):not(.ios) #genie-panel #genie-convo-reply-send{display:inline-flex;align-items:center;gap:6px;flex:none;height:44px;min-height:44px;padding:0 14px;border:0;border-radius:9px;background:var(--accent);color:var(--on-accent);font-size:13px;font-weight:600}
  :root:not(.android):not(.ios) #genie-panel #genie-convo-reply-send .icon{width:16px;height:16px}
  :root:not(.android):not(.ios) #genie-panel #genie-convo-reply-send:disabled,:root:not(.android):not(.ios) #genie-panel #genie-convo-reply-input:disabled{opacity:.55}
  :root:not(.android):not(.ios) #genie-panel .genie-mic-busy:not([hidden]){display:inline-flex;align-items:center;flex:none;height:44px;font-size:11.5px;color:var(--ink3);white-space:nowrap}
  :root:not(.android):not(.ios) #genie-panel .genie-convo-foot{display:flex;align-items:center;flex:none;min-height:30px;padding:0 16px 10px;border:0}
  :root:not(.android):not(.ios) #genie-panel .genie-convo-status{flex:1;min-width:0;font-size:12px;color:var(--ink3)}
}
@media (min-width:1280px){:root:not(.android):not(.ios){--genie-panel:380px}}
@media (min-width:1440px){:root:not(.android):not(.ios){--genie-panel:400px}}
@media (min-width:768px) and (prefers-reduced-motion:reduce){
  :root:not(.android):not(.ios) #shell.genie-over #genie-panel:not([hidden]){animation:none}
  :root:not(.android):not(.ios) #genie-convo[data-state=listening] .genie-mic:not([hidden]){animation:none}
}
