/* The assistant's own stylesheet.

   Everything the panel gained beyond a transcript and an input lives here: the
   starter questions, the source cards with their dates, the tool lines, the
   rating and the wait notice. The parts that were already in site.css stay
   there and are not restated, with one exception noted below.

   Two rules run through the whole file, and both come from the site's Content
   Security Policy rather than from taste:

     * style-src 'self' blocks the style attribute outright, so nothing in
       assistent.js may set element.style. Every value that has to vary per
       element arrives as a data- attribute and is selected on here. That is
       what the [data-i] rules under the starter questions are: an inline
       animation-delay would simply not apply, and it would not warn.

     * default-src 'none' means no font, no image and no gradient from anywhere
       but this origin. Nothing here loads anything.

   Loaded by a link element assistent.js writes into the head. build.py owns the
   page shell, and three of the pages the assistant appears on are hand written
   and never pass through it, so a link in the shell would have covered some of
   the pages and not others. */

/* --- the starter questions ------------------------------------------------- */

/* Offered only before the first turn, and derived by the service from the
   corpus rather than written by hand. A hand written suggestion goes stale the
   week the page behind it is rewritten, and the visitor then gets the refusal
   on a question the assistant itself proposed. */
.asst__start {
  padding: 0 var(--s-4) var(--s-4);
  display: grid;
  gap: var(--s-2);
}
.asst__start[hidden] { display: none; }

.asst__start-title {
  font-size: 0.68rem;
  font-weight: var(--w-strong);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.asst__start-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--s-2);
}

.asst__start-btn {
  width: 100%;
  padding: var(--s-2) var(--s-3);
  text-align: left;
  font: inherit;
  font-size: 0.86rem;
  line-height: 1.45;
  color: var(--ink-secondary);
  background: var(--surface-sunk);
  border: var(--rule-w) solid var(--rule);
  border-radius: var(--s-1);
  cursor: pointer;
  opacity: 0;
  animation: asst-in 220ms ease-out forwards;
}
.asst__start-btn:hover { color: var(--ink); border-color: var(--rule-strong); }

/* The stagger. One rule per position rather than a computed delay, because the
   attribute selector is the only way to get a per element value to CSS with the
   style attribute blocked. Five is the number of suggestions the service
   returns; a sixth would simply appear without a delay, which is a smaller
   failure than a sixth rule nobody remembers to add. */
.asst__start-btn[data-i='0'] { animation-delay: 0ms; }
.asst__start-btn[data-i='1'] { animation-delay: 40ms; }
.asst__start-btn[data-i='2'] { animation-delay: 80ms; }
.asst__start-btn[data-i='3'] { animation-delay: 120ms; }
.asst__start-btn[data-i='4'] { animation-delay: 160ms; }

@keyframes asst-in {
  from { opacity: 0; transform: translateY(3px); }
  to { opacity: 1; transform: none; }
}

/* A visitor who has asked for less motion gets the content and none of the
   movement. The suggestions still have to be visible, which is why this sets
   the end state rather than only cancelling the animation. */
@media (prefers-reduced-motion: reduce) {
  .asst__start-btn { opacity: 1; animation: none; }
}

/* --- the source cards ------------------------------------------------------ */

/* site.css styles .asst__sources as the list itself. It is now a labelled box
   around a list, so the padding that indented the bullets is cleared here and
   the list inside carries its own. This is the one rule in this file that
   restates something from there, and it is here rather than there because the
   markup change is this file's doing. */
.asst__sources {
  padding-left: 0;
  display: grid;
  gap: var(--s-2);
}

.asst__sources-title {
  font-size: 0.68rem;
  font-weight: var(--w-strong);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.asst__sources-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--s-2);
}

/* The card that arrives before the answer, saying what is being read. It used
   to be written to a data attribute and never drawn at all, so the one moment
   where the visitor could see the grounding happen was the one moment the
   widget was silent. Dimmer than the final list, because it is a promise and
   not yet a citation. */
.asst__sources--laser { opacity: 0.72; }

.asst__source {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--s-1) var(--s-2);
  align-items: baseline;
  font-size: 0.84rem;
  line-height: 1.45;
  color: var(--ink-muted);
}

/* K1, V1. The same marking the model writes in the text and the citation check
   matches on, so the card under an answer and the machinery behind it are
   visibly the same thing. */
.asst__source-mark {
  grid-row: span 2;
  padding: 0.1rem var(--s-2);
  font-size: 0.68rem;
  font-weight: var(--w-strong);
  letter-spacing: 0.04em;
  color: var(--ink-secondary);
  background: var(--surface-sunk);
  border: var(--rule-w) solid var(--rule);
  border-radius: var(--s-1);
}
.asst__source[data-typ='verktyg'] .asst__source-mark {
  color: var(--accent);
  border-color: var(--accent-soft);
}

