/* =============================================================================
   Annot — AI-förslagen
   =============================================================================

   Hör ihop med web/ai.js. Allt är prefixat `aai-` (annot ai) så att inget kan
   krocka med canvas.css och comments.css (`ac-`), share.css (`ash-`),
   landing.css (`lp-`), shortcuts.css (`akb-`), present.css (`pv-`),
   popover.css (`pr-`) eller history.css (`ahi-`).

   Regeln från design-systemet gäller: aldrig hex eller rgb, aldrig egna
   millisekunder. Färger, radier, mellanrum och tider kommer från tokens i
   theme.css — en hårdkodad tid överlever `prefers-reduced-motion`, och det
   felet är osynligt för alla utom den det gäller.

   Typfärgerna kommer från `--note-*` i theme.css, inte från de hex-värden
   comments.js bär i sin THREAD_TYPES. Det är samma fyra färger, men här
   uttryckta som tokens — en komponent får inte äga en råfärg, och `--note-issue`
   ÄR `--color-danger`, alltså samma betydelse på båda ställena.

   Ordningen i filen är byggordningen: telefonen först, desktop sist. Under
   820 px fyller panelen skärmen; över blir den en centrerad ruta.

   Träffytor: minst 44 × 44 CSS-px på allt man ska kunna peka på. Ikonknappen
   följer husregeln och växer med ett osynligt ::before, inte genom att bli
   större själv. "Lägg till" är bred nog i sig och är 44 px hög.
   ========================================================================== */

@import "./theme.css";

/* ------------------------------------------------------------ överlagringen */

.aai-overlay {
  /* 100dvh överallt utom på iOS med uppfällt tangentbord, där layoutvyn står
     still medan den synliga krymper. Panelen har inga fält, så det räcker. */
  --aai-vh: 100dvh;

  /* Prickens storlek och kortets tonade kant, samlade så att de går att
     ändra på ett ställe i stället för i sex regler. */
  --aai-dot: 8px;
  --aai-tint: var(--color-line);

  position: fixed;
  inset: 0;
  z-index: 9400;
  display: flex;
  align-items: stretch;
  justify-content: center;
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
}

.aai-overlay[hidden] { display: none; }
.aai-overlay.aai-open { opacity: 1; }

.aai-scrim {
  position: absolute;
  inset: 0;
  background: var(--color-bg);
  background: color-mix(in oklch, var(--color-bg) 55%, transparent);
  /* -webkit- FÖRE standarden. Minifierare behandlar de två som samma
     deklaration när värdena är identiska och behåller bara den sista —
     ligger prefixet sist tappar alla oprefixade webbläsare sitt sudd, och
     felet syns aldrig i dev eftersom dev-servern inte minifierar. */
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
}

/* Utan sudd är scrimen bara en halvgenomskinlig yta: canvasen lyser igenom
   och förslagen blir svårlästa. Byt då till en nästan täckande yta. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .aai-scrim { background: color-mix(in oklch, var(--color-bg) 88%, transparent); }
}
@supports not (background: color-mix(in oklch, red 50%, transparent)) {
  .aai-scrim { background: var(--color-bg); }
}

/* ------------------------------------------------------------------ panelen */

.aai-panel {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  width: 100%;
  height: var(--aai-vh);
  max-height: var(--aai-vh);
  background: var(--color-surface);
  color: var(--color-ink);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  overflow: hidden;
  padding-top: var(--safe-t);
  transform: translateY(var(--space-4));
  transition: transform var(--dur-base) var(--ease-out);
}

.aai-overlay.aai-open .aai-panel { transform: translateY(0); }

@media (prefers-reduced-motion: reduce) {
  .aai-overlay,
  .aai-panel { transition: none; }
}

/* ------------------------------------------------------------------ huvudet */

.aai-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-3) 0 var(--space-4);
}

.aai-title {
  flex: 1;
  min-width: 0;
  margin: 0;
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
}

/* Husregeln: knappen ser ut som 28 px och träffas som 44. Ett osynligt
   ::before med negativ inset i stället för en större knapp. 28 + 8 + 8 = 44. */
