/*
  Färgvariabler: ljust (standard) och mörkt läge.

  --data-theme styrs av theme.js och sätts som ett attribut på <html>.
  Frånvarande attribut (eller "light") ger standardläget i :root-blocket
  nedan; "dark" skriver över alla färgvariabler i det andra blocket.
  color-scheme sätts likadant, så webbläsarens EGNA kontroller (scrollbar,
  <select> m.m.) också följer läget - annars kan t.ex. en <select> på
  /full-list/ rendera mörk text på mörk botten i mörkt läge, se HANDOVER.

  --color-surface (kort, popovers, tabellrader) skiftar MED läget - till
  skillnad från den tidigare femfärgade bakgrundsväljaren är det här ett
  RIKTIGT mörkt/ljust tema, inte bara en tonad bakgrund på en i övrigt vit
  sida. Enda undantaget är karusellens egna bild-filer (kort-*.png) -
  Alexanders instruktion är att de behåller sina egna färger oförändrade,
  så INGEN filter/invert läggs på .wheel__image i mörkt läge.

  Alla textkombinationer nedan är kontrollräknade mot WCAG AA (>= 4.5:1
  för normal text) i båda lägena - se PR-beskrivningen för de uträknade
  kontrastkvoterna. Det mörka basvärdet (#121212) är Material Designs
  rekommenderade "mörk yta"-ton, ett medvetet neutralt val (ingen kulör,
  inte rent svart - rent svart mot vit text ger onödigt hög bländande
  kontrast och är sällan vad som avses med "mörkt läge") - Alexanders
  beslut att byta bort de fem pastellfärgerna mot det här.
*/
:root {
  --color-background: #ffffff;
  --color-background-alt: #f4f4f4;
  --color-surface: #ffffff;
  --color-border: #d9d9d9;
  --color-text: #1a1a1a;
  --color-text-muted: #5c5c5c;
  --color-accent: #333333;
  --color-focus-ring: #333333;
  color-scheme: light;

  /*
    Typsnitt.
    Systemtypsnitt som platshållare. När ett självhostat typsnitt väljs
    läggs @font-face-regler till här och filerna i docs/fonts/, ersätt
    inte detta med en extern CDN eller Google Fonts.
  */
  --font-family-base: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    Helvetica, Arial, sans-serif;

  --max-content-width: 72rem;
}

:root[data-theme="dark"] {
  --color-background: #121212;
  --color-background-alt: #262626;
  --color-surface: #1e1e1e;
  --color-border: #3a3a3a;
  --color-text: #f2f2f2;
  --color-text-muted: #a8a8a8;
  --color-accent: #e0e0e0;
  --color-focus-ring: #e0e0e0;
  color-scheme: dark;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

/*
  Sticky footer: bottenbannern ska ligga klistrad mot fönstrets
  nederkant när sidans innehåll är kortare än fönstret, och flyta med
  innehållet som vanligt annars (jämför blodprovspriser.se) - RÄTTELSE
  av en tidigare instruktion som bad om motsatsen (att bannern skulle
  följa direkt efter innehållet), se git-historiken.

  body är en flex-kolumn med min-height minst lika med
  visningsytans höjd (100dvh - dynamic viewport height, tar hänsyn till
  mobilers hopfällbara adressfält bättre än 100vh; vh som platshållare
  före dvh-stödet). <header>, <main> och <footer> är dess tre flex-barn
  i DOM-ordning; main {flex: 1 0 auto} (se den regeln) tar allt
  överskjutande utrymme, så footer alltid hamnar sist - antingen precis
  efter ett långt innehåll (main krymper naturligt till sitt innehåll då
  flex-basis är auto) eller nertryckt mot fönstrets botten när
  innehållet är kortare än fönstret.
*/
body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  font-family: var(--font-family-base);
  color: var(--color-text);
  background-color: var(--color-background);
  line-height: 1.5;
}

a {
  color: inherit;
}

h1,
h2 {
  line-height: 1.2;
}

:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}

