/* ============================================================
   Positronic — page-shell components
   Adds: breaking ticker, hero-card, sidebar, notis-list,
   section-header, grid, tag-cloud, filter-bar, toc, prev-next,
   reading-progress.
   Loads on top of tokens.css + article.css.
   ============================================================ */

/* ============================================================
   READING-PROGRESS bar (top of viewport)
   Static demo width — pages can change inline width.
   ============================================================ */
.reading-progress {
  position: fixed;
  top: 0; left: 0;
  height: 3px;
  background: var(--brand-primary);
  z-index: 200;
  width: 38%;
}

/* ============================================================
   STAMLÄGENA — en klass, och allt inuti följer med
   ============================================================
   Ett läge PEKAR OM --brand-paper/ink/muted/line för sin del av trädet. Custom properties ärvs,
   så temats tvåhundra befintliga var(--brand-ink)-läsningar följer med utan att en enda komponent
   behöver ändras. Det är samma mekanism som --section: den som beställer namnger avsikten, och
   CSS:en äger vad avsikten ser ut som.

   Muted och line HÄRLEDS ur grunden i stället för att återanvändas. --brand-muted är tonad för
   pappret; lagd på ett djupare underlag tappar den kontrast — Provenance föll till 4,1:1 och
   Atelier till 3,7:1 innan de blev härledda. Med color-mix är förhållandet detsamma på varje steg.

   ETT LÄGE ÄR EN SEKTION, INTE EN DEKORATION. Byter man läge mitt i ett stycke har man bytt
   underlag under en läsare som redan börjat läsa. Lägg det på ett block, aldrig på ett ord.
   ============================================================ */
.mood--paper,
.mood--raised,
.mood--anchor,
.mood--invert {
  background: var(--brand-paper);
  color: var(--brand-ink);
}

/* Nollställaren. Behövs för att komma TILLBAKA till pappret inuti ett djupare läge. */
.mood--paper {
  --brand-paper: var(--mood-paper);
  --brand-surface: var(--mood-raised);
}

.mood--raised {
  --brand-paper: var(--mood-raised);
  --brand-surface: var(--mood-anchor);
  --brand-muted: color-mix(in srgb, var(--brand-ink) 70%, var(--mood-raised));
  --brand-line: color-mix(in srgb, var(--brand-ink) 18%, var(--mood-raised));
}

/* GÅNGJÄRNET. Stegen har två sidor: på den ena är bläcket mörkt, på den andra ljust, och
   `invert` är vändpunkten. En YTA får aldrig korsa gångjärnet ensam, för bläcket följer inte
   med — ett kort som hämtar sin grund från andra sidan blir bläck på bläck.
   Därför: `anchor` är sista steget på sin sida, så dess kort LYFTER TILLBAKA till `raised`
   i stället för att stega vidare. Ett kort som är ljusare än sin grund läses lika väl som ett
   som är mörkare; det som inte läses är ett kort utan kontrast mot texten på det. */
.mood--anchor {
  --brand-paper: var(--mood-anchor);
  --brand-surface: var(--mood-raised);
  --brand-muted: color-mix(in srgb, var(--brand-ink) 74%, var(--mood-anchor));
  --brand-line: color-mix(in srgb, var(--brand-ink) 18%, var(--mood-anchor));
}

/* Bruket. Här byter även BLÄCKET sida, så den kan inte härledas — den läser invert-gruppen,
   som varje brand redan äger.
   Sidfoten och mastheadstrippen står med, för de ÄR kontrastzoner: de målar invert-grunden. En yta
   som vänder grunden men behåller pappersstämd muted, line och accent bär färger som inte är
   tonade för det den står på — därför finns invert-gruppen över huvud taget. */
.mood--invert,
.masthead__strip,
.footer {
  --brand-paper: var(--mood-invert);
  /* Samma skäl: bruket har ingen granne på sin egen sida, så dess kort härleds som ett lyft
     ur grunden i stället för att hämtas från stegen. */
  --brand-surface: color-mix(in srgb, var(--brand-on-invert) 10%, var(--mood-invert));
  --brand-ink: var(--brand-on-invert);
  --brand-muted: var(--brand-invert-muted);
  --brand-line: var(--brand-invert-line);
  --brand-accent: var(--brand-invert-accent);
}

/* SIDFOTEN PÅ ETT MÖRKT BRAND KORSAR INTE GÅNGJÄRNET. Sidfoten står i invert-gruppen för att
   den är en kontrastzon, och på de ljusa branden är det rätt: ett mörkt fält avslutar en ljus
   sida. På Substrate är inverten VIT — bruket ligger på andra sidan vändningen — och ett vitt
   fält i botten av en svart sida avslutar ingenting, det ser ut som en annan sajt.
   Stamlaget sa redan vems jobb sidfoten är: `anchor`, "avslutar ett flöde: sidfot". Det mörka
   brandet tar därför anchor — djupaste steget på sin EGEN sida — och läser bläck och accent ur
   de stabila aliasen, för invert-gruppen ovanför har redan pekat om dem. Ett nytt mörkt brand
   lägger sig i den här selektorn; de ljusa rörs inte. */
[data-brand="substrate"] .footer {
  --brand-paper: var(--mood-anchor);
  --brand-surface: var(--mood-raised);
  --brand-ink: var(--mood-ink);
  --brand-muted: color-mix(in srgb, var(--mood-ink) 74%, var(--mood-anchor));
  --brand-line: color-mix(in srgb, var(--mood-ink) 18%, var(--mood-anchor));
  --brand-accent: var(--mood-accent);
}