.aai-close {
  position: relative;
  flex: none;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--color-ink-muted);
  font-size: var(--text-sm);
  line-height: var(--leading-none);
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}

.aai-close::before {
  content: "";
  position: absolute;
  inset: -8px;
}

.aai-close:hover {
  background: var(--color-surface-2);
  color: var(--color-ink);
}

/* --------------------------------------------------------------- metaraden

   Vad modellen tittar på till vänster, vad anropet kostade till höger.
   Kostnaden står här och inte bakom en utfällning: den som betalar per anrop
   ska se siffran utan att leta, men den ska heller inte skrika. */

.aai-meta {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-4) var(--space-3);
}

.aai-mode {
  flex: 1;
  min-width: 0;
  color: var(--color-ink-muted);
  font-size: var(--text-xs);
}

.aai-usage {
  flex: none;
  max-width: 55%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--color-faint);
  font-size: var(--text-2xs);
  font-variant-numeric: tabular-nums;
  /* Siffror man vill kunna citera i en faktura. */
  -webkit-user-select: text;
  user-select: text;
}

.aai-usage[hidden] { display: none; }

/* ------------------------------------------------------------------ kroppen */

.aai-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 0 var(--space-3) var(--space-3);
}

/* ------------------------------------------------------------ tillståndsrutan

   Fem lägen, alla med text: tomt, laddar, förslag, inget dög, fel. En tom,
   tyst panel läser som "ingenting fanns" — och det är precis det svaret
   användaren inte får tro på när anropet gick fel eller aldrig gjordes.

   Rutan ligger kvar i DOM:en hela tiden och byter innehåll. En live-region
   som skapas i samma ögonblick som texten sätts hinner ofta inte annonseras. */

.aai-state {
  padding: var(--space-4) var(--space-3);
  text-align: center;
}

/* I lägena med förslag är rutan en kort rad ovanför listan, inte ett block
   mitt på skärmen — då är den en etikett, inte ett tomtillstånd. */
.aai-state[data-phase="ready"] {
  padding: var(--space-1) var(--space-2) var(--space-3);
  text-align: left;
}

.aai-state[data-phase="idle"],
.aai-state[data-phase="none"],
.aai-state[data-phase="error"] {
  padding-block: var(--space-8);
}

.aai-state-title {
  margin: 0 0 var(--space-1);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--color-ink);
}

.aai-state[data-phase="error"] .aai-state-title { color: var(--color-danger); }

.aai-state-hint {
  margin: 0;
  font-size: var(--text-xs);
  line-height: var(--leading-relaxed);
  color: var(--color-faint);
}

/* Serverns egen text, när den har något att tillägga. Den står under vår
   förklaring och inte i stället för den: ett felmeddelande skrivet för en
   logg svarar sällan på frågan "kan jag göra något åt det?". Markerbar,
   eftersom den är det man klistrar in i en buggrapport. */
.aai-state-detail {
  margin: var(--space-2) 0 0;
  font-family: var(--font-mono);
  font-size: var(--text-3xs);
  line-height: var(--leading-snug);
  color: var(--color-ink-muted);
  overflow-wrap: anywhere;
  -webkit-user-select: text;
  user-select: text;
}

/* ------------------------------------------------------------- laddningen

   Modellen kan ta flera sekunder, och en tom ruta i flera sekunder läser som
   en trasig panel. Två saker rör sig: en obestämd stapel och en sekundräknare
   bredvid hjälptexten. Stapeln stängs av under prefers-reduced-motion —
   räknaren fortsätter, eftersom siffror som byts inte är rörelse. */

.aai-bar {
  position: relative;
  width: 100%;
  max-width: var(--container-mobile);
  height: 3px;
  margin: var(--space-3) auto;
  border-radius: var(--radius-full);
  background: var(--color-surface-2);
  overflow: hidden;
}

.aai-bar::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 40%;
  border-radius: inherit;
  background: var(--color-accent);
  animation: aai-sweep calc(var(--dur-slower) * 3) var(--ease-in-out) infinite;
}