/*
  Används för element som ska finnas i DOM:en och nås av tangentbord/
  skärmläsare, men aldrig synas visuellt - t.ex. <legend> för
  karusellens radiogrupp och de faktiska (osynliga) radioknapparna under
  karusellens kort, se .wheel__radio.
*/
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/*
  Sidhuvudet.

  Bakgrunden är MEDVETET samma variabel som sidans bakgrund
  (--color-background) och HELT UTAN ram eller skugga - det ska inte
  synas som ett eget band, bara gå ihop med sidan (Alexanders
  instruktion).

  Allt utom sidtiteln är samlat i EN högerställd grupp
  (.site-header__right, meny + färgläge + språk) i stället för att
  menylänkarna flyta fritt i mitten - .site-header__inner har bara TVÅ
  flex-barn (titeln och den gruppen), så justify-content: space-between
  läggar dem exakt i var sin ände utan någon tredje mittenpost som
  annars skulle hamna någonstans mitt emellan beroende på de andras
  bredd.
*/
.site-header {
  background-color: var(--color-background);
}

.site-header__inner {
  max-width: var(--max-content-width);
  margin: 0 auto;
  padding: 1rem 1.5rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.site-title {
  font-size: 1.125rem;
  font-weight: 600;
  text-decoration: none;
  color: var(--color-text);
}

/*
  Startsidans sidhuvud innehåller ingen länk tillbaka till sig själv.
  visibility: hidden i stället för att ta bort elementet: det upptar
  fortfarande sin plats i flex-layouten, så den högerställda gruppen
  hamnar på exakt samma plats som på undersidorna.
*/
.site-header--home .site-title {
  visibility: hidden;
}

.site-header__right {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.5rem;
}

.site-nav {
  display: flex;
  gap: 1.25rem;
}

.site-nav a {
  color: var(--color-text);
  text-decoration: none;
  font-size: 0.9375rem;
  font-weight: 500;
}

.site-nav a:hover,
.site-nav a:focus-visible {
  text-decoration: underline;
}

.site-header__controls {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

/*
  Färgläges- och språkväljaren är båda en <details>/<summary> - ett
  fällbart menyval helt utan egen JS för själva öppna/stänga-logiken
  (bara VALET hanteras av theme.js respektive i18n.js, som stänger
  menyn efter ett klick). Samma knapp- och menystil delas av båda
  (.picker-button/.picker-menu/.picker-option), bara innehållet i menyn
  skiljer. Standardmarkören (pilen webbläsaren annars ritar ut på
  <summary>) tas bort eftersom knappstilen redan visar att den går att
  klicka på.
*/
.theme-picker,
.language-picker {
  position: relative;
}

.picker-button {
  display: inline-block;
  list-style: none;
  font: inherit;
  font-size: 0.875rem;
  background: transparent;
  color: var(--color-text);
  border: 1px solid var(--color-border);
  border-radius: 0.25rem;
  padding: 0.25rem 0.75rem;
  cursor: pointer;
}

.picker-button:hover {
  border-color: var(--color-accent);
}

.picker-button::-webkit-details-marker,
.picker-button::marker {
  display: none;
  content: "";
}

.picker-menu {
  position: absolute;
  right: 0;
  top: calc(100% + 0.375rem);
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  padding: 0.375rem;
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 0.5rem;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
  z-index: 10;
}

.picker-option {
  font: inherit;
  font-size: 0.875rem;
  text-align: left;
  white-space: nowrap;
  background: transparent;
  color: var(--color-text);
  border: 0;
  border-radius: 0.25rem;
  padding: 0.375rem 0.75rem;
  cursor: pointer;
}

.picker-option:hover {
  background-color: var(--color-background-alt);
}

.picker-option[aria-pressed="true"] {
  background-color: var(--color-accent);
  color: var(--color-background);
}

/*
  Mobilt sidhuvud: mindre text och knappar så raden blir diskret i
  stället för att dominera vyn. Desktopvyn (över brytpunkten) är
  oförändrad.
*/
@media (max-width: 640px) {
  .site-header__inner {
    padding: 0.5rem 1rem;
    gap: 0.5rem;
  }

  .site-title {
    font-size: 0.9375rem;
  }

  .site-header__right {
    gap: 0.75rem;
  }

  .site-nav {
    gap: 0.75rem;
  }

  .site-header__controls {
    gap: 0.5rem;
  }

  .picker-button {
    padding: 0.1875rem 0.5rem;
    font-size: 0.8125rem;
  }
}

/*
  Bottenpaddingen är MEDVETET liten (inte den stora 3rem den var förut) -
  <main> har ingen egen höjd (inget min-height: 100vh, ingen flex-
  layout med margin-top: auto på bottenbannern), så sidans totala höjd
  följer alltid bara det faktiska innehållet. Med en stor fast
  bottenpadding blev det tomma fältet mellan ett kort/tomt
  listinnehåll och bottenbannern oproportionerligt stort - se
  Alexanders instruktion. En liten padding räcker som andningsrum när
  listan är lång också.
*/
main {
  width: 100%;
  max-width: var(--max-content-width);
  margin: 0 auto;
  padding: 2rem 1.5rem 1.5rem;
  /* Tar allt utrymme body:s flex-kolumn har kvar utöver header/footer -
     se sticky footer-kommentaren vid body ovan. shrink: 0 så main
     aldrig krymper under sitt eget innehålls höjd. */
  flex: 1 0 auto;
}

/*
  margin-top ger utrymme för de utfällda meny-popoverna i sidhuvudet
  (.picker-menu, se Läge/Språk) att rymmas OVANFÖR sidans första
  innehåll utan att överlappa det - samma mått som .carousel-section
  använder på startsidan, se den kommentaren för hela resonemanget och
  de uppmätta talen.
*/
.page-intro {
  max-width: 40rem;
  margin-top: 4.5rem;
}

.page-intro h1 {
  margin: 0 0 1rem;
}

.page-intro p {
  color: var(--color-text-muted);
}

/*
  Karusellhjulet på startsidan.

  Undertill är detta en helt vanlig radiogrupp (<fieldset>/<input
  type="radio">) - fyra alternativ, ett valbart åt gången, precis som
  en vanlig knapprad. Det ger tangentbords- (piltangenter mellan
  alternativen, native webbläsarbeteende för radiogrupper) och
  skärmläsarstöd (grupp-namn, antal alternativ, vilket som är valt)
  helt GRATIS, utan egen tangentbordslogik - se js/carousel.js för hela
  resonemanget bakom "hjulet".

  .wheel__stage är scenen: en fast höjd (skalad mot fönsterhöjden, se
  nedan), position: relative, så de fyra .wheel__card kan placeras
  absolut och mitt-ankras (left/top: 50%). js/carousel.js sätter sedan
  BARA transform (translate+scale) och z-index per kort varje bildruta
  - HELA den elliptiska positioneringen, storleksskalningen och
  överlappningen (z-index) räknas ut där, i JS, inte här. CSS:en här
  äger bara kortens EGEN, oskalade form (bildens 1:2-proportion,
  bildtext under) och övergångsanimationen när hjulet "sätter sig"
  efter en dragning (.is-settling, se nedan) - aldrig positionerna
  själva.

  Höjden på scenen sätts med clamp() i vh, INTE uträknad i JS: det låter
  webbläsaren skala om direkt vid fönsterändring/rotation utan att
  js/carousel.js behöver en egen resize-lyssnare för STORLEKEN (bara en
  ResizeObserver för att läsa av den nya bredden/höjden till
  ellipsberäkningen). ~46vh ger fokuskortet ungefär halva den vertikala
  ytan (Alexanders instruktion), med golv/tak (240px/560px) så det
  varken blir orimligt litet på mycket låga fönster eller orimligt
  dominerande på mycket höga.

  margin-top (4.5rem, mer än de andra tre sidorna) ger plats åt Läge-/
  Språk-menyerna i sidhuvudet att fällas ut OVANFÖR karusellen utan att
  overlappa den. Uträknat mot det uppmätta värsta fallet (bredare
  fönster, sidhuvudet på en rad): sidhuvudet slutar ~43px ner,
  huvudinnehållets egen toppadding lägger till 32px, en öppen
  popover-meny sträcker sig då till ~123px - 4.5rem (72px) tar
  karusellen till ~147px, en marginal på dryga 20px. Kontrollerat vid
  flera fönsterbredder (se HANDOVER.md) eftersom sidhuvudet kan radbryta
  på smala skärmar.
*/
.carousel-section {
  margin: 4.5rem 0 2.5rem;
}

.wheel {
  margin: 0;
  padding: 0;
  border: 0;
}

.wheel__stage {
  position: relative;
  height: clamp(240px, 46vh, 560px);
  touch-action: pan-y;
  cursor: grab;
}

.wheel__stage.is-dragging {
  cursor: grabbing;
}

/*
  Ingen transition som standard - under en aktiv dragning ska kortet
  följa pekaren 1:1, utan eftersläpning. Bara när hjulet "sätter sig"
  efter en dragning, eller animerar till ett nytt val (klick/
  tangentbord), läggs .is-settling på scenen och transition slås på
  tillfälligt - se js/carousel.js::animeraTill().
*/
.wheel__card {
  position: absolute;
  left: 50%;
  top: 50%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  transition: none;
  will-change: transform;
  user-select: none;
  -webkit-user-drag: none;
}

.wheel__stage.is-settling .wheel__card {
  transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

/*
  Ingen ram/kant runt korten (Alexanders instruktion, gäller båda
  färglägena) - bara den mjuka skuggan för djup. box-shadow i sig är
  INTE en kant (ingen konturlinje, bara en diffus skugga i en neutral,
  tema-oberoende svart ton), så den är kvar.
*/
.wheel__image-wrap {
  flex: 1 1 auto;
  min-height: 0;
  aspect-ratio: 1 / 2;
  border-radius: 0.75rem;
  overflow: hidden;
  background-color: var(--color-surface);
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.16);
}

.wheel__image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}

.wheel__label {
  font-size: 1rem;
  font-weight: 600;
  color: var(--color-text);
  white-space: nowrap;
}

/*
  Valt kort visas fortfarande tydligt - det ligger redan störst och
  centrerat framför de andra (se js/carousel.js) - bara utan en
  extra färgad ring runt bilden ovanpå det.
*/
.wheel__radio:focus-visible ~ .wheel__image-wrap {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 3px;
}

@media (max-width: 640px) {
  .wheel__label {
    font-size: 0.875rem;
  }
}

/*
  Länken under startsidans lista till /full-list/ - visas bara när den
  valda kategorin faktiskt har fler poster än de 100 som visas här (se
  js/records.js::skapaListvy, opts.tak).
*/
.records__more-link {
  margin: 1rem 0 0;
  font-size: 0.9375rem;
}

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin: 1.5rem 0;
}

