/* =============================================================================
   Annot — flikarna
   =============================================================================

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

   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.

   Raden bor i #bar, som är 52 px högt och redan innehåller brödsmulor,
   närvaroavatarer och fem ikonknappar. Den har alltså inget utrymme att be
   om. Därför:

     · flikarna krymper till ett golv och rullar sedan i sidled, i stället
       för att pressa ihop resten av sidhuvudet,
     · texten kortas med ellips — raden kortas aldrig,
     · rullisten göms, precis som #bar gömmer sin.

   Måtten står som egna custom properties högst upp. Träffytorna räknas ur
   dem med calc(), så att en ändrad flikhöjd inte tyst krymper ytan man
   träffar — se DESIGN.md avsnitt 7, där just det felet står beskrivet.
   ========================================================================== */

@import "./theme.css";

/* ------------------------------------------------------------------- raden */

.atb-strip {
  /* Synliga mått. Ändras något av dem följer träffytorna med av sig själva. */
  --atb-h: 30px;              /* flikens höjd */
  --atb-close: 20px;          /* krysset, synlig storlek */
  --atb-hit: 44px;            /* träffytan, alltid */

  /* Golv och tak för en flik. Under golvet blir namnet obegripligt och man
     klickar på fel board; över taket äter tre flikar upp hela sidhuvudet. */
  --atb-min: 8.5rem;
  --atb-max: 14rem;

  /* Plats som reserveras för krysset i flikens slut. Exakt lika stor som
     krysset plus dess träffyta, se .atb-close::before. */
  --atb-gutter: var(--space-10);

  display: flex;
  align-items: center;
  gap: var(--space-2);

  /* min-width: 0 låter raden krympa i #bar:s flexbox i stället för att sätta
     en minsta bredd på hela sidhuvudet. Samma fel som #bar självt hade en
     gång: utan detta stack sidan ut till höger och innehållet klipptes. */
  min-width: 0;
  flex: 0 1 auto;

  overflow-x: auto;
  overflow-y: hidden;
  /* Rullningen ska stanna i raden. Utan detta fortsätter en tröghetsrullning
     ut i sidan och tar canvasen med sig. */
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  -ms-overflow-style: none;

  /* Måste rymma träffytan, inte bara flikens synliga höjd.
     `overflow-y: hidden` klipper hit-testing till scrollporten, så ett
     ::before som sticker ut vertikalt kapas — 44 px blev 38 i praktiken.
     Med space-2 ryms hela ytan innanför porten. */
  padding-block: var(--space-2);
  font-family: var(--font-sans);
}

/* Rullisten skulle äta av en redan låg rad, och den säger inget som inte
   flikarnas egen kant redan säger. Samma val som #bar gör. */
.atb-strip::-webkit-scrollbar { display: none; }

.atb-strip[hidden] { display: none; }

/* -------------------------------------------------------------- en flik */

.atb-tab {
  position: relative;
  display: flex;
  align-items: center;
  flex: 0 1 auto;
  min-width: var(--atb-min);
  max-width: var(--atb-max);
}

.atb-face {
  position: relative;
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  height: var(--atb-h);
  /* Slutet är alltid reserverat åt krysset, även på inaktiva flikar där det
     inte syns. Annars hoppar namnet i sidled i samma ögonblick som fliken
     blir aktiv, och man tappar bort vad man just läste. */
  padding-inline: var(--space-3) var(--atb-gutter);
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-ink-muted);
  font-size: var(--text-xs);
  line-height: var(--leading-none);
  white-space: nowrap;
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}

/* Träffytan: 30 px syns, 44 px träffas. Bara vertikalt — vågrätt är fliken
   redan minst 136 px, och en vågrät utvidgning hade lagt sig över grannen.
   Se DESIGN.md avsnitt 7: två träffytor som överlappar är ett tyst fel. */
.atb-face::before {
  content: "";
  position: absolute;
  inset: calc((var(--atb-h) - var(--atb-hit)) / 2) 0;
}

.atb-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.atb-face:hover { background: var(--color-surface-2); color: var(--color-ink); }

/* --------------------------------------------------------- aktiv flik

   Läge bärs av attribut, inte av en klass (DESIGN.md 4b): aria-selected och
   stilen läser samma sanning, så skärmläsaren kan inte få ett annat svar än
   ögat.

   Skillnaden måste vara omöjlig att missa. En aning ljusare yta räcker inte
   i ett sidhuvud som redan har en suddad bakgrund bakom sig — den aktiva
   fliken får därför en egen yta, en hårfin ram, en skugga, tyngre text och
   en accentmarkör i underkanten. Fyra signaler, varav en klarar sig utan
   färgseende och en utan färg alls. */