@keyframes aai-sweep {
  from { transform: translateX(-110%); }
  to   { transform: translateX(310%); }
}

.aai-elapsed {
  color: var(--color-ink-muted);
  font-variant-numeric: tabular-nums;
}

/* En animation med noll duration hoppar till slutläget i stället för att
   stå still, så den måste stängas av var för sig — nollningen av --dur-*
   räcker inte. Kvar blir en fylld stapel: "det pågår", utan rörelse. */
@media (prefers-reduced-motion: reduce) {
  .aai-bar::after {
    animation: none;
    width: 100%;
    opacity: 0.55;
  }
}

/* -------------------------------------------------------------------- listan */

.aai-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.aai-list[hidden] { display: none; }

/* --------------------------------------------------------------------- kortet

   Ett förslag är text man ska kunna läsa, markera och klistra in — inte en
   klickbar rad. Därför är kortet ingen knapp: knappen sitter i kortet, och
   allt annat är vanlig, markerbar text. Ett kort som i sin helhet är en
   knapp går inte att kopiera ur, och det är det man vill göra med ett
   förslag man inte tänker lägga till rakt av. */

.aai-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-1-5);
  padding: var(--space-3);
  padding-left: var(--space-4);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  list-style: none;
  -webkit-user-select: text;
  user-select: text;
}

/* Den tonade kanten säger typen en gång till, för den som skummar. Färgen
   kommer från --aai-tint, som typen sätter nedan. */
.aai-card::before {
  content: "";
  position: absolute;
  top: var(--space-3);
  bottom: var(--space-3);
  left: 0;
  width: 3px;
  border-radius: var(--radius-full);
  background: var(--aai-tint);
}

.aai-card-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* Typen bär färg OCH text. En färgad prick ensam är ingen information för
   den som inte ser färgen — issue och question är samma prick i gråskala. */
.aai-type {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1-5);
  color: var(--color-ink-muted);
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
}

.aai-dot {
  flex: none;
  width: var(--aai-dot);
  height: var(--aai-dot);
  border-radius: var(--radius-full);
  background: var(--color-faint);
}

/* Samma fyra betydelser som i resten av verktyget: problem är fara, möjlighet
   är framgång, fråga är information, heuristik är varumärkesfärgen. */
.aai-card[data-type="issue"]       { --aai-tint: var(--note-issue-soft); }
.aai-card[data-type="opportunity"] { --aai-tint: var(--note-opportunity-soft); }
.aai-card[data-type="question"]    { --aai-tint: var(--note-question-soft); }
.aai-card[data-type="heuristic"]   { --aai-tint: var(--note-heuristic-soft); }

.aai-card[data-type="issue"]       .aai-dot { background: var(--note-issue); }
.aai-card[data-type="opportunity"] .aai-dot { background: var(--note-opportunity); }
.aai-card[data-type="question"]    .aai-dot { background: var(--note-question); }
.aai-card[data-type="heuristic"]   .aai-dot { background: var(--note-heuristic); }

.aai-card-title {
  margin: 0;
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-snug);
  letter-spacing: var(--tracking-tight);
  color: var(--color-ink);
  overflow-wrap: anywhere;
}

.aai-card-body {
  margin: 0;
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
  color: var(--color-ink-muted);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.aai-heur {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-1-5);
  margin: 0;
  font-size: var(--text-xs);
  color: var(--color-faint);
}

.aai-heur-label {
  color: var(--note-heuristic);
  font-weight: var(--weight-medium);
}

/* Det som inte gick: att kortet inte kunde läggas till, eller att skalet inte
   kan ta emot förslag alls. Står i kortet, inte som en toast — felet gäller
   just det här förslaget. */
.aai-card-note {
  margin: 0;
  font-size: var(--text-xs);
  color: var(--color-danger);
}

/* ------------------------------------------------------------ lägg till-knappen

   Varje förslag har sin egen. Panelen skriver aldrig till boarden själv —
   den här knappen är den enda vägen dit, och den går genom skalet. */