.filters__field {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-size: 0.875rem;
}

.filters__field label {
  color: var(--color-text-muted);
}

.filters__field select {
  font: inherit;
  font-size: 0.9375rem;
  padding: 0.375rem 0.5rem;
  border: 1px solid var(--color-border);
  border-radius: 0.375rem;
  background-color: var(--color-surface);
  color: var(--color-text);
  min-width: 12rem;
}

.records {
  margin-top: 2.5rem;
  padding-top: 2rem;
  border-top: 1px solid var(--color-border);
}

/*
  Startsidans lista följer direkt på karusellen, inte på ett filter-
  eller rubrikblock som på /full-list/ - linjen ovanför fyllde ingen
  funktion där (Alexanders instruktion) och tas bort bara i det fallet,
  via den här kombinatorn, i stället för att ta bort den från .records
  helt (vilket även skulle ha påverkat /full-list/, som fortfarande vill
  skilja listan visuellt från filtren ovanför).
*/
.carousel-section + .records {
  margin-top: 1.5rem;
  padding-top: 0;
  border-top: none;
}

.records h2 {
  margin: 0 0 1rem;
  font-size: 1.125rem;
}

.records__empty {
  margin: 0;
  color: var(--color-text-muted);
  font-size: 0.9375rem;
}

.records__note {
  margin: 0 0 1rem;
  color: var(--color-text-muted);
  font-size: 0.8125rem;
}

