/* ============================================================================
   assist.css — the ysdk.org hybrid assistant's skin (R325/§318 SESSION-YSDK,
   piece ysdk-avatar-hybrid). Loaded by index.html beside ysdk.css and styled
   from ITS tokens only (--brand, --surf, --edge, --ink*, --s*, --r*, --tap):
   no colour literal off the goldenratiocolors ladder is introduced here.

   LAWS this file keeps, each one tested by gauntlet/fivego/tests:
   · 8.5 agent-dark — everything here lives in a FIXED layer (the launcher and
     the sheet); nothing is in the document flow, so turning the assistant on
     or off cannot reflow a single landmark.
   · §5.1 container queries, not media queries — the sheet is its own
     container (`assist`); media queries appear ONLY for pointer,
     prefers-reduced-motion and forced-colors.
   · §5.5 focus survives clip-path — the launcher is a real hexagon (clip-path)
     and draws its focus ring INSIDE the clip as an inset box-shadow, the same
     idiom as .hx in ysdk.css. A normal outline would be clipped away.
   · §5.6 floors, not fixed sizes — min-* everywhere; the sheet has no px size.
   · §5.7 reduced motion is a REAL path — under reduce the sheet opens by an
     instant state change and the thinking / answered states are told by
     colour and a persistent rim, not by an animation that was merely removed.
   · CSP style-src 'self' — no inline styles anywhere; state is data-* + classes.
============================================================================ */