/* ============================================================
   BRICKORNA — små ytor INUTI flödet
   ============================================================
   Samma mekanism som stamlägena: en klass som pekar om brandtoken för sin del av trädet. Men en
   bricka är inte en grund. Den är ett stycke, inte en sektion, och den svarar på vad påståendet är
   värt — inte på var i flödet läsaren befinner sig.

   EN BRICKA ÄR ETT PAPPER SOM LAGTS PÅ SIDAN. Tvätten blandas mot --mood-paper och bläcket tas
   ur --mood-ink, alltså bär den brandets pappersida i VARJE zon — också inuti ett bruk, där
   --brand-ink annars pekar åt andra hållet och skulle ge vit text på en ljus tvätt (1,27:1).
   Den följer inte grunden den ligger på; den avbryter den. Att i stället låta tvätten följa
   zonen kräver författade bläck för brukssidan, som --brand-invert-accent — ett härlett
   bläck går inte: det som ger etiketten kontrast (5,3:1) drar ihop de tre till dE 15.

   BLÄCKET STANNAR SVART. Det är etiketten som tar brickans röst, inte brödtexten: en hel bricka
   satt i larmrött läses som en bild, inte som en mening. Därför pekas --brand-primary och
   --section om (så en kicker inuti brickan bär brickans färg och inte avdelningens), medan
   --brand-ink lämnas i fred.

   TAKET ÄR EN DEL AV DESIGNEN. Högst en bricka per artefakt. De är starka för att de nästan aldrig
   syns — samma regel som `invert`. En bricka anger vad ORDERN kan bevisa, aldrig vad skribenten
   vill betona; utan den regeln är `larm` en betoningsknapp och betyder ingenting inom en vecka.
   ============================================================ */
.tile--confirmed,
.tile--caution,
.tile--alarm {
  background: var(--brand-paper);
  color: var(--brand-ink);
  border-left: 3px solid var(--tile);
  padding: var(--space-4) var(--space-5);
  margin: var(--space-5) 0;
}
.tile--confirmed .kicker,
.tile--caution .kicker,
.tile--alarm .kicker { color: var(--tile); }

.tile--confirmed {
  --tile: var(--tile-confirmed);
  --brand-paper: color-mix(in srgb, var(--tile-confirmed) 14%, var(--mood-paper));
  --brand-ink: var(--mood-ink);
  --brand-primary: var(--tile-confirmed);
  --section: var(--tile-confirmed);
  --brand-muted: color-mix(in srgb, var(--brand-ink) 74%, var(--brand-paper));
  --brand-line: color-mix(in srgb, var(--tile-confirmed) 40%, var(--brand-paper));
}
.tile--caution {
  --tile: var(--tile-caution);
  --brand-paper: color-mix(in srgb, var(--tile-caution) 14%, var(--mood-paper));
  --brand-ink: var(--mood-ink);
  --brand-primary: var(--tile-caution);
  --section: var(--tile-caution);
  --brand-muted: color-mix(in srgb, var(--brand-ink) 74%, var(--brand-paper));
  --brand-line: color-mix(in srgb, var(--tile-caution) 40%, var(--brand-paper));
}
.tile--alarm {
  --tile: var(--tile-alarm);
  --brand-paper: color-mix(in srgb, var(--tile-alarm) 14%, var(--mood-paper));
  --brand-ink: var(--mood-ink);
  --brand-primary: var(--tile-alarm);
  --section: var(--tile-alarm);
  --brand-muted: color-mix(in srgb, var(--brand-ink) 74%, var(--brand-paper));
  --brand-line: color-mix(in srgb, var(--tile-alarm) 40%, var(--brand-paper));
}

/* ============================================================
   BREAKING TICKER
   ============================================================ */
/* TICKERN ÄR ETT BAND, INTE EN HELOMVÄNDNING.
   Den satt på --brand-ink mot --brand-paper — full inversion, i varje brand, direkt under
   mastheaden. Det var inte en designavsikt utan bristen på ett mellansteg: systemet hade bara
   papper och invert, så allt som ville skilja sig ut måste vända hela vägen. Nu tar den `anchor`,
   som är ett steg ner i samma familj — den läses som en avsats, inte som en annan sajt. */
.ticker {
  background: var(--brand-paper);
  color: var(--brand-ink);
  border-block: 1px solid var(--brand-line);
  display: flex;
  align-items: stretch;
  overflow: hidden;
  font-family: var(--font-headline);
  position: relative;
}
.ticker__label {
  flex-shrink: 0;
  background: var(--brand-primary);
  color: var(--brand-on-primary);
  padding: 0 var(--space-4);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: 800;
  font-size: var(--text-xs);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  position: relative;
  z-index: 2;
}
.ticker__label::after {
  /* slanted edge */
  content: "";
  position: absolute;
  top: 0; right: -14px; bottom: 0;
  width: 14px;
  background: var(--brand-primary);
  clip-path: polygon(0 0, 100% 0, 0 100%);
}
.ticker__pulse {
  width: 8px; height: 8px;
  background: var(--brand-on-primary);
  border-radius: 50%;
  display: inline-block;
  animation: tick-pulse 1.6s ease-in-out infinite;
}
@keyframes tick-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.4; transform: scale(0.7); }
}
.ticker__viewport {
  flex: 1;
  overflow: hidden;
  position: relative;
  display: flex;
  align-items: center;
}
.ticker__track {
  display: flex;
  gap: var(--space-7);
  white-space: nowrap;
  padding-left: var(--space-5);
  animation: ticker-scroll 60s linear infinite;
}
@keyframes ticker-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
.ticker__item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--brand-ink);
  text-decoration: none;
  padding: 12px 0;
}
.ticker__item:hover { color: var(--brand-accent); }
.ticker__time {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  /* Accenten satt här när bandet var svart — gul på nästan svart. På en ljus grund blir samma
     gul oläslig. Signalfärgen är den som är tonad för att sitta på papper. */
  color: var(--brand-primary);
  font-weight: 600;
}
.ticker__dot {
  width: 4px; height: 4px;
  background: var(--brand-muted);
  border-radius: 50%;
  flex-shrink: 0;
}
.ticker__viewport::after {
  /* fade right edge */
  content: "";
  position: absolute;
  right: 0; top: 0; bottom: 0;
  width: 80px;
  background: linear-gradient(to right, transparent, var(--brand-paper));
  pointer-events: none;
}