/*
  Tabellen kan bli mycket bred (åtta kolumner, varav en fri text). En
  egen rullningsbehållare håller sidans egen bredd stabil på smala
  skärmar i stället för att tabellen tvingar horisontell scroll på hela
  sidan.
*/
.records-table-wrap {
  overflow-x: auto;
}

.records-table {
  width: 100%;
  min-width: 40rem;
  border-collapse: collapse;
  font-size: 0.875rem;
}

.records-table th,
.records-table td {
  padding: 0.5rem 0.75rem;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--color-border);
}

.records-table th {
  font-weight: 600;
  color: var(--color-text-muted);
  white-space: nowrap;
}

/*
  Sorterbara kolumnrubriker (/full-list/ - startsidans tabell är inte
  sorterbar). role="button"+tabindex på <th> eftersom en tabellrubrik
  inte är interaktiv av sig själv; aria-sort på SAMMA element (WAI-ARIA
  table sort-mönstret), uppdaterad av js/full-list.js vid varje klick/
  Enter/Space.
*/
.records-table th[data-sort] {
  cursor: pointer;
  user-select: none;
}

.records-table th[data-sort]:hover,
.records-table th[data-sort]:focus-visible {
  color: var(--color-text);
}

.records-table th[data-sort]::after {
  display: inline-block;
  width: 1em;
  margin-left: 0.25em;
  content: "";
}