.asst__source-name a { color: var(--accent); text-underline-offset: 2px; }

/* The date, which the widget used to drop. On a site that sells traceability an
   answer built on a page last touched two years ago reads exactly like one
   built on a page touched yesterday, and only one of them should be trusted
   without checking. A page with no date says so rather than showing nothing,
   because a missing field and an absent field look identical when both are
   blank. */
.asst__source-meta {
  font-size: 0.72rem;
  color: var(--ink-faint);
}

/* --- the tool lines -------------------------------------------------------- */

/* One line per tool the turn ran, written as it runs. A tool that failed says
   so in the same place, because a source that is missing from an answer is
   something the reader has to be able to see. */
.asst__tool {
  font-size: 0.78rem;
  line-height: 1.45;
  color: var(--ink-muted);
  padding-left: var(--s-3);
  border-left: 2px solid var(--rule);
}
.asst__tool[data-status='kord'] { border-left-color: var(--accent-soft); }
.asst__tool[data-status='fel'],
.asst__tool[data-status='tomt'] { border-left-color: var(--rule-strong); }

/* --- the rating ------------------------------------------------------------ */

.asst__rating {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  align-items: center;
}

.asst__rate {
  min-width: 2rem;
  min-height: 2rem;
  font: inherit;
  font-size: 1rem;
  line-height: 1;
  color: var(--ink-muted);
  background: none;
  border: var(--rule-w) solid var(--rule);
  border-radius: var(--s-1);
  cursor: pointer;
}
.asst__rate:hover { color: var(--ink); border-color: var(--rule-strong); }
.asst__rate:disabled { cursor: default; opacity: 0.45; }
.asst__rating[data-valt='upp'] .asst__rate[data-val='upp'],
.asst__rating[data-valt='ned'] .asst__rate[data-val='ned'] {
  opacity: 1;
  color: var(--accent);
  border-color: var(--accent);
}

.asst__rating-tack { font-size: 0.78rem; color: var(--ink-faint); }

.asst__rating-text {
  flex: 1 1 12rem;
  min-width: 0;
  padding: var(--s-2) 0;
  font: inherit;
  font-size: 0.86rem;
  color: var(--ink);
  background: none;
  border: 0;
  border-bottom: 2px solid var(--rule-strong);
  border-radius: 0;
}
.asst__rating-text::placeholder { color: var(--ink-faint); }
.asst__rating-text:focus { outline: none; border-bottom-color: var(--accent); }

.asst__rating-send {
  padding: var(--s-2) var(--s-3);
  font: inherit;
  font-size: 0.8rem;
  color: var(--ink-secondary);
  background: none;
  border: var(--rule-w) solid var(--rule);
  border-radius: var(--s-1);
  cursor: pointer;
}

/* --- waiting --------------------------------------------------------------- */

/* Pressing Enter during a streaming answer used to do nothing at all: the send
   button was disabled and the submit fell on the floor. The field is enabled
   now and this is what the keystroke produces, so the visitor gets a reason
   instead of silence. */
.asst__wait {
  font-size: 0.8rem;
  line-height: 1.45;
  color: var(--ink-secondary);
  padding: var(--s-2) var(--s-3);
  background: var(--surface-sunk);
  border-radius: var(--s-1);
}

/* The send button is no longer disabled while a turn runs, so the busy state
   has to say something on its own. */
.asst[data-busy='true'] .asst__send { opacity: 0.55; }

/* --- assistenten som sida ---------------------------------------------------
   Samma widget, monterad i dokumentet i stället för i hörnet. Reglerna nedan
   upphäver bara positioneringen och storleken; allt annat, inklusive
   upplysningen, källkorten och strömningen, är oförändrat och delas med
   panelen. En andra implementation hade blivit ett andra ställe där
   upplysningen kan glida, och den är ett lagkrav och inte en designdetalj. */
.asst--sida {
  position: static;
  display: block;
  max-width: none;
  margin-top: var(--s-5);
}
.asst--sida .asst__open { display: none; }
.asst--sida .asst__panel {
  width: 100%;
  /* Höjden följer fönstret i stället för ett tak i rem. En assistent som ska
     bära ett riktigt arbetspass ska använda skärmen som finns. */
  max-height: min(46rem, calc(100svh - 16rem));
  min-height: 28rem;
  box-shadow: none;
  border-radius: var(--r-md);
}
/* Stängknappen stänger ingenting när panelen är sidan. Att låta den stå kvar
   och göra panelen tom vore en knapp som förstör sidan man just öppnade. */
.asst--sida .asst__close { display: none; }

@media (max-width: 40rem) {
  .asst--sida .asst__panel { max-height: calc(100svh - 12rem); }
}