/* ============================================================
   PAGE LAYOUT
   ============================================================ */
.page-wrap {
  max-width: var(--col-bleed);
  margin: 0 auto;
  padding: var(--space-6) var(--gutter);
}
.page-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-8);
  max-width: 1000px;
  margin: 0 auto;
  align-items: start;
}
.page-grid > * { min-width: 0; }   /* prevent grid children from overflowing */

/* ============================================================
   SECTION HEADER
   ============================================================ */
.section-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  /* 96 över, 16 under. Det var 48/24 — alltså exakt lika mycket UNDER rubriken som mellan två
     kort, så rubriken flöt mitt emellan i stället för att äga blocket under sig. Vitrum bär
     hierarki bara när förhållandet är stort; är varje mellanrum lika stort bär det ingenting. */
  margin: var(--space-9) 0 var(--space-4);
  padding-top: var(--space-3);
  border-top: 3px solid var(--brand-ink);
}
.section-header__title {
  font-family: var(--brand-display-font);
  font-weight: var(--brand-display-weight);
  text-transform: var(--brand-display-case);
  letter-spacing: var(--brand-display-tracking);
  font-size: clamp(1.75rem, 3.2vw, 2.5rem);
  line-height: 1;
  margin: 0;
}
.section-header__title .accent {
  color: var(--brand-primary);
}
.section-header__more {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--brand-ink);
  text-decoration: none;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}
.section-header__more:hover { color: var(--brand-primary); }

/* ============================================================
   HERO CARD (front-page lead story)
   ============================================================ */
.hero-card {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: var(--space-6);
  padding: var(--space-6) 0 var(--space-7);
  border-bottom: 1px solid var(--brand-line);
  text-decoration: none;
  color: inherit;
}
@media (max-width: 760px) {
  .hero-card { grid-template-columns: 1fr; gap: var(--space-4); margin: 0 calc(-1 * var(--gutter)); padding: 0 0 var(--space-6); border-bottom: 0; }
  .hero-card__body { padding: 0 var(--gutter); }
}
.hero-card__art {
  aspect-ratio: 4 / 3;
  background: var(--brand-ink);
  position: relative;
  overflow: hidden;
  color: var(--brand-primary);
}
.hero-card__art > svg { width: 100%; height: 100%; }
.hero-card__art > img { width: 100%; height: 100%; object-fit: cover; }
.hero-card__live {
  position: absolute;
  top: var(--space-3); left: var(--space-3);
  background: var(--brand-primary);
  color: var(--brand-paper);
  padding: 4px 10px;
  font-family: var(--font-headline);
  font-weight: 800;
  font-size: var(--text-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  display: inline-flex; align-items: center; gap: 6px;
}
.hero-card__live::before {
  content: "";
  width: 7px; height: 7px;
  background: var(--brand-paper);
  border-radius: 50%;
  animation: tick-pulse 1.6s infinite;
}
.hero-card__body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-4);
}
.hero-card__kickline {
  display: flex; gap: var(--space-3);
  align-items: center;
  flex-wrap: wrap;
}
.hero-card__title {
  font-family: var(--brand-display-font);
  font-weight: var(--brand-display-weight);
  text-transform: var(--brand-display-case);
  letter-spacing: var(--brand-display-tracking);
  line-height: var(--leading-none);
  font-size: clamp(0.9rem, 2.08vw, 1.7rem);
  margin: 0;
  color: var(--brand-ink);
  text-wrap: balance;
}
[data-brand="ledger"] .hero-card__title {
  font-size: clamp(0.8rem, 1.76vw, 1.4rem);
  line-height: var(--leading-tight);
}
.hero-card__lede {
  font-family: var(--font-serif);
  font-size: clamp(1.0625rem, 1.4vw, 1.25rem);
  line-height: var(--leading-snug);
  color: var(--brand-ink);
  margin: 0;
  text-wrap: pretty;
}
[data-brand="vector"] .hero-card__lede { font-family: var(--font-body); }
.hero-card__meta {
  display: flex; gap: var(--space-3); align-items: center;
  margin-top: var(--space-2);
}
.hero-card__meta strong { font-weight: 700; color: var(--brand-ink); }

/* ============================================================
   ARTICLE GRID — tolv kolumner, spann på barnet
   12 kolumner desktop · 4 under 1024 · 1 under 641
   Artefaktens syskon är .art-grid i article.css: samma tolv
   kolumner, samma trösklar, men frågade av behållaren.
   ============================================================ */
.grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--gap-grid);
}
.grid > * {
  min-width: 0;                       /* annars spränger långa ord kolumnen */
  grid-column: span var(--span, 4);
}

/* A row reads as a band only if every card ends on the same line. The grid
   stretches the wrapper div to the row height; the <a> inside it takes only
   its content height unless told to fill. The byline already sits on
   margin-top:auto, so the slack lands above it. */
.grid > * > .story { height: 100%; }