@layer components {
  /* ── the launcher: a flat-top hexagon, 2r wide × √3·r tall (r = 1.875rem → 3.75 × 3.25rem ≥ 44px) ── */
  .as-launch {
    position: fixed; z-index: 60;
    inset-block-end: max(.75rem, env(safe-area-inset-bottom, 0px));
    inset-inline-end: max(.75rem, env(safe-area-inset-right, 0px));
    min-inline-size: 3.75rem; min-block-size: 3.25rem;
    display: grid; place-items: center; padding: 0; border: 0; cursor: pointer;
    clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
    background: linear-gradient(158deg, oklch(from var(--brand) l c h / .55), var(--sunk) 58%, var(--void));
    color: var(--brand-lit);
    font: 700 .75rem/1 var(--mono); letter-spacing: .1em; text-transform: uppercase;
  }
  .as-launch::after {
    content: ""; position: absolute; inset: 0; clip-path: inherit; padding: 1.5px; pointer-events: none;
    background: linear-gradient(150deg, var(--brand-lit), transparent 72%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor; mask-composite: exclude;
  }
  .as-launch:hover { color: var(--ink); }
  .as-launch[aria-expanded="true"] { color: var(--ink); background: linear-gradient(158deg, oklch(from var(--brand) l c h / .8), var(--sunk) 70%); }
  /* agent-dark: the same hexagon, dimmed; the ONLY visual difference between on and off (fixed layer, no flow) */
  .as-launch[data-off] { color: var(--ink3); background: linear-gradient(158deg, var(--surf2), var(--void)); }
  .as-launch[data-off]::after { background: linear-gradient(150deg, var(--edge2), transparent 72%); }

  /* ── the sheet ── */
  .as-sheet {
    position: fixed; z-index: 60; margin: 0; padding: 0;
    inset-block-end: calc(max(.75rem, env(safe-area-inset-bottom, 0px)) + 3.25rem + .625rem);
    inset-inline-end: max(.75rem, env(safe-area-inset-right, 0px));
    inset-block-start: auto; inset-inline-start: auto;
    inline-size: min(100% - 1.5rem, 27rem);
    max-block-size: min(100dvb - 6.5rem, 44rem);
    border: 1px solid var(--edge2); border-radius: var(--r3);
    background: oklch(from var(--surf) l c h / .97);
    color: var(--ink2);
    box-shadow: 0 1.25rem 3rem oklch(from var(--void) l c h / .65);
    container-type: inline-size; container-name: assist;
    display: grid; grid-template-rows: auto minmax(0, 1fr) auto auto auto;
    overflow: hidden;
  }
  .as-sheet:not([open]) { display: none; }
  .as-sheet[data-state="thinking"] { border-color: var(--warn); }      /* told by colour, in every motion mode */
  .as-sheet[data-state="answered"] { border-color: var(--brand-dim); }

  .as-head { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--s2) var(--s3);
    padding: var(--s3) var(--s4); border-block-end: 1px solid var(--edge); }
  .as-title { font-size: 1rem; color: var(--ink); letter-spacing: -.01em; }
  .as-sub { grid-column: 1 / -1; font-size: .8125rem; color: var(--ink3); max-inline-size: 48ch; }
  .as-sub b { color: var(--ink2); font-weight: 600; }
  .as-head-actions { display: flex; gap: var(--s2); align-items: center; }
  .as-off, .as-close {
    display: inline-flex; align-items: center; justify-content: center;
    min-block-size: var(--tap-fine); min-inline-size: var(--tap-fine);
    padding: .3rem .7rem; border-radius: var(--r1); border: 1px solid var(--edge);
    background: oklch(from var(--surf2) l c h / .6); color: var(--ink3);
    font: 600 .75rem var(--mono); cursor: pointer;
  }
  .as-off:hover, .as-close:hover { color: var(--ink); border-color: var(--edge2); }
  .as-close svg { inline-size: 1rem; block-size: 1rem; }

  /* ── the transcript: a role=log wrapper around an <ol> (list semantics + live region), scrolls internally ── */
  .as-log { min-block-size: 0; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin;
    padding: var(--s3) var(--s4); }
  .as-turns { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--s3); }
  .as-turn { display: grid; gap: .2rem; min-inline-size: 0; padding-inline-start: var(--s3);
    border-inline-start: 2px solid transparent; }
  .as-meta { display: flex; gap: var(--s2); align-items: center; flex-wrap: wrap;
    font: 600 .6875rem/1.2 var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--ink3); }
  .as-text { margin: 0; font-size: .9375rem; line-height: 1.5; color: var(--ink); overflow-wrap: anywhere; }
  .as-turn--you { border-inline-start-color: var(--edge2); }
  .as-turn--you .as-text { color: var(--ink2); }
  /* the SOURCE label: every answer wears one; fixed-floor width so the word swap cannot move the row */
  .as-src { display: inline-flex; align-items: center; min-inline-size: 5.5rem; min-block-size: 1.25rem;
    padding: .1rem .5rem; border-radius: 999px; letter-spacing: .08em; text-transform: none;
    font-weight: 600; justify-content: center; border: 1px solid transparent; }
  .as-src[data-source="pending"] { color: var(--ink3); border-color: var(--edge2); border-style: dashed; }
  .as-src[data-source="gateway"] { color: var(--brand-lit); background: oklch(from var(--brand) l c h / .16); }
  .as-src[data-source="on-device"] { color: var(--ok); background: oklch(from var(--ok) l c h / .14); }
  /* the answer slot: the on-device text is rendered INVISIBLY at once so the slot already has its final
     height; a gateway answer replaces it, a fallback merely reveals it — no reflow either way (brief item 10) */
  .as-answer { position: relative; min-inline-size: 0; }
  .as-answer .as-ghost { visibility: hidden; }
  .as-wait { position: absolute; inset-block-start: 0; inset-inline-start: 0;
    font: 600 .75rem/1.5 var(--mono); letter-spacing: .06em; color: var(--ink3); }
  .as-turn--a[data-source="gateway"] { border-inline-start-color: var(--brand); }     /* the persistent rim: the */
  .as-turn--a[data-source="on-device"] { border-inline-start-color: var(--ok); }      /* answered cue under reduce */
  .as-note { margin: 0; font: .75rem/1.5 var(--mono); color: var(--ink3); overflow-wrap: anywhere; }
  .as-note::before { content: "→ "; color: var(--brand-lit); }
  .as-sources { margin: 0; font-size: .75rem; color: var(--ink3); display: flex; flex-wrap: wrap; gap: .2rem .6rem; }
  .as-sources a { color: var(--brand-lit); text-decoration: none; }
  .as-sources a:hover { text-decoration: underline; }

  /* ── chips + composer ── */
  .as-chips { display: flex; flex-wrap: wrap; gap: var(--s2); padding: 0 var(--s4) var(--s2); }
  .as-chip { display: inline-flex; align-items: center; min-block-size: var(--tap-fine);
    padding: .3rem .8rem; border-radius: 999px; border: 1px solid var(--edge);
    background: oklch(from var(--sunk) l c h / .7); color: var(--ink2);
    font-size: .8125rem; cursor: pointer; text-align: start; }
  .as-chip:hover { color: var(--ink); border-color: var(--edge2); }
  .as-form { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--s2);
    padding: var(--s2) var(--s4); border-block-start: 1px solid var(--edge); }
  .as-in { min-inline-size: 0; min-block-size: var(--tap-fine); padding: .55rem .85rem;
    border-radius: var(--r2); border: 1px solid var(--edge); background: #000e0e; /* grc011, the host's field ground */
    color: var(--ink); font-family: var(--ui); font-size: max(1rem, .9375rem); }
  .as-in::placeholder { color: var(--ink3); opacity: 1; }
  .as-in:focus-visible { border-color: var(--brand); }
  .as-send { display: inline-grid; place-items: center; min-inline-size: var(--tap-fine); min-block-size: var(--tap-fine);
    padding: 0 .6rem; border-radius: var(--r2); border: 1px solid var(--edge);
    background: var(--brand); color: #0e0e0e; cursor: pointer; }
  .as-send:hover { background: var(--brand-lit); }
  .as-send svg { inline-size: 1.125rem; block-size: 1.125rem; }
  .as-foot { margin: 0; padding: .45rem var(--s4) var(--s3); font: .6875rem/1.4 var(--mono); color: var(--ink3); }
  .as-gw[data-gw="ready"] { color: var(--ok); }
  .as-gw[data-gw="cold"], .as-gw[data-gw="held"] { color: var(--warn); }
  .as-gw[data-gw="unreachable"] { color: var(--ink3); }
  .as-sr { position: absolute; inline-size: 1px; block-size: 1px; margin: -1px; padding: 0; overflow: hidden;
    clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }

  /* the sheet's own container decides its inner layout, never the viewport (§5.1) */
  @container assist (inline-size < 22rem) {
    .as-sub { display: none; }
    .as-head { padding-inline: var(--s3); }
    .as-log, .as-chips, .as-form, .as-foot { padding-inline: var(--s3); }
    .as-off { padding-inline: .5rem; }
  }
  @container assist (inline-size >= 22rem) {
    .as-chips { padding-block-start: var(--s2); }
  }

  /* touch floors (§5.6): 44px under a coarse pointer, still a floor */
  @media (pointer: coarse) {
    .as-chip, .as-in, .as-send, .as-off, .as-close { min-block-size: var(--tap); }
    .as-launch { min-inline-size: 4rem; min-block-size: 3.5rem; }
  }
}