.records-table th[aria-sort="ascending"]::after {
  content: "▲";
}

.records-table th[aria-sort="descending"]::after {
  content: "▼";
}

.records-table__title {
  min-width: 14rem;
}

.records-table__title a {
  text-decoration: underline;
}

.records-table__date,
.records-table__updated,
.records-table__event {
  white-space: nowrap;
}

.records-table__match {
  min-width: 12rem;
  color: var(--color-text-muted);
}

.records-table__source,
.records-table__method,
.records-table__type {
  min-width: 9rem;
}

/*
  Publicisten/publicisterna (t.ex. "MedPage Today", eller "MedPage
  Today, The Guardian" om två utgivare råkade länka till samma URL) för
  en sammanfogad post - se filkommentaren vid byggRad()/tdKalla i
  records.js. Bara en kort, kommaseparerad textrad ovanför de vanliga
  käll-pillren, ingen egen pill-lista (den ska läsas som en RUBRIK över
  de enskilda flödena, inte som ytterligare ett värde i samma
  flervärdeslista) - text wrappar naturligt i cellen om den blir lång,
  ingen särskild brytningsregel behövs.
*/
.records-table__publisher {
  font-weight: 600;
  margin-bottom: 0.25rem;
}

/*
  En publikation kan höra till flera källor/metoder/typer sedan
  sammanfogningen mellan källor (t.ex. "pubmed, europepmc", eller
  "forskningsartikel, preprint" om en preprint senare publicerats).
  Varje värde visas som en egen liten pill i en flex-wrap-behållare i
  stället för en lång kommaseparerad textrad, så kolumnen förblir
  läsbar och bryter naturligt till fler rader om antalet källor/typer
  växer.
*/
.pill-lista {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
}

.pill {
  display: inline-block;
  padding: 0.0625rem 0.5rem;
  background-color: var(--color-background-alt);
  border: 1px solid var(--color-border);
  border-radius: 999px;
  font-size: 0.8125rem;
  white-space: nowrap;
}

.records__more {
  display: block;
  margin: 1rem auto 0;
  padding: 0.5rem 1.25rem;
  background-color: var(--color-surface);
  color: var(--color-text);
  border: 1px solid var(--color-border);
  border-radius: 0.375rem;
  font: inherit;
  font-size: 0.9375rem;
  cursor: pointer;
}

.records__more:hover,
.records__more:focus-visible {
  border-color: var(--color-accent);
}

/*
  /sources/-sidans lista av källor per metod.
*/
.source-group {
  margin: 0 0 2rem;
}

.source-group h2 {
  font-size: 1.0625rem;
  margin: 0 0 0.75rem;
}

.source-group__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.source-group__list li a {
  display: inline-block;
  padding: 0.375rem 0.875rem;
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 999px;
  text-decoration: none;
  font-size: 0.9375rem;
}

.source-group__list li a:hover,
.source-group__list li a:focus-visible {
  border-color: var(--color-accent);
}

.source-group__empty {
  color: var(--color-text-muted);
  font-size: 0.9375rem;
}

/*
  Bottenbannern: EN rad text (datum + disclaimer i samma mening, samma
  <p>) i stället för två separata rader - ett fotavtryck på en rad på
  dator, som bara bryter naturligt (vanligt textflöde, ingen egen
  brytpunktsregel behövs) på smala skärmar. Datumet i #footer-date sätts
  av js/footer.js, uträknat ur den redan hämtade datan (senast sedd) -
  se den filen för resonemanget, samma princip som senasteHamtadDatum()
  i records.js.
*/
.site-footer {
  border-top: 1px solid var(--color-border);
  padding: 0.75rem 1.5rem;
  text-align: center;
}

.site-footer p {
  margin: 0;
  color: var(--color-text-muted);
  font-size: 0.8125rem;
}