/* Spannen, namngivna efter vad de ÄR på sidan — inte efter hur många kolumner de tar, för det
   talet ändras med brytpunkten och namnet ska inte göra det. */
.grid__item--lead    { --span: 12; }
.grid__item--feature { --span: 6; }
.grid__item--narrow  { --span: 4; }
.grid__item--half    { --span: 6; }   /* används av author.hbs */
.grid__item--wide    { --span: 8; }
.grid__item--full    { --span: 12; }

/* RYTMEN ÄR CSS:ENS, INTE MALLENS.
   Mallen försökte {{#match @index "%" 5 "==" 0}}. Ghosts match kan =, !=, < och > med tre
   argument — inte %, inte fem — och svarar då tyst nej, så varje kort blev smalt och varje
   rutnät en tegelvägg. Positionen känner CSS redan, utan helper: 5n+1 och 5n+2 halvbreda
   (6+6), 5n+3…5n+5 tredjedelar (4+4+4), och båda går ihop till tolv kolumner så varje rad
   blir hel. Rytmen gäller RUTNÄTET och SVANSEN; axeln är ett band av tre och förblir det.

   BRYTARNA STÅR FÖRST OCH TAR RYTMENS TVÅ BREDA PLATSER. Därför frågar rutnätet efter högst
   två brytare: en tredje hade fått en tredjedelsplats, och en w3 på en smal plats säger
   emot sin vikt.

   SISTA RADEN PACKAS. Ett ensamt kort hade lämnat halva raden tom: ett ensamt 5n+1 eller
   5n+3 tar hela raden, och står två kvar på en tredjedelsrad tar de var sin halva. Så
   packar varje antal, och "Hämta fler" kan fylla på i svansen utan att räkna. */
.grid--rhythm > :nth-child(5n+1),
.grid--rhythm > :nth-child(5n+2) { --span: 6; }
.grid--rhythm > :nth-child(5n+1):last-child,
.grid--rhythm > :nth-child(5n+3):last-child { --span: 12; }
.grid--rhythm > :nth-child(5n+3):nth-last-child(2),
.grid--rhythm > :nth-child(5n+4):last-child { --span: 6; }

/* Det ensamma kortet som tar hela raden LIGGER NER: bilden till vänster, texten till höger.
   Stående över tolv kolumner blev bilden en vägg — en tredjedelsbild uppskalad tre gånger,
   utan att vara ett led. Liggande är det ett brett kort, vilket är vad raden bad om. */
.grid--rhythm > :is(:nth-child(5n+1), :nth-child(5n+3)):last-child > .story,
.grid__item--full > .story {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  grid-template-rows: auto auto 1fr auto;
  column-gap: var(--gap-grid);
  align-items: start;
}
.grid--rhythm > :is(:nth-child(5n+1), :nth-child(5n+3)):last-child > .story > .story__art,
.grid__item--full > .story > .story__art {
  grid-row: 1 / -1;
  margin-bottom: 0;
}
.grid--rhythm > :is(:nth-child(5n+1), :nth-child(5n+3)):last-child > .story > :not(.story__art),
.grid__item--full > .story > :not(.story__art) {
  grid-column: 2;
}
@media (max-width: 640px) {
  .grid--rhythm > :is(:nth-child(5n+1), :nth-child(5n+3)):last-child > .story,
  .grid__item--full > .story { display: flex; }
}

/* SEKTIONSBANDETS TOPP (partials/front-band.hbs) är samma liggande kort, men vald — inte packad:
   bandets första kort är avdelningens etta (featured) och tar hela raden med flit, de tre under
   är tredjedelar. Platsen ges av klassen, för här är positionen ett redaktionellt beslut. */
.band .section-header__title a { color: inherit; text-decoration: none; }
.band .section-header__title a:hover { color: var(--section, var(--brand-primary)); }

@media (max-width: 1023px) {
  /* Två spalter: en tredjedel blir en halva, allt större blir helt. */
  .grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .grid > * { grid-column: span 2; }
  .grid__item--lead,
  .grid__item--feature,
  .grid__item--wide,
  .grid__item--full,
  .grid--rhythm > :nth-child(5n+1),
  .grid--rhythm > :nth-child(5n+2) { grid-column: span 4; }
}
@media (max-width: 640px) {
  .grid { grid-template-columns: minmax(0, 1fr); }
  .grid > * { grid-column: span 1 !important; }
}

/* STORYKORTET ÄR INGEN BOX.
   Det var en: ram, 6 px radie, skugga vid hover och ett lyft. tokens.css säger själv "RADII —
   minimal; this is editorial, not SaaS", och kortet struntade i det. Ingen kvalitetstidning
   boxar in sina förstasidesartiklar — Guardian, NYT, FT och Economist separerar med en hårlinje
   eller med ingenting alls utom vitrum och bildens kant. Ramen lade dessutom till en synlig
   rektangel per kort som konkurrerade med bilden inuti.
   Kvar är EN linje: sektionens, över kortet. Den bär färgen och gör radbrytningen läsbar. */
.story {
  display: flex;
  flex-direction: column;
  text-decoration: none;
  color: inherit;
  border-top: 3px solid var(--section, var(--brand-line));
  padding-top: var(--space-3);
  background: transparent;
  max-width: 100%;
  min-width: 0;
  box-sizing: border-box;
}
/* Hovern byter rubrikfärg och ingenting annat — se .story:hover .story__title nedan. */