.aai-add {
  align-self: flex-start;
  min-height: 44px;
  margin-top: var(--space-1);
  padding: 0 var(--space-4);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-lg);
  background: var(--color-surface-2);
  color: var(--color-ink);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}

.aai-add:not([aria-disabled]):hover { border-color: var(--color-line-2); }

/* `aria-disabled`, inte `disabled`: en knapp som säger "Tillagd" ska ligga
   kvar i tabbordningen, annars hoppas kortet tyst över av den som tabbar sig
   igenom listan. Att den inte går att aktivera sköts i ai.js. */
.aai-add[aria-disabled="true"] {
  color: var(--color-disabled);
  cursor: default;
}

/* Tillagd. Knappen blir en markering i stället för att försvinna: den säger
   vad som hänt och går inte att trycka på igen. Att ta bort den hade gjort
   kortet tvetydigt — var det tillagt, eller är kortet bara annorlunda? */
.aai-add[data-added] {
  border-color: var(--color-success);
  background: var(--color-success-soft);
  color: var(--color-success);
  cursor: default;
}

.aai-add[data-added]::before {
  content: "✓";
  margin-right: var(--space-1-5);
}

.aai-card[data-added] { border-color: var(--color-success); }

/* --------------------------------------------------------------------- foten */

.aai-foot {
  flex: none;
  padding: var(--space-2) var(--space-3);
  padding-bottom: max(var(--space-2), var(--safe-b));
  border-top: 1px solid var(--color-line);
}

/* Hämta, hämta om, försök igen — samma knapp, olika uppgift. Full bredd och
   44 px hög: bredden ÄR träffytan, så inget pseudoelement behövs. */
.aai-run {
  width: 100%;
  min-height: 44px;
  padding: 0 var(--space-4);
  border: 1px solid var(--color-accent);
  border-radius: var(--radius-lg);
  background: var(--color-accent);
  color: var(--color-accent-ink);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  cursor: pointer;
  transition: opacity var(--dur-fast) var(--ease-out);
}

.aai-run:hover { opacity: 0.92; }

.aai-run[disabled] {
  border-color: var(--color-line);
  background: var(--color-surface-2);
  color: var(--color-disabled);
  cursor: default;
  opacity: 1;
}

/* --------------------------------------------------------------- pekvänlighet

   Frågan är inmatningsmetod, inte skärmbredd — en iPad i liggande läge är
   1024 px och styrs med ett finger. */

@media (pointer: coarse) {
  .aai-close { width: 34px; height: 34px; }
  /* 34 + 5 + 5 = 44. Ändra det ena utan det andra och träffytan krymper tyst. */
  .aai-close::before { inset: -5px; }

  .aai-add { align-self: stretch; }
}

/* ------------------------------------------------------------------- desktop

   820 px är annots brytpunkt för layout. Över den är panelen en centrerad
   ruta som svävar över canvasen — man ser vad man lämnar. */

@media (min-width: 821px) {
  .aai-overlay {
    align-items: flex-start;
    padding: var(--space-12) var(--space-4) var(--space-4);
  }

  .aai-panel {
    width: 460px;
    max-width: 100%;
    height: auto;
    max-height: min(78vh, 42rem);
    padding-top: 0;
    border: 1px solid var(--color-line);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-xl);
    transform: translateY(calc(var(--space-2) * -1));
  }

  .aai-card:hover { border-color: var(--color-line-2); }
  .aai-card[data-added]:hover { border-color: var(--color-success); }
}

/* --------------------------------------------------------------------- 390 px

   Den smalaste skärm som ska fungera. Metaraden bryter hellre till två rader
   än klämmer ihop kostnaden till en oläslig stump — siffran är hela poängen
   med att den står där. */

@media (max-width: 400px) {
  .aai-head { padding-left: var(--space-3); }
  .aai-meta {
    flex-wrap: wrap;
    padding-inline: var(--space-3);
  }
  .aai-usage { max-width: 100%; }

  .aai-card { padding: var(--space-3); padding-left: var(--space-4); }
  .aai-add { align-self: stretch; }
}