.atb-face[aria-selected="true"] {
  background: var(--color-surface);
  color: var(--color-ink);
  font-weight: var(--weight-semibold);
  box-shadow: var(--shadow-sm), inset 0 0 0 1px var(--color-line);
}

.atb-face[aria-selected="true"]::after {
  content: "";
  position: absolute;
  left: var(--space-2);
  right: var(--space-2);
  bottom: 0;
  height: 2px;
  border-radius: var(--radius-full);
  background: var(--color-accent);
}

.atb-face[aria-selected="true"]:hover { background: var(--color-surface); }

/* ------------------------------------------------------------- krysset

   Varför krysset är dött på inaktiva flikar
   -----------------------------------------
   Det vanliga misstaget är att visa krysset vid hover. Då händer det här:
   pekaren är på väg mot flik 3 för att byta dit, hover får krysset att dyka
   upp precis där pekaren landar, och klicket stänger boarden i stället för
   att öppna den. Handlingen man ville göra och handlingen man råkade göra är
   varandras motsatser, och den senare är den som inte går att ångra.

   Lösningen här är att krysset bara är levande på den flik som redan är
   aktiv. På alla andra ligger det kvar i layouten men är genomskinligt och
   pointer-events: none — ett klick var som helst på en inaktiv flik byter
   alltså till den, aldrig något annat. tabs.js sätter samtidigt tabindex=-1
   och aria-hidden på samma kryss, för pointer-events säger ingenting om
   tabbordningen eller om vad en skärmläsare hittar.

   Priset är att en bakgrundsflik kostar två klick att stänga: ett för att gå
   dit, ett för att stänga. Det är rätt pris. Det första klicket är
   ofarligt och syns direkt; det klick vi bytt bort var osynligt tills
   boarden var borta.

   Syskonväljaren gör att CSS:en läser samma aria-selected som allt annat —
   ingen extra tillståndsklass som kan hamna i otakt. */
.atb-close {
  position: absolute;
  inset-block: 0;
  margin-block: auto;
  inset-inline-end: var(--space-2);
  z-index: 1;

  width: var(--atb-close);
  height: var(--atb-close);
  display: grid;
  place-items: center;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-faint);
  font-size: var(--text-sm);
  line-height: var(--leading-none);

  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out);
}

/* 20 px syns, 44 px träffas. Utvidgningen åt höger är 12 px och flikens egen
   marginal dit är 8 px — resten faller i gapet mellan flikarna (8 px) och
   når därför aldrig grannen. Åt vänster faller den i den reserverade
   gutter-ytan, inte på namnet: gutter (40) = kryss (20) + 8 höger + 12
   vänster. Ändras --atb-gutter eller --atb-close måste den summan stämma
   igen, annars flyttas stängytan in över texten. */
.atb-close::before {
  content: "";
  position: absolute;
  inset: calc((var(--atb-close) - var(--atb-hit)) / 2);
}

.atb-face[aria-selected="true"] ~ .atb-close {
  opacity: 1;
  pointer-events: auto;
}

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

/* ---------------------------------------------------------------- rörelse */

@media (prefers-reduced-motion: reduce) {
  .atb-face,
  .atb-close { transition: none; }
}

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

   Anpassningen hänger på inmatningsmetod, inte på skärmbredd (DESIGN.md 4c).
   En iPad i liggande läge visar flikarna och styrs med ett finger.
   Båda måtten ändras, aldrig bara det ena: träffytan räknas ur dem och
   krymper tyst om de glider isär. */
@media (pointer: coarse) {
  .atb-strip {
    --atb-h: 34px;
    --atb-close: 24px;
    --atb-min: 9.5rem;
  }
}

/* ------------------------------------------------------------- telefon

   Under 720 px göms raden helt.

   Flikar är fel verktyg på en liten skärm. #bar är 52 px högt och rymmer på
   390 px redan brödsmula, meny och ikonknappar; en flikrad där hade fått
   under 60 px per flik, vilket är ett par tecken och en ellips — man klickar
   på "Che…" och hoppas. Och genvägen som gör flikar snabba, Mod+siffra,
   finns inte på en telefon utan tangentbord.

   Det som ersätter dem finns redan och är byggt mobilen först: projektlådan
   och skärmnavigatorn. Att gömma raden är alltså inte att ta bort en
   funktion, det är att låta rätt verktyg synas.

   720 px, inte 820: 820 är brytpunkten där panelen blir ett ark i
   underkanten, och den handlar om canvasen. Flikarnas fråga är en annan —
   vid vilken bredd får sidhuvudet plats med mer än sig självt — och den
   inträffar tidigare. Två frågor, två tal. */
@media (max-width: 719px) {
  .atb-strip { display: none; }
}