/* Art fills the card width, fixed aspect ratio */
.story__art {
  aspect-ratio: 16 / 10;
  background: var(--brand-surface);
  color: var(--section, var(--brand-muted));
  overflow: hidden;
  width: 100%;
  margin-bottom: var(--space-3);
}
.story__art > svg { width: 100%; height: 100%; }
.story__art > img { width: 100%; height: 100%; object-fit: cover; }
/* Platshållaren är tyst. Ytan är papprets granne, och linjekonsten ritas i sektionens färg
   via currentColor — så en bildlös artikel bär samma signal som en med bild, i stället för att
   bli sidans starkaste färgfält. */

/* Text content sits inside the card with padding */
.story__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: 0;
  flex: 1;
}

/* Ingen box, alltså ingen inre marginal som håller texten borta från en ram. Kortets kant ÄR
   linjens och bildens; texten står i liv med båda. */
.story__kickline { padding-top: 0; }

.story__kickline {
  display: flex;
  gap: var(--space-3);
  align-items: center;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
/* SEKTIONEN LÄSES HÄR, INTE SOM EN HEX. --section sätts av regeln i default.hbs ur
   Design → section_1..6; en sektion som inte står i listan faller tillbaka på signalfärgen.
   Färgen är skiljetecken, aldrig fyllning: kickern och hårlinjen, aldrig rubriken eller
   en yta bakom text. */
.story__kickline .kicker { color: var(--section, var(--brand-primary)); font-weight: 600; }
.feature-card__kickline .kicker,
.hero-card__kickline .kicker { color: var(--section, var(--brand-primary)); }
.story__kickline .time { color: var(--brand-muted); font-weight: 500; }

/* ─── Typfärgerna (2026-09-05) ───────────────────────────────────────────────
   Kickern bär artefakttypen (partials/type-label.hbs, data-type ur typregistret) och
   färgkodas per FAMILJ ur den kategoriska paletten i tokens.css — samma system som
   graferna, retokenat per brand. Nyhetsfamiljen (nyhet/fördjupning/notis) behåller
   sektionsfärgen ovan: nyheten ÄR sektionen, det är specialformerna som ska sticka ut.
   -700-tonen är vald för läsbarhet som text på papper; en familj = en hue, aldrig en
   färg per typ — sjutton färger är ingen kod, det är konfetti. */
.kicker[data-type] { font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; }
.kicker[data-type="car-review"],
.kicker[data-type="product-review"],
.kicker[data-type="destination-review"] { color: var(--cat-2-700); }
.kicker[data-type="tech-explainer"],
.kicker[data-type="owner-guide"],
.kicker[data-type="place-guide"],
.kicker[data-type="destination-guide"] { color: var(--cat-3-700); }
.kicker[data-type="company-analysis"],
.kicker[data-type="person-dossier"],
.kicker[data-type="org-dossier"],
.kicker[data-type="place-profile"] { color: var(--cat-4-700); }
.kicker[data-type="comparison"] { color: var(--cat-5-700); }
.kicker[data-type="exposition"],
.kicker[data-type="theme"] { color: var(--cat-6-700); }

.story__title {
  font-family: var(--font-headline);
  font-weight: 800;
  font-size: clamp(1.125rem, 1.5vw, 1.4rem);
  line-height: 1.2;
  margin: 0;
  color: var(--brand-ink);
  text-wrap: balance;
}
[data-brand="ledger"] .story__title { font-family: var(--font-serif); font-weight: 700; }

/* Ett halvbrett kort bär en större rubrik än en tredjedel. Storleken styrs av PLATSEN, inte av
   en modifierare på kortet: rytmen är rutnätets beslut, och kortet ska inte behöva veta var det
   hamnade. Utan den här raden ser en tvåspaltsrad ut som en tredjedel som råkat bli bred. */
.story--wide .story__title,
.grid__item--feature > .story .story__title,
.grid__item--half > .story .story__title,
.grid--rhythm > :nth-child(5n+1) > .story .story__title,
.grid--rhythm > :nth-child(5n+2) > .story .story__title,
.grid--rhythm > :nth-child(5n+3):last-child > .story .story__title,
.grid--rhythm > :nth-child(5n+3):nth-last-child(2) > .story .story__title,
.grid--rhythm > :nth-child(5n+4):last-child > .story .story__title,
.grid__item--full > .story .story__title { font-size: clamp(1.5rem, 2.4vw, 2rem); }
.story__excerpt {
  font-family: var(--font-serif);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
  color: var(--brand-muted);
  margin: 0;
  text-wrap: pretty;
}
[data-brand="vector"] .story__excerpt { font-family: var(--font-body); }
.story__byline {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--brand-muted);
  margin-top: auto;
}
.story:hover .story__title { color: var(--brand-primary); }

/* Featured horizontal "fördjupning" card */
.feature-card {
  display: grid;
  grid-template-columns: 1fr 1.2fr;
  gap: 0;
  text-decoration: none;
  color: inherit;
  background: var(--brand-paper);
  border: 1px solid var(--brand-line);
  overflow: hidden;
}
.feature-card + .feature-card { margin-top: var(--space-5); }
@media (max-width: 640px) {
  .feature-card { grid-template-columns: 1fr; }
}
.feature-card__art {
  aspect-ratio: 4 / 3;
  background: var(--brand-ink);
  color: var(--brand-primary);
  overflow: hidden;
}
[data-brand="ledger"] .feature-card__art { background: var(--brand-surface); color: var(--brand-primary); }
.feature-card__art > svg { width: 100%; height: 100%; }
.feature-card__art > img { width: 100%; height: 100%; object-fit: cover; }
.feature-card__body {
  padding: var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  justify-content: center;
}
.feature-card__title {
  font-family: var(--brand-display-font);
  font-weight: var(--brand-display-weight);
  text-transform: var(--brand-display-case);
  letter-spacing: var(--brand-display-tracking);
  line-height: var(--leading-tight);
  font-size: clamp(1.5rem, 2.6vw, 2.25rem);
  margin: 0;
  text-wrap: balance;
}
.feature-card__lede {
  font-family: var(--font-serif);
  font-size: var(--text-base);
  line-height: 1.55;
  color: var(--brand-ink);
  margin: 0;
  text-wrap: pretty;
}
[data-brand="vector"] .feature-card__lede { font-family: var(--font-body); }
.feature-card__meta {
  display: flex; gap: var(--space-3); align-items: center;
  margin-top: var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--brand-muted);
}
@media (max-width: 760px) {
  .feature-card { grid-template-columns: 1fr; }
}