@layer a11y {
  /* clip-path clips an outline away; the launcher's ring is drawn INSIDE the hexagon (§5.5) */
  .as-launch:focus-visible { outline: none; }
  .as-launch:focus-visible::before {
    content: ""; position: absolute; inset: 3px; clip-path: inherit; z-index: 2; pointer-events: none;
    box-shadow: inset 0 0 0 3px var(--brand-lit);
  }
  .as-launch[data-off]:focus-visible::before { box-shadow: inset 0 0 0 3px var(--ink); }
  .as-sheet :focus-visible { outline: 3px solid var(--brand-lit); outline-offset: 2px; }
  .as-in:focus-visible { outline-offset: 1px; }
  /* a section the assistant focused: a soft ring, so "you are here" is visible without being a wall */
  .band:focus-visible, .rung:focus-visible { outline: 2px solid var(--brand-dim); outline-offset: .5rem; }

  @media (forced-colors: active) {
    .as-sheet, .as-in, .as-chip, .as-off, .as-close, .as-send, .as-src { border: 1px solid CanvasText; }
    .as-launch { forced-color-adjust: none; }
  }

  /* MOTION, only where the visitor allows it. Under reduce none of this exists and the states above
     (border colours, the rim, the dashed pending badge) carry the same information instantly (§5.7). */
  @media (prefers-reduced-motion: no-preference) {
    .as-sheet[open] { animation: as-in 200ms var(--ease) both; }
    .as-src[data-source="pending"] { animation: as-pulse 1.1s ease-in-out infinite; }
    .as-turn--a[data-source="gateway"], .as-turn--a[data-source="on-device"] { animation: as-rise 220ms var(--ease) both; }
    .as-launch, .as-chip, .as-off, .as-close, .as-send { transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease), background var(--dur) var(--ease); }
    .as-sheet { transition: border-color var(--dur) var(--ease); }
  }
  @media (prefers-reduced-motion: reduce) {
    .as-sheet[open], .as-src[data-source="pending"], .as-turn--a { animation: none; }
    .as-launch, .as-chip, .as-off, .as-close, .as-send, .as-sheet { transition: none; }
  }
  @keyframes as-in { from { opacity: 0; translate: 0 .5rem; } }
  @keyframes as-pulse { 50% { opacity: .45; } }
  @keyframes as-rise { from { opacity: 0; } }
}
