/* Embeds: the interactive components a post places with ```embed:<name>
   (src/content/embeds.odin, src/assets/static/js/embed-*.js). Only posts
   that use one load this sheet. It sits in the garden layer, after
   garden.css, so its classes win over the theme's element styles. */

@layer garden {
  .article-body > .embed {
    grid-column: text;
  }
  .embed > * {
    display: block;
  }
  /* A component with no fallback takes no room until its script runs. */
  .embed:has(> :not(:defined):empty) {
    display: none;
  }
  /* Components toggle parts with `hidden`; keep it winning over display. */
  .embed [hidden] {
    display: none;
  }
  .visually-hidden {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  /* Margin embeds hang beside the text, like sidenotes, once main has room
     for a wider note: about 18rem at 58rem (see the sidenote container
     query in site.css, which positions .article-body). The wrapper stays
     in the column with no height, so the component's static position is
     where it sits in the text; it takes no space there. footnotes.js lays
     these out with the sidenotes, so neither covers the other. Until the
     script runs, the fallback stays in the column. */
  @container main (min-width: 58rem) {
    .article-body > .embed[data-margin]:has(> :defined) {
      margin-block-start: 0;
    }
    .embed[data-margin] > :defined {
      position: absolute;
      margin-block-start: var(--flow);
      inset-inline-start: calc(var(--measure) + var(--sidenote-gap));
      inline-size: min(
        24rem,
        100cqi - var(--measure) - var(--sidenote-gap) + var(--pad-inline) / 2
      );
    }
  }

  /* Shared voice for labels and readouts: the site's mono subtitles. */
  .copilot-key,
  .latency-label,
  .latency-value,
  .latency-delay,
  .latency-pending,
  .latency-run,
  .latency-caption,
  .ping {
    font-family: var(--font-mono);
    font-size: 0.72rem;
    color: var(--ink-soft);
  }

  /* Copilot: a 2021 editor, dark in both themes, set into the page like a
     screenshot that moves. */
  .copilot {
    --copilot-bg: #1e1e1e;
    --copilot-chrome: #252526;
    --copilot-text: #d4d4d4;
    --copilot-ghost: #7c7c7c;
    display: grid;
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--copilot-bg);
    color: var(--copilot-text);
    box-shadow: 0 0.5rem 1.5rem -0.75rem rgb(0 0 0 / 0.45);
  }
  .copilot-tabs {
    display: flex;
    background: var(--copilot-chrome);
    font-family: var(--font-mono);
    font-size: 0.68rem;
  }
  .copilot-tab {
    padding: 0.4rem 0.9rem;
    background: var(--copilot-bg);
    border-block-start: 1px solid #0e639c;
    color: #ffffff;
  }
  .copilot-code {
    margin: 0;
    padding: 0.85rem 1rem;
    min-block-size: calc(var(--copilot-rows, 8) * 1.55em + 1.7rem);
    border: 0;
    border-radius: 0;
    background: transparent;
    color: inherit;
    font-size: 0.74rem;
    /* 2021's editor fonts had no ligatures: >= stays two characters. */
    font-variant-ligatures: none;
    line-height: 1.55;
    white-space: pre;
    overflow-x: auto;
  }
  .copilot-code:focus-visible {
    outline: 2px solid #0e639c;
    outline-offset: -2px;
  }
  .copilot-ghost {
    color: var(--copilot-ghost);
  }
  .copilot-caret {
    display: inline-block;
    inline-size: 0;
    block-size: 1.2em;
    margin-inline-end: -1px;
    border-inline-start: 1.5px solid #aeafad;
    vertical-align: text-bottom;
  }
  .tok-comment {
    color: #6a9955;
  }
  .tok-string {
    color: #ce9178;
  }
  .tok-keyword {
    color: #569cd6;
  }
  .tok-number {
    color: #b5cea8;
  }
  .copilot-status {
    display: flex;
    justify-content: space-between;
    padding: 0.2rem 0.75rem;
    background: #007acc;
    color: #ffffff;
    font-family: var(--font-mono);
    font-size: 0.66rem;
  }
  .copilot-status-text::before {
    content: "✦ ";
  }
  /* The row keeps its height while empty, so the keys appearing don't move
     the page. */
  .copilot-keys {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    min-block-size: 3rem;
    padding: 0.5rem 0.75rem;
    background: var(--copilot-chrome);
  }
  .copilot-key {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    min-block-size: 2rem;
    padding: 0.2rem 0.6rem;
    border: 1px solid #3c3c3c;
    border-radius: 0.3rem;
    background: #2d2d2d;
    color: #cccccc;
    cursor: pointer;
  }
  .copilot-key:hover:not(:disabled) {
    background: #37373d;
  }
  .copilot-key:disabled {
    opacity: 0.45;
    cursor: default;
  }
  .copilot-key kbd {
    padding: 0.05rem 0.35rem;
    border: 1px solid #5a5a5a;
    border-block-end-width: 2px;
    border-radius: 0.2rem;
    background: #1e1e1e;
    color: #ffffff;
    font-family: inherit;
    font-size: 0.66rem;
  }
  @media (prefers-reduced-motion: no-preference) {
    .copilot[data-state="thinking"] .copilot-status-text {
      animation: copilot-think 0.9s var(--ease-in-out) infinite alternate;
    }
    .copilot[data-state="suggesting"] .copilot-ghost {
      animation: copilot-appear 160ms var(--ease-out);
    }
    .copilot-accepted {
      animation: copilot-accept 900ms var(--ease-out);
    }
    /* Nothing here loops for good: a page left open on this post should
       go quiet. The Tab key nudges a few times, and the caret blinks only
       while the editor types or has focus, as a real one does. */
    .copilot[data-state="suggesting"] .copilot-key:first-child kbd {
      animation: copilot-nudge 1.6s var(--ease-in-out) 1s 3;
    }
    .copilot:is([data-state="typing"], [data-state="thinking"], :focus-within) .copilot-caret {
      animation: embed-blink 1.05s steps(1) infinite;
    }
  }
  @keyframes copilot-think {
    to {
      opacity: 0.4;
    }
  }
  @keyframes copilot-appear {
    from {
      opacity: 0;
    }
  }
  @keyframes copilot-accept {
    from {
      background: rgb(14 99 156 / 0.55);
    }
  }
  @keyframes copilot-nudge {
    0%,
    70%,
    100% {
      translate: 0;
    }
    80% {
      translate: 0 2px;
    }
  }
  @keyframes embed-blink {
    50% {
      opacity: 0;
    }
  }

  /* Latency: the platformer, drawn in the page's ink. */
  .latency {
    display: grid;
    gap: 0.75rem;
  }
  .latency-world {
    inline-size: 100%;
    aspect-ratio: 16 / 9;
    border: 1px solid var(--rule);
    border-radius: var(--radius-organic);
    touch-action: pan-y;
  }
  .latency-swatch[data-swatch="ink"] {
    color: var(--ink);
  }
  .latency-swatch[data-swatch="soft"] {
    color: var(--ink-soft);
  }
  .latency-swatch[data-swatch="accent"] {
    color: var(--accent);
  }
  .latency-swatch[data-swatch="paper"] {
    color: var(--paper);
  }
  .latency-controls {
    display: grid;
    gap: 0.6rem;
  }
  .latency-jump {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) 3ch;
    align-items: center;
    gap: 0.6rem;
  }
  .latency-jump input {
    inline-size: 100%;
    min-block-size: 2rem;
    accent-color: var(--accent);
  }
  .latency-value {
    color: var(--ink);
    font-variant-numeric: tabular-nums;
    text-align: end;
  }
  .latency-delays {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    margin: 0;
    padding: 0;
    border: 0;
  }
  .latency-delays legend {
    float: inline-start;
    margin-inline-end: 0.3rem;
  }
  .latency-delay {
    position: relative;
    display: inline-grid;
  }
  .latency-delay input {
    position: absolute;
    inset: 0;
    margin: 0;
    opacity: 0;
    cursor: pointer;
  }
  .latency-delay span {
    padding: 0.3rem 0.6rem;
    border: 1px solid var(--rule-strong);
    border-radius: 999px;
  }
  .latency-delay input:checked + span {
    border-color: var(--accent);
    background: var(--highlight);
    color: var(--ink);
  }
  .latency-delay input:focus-visible + span {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
  }
  .latency-pending {
    color: var(--accent);
  }
  .latency-run {
    margin-inline-start: auto;
    padding: 0.3rem 0.6rem;
    border: 1px solid var(--rule-strong);
    border-radius: 999px;
    background: none;
    cursor: pointer;
  }
  /* The run button matters only when nothing runs on its own. */
  @media (prefers-reduced-motion: no-preference) {
    .latency-run {
      display: none;
    }
  }
  .latency-caption {
    margin: 0;
    line-height: 1.5;
  }

  /* Steve's readout: one line in the rust ink, set apart from the prose.
     It's written out with blanks as soon as the script runs and filled in
     where it stands, so measuring never moves the text around it. */
  .ping {
    margin: 0;
    padding-inline-start: 0.75rem;
    border-inline-start: 2px solid var(--rust);
    color: var(--rust);
    line-height: 1.5;
  }

  /* Slow: each character is hidden until its turn; the caret follows. */
  wlls-slow[data-state] .slow-char {
    position: relative;
    visibility: hidden;
  }
  wlls-slow[data-state] .slow-char.is-shown {
    visibility: visible;
  }
  wlls-slow .slow-char.is-caret::after {
    content: "";
    position: absolute;
    inset-block: 0.1em;
    inset-inline-start: 100%;
    border-inline-start: 2px solid var(--accent);
    animation: embed-blink 1.05s steps(1) infinite;
  }

  @media print {
    .embed[data-margin] > :defined {
      position: static;
    }
    .copilot-keys,
    .latency-controls,
    .latency-caption,
    .ping {
      display: none;
    }
    wlls-slow[data-state] .slow-char {
      visibility: visible;
    }
  }
}