/* ============================================================
   SIDEBAR
   ============================================================ */
.sidebar { display: flex; flex-direction: column; gap: var(--space-6); }
@media (min-width: 1024px) {
  .sidebar { position: sticky; top: 96px; }
}
.sidebar__section {
  border-top: 3px solid var(--brand-ink);
  padding-top: var(--space-3);
}
.sidebar__head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: var(--space-3);
}
.sidebar__title {
  font-family: var(--font-headline);
  font-weight: 800;
  font-size: var(--text-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  margin: 0;
  color: var(--brand-ink);
}
.sidebar__title .accent { color: var(--brand-primary); }

/* Story badges (live topics) */
.topic-stack { display: flex; flex-direction: column; gap: var(--space-2); }
.topic {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-3);
  background: var(--brand-paper);
  border: 1px solid var(--brand-line);
  text-decoration: none;
  color: inherit;
  transition: all 120ms;
}
.topic:hover { border-color: var(--brand-ink); }
.topic__heat {
  width: 6px;
  align-self: stretch;
  background: var(--brand-primary);
  flex-shrink: 0;
}
.topic[data-heat="hot"] .topic__heat { background: var(--brand-primary); }
.topic[data-heat="warm"] .topic__heat { background: var(--brand-accent); }
.topic[data-heat="cool"] .topic__heat { background: var(--brand-line); }

.topic__body { flex: 1; display: flex; flex-direction: column; gap: 2px; }
.topic__label {
  font-family: var(--font-headline);
  font-weight: 800;
  font-size: var(--text-sm);
  letter-spacing: 0.04em;
  color: var(--brand-ink);
  line-height: 1.2;
}
.topic__meta {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--brand-muted);
}
.topic__count {
  font-family: var(--brand-display-font, var(--font-headline));
  font-weight: var(--brand-display-weight, 800);
  text-transform: var(--brand-display-case, uppercase);
  font-size: var(--text-2xl);
  line-height: 1;
  color: var(--brand-primary);
  flex-shrink: 0;
}

/* Notis list — compact */
/* ============================================================
   STORYPAKETET — ledets förlopp
   ============================================================
   Ingen egen box och ingen ram: paketet är en FORTSÄTTNING på ledet, inte ett block bredvid det.
   En hårlinje i sektionens färg binder ihop dem, och listan står indragen så ögat läser den som
   underordnad rubriken ovanför i stället för som en ny avdelning.
   Behållaren är `hidden` tills JS gett den något — se initStoryPackage. */
.package {
  margin: var(--space-5) 0 var(--space-8);
  padding-left: var(--space-5);
  border-left: 3px solid var(--section, var(--brand-line));
}
.package[hidden] { display: none; }
.package__head {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-widest);
  text-transform: uppercase;
  color: var(--brand-muted);
  font-weight: 600;
  margin: 0 0 var(--space-3);
}
.package__list .notis-list__item { padding: var(--space-2) 0; }

.notis-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.notis-list__item {
  display: grid;
  grid-template-columns: 56px 1fr;
  gap: var(--space-3);
  align-items: start;
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--brand-line);
  text-decoration: none;
  color: inherit;
}
.notis-list__item:first-child { padding-top: 0; }
.notis-list__item:last-child { border-bottom: 0; }
/* Datum över klockslag, i samma 56 px-kolumn. Ett blott klockslag är sant bara där sammanhanget
   garanterar "i dag" — tickern gör det, en notislista i ett arkiv gör det inte. */
.notis-list__time {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
  color: var(--brand-primary);
  font-weight: 600;
  padding-top: 2px;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.notis-list__date {
  color: var(--brand-muted);
  font-weight: 500;
  white-space: nowrap;
}
.notis-list__title {
  font-family: var(--font-headline);
  font-weight: 700;
  font-size: var(--text-sm);
  line-height: 1.3;
  color: var(--brand-ink);
  margin: 0;
}
[data-brand="ledger"] .notis-list__title { font-family: var(--font-serif); }
.notis-list__kicker {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--brand-muted);
  display: block;
  margin-bottom: 2px;
}
.notis-list__item:hover .notis-list__title { color: var(--brand-primary); }

/* NOTISLISTAN PÅ FÖRSTASIDAN: två spalter på desktop, tio synliga.
   Zonen frågar efter tio; reservvägens lista frågar efter trettio och visar tio i taget
   med sin knapp. En spalt om fem fyllde inte bredden — det var en sidopanel utan sida. */
.front-notiser {
  margin-bottom: var(--space-8);
  border-bottom: 1px solid var(--brand-line);
  padding-bottom: var(--space-6);
}
.front-notiser__list {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0 var(--space-6);
}
@media (min-width: 760px) {
  .front-notiser__list { grid-template-columns: 1fr 1fr; }
}
.front-notiser__list > li { display: none; }
.front-notiser__list > li:nth-child(-n+10) { display: block; }
.front-notiser__btn { display: block; margin: var(--space-6) auto 0; }

/* "Hämta fler" — samma knapp som resten av sajten (.iconbtn), centrerad under svansen. */
.load-more { text-align: center; margin: var(--space-7) 0 var(--space-4); }
.load-more__btn[hidden] { display: none; }

/* Tag cloud */
.tag-cloud { display: flex; flex-wrap: wrap; gap: 6px; }
.tag {
  font-family: var(--font-headline);
  font-weight: 700;
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 6px 10px;
  background: var(--brand-paper);
  border: 1px solid var(--brand-line);
  color: var(--brand-ink);
  text-decoration: none;
}
.tag:hover { border-color: var(--brand-ink); }
.tag--lg { font-size: var(--text-sm); padding: 8px 14px; }
.tag--xl { font-size: var(--text-base); padding: 10px 16px; }
.tag--accent { background: var(--brand-ink); color: var(--brand-paper); border-color: var(--brand-ink); }
.tag .count {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--brand-primary);
  margin-left: 6px;
  vertical-align: top;
  font-weight: 600;
}
.tag--accent .count { color: var(--brand-accent); }

/* ============================================================
   FILTER BAR
   ============================================================ */
.filter-bar {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  border-top: 1px solid var(--brand-line);
  border-bottom: 1px solid var(--brand-line);
  padding: var(--space-3) 0;
  margin: var(--space-5) 0 var(--space-6);
  font-family: var(--font-headline);
  flex-wrap: wrap;
}
.filter-bar__label {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--brand-muted);
  font-weight: 600;
  margin-right: var(--space-3);
}
.filter-bar__chip {
  font-family: var(--font-headline);
  font-weight: 700;
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 8px 14px;
  background: transparent;
  border: 1px solid var(--brand-line);
  color: var(--brand-ink);
  text-decoration: none;
  cursor: pointer;
}
.filter-bar__chip:hover { border-color: var(--brand-ink); }
.filter-bar__chip.is-active {
  background: var(--brand-ink);
  color: var(--brand-paper);
  border-color: var(--brand-ink);
}
.filter-bar__count {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--brand-muted);
}

/* ============================================================
   PAGE HEADER (tag/category)
   ============================================================ */
.page-head {
  padding: var(--space-7) 0 var(--space-5);
  border-bottom: 3px solid var(--brand-ink);
}
.page-head__crumbs {
  display: flex; gap: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--brand-muted);
  margin-bottom: var(--space-4);
}
.page-head__crumbs a { color: inherit; text-decoration: none; }
.page-head__crumbs a:hover { color: var(--brand-primary); }
.page-head__title {
  font-family: var(--brand-display-font);
  font-weight: var(--brand-display-weight);
  text-transform: var(--brand-display-case);
  letter-spacing: var(--brand-display-tracking);
  font-size: clamp(3rem, 7vw, 6rem);
  line-height: var(--leading-none);
  margin: 0 0 var(--space-3);
  color: var(--brand-ink);
}
.page-head__title .count {
  color: var(--brand-primary);
  font-feature-settings: "tnum";
  margin-left: var(--space-3);
}
.page-head__lede {
  font-family: var(--font-serif);
  font-size: var(--text-lg);
  line-height: 1.55;
  color: var(--brand-ink);
  max-width: 60ch;
  margin: 0 0 var(--space-3);
}

/* ============================================================
   PREV / NEXT navigation
   ============================================================ */
.prevnext {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  border-top: 3px solid var(--brand-ink);
  border-bottom: 1px solid var(--brand-line);
  margin: var(--space-7) 0 var(--space-6);
}
.prevnext > a {
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  text-decoration: none;
  color: inherit;
  border-left: 1px solid var(--brand-line);
}
.prevnext > a:first-child { border-left: 0; border-right: 1px solid var(--brand-line); }
.prevnext__dir {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--brand-primary);
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 6px;
}
.prevnext__kicker {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--brand-muted);
}
.prevnext__title {
  font-family: var(--font-headline);
  font-weight: 800;
  font-size: var(--text-lg);
  line-height: 1.25;
  color: var(--brand-ink);
  margin: 0;
}
[data-brand="ledger"] .prevnext__title { font-family: var(--font-serif); font-weight: 700; }
.prevnext__next { text-align: right; }
.prevnext__next .prevnext__dir { justify-content: flex-end; }
.prevnext > a:hover .prevnext__title { color: var(--brand-primary); }
@media (max-width: 760px) {
  .prevnext { grid-template-columns: 1fr; }
  .prevnext > a:first-child { border-right: 0; border-bottom: 1px solid var(--brand-line); }
}

/* ============================================================
   TABLE OF CONTENTS (fördjupning sidebar)
   ============================================================ */
.toc {
  display: flex;
  flex-direction: column;
}
.toc__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}
.toc__list li {
  border-left: 2px solid var(--brand-line);
  padding: 6px 0 6px var(--space-3);
  margin-left: 0;
  position: relative;
}
.toc__list li.is-active {
  border-left-color: var(--brand-primary);
}
.toc__list a {
  font-family: var(--font-headline);
  font-weight: 700;
  font-size: var(--text-sm);
  line-height: 1.3;
  color: var(--brand-muted);
  text-decoration: none;
  display: block;
}
[data-brand="ledger"] .toc__list a { font-family: var(--font-serif); }
.toc__list li.is-active a { color: var(--brand-ink); }
.toc__list a:hover { color: var(--brand-ink); }
.toc__list .toc__num {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  color: var(--brand-primary);
  display: block;
  margin-bottom: 2px;
  font-weight: 600;
}

/* .ai-disclosure ags av instruments.css (en definition, bagge ytorna). */

/* ============================================================
   NOTIS PAGE — minimal column
   ============================================================ */
.notis-page {
  max-width: 600px;
  margin: 0 auto;
  padding: var(--space-7) var(--gutter);
}
.notis-page__head {
  margin-bottom: var(--space-5);
}
.notis-page__title {
  font-family: var(--brand-display-font);
  font-weight: var(--brand-display-weight);
  text-transform: var(--brand-display-case);
  letter-spacing: var(--brand-display-tracking);
  font-size: clamp(1.75rem, 3.6vw, 2.5rem);
  line-height: var(--leading-tight);
  margin: var(--space-3) 0 var(--space-4);
  color: var(--brand-ink);
  text-wrap: balance;
}
.notis-page__body {
  font-family: var(--font-serif);
  font-size: var(--text-base);
  line-height: 1.7;
  color: var(--brand-ink);
}
[data-brand="vector"] .notis-page__body { font-family: var(--font-body); }
.notis-page__body p { margin: 0 0 var(--space-4); text-wrap: pretty; }
.notis-page__rule {
  border: 0;
  border-top: 1px solid var(--brand-line);
  margin: var(--space-5) 0;
}

/* ============================================================
   ARTICLE SIDEBAR (Ledger / vector article)
   ============================================================ */
.article-sidebar {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}
@media (min-width: 1024px) {
  .article-sidebar {
    position: sticky;
    top: 96px;
  }
}
.article-shell {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-8);
  /* Sidmåttet, inte ett eget tal: 1200 var varken --col-page (1280) eller --col-wide (960),
     och .bleed__inner går till --col-page — blödningen kunde aldrig bli bredare än skalet. */
  max-width: var(--col-page);
  margin: 0 auto;
  padding: var(--space-6) var(--gutter);
  align-items: start;
}
.article-shell__main { min-width: 0; }
.article-shell__main .article__head,
.article-shell__main .article__body,
.article-shell__main .article__hero {
  max-width: 100%;
  margin-left: auto;
  margin-right: auto;
}
.article-shell__main .article__hero { margin-bottom: var(--space-6); }
.article-shell--wide { max-width: var(--col-page); }
.article-shell--wide .article-shell__main .article__head,
.article-shell--wide .article-shell__main .article__body,
.article-shell--wide .article-shell__main .article__hero {
  max-width: 100%;
}

/* ============================================================
   PAGINATION
   ============================================================ */
.pagination {
  display: flex;
  justify-content: center;
  gap: var(--space-2);
  margin: var(--space-7) 0;
  padding-top: var(--space-5);
  border-top: 1px solid var(--brand-line);
}
.pagination a, .pagination span {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  padding: 10px 16px;
  border: 1px solid var(--brand-line);
  text-decoration: none;
  color: var(--brand-ink);
  font-weight: 600;
}
.pagination a:hover { border-color: var(--brand-ink); }
.pagination .is-active {
  background: var(--brand-ink);
  color: var(--brand-paper);
  border-color: var(--brand-ink);
}
.pagination .ellipsis { border-color: transparent; color: var(--brand-muted); }

/* ============================================================
   TWEAKS PANEL (brand switcher)
   Floating control pinned to lower-right.
   ============================================================ */
.tweaks {
  position: fixed;
  right: 16px;
  bottom: 16px;
  background: var(--brand-invert);
  color: var(--brand-on-invert);
  border-radius: 8px;
  padding: 10px;
  z-index: 200;
  box-shadow: 0 16px 40px rgba(0,0,0,0.35);
  font-family: var(--font-mono);
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 220px;
}
.tweaks__title {
  font-size: var(--text-xs);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--brand-on-invert) 55%, transparent);
  font-weight: 600;
}
.tweaks__row { display: flex; gap: 4px; }
.tweaks__btn {
  flex: 1;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  padding: 8px 10px;
  border: 0;
  border-radius: 6px;
  background: color-mix(in srgb, var(--brand-on-invert) 8%, transparent);
  color: var(--brand-on-invert);
  cursor: pointer;
  font-weight: 600;
}
.tweaks__btn:hover { background: color-mix(in srgb, var(--brand-on-invert) 16%, transparent); }
.tweaks__btn.is-active {
  background: var(--brand-primary);
  color: var(--brand-on-primary);
}

/* ============================================================
   BRAND COMPARE GRID (used by masthead/footer demo pages)
   ============================================================ */
.compare {
  display: flex;
  flex-direction: column;
  gap: 0;
}
.compare__panel {
  border-top: 3px solid var(--brand-ink);
  padding: var(--space-5) var(--gutter) var(--space-7);
}
.compare__panel:first-child { border-top: 0; }
.compare__label {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--brand-muted);
  margin-bottom: var(--space-4);
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.compare__swatch {
  width: 14px; height: 14px;
  background: var(--brand-primary);
}

/* Visual hint styles for component-only demos */
.demo-frame {
  background: var(--brand-surface);
  padding: var(--space-5);
  border: 1px solid var(--brand-line);
}

/* ============================================================
   BOTTOM WIDGETS (Tags & Topics moved from sidebar)
   ============================================================ */
.bottom-widgets {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-6);
  margin-top: var(--space-8);
  padding-top: var(--space-6);
  border-top: 2px solid var(--brand-ink);
}
.bottom-widgets .sidebar__section {
  border-top: 0;
  padding-top: 0;
}
@media (max-width: 640px) {
  .bottom-widgets { grid-template-columns: 1fr; }
}

.badge-internal ~ .badge-internal { display: none; }
