:root {
  /* TELEFONENS STATUSRAD (Pers fynd 2026-09-30, i mobilappen). viewport-fit=
     cover låter sidan rita ända upp under klockan och batteriet. Två källor,
     den största vinner: env() från webbläsaren, och variabeln som
     mobilappens skal (Capacitor) sätter på <html> - env() har varit opålitlig
     i Androids WebView. I en vanlig webbläsare är båda 0. Kartan använder den
     också (live.css) men har egen padding och fyller hela ytan. */
  --statusrad: max(env(safe-area-inset-top), var(--safe-area-inset-top, 0px));
  --bg:           #0f1117;
  --surface:      #1c1f2a;
  --border:       #2a2d3a;
  --border-input: #3a3d4a;
  /* FALTEN. Ett falt sag tidigare ut som sin bakgrund: den variant varenda
     redigeringsvy da anvande (.field-input.compact, borttagen 2026-09-20 nar
     appen fick EN faltstorlek) fyllde med --bg, alltsa exakt sidans farg, och
     ramen (#d0d0d8 i ljust lage) var sa svag att ingenting sa att man kunde
     skriva dar (anvandarens iakttagelse 2026-09-06).

     Tva signaler i stallet for en halv: en fyllning som skiljer sig fran BADE
     sidan och kortet, och en ram med tillrackligt hog kontrast for att synas
     som en ram (~3:1, WCAG 1.4.11 for gransnittsdelar). Egna variabler och
     inte --border-input: den halls kvar for listrader, popovers och piller,
     som INTE ska bli lika kraftiga som ett falt. */
  --field-bg:     #14171f;
  --field-border: #767c8c;
  /* Knappen ar inte ett falt. Med samma fyllning som --surface var en
     sekundarknapp omojlig att skilja fran ett textfalt bredvid ("Redigera
     bana" i Andra tavling). Knappen far en TONAD yta, faltet en ljus. */
  --btn-bg:       #262a36;
  --text:         #e0e0e0;
  --text-muted:   #888;
  --text-heading: #fff;
  --accent:       #4ade80;
  --accent-hover: #22c55e;
  --red:          #f87171;
  /* VARNING, före rött: nära en gräns men inte över (reptiderna, 2026-09-25). */
  --varning:      #fbbf24;
  /* Sidonavigeringens bredd fran 541px och uppat. Lag tidigare hardkodad som
     120px/144px i app.css, settings.css och live.py var for sig - byt har. */
  --nav-width:    104px;
  --nav-gutter:   calc(var(--nav-width) + 24px);
  --radius-sm:    6px;
  --radius-md:    8px;
  --radius-lg:    12px;
  --radius-xl:    16px;
  /* SKUGGORNA, fyra syften (2026-09-21). Har lag elva varden for samma sak:
     samma skugga fanns fem ganger med tva skrivsatt (.35 och 0.35), och arkets
     skugga i tva varianter som skilde 4px. Ingen hade valt det - det hade vaxt.
     Ljust lage anvander samma varden som morkt tills nagon matt att de behover
     vara svagare; det ar en egen fraga och inte en del av normaliseringen. */
  --skugga-ark:    0 -6px 20px rgba(0,0,0,.25);   /* ett ark som reser sig underifran */
  --skugga-lyft:   0 4px 16px rgba(0,0,0,.35);    /* meny, toast, popover over sidan */
  --skugga-knapp:  0 2px 10px rgba(0,0,0,.3);     /* flytande knapp pa kartan */
  /* KARTANS KONTROLLER (Pers beslut 2026-10-05): kartan ar alltid ljus, och i
     morkt lage gav --surface nastan svarta knappar ovanpa den - en hard kontrast
     som drog blicken. En dampad, lite genomskinlig skiffergra i stallet, egen
     sa att den kan justeras utan att resten av appen andras. I ljust lage ar
     den samma som --surface. */
  --kartkontroll:  rgba(62, 67, 80, 0.88);
  /* Text på en färgad yta - accenten, åkarens färg (2026-10-09). Tre regler
     använde den med #fff som reserv innan den fanns. */
  --on-accent:     #fff;
  /* KLASSNINGENS FÄRGER (klassning.js klassensFärg, 2026-10-09 från
     aktiviteter.css): en per sorts pass, samma i båda färglägena - brickan har
     vit text och egen fyllning. */
  --klass-distans:      #3a7d44;
  --klass-langpass:     #1a5fa8;
  --klass-intervall:    #9b2335;
  --klass-troskel:      #c05a1f;
  --klass-aterhamtning: #5a7a2e;
  --klass-styrka:       #5b3a8c;
  --klass-teknik:       #2a7a7a;
  --klass-test:         #8c3a3a;
  --klass-ovrigt:       #555;
  /* Stravas orange, för deras knapp - riktlinjerna säger att den ska kännas
     igen som Strava och inte som vår (auth.css, 2026-10-06). */
  --strava:       #fc4c02;
  --strava-hover: #e34402;
  --skugga-reglage: 0 1px 3px rgba(0,0,0,.3);     /* reglagets knopp (.field-switch) */
  --skugga-dialog: 0 25px 70px rgba(0,0,0,0.42);  /* det som tar hela skarmen */
  /* Inte en skugga utan LASBARHET mot en kartbild vi inte styr. */
  --kontur-karta:  0 0 2px rgba(0, 0, 0, 0.5);
  /* TEXTROLLERNA (Pers beslut 2026-09-21). Appen hade 20 storlekar i 123
     regler; tre roller tacker det appen faktiskt gor. Namnen beskriver NIVAN i
     hierarkin, inte platsen de uppstod pa - `--text-etikett` hade tvingat fram
     ett nytt namn sa fort metatexten behovde samma matt.
     Rubriken ar en medelvag: sidrubriken krympte fran 1.3rem, vyrubriken vaxte
     fran 1.05. Normal ar faltens storlek, redan beslutad 2026-09-20. */
  --text-rubrik:  1.1rem;   /* sidans namn, vyns namn, avsnittsrubrik */
  --text-normal:  0.85rem;  /* allt man laser och skriver */
  --text-stod:    0.75rem;  /* etiketter, hjalptext, metatext, flikrad */
  --text-nedrakning: 1.6rem; /* enda uttryckliga specialiteten */

  /* LUFTEN, i en stege (2026-09-20, Pers fynd att halvarket var för luftigt och
     att tätheten ska vara konsekvent).
     Måtten fanns redan - 216 padding-, margin- och gap-värden spridda över tolv
     stilmallar - men utan namn, och då blev 14 px lika rimligt som 12 för den
     som skrev näst. Stegen nedan är de tal som faktiskt dominerade: 8 förekom
     41 gånger, 6 sjutton, 10/8/12 ett dussin var.
     Skalan införs för VYERNAS luft, som var det Per reagerade på. Resten av
     appen får växa in i den efter hand - att skriva om alla 216 på en gång vore
     en refaktorering, inte den här rättelsen. */
  --luft-xs:      4px;
  --luft-sm:      8px;
  --luft-md:      12px;
  --luft-lg:      16px;

  /* LUFTEN EFTER EN AVDELARLINJE (Pers fynd 2026-09-21: "Bannamnet står för
     nära fliklinjen"). En linje - flikrad, sektionslinje, rubrikrad - markerar
     en gräns, men avståndet ner till det som står under den ägdes av ingen:
     `.course-panel-body` har `padding: 0 ...`, så gapet blev vad första barnet
     råkade ha för egen täthet. UPPMÄTT: 8px under Information-fliken mot 12,5px
     under Platser och sträckor - samma linje, två olika luft.

     Att bara ge behållaren padding räcker inte. Då blir det 12+8 mot 12+12,5,
     och skillnaden står kvar: den kommer av att .field-row och
     .place-row-summary har olika täthet, och det är RÄTT - inre padding är
     komponentens form. Därför måste den som ritar linjen bära hela luften, och
     första raden inte lägga till sin egen. Samma regel som `.card > :first-child
     { margin-top: 0 }` redan är, fast generaliserad från kort till varje gräns.

     Ett värde i hela appen (Pers beslut 2026-09-21). Det stod i fyra:
     .edit-view-footer 16, .sort-dir-toggle 12, .trim-consequences 10 och
     .action-menu-group 6 - fyra regler, samma uppgift, fyra tal. */
  --luft-efter-linje: var(--luft-md);

  /* LAGREN, i en enda stege (2026-09-17). Talen stod utspridda i fem
     stilmallar, och en ny vy fick da sitt tal genom att nagon letade upp vad
     den skulle ligga over - sa Traningsbanans sida behovde ett eget
     `#course-view { z-index: 70 }` for att komma over navigeringen, medan
     tavlingens vy av samma typ klarade sig pa 30 eftersom den sidan inte har
     nagon navigering. Samma vytyp lag alltsa pa tva hojder.

     Ordningen ar: kartans egna dekorationer under sidans navigering, en
     sidnivavy over den (en vy TACKER sidan, navigeringen inrakad), en
     redigeringsvy over det, och kontrollfragan overst - den galler alltid det
     som redan ligger uppe. */
  --z-karta-dekor:  50;  /* knappar och remsor som ligger pa kartan */
  --z-nav:          60;  /* bottom-nav och sidokolumnen */
  --z-sidvy:        70;  /* .page-view - en sida ovanpa en sida */
  --z-vy-tacke:     80;  /* .panel-overlay - morkret bakom en redigeringsvy */
  --z-vy:           90;  /* .full-modal/.edit-view */
  --z-fraga:        95;  /* .confirm-overlay - alltid overst */

  /* Akarpaletten. Bor har och inte i map.css sedan topplistan borjade rita
     samma farg utan att ha nagon karta - fargen ar AKARENS identitet, inte
     kartans. Namnen behaller --map-prefixet: det ar sa mapColor() slar upp dem.

     **Framrakad, inte vald pa kansla, och avstamd mot kartans ljusa bakgrund** -
     se den langa motiveringen i map.css. Andra inte ett varde utan att rakna om
     alla 15 par. EN uppsattning, ingen mork variant: kartan ar alltid ljus, och
     tva uppsattningar hade betytt att samma akare bytte farg mellan kartan och
     topplistan. */
  /* DIAGRAMMENS FÄRGER (Formkurva: volym, kondition och form). Linjen för
     innevarande år är --accent; åren att jämföra med följer i ordning. Skilda
     värden för mörkt och ljust läge, som resten av ytorna. */
  --diagram-fyllning: rgba(74,222,128,0.15);
  --diagram-bla:      #60a5fa;
  --diagram-rutnat:   rgba(255,255,255,0.06);
  --diagram-axel:     #666;
  --diagram-ar2:      rgba(96,165,250,0.9);
  --diagram-ar3:      rgba(249,115,22,0.9);
  --diagram-ar4:      rgba(167,139,250,0.9);
  --diagram-ar5:      rgba(251,113,133,0.9);
  --diagram-ar6:      rgba(250,204,21,0.9);
  --diagram-vald:     rgba(96,165,250,0.55);
  --diagram-ovald:    rgba(96,165,250,0.2);
  --diagram-plan:     rgba(250,204,21,0.6);
  --diagram-snitt:    rgba(251,191,36,0.9);
  --diagram-prognos:  rgba(45,212,191,0.85);
  /* Formens zoner, uppifrån: övergång, utvilad, grå zon, optimal, hög risk. */
  --diagram-form-overgang: rgba(251,191,36,0.12);
  --diagram-form-utvilad:  rgba(96,165,250,0.12);
  --diagram-form-gra:      rgba(156,163,175,0.10);
  --diagram-form-optimal:  rgba(134,239,172,0.14);
  --diagram-form-risk:     rgba(248,113,113,0.18);
  /* PULSZONERNAS FÄRGER, Garmins (Pers beslut 2026-09-25): grå, blå, grön,
     orange, röd - samma som på klockan. Bara trappan i åkarraden använder dem. */
  --hr-zone-1: #9aa0a6;
  --hr-zone-2: #1a73e8;
  --hr-zone-3: #1e8e3e;
  --hr-zone-4: #f29900;
  --hr-zone-5: #d93025;
  --map-athlete-1:     #2389e2;  /* bla */
  --map-athlete-2:     #ac2f3b;  /* rod */
  --map-athlete-3:     #00a061;  /* gron */
  --map-athlete-4:     #d36c00;  /* orange */
  --map-athlete-5:     #bd5caf;  /* lila */
  --map-athlete-6:     #b5b100;  /* gul */
}
@media (prefers-color-scheme: light) {
  :root {
    --bg:           #f5f5f7;
    --surface:      #ffffff;
    --kartkontroll: #ffffff;
    --border:       #e2e4ea;
    --border-input: #d0d0d8;
    --field-bg:     #ffffff;
    --field-border: #868a96;
    --btn-bg:       #ececf0;
    --text:         #1a1a1a;
    --text-muted:   #666;
    --text-heading: #111;
    --accent:       #16a34a;
    --accent-hover: #15803d;
    --red:          #dc2626;
    --varning:      #b45309;
    --diagram-fyllning: rgba(22,163,74,0.12);
    --diagram-bla:      #2563eb;
    --diagram-rutnat:   rgba(0,0,0,0.06);
    --diagram-axel:     #999;
    --diagram-ar2:      rgba(37,99,235,0.9);
    --diagram-ar3:      rgba(234,88,12,0.9);
    --diagram-ar4:      rgba(109,40,217,0.9);
    --diagram-ar5:      rgba(190,18,60,0.9);
    --diagram-ar6:      rgba(161,98,7,0.9);
    --diagram-vald:     rgba(37,99,235,0.55);
    --diagram-ovald:    rgba(37,99,235,0.2);
    --diagram-plan:     rgba(161,98,7,0.6);
  }
}
* { box-sizing: border-box; }
/* Studsen vid sidans kant, och Androids dra-for-att-ladda-om, slap igenom till
   dokumentet - och allt som ar position:fixed foljer med den rorelsen. Appen
   har inget pull-to-refresh att bevara: sidorna hamtar sitt eget innehall. */
html { overscroll-behavior-y: none; }
/* Innehallskolumnen. Sjalva centreringen och brytpunkten star har i stallet for
   upprepad i varje sidas stilmall. En sida utan --col (kartan) far ingen
   begransning alls och fyller ytan.

   LISTSIDORNA DELAR EN BREDD, satt har och inte i varje stilmall (Pers fraga
   2026-09-17: "har du duplicerat kod?"). Tavlingar, Banor och Pass var
   undersidor till Planera och bar den i body.undersida; sedan 2026-10-02 ar de
   flikar respektive sidor under ⋮, och regeln gar pa sidornas namn (Pass togs
   bort 2026-10-08 och star i Aktiviteter). Datorns kolumn (860) ar gemensam
   for alla sidor, se has-bottom-nav langre ner. */
body[data-sida="races"], body[data-sida="arrangera"], body[data-sida="courses"] { --col: 480px; }
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  background: var(--bg);
  color: var(--text);
  padding: 24px 24px 32px;
  /* Under statusraden - se --statusrad. */
  padding-top: calc(24px + var(--statusrad));
  /* svh och inte vh: 100vh ar den STORA viewporten (webblasarens kontrollyta
     undanfjadrad), sa en sida som egentligen ryms blev anda nagra tiotal pixlar
     hogre an det man ser och gick darfor alltid att skrolla lite. 100svh ar den
     minsta viewporten: ryms innehallet finns ingen skroll att gora. vh forst
     som fallback for webblasare utan svh. */
  min-height: 100vh;
  min-height: 100svh;
  margin: 0 auto;
  max-width: var(--col, none);
}
@media (max-width: 540px) {
  html { font-size: 112%; }
  /* --sida-topp: marginalen OVANFOR innehallet i skrollytan. En sticky rubrik
     (topplistans mellantider) lagger sig annars sa langt ner, och det som
     skrollas syns i glipan ovanfor den. */
  /* Statusraden läggs OVANPÅ --sida-topp och inte i den: den sticky rubriken
     räknar med --sida-topp och stannar då precis under statusraden. */
  body { --sida-topp: 20px;
         padding: calc(var(--sida-topp) + var(--statusrad)) var(--luft-lg) 20px; }
  /* Bottom-nav ska sta ABSOLUT still nar man skrollar. Den gled tidigare ner
     ca 15 px pa /sharing och /settings men aldrig pa kartan, och skillnaden var
     att kartsidan inte skrollar alls.
     Uppmatt pa en installerad app i Android (2026-08-22): layoutviewporten ar
     785 px medan den SYNLIGA ar 769,7, och den synliga panorerar 0-16 px inom
     den nar dokumentet skrollar - webblasaren fjadrar undan sin kontrollyta
     aven nar den inte har nagot synligt adressfalt. position:fixed hanger i
     LAYOUT-viewporten, sa navigeringens lage (navT 739) star still hela tiden
     medan det man ser av den glider. Ingen CSS kan fasta ett element i den
     synliga viewporten - det som gar att gora ar att ta bort rorelsen.
     Darav: skrollen flyttas fran dokumentet till body, och med overflow:hidden
     pa <html> ar rot-skrollern tom, sa kontrollytan aldrig fjadrar.
     Priset ar att adressfaltet star kvar hela tiden i webblasarlaget. */
  html { height: 100%; overflow: hidden; }
  body {
    height: 100%;
    overflow-y: auto;
    /* Kolumnen centreras med indrag i stallet for max-width: hela skarmens
       bredd maste vara skrollbar yta, annars blir kanterna doda att dra i pa
       en sida med smal kolumn (--col: 360px pa /sharing och /settings). Samma
       resultat som max-width ger - innehallet ar lika brett och lika centrerat. */
    max-width: none;
    /* +16px: --col ar bredden INKLUSIVE sidmarginalen (box-sizing: border-box),
       sa indraget ar halva overskottet plus den vanliga marginalen. */
    padding-inline: max(16px, (100% - var(--col, 100%)) / 2 + 16px);
  }
}
/* 1.3rem ar appens sidrubrik-storlek overallt (samma som .header-back h1/h2
   i komponentdelen nedan) - lag tidigare som en 1.3rem-override i var och en
   av de tio sidmallarna, med 1.6rem har som ingen sida faktiskt anvande. */
/* Explicit margin-top:0 - annars ger webblasarens standardstil h1 ~16px
   toppmarginal pa de sidor dar rubriken star for sig sjalv, men inte dar den
   ligger i en .header-back-rad, sa rubrikerna hamnade pa olika hojd. */
/* VIKT 400 EXPLICIT och inte borttagen deklaration: rubrikelement arver
   webblasarens bold, sa utan raden blir de feta igen. Storleken racker for att
   visa att det ar en rubrik - halvfet anvands bara nar den inte gor det
   (ux-principer punkt 41). */
/* MARGIN 0 (2026-10-09): courses.css och races.css satte h1 { margin: 0 }
   utan att binda det till sin sida, och eftersom alla stilark laddas i samma
   dokument gällde det i hela appen. Det är alltså så appen redan ser ut - nu
   står det där det gäller. */
h1 { font-size: var(--text-rubrik); font-weight: 400; margin: 0; color: var(--text-heading); }
/* ── Knapparnas fyra typer ───────────────────────────────────────────────
   Primar (ytans huvudhandling, hogst en per yta), sekundar, textknapp
   (.btn-linklike) och destruktiv. Se server/docs/ux-principer.md punkt 5-7.

   44 PX TRAFFYTA. Alla tre typerna ar minst 44px hoga - det ar mattet en
   tumme trager, och appen anvande det redan i redigeringsvyns overkant men
   ingen annanstans. Uppmatt fore: 39-43px pa nastan varje knapp i appen.
   Ikonknappar INUTI en rad vaxer i stallet med padding (se
   .course-row-favorite), sa traffytan blir 44 utan att raden blir det.

   TYPEN BAR INTE LAYOUT. Bredd, marginal och placering hor till platsen
   knappen star pa - .btn-block for full bredd, .btn-compact for en tatare
   rad. .btn-primary bar tidigare width:100% och margin-top i sig sjalv,
   vilket tvingade fram undantag i fyra stilmallar: en knapp som maste
   skrivas om for att fa sta bredvid nagot ar inte langre samma knapp. */
.btn-primary {
  min-height: 44px;
  background: var(--accent);
  color: var(--bg);
  border: none;
  border-radius: var(--radius-md);
  padding: var(--luft-md) var(--luft-lg);
  font-size: var(--text-normal);
  cursor: pointer;
}
.btn-primary:hover { background: var(--accent-hover); }
.btn-primary:disabled { opacity: 0.5; cursor: default; }
.bottom-nav {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  z-index: var(--z-nav);
  display: flex;
  align-items: stretch;
  background: var(--surface);
  border-top: 1px solid var(--border);
  padding-bottom: env(safe-area-inset-bottom);
}
.bottom-nav-item {
  /* Flikarna ar <button> och inte lankar (Pers beslut 2026-09-17): sidorna har
     ingen adress, sa det finns ingenting att lanka till. En knapp arver inte
     typsnittet av sig sjalv. */
  font-family: inherit;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--luft-md) 0;
  background: none;
  border: none;
  text-decoration: none;
  cursor: pointer;
  color: var(--text-muted);
  font-size: var(--text-stod);
  font-weight: 500;
  transition: color 0.15s;
  -webkit-tap-highlight-color: transparent;
}
.bottom-nav-item:hover { color: var(--text); }
/* Liten siffra pa fliken dar man svarar pa inbjudningar. Position relativt
   sjalva flik-lanken, som darfor ar position:relative. */
.bottom-nav-item { position: relative; }
.nav-badge {
  position: absolute; top: 4px; left: 50%; margin-left: var(--luft-xs);
  min-width: 16px; height: 16px; padding: 0 var(--luft-xs); border-radius: 8px;
  background: var(--red); color: #fff;
  font-size: var(--text-stod); font-weight: 700; line-height: 16px; text-align: center;
}
.bottom-nav-item.active { color: var(--accent); }
/* ⋮-menyn (nav-mer.js, 2026-10-02): reser sig ovanför flikraden, mot högerkanten
   där knappen sitter. Raderna är sidlänkar som flikarna. */
.nav-mer-meny {
  position: absolute; right: var(--luft-sm); bottom: calc(100% + var(--luft-xs));
  min-width: 11em; padding: var(--luft-xs); display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md);
  box-shadow: var(--skugga-knapp);
  /* Hela navigationen sedan fas 4 (2026-10-06): på en låg skärm rullar menyn
     i stället för att växa ut över överkanten. */
  max-height: calc(100dvh - 56px - env(safe-area-inset-bottom) - var(--luft-lg)); overflow-y: auto;
}
.nav-mer-meny[hidden] { display: none; }
/* Anpassa och felrapporten är inga sidor: ett streck skiljer dem från listan. */
/* Anpassa navigation (nav-anpassa.js): kryssrutan och namnet är en träffyta,
   pilarna flyttar en vald sida i raden. */
.nav-anpassa-val { display: flex; align-items: center; gap: var(--luft-md); cursor: pointer; min-height: 44px; }
.nav-anpassa-rad .btn-compact { min-width: 44px; }
.nav-anpassa-lista { margin-bottom: var(--luft-md); }
.nav-anpassa-val input, .kom-igang-val input { accent-color: var(--accent); width: 20px; height: 20px; }
/* Kom igång (kom-igang.js): valen är rader, knapparna står under varandra. */
.kom-igang-val { cursor: pointer; }
.kom-igang .btn-block { margin-top: var(--luft-md); }
.kom-igang-bort { display: block; margin: 0 0 var(--luft-sm) auto; font-size: var(--text-stod); }
.nav-mer-anpassa { border-top: 1px solid var(--border); border-radius: 0 0 var(--radius-sm) var(--radius-sm); }
/* Öppen meny: flikraden över vyerna, annars ligger menyn bakom en öppen vy
   (nav-mer.js). Under en transaktion täcks raden helt, så ⋮ går inte att nå
   där - då kan heller ingen meny öppnas förbi vyns fråga. */
.bottom-nav.meny-oppen { z-index: var(--z-fraga); }
.nav-mer-item {
  display: flex; align-items: center; gap: var(--luft-md); padding: var(--luft-md);
  font: inherit; font-size: var(--text-normal); color: var(--text); text-align: left;
  background: none; border: 0; border-radius: var(--radius-sm); cursor: pointer;
}
.nav-mer-item:hover { background: var(--border); }
.nav-mer-item.active { color: var(--accent); }
.nav-mer-badge {
  margin-left: auto; min-width: 16px; height: 16px; padding: 0 var(--luft-xs); border-radius: 8px;
  background: var(--red); color: #fff; font-size: var(--text-stod); font-weight: 700;
  line-height: 16px; text-align: center;
}
body.has-bottom-nav { padding-bottom: calc(56px + env(safe-area-inset-bottom)); }
/* Ikonerna star ensamma i bottom-nav pa mobil (namnet finns i aria-label);
   pa dator ar det en riktig sidonavigering och da skrivs namnen ut. */
.bottom-nav-label { display: none; }
@media (min-width: 541px) {
  /* Sidokolumn: pricken flyttar in mot ikonen i stallet for att sitta mitt i. */
  .nav-badge { top: 6px; left: 50%; margin-left: 6px; }
  .bottom-nav { flex-direction: column; top: 0; bottom: 0; right: auto; width: var(--nav-width);
    border-top: none; border-right: 1px solid var(--border); align-items: stretch; justify-content: flex-start;
    gap: var(--luft-xs); padding: var(--luft-md) var(--luft-sm); }
  /* Ikonen over etiketten i stallet for bredvid: kolumnen blir smal utan att
     namnen forsvinner, och den aktiva fliken kan ramas in som en egen ruta
     i stallet for att bara byta textfarg. */
  .bottom-nav-item { flex: none; flex-direction: column; justify-content: center; gap: var(--luft-xs);
    padding: var(--luft-md) 0; font-size: var(--text-stod); border: 1px solid transparent; border-radius: var(--radius-lg); }
  .bottom-nav-item.active { color: var(--accent); border-color: var(--accent); }
  .bottom-nav-label { display: inline; }
  .nav-mer-meny { right: auto; bottom: auto; left: calc(100% + var(--luft-xs)); top: var(--luft-md);
    max-height: calc(100dvh - 2 * var(--luft-md)); }
  body { max-width: var(--col-desktop, var(--col, none)); }
  /* Kolumnen centreras i ytan BREDVID navigeringen, inte i hela fonstret, och
     lagger sig tatt efter den sa fort fonstret ar for smalt for att centrera
     - darav max(). --content-left finns for sidor med en egen andrakolumn sa
     de foljer med i centreringen; Jag hade en sadan flikkolumn till
     2026-09-17, da den blev en radlista i sidans eget flode. */
  /* Huvudsidorna - flikarna i navigeringen - delar EN kolumnbredd, satt har
     och inte i varje sidas stilmall. Att Planera, Delning och Profil hamnade
     pa olika bredder syntes direkt nar man bytte flik (Delning ar sedan
     2026-09-17 en undersida till Jag, men poangen star kvar). En sida som inte kan
     ha en kolumn alls (kartan) sager --col-desktop: none med samma
     specificitet i sin egen stilmall. Formular inuti kolumnen far garna vara
     smalare an den (se .settings-view-body, .share-row) - det ar kolumnen som
     ska ligga still mellan flikarna, inte varje enskilt falt. */
  body.has-bottom-nav {
    --col-desktop: 860px;
    --content-left: max(var(--nav-gutter),
      calc(var(--nav-gutter) + (100vw - var(--nav-gutter) - var(--col-desktop, 860px)) / 2));
    padding-bottom: 32px;
    margin-left: var(--content-left);
    margin-right: auto;
  }
}

/* ── Delade UI-komponenter ───────────────────────────────────────────────
   Anvands av flera sidmallar och ligger darfor har istallet for duplicerade
   i varje sidas egen <style>. En sidmall som behover avvika lagger sin
   override efter den har blocket i sin egen style-tagg (senare regel med
   samma specificitet vinner). */

/* LUFTEN OVANFÖR (2026-10-09): stod i settings.css som h2 { margin-top: 32px }
   och gällde av samma skäl i hela appen. Den första rubriken i ett kort får
   ingen (.card > :first-child). */
h2 { font-weight: 400; font-size: var(--text-rubrik); color: var(--text-heading); margin: 32px 0 var(--luft-sm); }
/* Två formulär efter varandra (låg i settings.css och sharing.css). */
form + form { margin-top: var(--luft-sm); }
/* Antalet bredvid en rubrik: "Åkare du följer 2". Tomt nar listan ar tom -
   en nolla bredvid en rubrik ar brus. */
.count-badge { color: var(--text-muted); font-weight: 400; }
.count-badge:empty { display: none; }
.meta { font-size: var(--text-stod); color: var(--text-muted); }
p.hint { font-size: var(--text-stod); color: var(--text-muted); margin-top: var(--luft-sm); }
/* Statusrader efter ett formularanrop (?error=/?success= i URL:en). */
p.form-error { color: var(--red); font-size: var(--text-normal); }
p.form-success { color: var(--accent); font-size: var(--text-normal); }
.btn-secondary {
  min-height: 44px;
  background: var(--btn-bg); color: var(--text); border: 1px solid var(--border-input);
  border-radius: var(--radius-md); padding: var(--luft-sm) var(--luft-md); font-size: var(--text-normal); cursor: pointer;
  white-space: nowrap;
}
.btn-secondary:disabled { opacity: 0.5; cursor: default; }
/* Intryckt lage - grundmarkeringen, densamma overallt (ux-principer punkt 8).
   Lagen som andrar vad en GEST betyder forstarker den vid ytan i stallet, se
   .places-actions i course-places.css. */
.btn-secondary[aria-pressed="true"] { border-color: var(--accent); color: var(--accent); }

/* Destruktiv. Lag i tre skepnader - .danger-btn pa Profil, .btn-secondary
   .danger-text pa Hantera banor, och en egen rod ram pa enhetsraden - trots
   att alla tre betyder samma sak. */
.btn-danger {
  min-height: 44px;
  background: none; color: var(--red); border: 1px solid var(--red);
  border-radius: var(--radius-md); padding: var(--luft-sm) var(--luft-md); font-size: var(--text-normal);
  cursor: pointer; white-space: nowrap;
}
.btn-danger:hover { background: var(--red); color: #fff; }
.btn-danger:disabled { opacity: 0.5; cursor: default; }

/* Layout, inte typ: far kombineras med vilken av de fyra som helst. */
.btn-block { display: flex; width: 100%; }
/* Flex for att texten ska sta mitt i den 44px hoga ytan. */
.btn-primary, .btn-secondary, .btn-danger {
  display: inline-flex; align-items: center; justify-content: center;
}
/* En LÄNK som ser ut som en knapp (offlinesidans Försök igen) ska inte vara
   understruken - det är knappens form som säger att den går att trycka på. */
a.btn-primary, a.btn-secondary, a.btn-danger { text-decoration: none; }
/* Tatare TEXT, inte mindre yta: paddingen kryper in, hojden gor det inte.
   EGET MATT, och det ar poangen med komponenten. Avstandsmigreringen rundade
   6px -> 8 och 10px -> 12 och gjorde den darmed IDENTISK med .btn-secondary
   (2026-09-21) - knappen fanns kvar i namnet men gjorde ingenting. En komponents
   inre padding ar dess FORM, inte luft mellan element, och hor darfor inte till
   luftskalan. test_knapparnas_tathet haller ordningen. */
.btn-compact { padding: 6px 10px; font-size: var(--text-stod); }

/* EN KONTROLL ÄR INTE TEXT (Pers fynd 2026-09-20: "Plus och minus ska inte bete
   sig som text och kunna markeras").
   Ett långt tryck på stegarens + gav iOS textmarkering med handtag och
   "Kopiera / Markera allt" ovanpå halvarket. Etiketten på en knapp är en del av
   kontrollen, inte innehåll man plockar ur sidan.
   PÅ ELEMENTET och inte per komponent: regeln gäller varje knapp i appen,
   inklusive de som byggs i morgon. [role="button"] tar med panelernas handtag,
   som man DRAR i - där startar en markering annars mitt i gesten.
   -webkit-touch-callout stänger iOS egen meny; user-select ensam räcker inte. */
button, [role="button"] {
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
}

/* DISTANSSTEGAREN (km-stepper.js). Komponenten är delad, och då hör utseendet
   hemma här och inte i en sidas egen stilmall - annars är den bara halvdelad.
   Knapparna är 44px, samma minsta träffyta som resten av appen.

   MEN KONTROLLEN SER 35 UT (Pers val 2026-09-20). Steppern stod bredvid
   namnfältet i platsformuläret och var 46px mot fältets 35 - ensningen av
   fältstorleken gjorde glappet större, inte mindre. Samma grepp som
   favoritstjärnan: måttet gäller TRÄFFYTAN, inte höjden man ser
   (tests/webblasare/test_traffytor.py). Knappen är alltså kvar på 44px och
   sticker ut 5,5px upp och ner utanför stepperns 35.

   Därför INGEN overflow: hidden längre. Den klippte inte bara målningen utan
   också träffytan, vilket hade gjort hela greppet meningslöst. Följden är att
   trycklaget måste målas på en pseudo som bara täcker de 33 synliga pixlarna -
   annars flammar den utanför ramen när man håller inne. */
.km-stepper { display: flex; align-items: center; gap: 0;
  height: 35px; box-sizing: border-box;
  border: 1px solid var(--field-border); border-radius: var(--radius-md);
  background: var(--field-bg); }
.km-step { flex: none; width: 44px; min-height: 44px; position: relative;
  border: none; background: none;
  color: var(--text); font-size: 1.25rem; line-height: 1; cursor: pointer;
  -webkit-tap-highlight-color: transparent; touch-action: manipulation; }
/* Den SYNLIGA ytan, inte knappen. Radien sitter här och inte på steppern,
   eftersom overflow inte längre klipper åt oss. */
.km-step::before {
  content: ""; position: absolute; left: 0; right: 0; top: 50%;
  height: 33px; transform: translateY(-50%);
}
.km-step:first-child::before {
  border-radius: calc(var(--radius-md) - 1px) 0 0 calc(var(--radius-md) - 1px); }
.km-step:last-child::before {
  border-radius: 0 calc(var(--radius-md) - 1px) calc(var(--radius-md) - 1px) 0; }
.km-step:active::before { background: var(--border); }
.km-value { flex: 1; display: flex; align-items: center; justify-content: center;
  min-width: 84px; padding: 0 var(--luft-xs); font-size: var(--text-normal); font-weight: 600;
  color: var(--text-heading); font-variant-numeric: tabular-nums; }

/* VISA OCH ÄNDRA PÅ SAMMA RAD (inline-rad.js, Pers beslut 2026-09-21).
   Samma lodräta modell som .field-row - 12px padding, min-height 44, inga
   marginaler - så raderna tilar på sina träffytor och luften efter en
   avdelarlinje blir densamma oavsett vilken radtyp som står först.

   align-items: center och inte baseline: raden bär nu ikoner, och en symbol på
   textens baslinje hamnar för lågt (samma skäl som .field-row svg redan hade). */
/* INGEN EGEN VERTIKAL PADDING. Raden bär en 44px-ikon (✎/✓/✕), så innehållet
   är redan 44 högt - lägger raden 12+12 ovanpå blir lådan 68, och texten
   centreras då 25,5 ner i den. Uppmätt 2026-09-22: namnet hamnade 37,5px under
   fliklinjen mot Platser-flikens 24,5, alltså precis den skevhet Per
   rapporterade fast åt andra hållet.
   .field-row slapp undan samma sak för att dess innehåll bara var text (17px),
   så min-height styrde. Här styr ikonen, och min-height räcker som golv. */
.inline-rad {
  display: flex; align-items: center; gap: var(--luft-md); flex-wrap: wrap;
  width: 100%; min-height: 44px; padding: 0;
  color: inherit; text-align: left; font: inherit;
}
.inline-rad .field-label { flex: none; min-width: 3.5em; margin-bottom: 0; }
.inline-rad .field-value { flex: 1; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.inline-rad-falt { flex: 1; min-width: 0; display: flex; align-items: center; }
/* Förklaringen behövs inte medan man skriver - den tar bara fältets plats
   (2026-09-26: med en lång etikett fick fältet 40 px och visade tre bokstäver). */
.inline-rad.redigerar > .info-btn { display: none; }
/* HIDDEN MÅSTE VINNA. En författarstil slår webbläsarens [hidden]{display:none},
   så `display: flex` ovan höll fälthöljet kvar i layouten även när raden var
   stängd - med flex:1 tog det plats, raden bröts till två och blev 68px i
   stället för 44. Följden syntes som fel avstånd: namnet hamnade 37,5px under
   fliklinjen mot Platser-flikens 24,5 (uppmätt 2026-09-22). */
.inline-rad-falt[hidden] { display: none; }
.inline-rad-falt .field-input { width: 100%; }

/* IKONEN ÄR 44 OCH SER MINDRE UT - samma grepp som .km-step och
   favoritstjärnan: knappen bär träffytan, pseudon målar det man ser. Tre
   ikoner i rad utan det blir tre 24px-mål bredvid varandra, alltså under
   appens mått (ux-principer punkt 38, test_traffytor.py). */
.inline-rad-ikon {
  flex: none; width: 44px; min-height: 44px; position: relative;
  border: none; background: none; cursor: pointer;
  color: var(--text-muted); font-size: 1.05rem; line-height: 1;
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
.inline-rad-ikon::before {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 32px; height: 32px; transform: translate(-50%, -50%);
  border-radius: var(--radius-sm);
}
.inline-rad-ikon:active::before { background: var(--border); }
.inline-rad-ikon:hover { color: var(--text-heading); }
.inline-rad-ikon:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px;
  border-radius: var(--radius-sm); }

/* Felet tar hela raden under fältet: det hör till värdet man just skrev, och
   ska inte tränga ihop kontrollerna bredvid. */
.inline-rad-fel { flex-basis: 100%; margin: 0; color: var(--red); }

/* Kort: en egen yta runt en sammanhallen del av sidan, i stallet for text
   direkt mot bakgrunden. Det ar det som gor att en sida laser som gjord
   snarare an som ett dokument - samma grepp som formkurvans datorvy. Radien
   ar medvetet storre an knapparnas och falens (--radius-xl mot -md): kortet
   ar ytan de ligger PA och ska las som ett lager, inte som ytterligare en
   kontroll i raden. */
.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-xl); padding: 20px; margin-bottom: var(--luft-lg);
}
.card > :first-child { margin-top: 0; }
.card > :last-child { margin-bottom: 0; }

/* ── Falt ────────────────────────────────────────────────────────────────
   ETT faltutseende, i tva storlekar. Textfalt definierades tidigare om i tio
   stilmallar med olika padding (7/8/9/10px), olika radie, olika bakgrund och
   olika textstorlek - alltsa tio svar pa hur ett falt ser ut i den har appen.

   .field-input ar formularfaltet: eget block, full bredd, samma hojd som en
   knapp. .compact ar samma falt i en tat rad - i en popover, i en verktygsrad
   eller inuti en listrad - dar ett fullstort falt hade sprangt raden.

   Etiketten star ovanfor faltet och blir kvar nar man skriver
   (server/docs/ux-principer.md punkt 1); .field haller ihop de tva. */
.field { margin-bottom: 20px; }
.field-label { display: block; font-size: var(--text-stod); color: var(--text-muted); margin-bottom: var(--luft-xs); }
.field-value { font-size: var(--text-normal); }
/* ETT FALT, EN STORLEK (Pers beslut 2026-09-20, om platsnamnet i
   banredigeraren: "jag tycker det har faltet ar lagom stort").

   Det fanns TVA som bada var standard - .field-input pa 10px/0.9rem och
   .field-input.compact pa 8px/0.85rem - och vilken man fick berodde pa VAR
   faltet bodde, inte pa vad det var. Tavlingens namnfalt var mindre an
   Delnings, fast bada ar ett namn man skriver i ett formular.

   Varianten motiverades med "faltet i en tat rad - i en popover, i en
   verktygsrad eller inuti en listrad". Men nio av nio compact-falt i
   tavlingsformularet lag i en vanlig flex-kolumn med etikett ovanfor
   (uppmatt 2026-09-20). Klassen hade blivit "tavlingsformularets stil", och sa
   uppstar tva storlekar for samma sak.

   Popoverns falt far utseendet UTAN att bara klassen i markupen: de star i
   selektorlistan har i stallet for som en egen kopia av samma deklarationer.
   Radio och kryssruta undantas - de ar inte textfalt och ska inte fylla raden. */
.field-input,
.popover input:not([type="radio"]):not([type="checkbox"]),
.popover select {
  display: block; width: 100%; box-sizing: border-box;
  padding: var(--luft-sm); border-radius: var(--radius-sm);
  border: 1px solid var(--field-border); background: var(--field-bg);
  color: var(--text); font-size: var(--text-normal); font-family: inherit;
}
/* Samma fokusmarkering som listraderna redan har - inte webblasarens
   standardring, som ar olika i varje webblasare och ibland osynlig mot
   den morka bakgrunden. */
.field-input:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.field-input:disabled { color: var(--text-muted); }
/* Kryssrutor och radioknappar ar inte textfalt och ska inte fylla raden. */
.field-check { display: flex; align-items: center; gap: var(--luft-sm); font-size: var(--text-normal);
  margin: var(--luft-md) 0 var(--luft-xs); }
/* Luften kring ett fält (låg i settings.css och gällde hela appen,
   2026-10-09). Ett fält i sin .field-grupp har ingen egen: .field bär
   avståndet till nästa fält, och etiketten sitter 4px över sitt eget - med
   4 + 8 px låg etiketten lika nära fältet ovanför och lästes till fel sak. */
.field-input { margin: var(--luft-sm) 0; }
.field .field-input { margin: 0; }

/* BRYTAREN (Pers beslut 2026-10-01): en inställning som slår igenom DIREKT är
   en brytare, som på telefonens egna inställningar - kryssrutan ser ut som ett
   webbformulär. Kryssrutan finns kvar där den betyder något annat: i ett
   formulär som sparas med en knapp (Varvlopp) och i listor där man väljer
   flera.

   EN komponent: texten till vänster, brytaren till höger, och en förklaring
   som en egen .hint UNDER raden. Det är samma <input type="checkbox"> med
   role="switch" - skärmläsare och tangentbord fungerar som förut, bara
   utseendet är brytarens. Raden är minst 44 px, appens träffyta. */
.field-switch { display: flex; align-items: center; justify-content: space-between;
  gap: var(--luft-md); min-height: 44px; margin: var(--luft-md) 0 0;
  font-size: var(--text-normal); color: var(--text); cursor: pointer; }
.field-switch + .hint { margin-top: 2px; }
.field-switch input[role="switch"] {
  appearance: none; -webkit-appearance: none; flex: none; position: relative;
  width: 46px; height: 28px; margin: 0; border-radius: 14px; cursor: pointer;
  background: var(--border); transition: background 0.15s; }
.field-switch input[role="switch"]::before {
  content: ""; position: absolute; top: 3px; left: 3px; width: 22px; height: 22px;
  border-radius: 50%; background: #fff; box-shadow: var(--skugga-reglage);
  transition: transform 0.15s; }
.field-switch input[role="switch"]:checked { background: var(--accent); }
.field-switch input[role="switch"]:checked::before { transform: translateX(18px); }
.field-switch input[role="switch"]:disabled { opacity: 0.45; cursor: default; }
.field-switch input[role="switch"]:focus-visible { outline: 2px solid var(--accent);
  outline-offset: 2px; }

/* Undanstadat innehall under en lista: arkiverade banor pa /courses,
   genomforda tavlingar pa /races. En sektion avdelad med en linje, med en
   rubrik som ar en riktig knapp med chevron (ux-principer punkt 13 - den fals
   ut PA PLATS, alltsa samma sorts pil som en listrad som fals ut).

   Delad och inte kopierad: sektionen fanns forst bara i arkivet, och nar
   tavlingarna behovde samma sak (2026-09-06) var alternativet en andra
   uppsattning nastan lika regler. Vad som ligger I sektionen hor till sidan -
   se .archived-row i courses.css. */
.list-section { margin-top: 24px; border-top: 1px solid var(--border); }
/* Först i ett eget kort - arkivet under Banor och tävlingarna (2026-10-03) -
   står gruppen inte under något, och då är linjen och luften ovanför bara i
   vägen. Två grupper i samma kort skiljs fortfarande åt av linjen. */
.card > .list-section:first-child { margin-top: 0; border-top: none; }
.list-section-toggle {
  display: flex; align-items: center; justify-content: space-between; gap: var(--luft-md);
  width: 100%; min-height: 44px; padding: var(--luft-md) 0;
  background: none; border: none; color: var(--text-muted);
  font: inherit; font-weight: 600; cursor: pointer; text-align: left;
}
.list-section-toggle:hover { color: var(--text-heading); }
.list-section-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px;
  border-radius: var(--radius-sm); }
.list-section-chevron { flex: none; display: flex; }

/* ── Visa en uppgift ─────────────────────────────────────────────────────
   Etikett till vanster, varde till hoger, en rad per sak. Raden VISAR bara -
   den leder ingenstans och gar inte att trycka pa.

   Lag i races.css till 2026-09-20 och var darmed tavlingsvyns egen, medan Konto
   och banredigeraren ritade samma sorts uppgift pa var sitt satt (Pers fynd:
   "vi har olika stil pa att visa information i appen"). Uppgifterna stod forr
   som en enda lang gra rad - sidans tataste information i dess blekaste stil,
   omojlig att skumma. */
.fact-list { margin-bottom: var(--luft-xs); }
.fact-row { display: grid; grid-template-columns: 9.5em 1fr; gap: var(--luft-sm);
  padding: var(--luft-sm) 0; align-items: baseline; }
.fact-row + .fact-row { border-top: 1px solid var(--border); }
.fact-label { font-size: var(--text-stod); color: var(--text-muted);
  text-transform: uppercase; letter-spacing: 0.03em; }

/* EN RUBRIK ÖVER EN GRUPP RADER (Pers beslut 2026-09-22). Låg som .trim-group i
   course-places.css och var därmed döpt efter STÄLLET den användes på - samma
   sort som `.compact` en gång var. Nu bär den sitt syfte.

   IDAG RENDERAS DEN AV EXAKT EN YTA: målets rubrik i banredigeraren. Den andra
   tänkta användaren - avkortningsvyns grupper - bygger sina rubriker i
   `grupprubrik()` i course-places-editor.js, och den funktionen anropas inte
   från någonstans (svept 2026-09-22). Klassen är alltså delad till sin form men
   inte till sin användning ännu; det skrivs ut här för att motsatsen vore ett
   skäl i presens som inte stämmer.

   MINDRE ÄN DET DEN RUBRICERAR, och halvfet därför: appens regel säger att
   halvfet bara används när storleken inte räcker, och en rubrik som är mindre
   än sin text är precis ett sådant fall. Den läses som en rubrik för att den
   skiljer sig i karaktär, inte för att den är stor.

   VERSALERNA BESTÄMS HÄR och ingen annanstans. Texten skrivs som "Mål" i
   markup och JS; vill man ändra hur grupprubriker ser ut är det den här raden
   man ändrar, och då följer varje yta med. En sida som skrev MÅL för hand hade
   sett likadan ut i dag och glidit isär i morgon.

   margin: 0 - elementet är en h3 och skulle annars bära webbläsarens egen
   marginal. Var den ska ligga är sidans sak (frontend.md, kontextlagret). */
.grupprubrik {
  margin: 0;
  font-size: var(--text-stod);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
}
.fact-value { font-size: var(--text-normal); color: var(--text); }

/* En rad som VISAR ett varde och oppnar redigeringsvyn - alltsa en
   navigationsrad och inte ett falt (server/docs/ux-principer.md punkt 13 och 35). */
.field-row {
  display: flex; align-items: baseline; gap: var(--luft-md); width: 100%;
  /* PADDING 12 OCH INTE 8 (Pers fynd 2026-09-21: "avstånden är oproportionerliga
     i höjdled"). Raden är 44px för tummen, texten 17 - och med 8px padding blev
     33 av 44 använda, så 27px slack hängde UNDER texten (baseline lägger
     gruppen i överkant). Uppmätt gav det 12px över namnet och 43 ner till nästa
     rad: ingen hade valt 43, det var träffytan som syntes som luft.
     Med 12 blir innehållet 41 av 44 och slacket 3px - osynligt. Samma tal som
     .list-row redan har: appen hade två radmodeller där den borde ha en.
     Marginalen är borta av samma skäl; raderna tilar på sina 44px, vilket är
     precis vad två träffytor bredvid varandra kräver för att inte överlappa. */
  min-height: 44px; padding: var(--luft-md) 0; margin-bottom: 0; background: none; border: none;
  color: inherit; text-align: left; font: inherit; cursor: pointer;
}
.field-row:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px;
  border-radius: var(--radius-sm); }
/* MIN-WIDTH OCH INTE EN FAST BREDD (2026-09-21). Banpanelens tva rader fick
   etiketter samma dag, och da borjade vardena pa olika x: "Namn" ar 36px och
   "Mal" 22, sa de lag 14px ur linje. En fast kolumn hade ratat till det men
   klippt Kontos "Namnet andra ser", som ar bredare an bada. Med min-width vaxer
   korta etiketter upp till samma kolumn medan langa far ga forbi.
   3.5em ar matt och inte valt: pa en 358px rad linjerar den vardena for 11px av
   namnets bredd (282 -> 271). .fact-row:s 9.5em hade kostat 92px - den kolumnen
   ar satt for en annan komponent, och de tva star aldrig bredvid varandra. */
.field-row .field-label { flex: none; min-width: 3.5em; margin-bottom: 0; }
.field-row .field-value { flex: 1; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
/* CHEVRONEN sager att raden leder vidare (ux-principer punkt 13). Har stod till
   2026-09-20 ordet "Andra" i stallet, och da hade appen TVA ingangar till samma
   sak: ordet pa Konto, chevron i banredigeraren och under Jag. En markor racker,
   och chevronen ar den som redan har en enda kalla (chevron() i course-row.js
   och _chevron.html).
   align-self: center - raden ligger pa baseline, vilket ar ratt for etikett och
   varde men lagger en symbol for lagt. */
.field-row svg { flex: none; align-self: center; color: var(--text-muted); }
.field-row:hover .field-value { color: var(--text-heading); }
.field-check input { width: auto; margin: 0; }

/* ── Laddar och tomt ─────────────────────────────────────────────────────
   Tva av de fyra lagena (server/docs/ux-principer.md punkt 22); fel och klart bor i
   .form-status nedan. Lag i fyra namn - .meta, .hint, .follow-empty,
   .device-list-empty - for exakt samma grabruna rad. */
.state-text { color: var(--text-muted); font-size: var(--text-normal); padding: var(--luft-md) 0 0; }

/* Statusraden under en atgard: "Sparat", "Kunde inte spara", "2 akare
   startade". Fanns i fem varianter under olika namn (.course-row-status plus
   fyra id-regler pa /sharing och /settings) innan den flyttades hit.
   min-height halller raden pa plats sa innehallet inte hoppar nar texten
   dyker upp och forsvinner. */
.form-status { margin-top: var(--luft-sm); min-height: 1em; font-size: var(--text-stod); color: var(--text-muted); }
.form-status.error { color: var(--red); }
.form-status.success { color: var(--text-muted); }

/* Text som klickar som en lank men ar en knapp - anvands dar en atgard ser ut
   som text (byt namn pa en rad, "Skicka om"). Lag i followed.css, sidscopad,
   men behovs pa tva sidor. */
.btn-linklike {
  background: none; border: none; padding: 0; margin: 0;
  color: inherit; font: inherit; text-align: left; cursor: pointer;
}
.btn-linklike:hover { color: var(--text-heading); }
.btn-linklike.accent { color: var(--accent); text-decoration: underline; }

/* Ja/nej-status i ett faltvarde: bekraftad e-post, ansluten tjanst. */
.status-ok { color: var(--accent); }
.status-bad { color: var(--red); }
.inline-form { display: inline; }
/* En lank som ser ut som en knapp. */
.btn-link { display: inline-block; text-decoration: none; text-align: center; }

/* En knapp som tar bort nagot. Lag i tre stilmallar, scopad till var sin sida,
   trots att den betyder samma sak overallt. */

/* Rubrikrad hogst upp pa en undersida: tillbaka-header till vanster och en
   eventuell atgard (t.ex. "Lagg till" pa /courses) till hoger. Delad av
   /courses och /races - lag tidigare bara i courses.css. */
.page-header-row { display: flex; align-items: center; justify-content: space-between; gap: var(--luft-md); margin-bottom: var(--luft-lg); }
.page-header-row h1 { margin: 0; }
/* VALJAREN (lopp-valjare.js, Pers beslut 2026-10-02): en knapp som AR rubriken
   i loppets ruta och oppnar ett halvark. Den ersatte lagesraden Tavling/Foljer
   och en <select> - tva rader overst pa kartan. Samma matt som rubriken hade:
   ingen ram, centrerad, kapad med ... i stallet for att vaxa med namnet.
   EGET MATT (0.95rem): valjaren ar det enda stallet dar en rubrik visas i en
   flytande ruta, och --text-rubrik vore for stort for den. */
.watch-picker {
  display: inline-flex; align-items: center; gap: var(--luft-xs); max-width: 100%;
  border: 0; background: none; padding: 0; cursor: pointer;
  color: var(--text-heading); font: inherit; font-size: 0.95rem; font-weight: 700;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.watch-picker::after { content: "▾"; color: var(--text-muted); font-weight: 400; }
/* En enda sak att visa ar ett namn och inget val - ingen pil, inget att trycka pa. */
.watch-picker.ensam { cursor: default; }
.watch-picker.ensam::after { content: none; }
.watch-picker:disabled { color: var(--text-heading); }
/* Väljarens halvark (lopp-valjare.js): Karta och Topplista. "Åkare jag följer"
   står avskild överst med en egen ikon - i en lista där alla rader såg likadana
   ut såg den ut som ett lopp bland andra (2026-09-12). */
.lopp-valjare { display: flex; flex-direction: column; }
.lopp-val {
  display: flex; align-items: center; gap: var(--luft-md); width: 100%; text-align: left;
  padding: var(--luft-md); background: none; border: 0; border-radius: var(--radius-sm);
  font: inherit; color: var(--text); cursor: pointer;
}
.lopp-val + .lopp-val { border-top: 1px solid var(--border); }
.lopp-val-foljer { margin-bottom: var(--luft-sm); }
.lopp-val-foljer + .lopp-val { border-top-width: 2px; }
.lopp-val-ikon { flex: none; display: flex; color: var(--text-muted); }
.lopp-val-text { display: flex; flex-direction: column; min-width: 0; }
.lopp-val-namn { font-weight: 600; color: var(--text-heading); }
.lopp-val.vald .lopp-val-namn, .lopp-val.vald .lopp-val-ikon { color: var(--accent); }
/* PLUSKNAPPEN i rubrikraden - Banor och Arrangera (flyttad hit ur courses.css
   2026-10-02, när Arrangera fick samma i stället för en knapp längst ner).
   Fast högst upp och inte efter listan: man ska aldrig behöva skrolla förbi
   hela listan för att hitta den. Text och ikon på bredare skärmar, en rund
   ikonknapp på mobil - en ensam plusikon är otydlig på dator. */
.btn-add {
  display: flex; align-items: center; gap: var(--luft-sm); flex: none; white-space: nowrap;
  background: var(--accent); color: var(--bg); border: none; border-radius: var(--radius-md);
  padding: var(--luft-md) var(--luft-lg); font-size: var(--text-normal); cursor: pointer;
}
.btn-add[hidden] { display: none; }
@media (hover: hover) { .btn-add:hover { background: var(--accent-hover); } }
.btn-add svg { flex: none; }
@media (max-width: 540px) {
  .btn-add { width: 44px; height: 44px; padding: 0; justify-content: center; border-radius: 50%; }
  .btn-add-label { display: none; }
}

/* ── Sidan ovanpa sidan ──────────────────────────────────────────────────
   En undersida som tacker sin sida helt, med tillbaka-pil och innehallet i kort
   i den vanliga kolumnen: tavlingens sidor pa /races och Traningsbanans sida pa
   Planera (2026-09-12). Stod forut som .race-detail i races.css; tva sidor av
   samma typ ska se ut och bete sig likadant, och en kopia hade glidit isar.

   Vyn ar position:fixed och ligger darfor UTANFOR body:s kolumnregel
   (`body { max-width: var(--col-desktop, ...) }`) - ett fixerat element mater
   sig mot fonstret, inte mot sin foralder. Den maste alltsa halla kolumnen
   sjalv, annars tacker den hela skarmbredden pa dator medan sidan bakom ar
   smalare. Rakningen ar densamma som mobilens body-regel: indraget ar halva
   overskottet plus den vanliga sidmarginalen (24 px pa dator), och max() haller
   det vid sidmarginalen sa fort fonstret ar smalare an kolumnen.

   Raden hette tidigare `padding-left: var(--content-left)`. Den variabeln
   definieras bara pa `body.has-bottom-nav`, och Tavlingar hade ingen sadan klass
   da (2026-09-12) - odefinierad var() gor deklarationen ogiltig vid berakning,
   sa padding-left foll till 0 och tog dessutom med sig de 16 px kortformen satt.
   Undersidorna bar klassen sedan 2026-09-18, men raden star kvar rakad mot
   fonstret: den ska halla sin kolumn aven pa en sida utan navigering. */
/* HAR LAG .page-view - en sidnivavy som tackte hela skarmen, navigeringen
   inraknad. Den var appens TREDJE sorts vy vid sidan av redigeringsvyn och
   Jags undervyer, och skillnaden syntes: Traningsbanans sida och tavlingens tva
   sidor tackte flikraden medan Redigera bana lat den sta kvar (Pers
   iakttagelse 2026-09-18). Alla tre ligger nu i samma ram, .edit-view ovan.
   Vad som SKILJER en sida fran en transaktion ar rubrikraden - pil mot X plus
   Spara - inte ramen runt omkring. */
/* EN regel for hela vyn: ett tomt <p> bar fortfarande sin marginal, sa varje
   oanvand statusrad lamnade ett dott falt. Regeln fanns i fyra kopior i
   tavlingens vyer, en per stalle den upptacktes, och lag pa .page-view till
   2026-09-18 - vyernas innehall flyttade da in i den delade ramen och tog
   raderna med sig. */
.edit-view .form-status:empty { display: none; }

/* Header pa vyer man kan backa fran: pil + rubrik ar EN klickbar yta.
   div role="button" i markupen (inte <button>) - en rubrik ar flow content
   och far inte ligga inuti en <button>, men ska behalla sin
   rubrik-semantik. */
.header-back {
  flex: 1; min-width: 0; min-height: 44px; display: flex; align-items: center; gap: var(--luft-sm);
  margin-left: -6px; background: none; border: none; padding: 0;
  color: inherit; text-decoration: none; text-align: left; cursor: pointer;
}
.header-back-icon {
  flex: none; display: flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: var(--radius-sm); color: var(--text-muted);
}
.header-back:hover .header-back-icon { background: var(--surface); color: var(--text); }
.header-back h1, .header-back h2 {
  margin: 0; font-size: var(--text-rubrik); min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Helskarmsvy pa mobil, centrerad dialog fran 541px. Fast positionering
   (inte width/height:100% i en grid-cell) - procentuell hojd genom en
   icke-stretchad grid-cell ar opalitlig i WebKit, vilket gjorde att
   innehallet vaxte forbi skarmen istallet for att .panel-body fick en
   andlig hojd att scrolla inom. */
.panel-overlay {
  position: fixed; inset: 0; z-index: var(--z-vy-tacke); display: grid; place-items: center;
  background: rgba(0,0,0,0.5); opacity: 0; pointer-events: none; transition: opacity 0.15s; box-sizing: border-box;
}
.panel-overlay.open { opacity: 1; pointer-events: auto; }
/* FLIKRADEN ÄR ALLTID NÅBAR, också med en vy uppe (Pers beslut 2026-09-18).
   Vyn och dess mörker slutar därför ovanför raden - de låg ÖVER den till dess,
   så raden syntes men gick inte att trycka på (uppmätt i mobil viewport: både
   Träningsbanan och Redigera bana täckte raden på 797-844 px).
   Regeln gällde först bara vyer som sparar direkt. Nu gäller den alla: ett
   flikklick ur en TRANSAKTION går genom vyns egen fråga om osparade ändringar,
   så vägen ut kan inte kasta arbete. Den kopplingen fanns redan - navigateTo i
   app-back.js stänger vyerna med en popstate och landar på fliken efteråt, och
   svarar en vy 'behåll' läggs de tillbaka och landningen körs aldrig. Se
   test_flikraden_med_vy_uppe.py.
   Mobilen mäter mot radens höjd - samma 56px som body.has-bottom-nav drar av.
   På dator är vyn en ruta i överläggets grid-cell, och där räcker indraget mot
   sidokolumnen längre ner. */
@media (max-width: 540px) {
  /* MÅTTET KOMMER FRÅN RADEN SJÄLV (--nav-höjd, satt av app-back.js): avståndet
     från viewportens botten till radens överkant. Raden bär redan
     env(safe-area-inset-bottom) i sin padding, så `56px + env(...)` räknade
     safe-area två gånger OCH gissade höjden (47 px) - kvar blev en springa där
     sidan bakom syntes, vilket såg ut som något dolt bakom raden (Pers
     skärmbild 2026-09-18). Reserven gäller bara innan skriptet mätt. */
  body.has-bottom-nav .edit-view-overlay,
  body.has-bottom-nav .edit-view {
    bottom: var(--nav-höjd, calc(47px + env(safe-area-inset-bottom)));
  }
}
.full-modal {
  position: fixed; inset: 0; z-index: var(--z-vy);
  background: var(--bg); border: none; border-radius: 0; box-shadow: none;
  display: flex; flex-direction: column;
  opacity: 0; transition: opacity 0.15s;
}
.full-modal.open { opacity: 1; }
/* Vyerna i helskärm börjar också under statusraden - se body ovan. Ett halvark
   når inte upp dit och behöver ingen. */
.full-modal:not(.edit-view-sheet) { padding-top: var(--statusrad); }
@media (min-width: 541px) {
  .panel-overlay { padding: 20px; }
  /* RUTAN CENTRERAS DÄR KOLUMNEN GÖR DET, inte i hela fönstret. Överlägget
     täcker fortsatt allt - mörkret ska ligga över navigeringen som förut - men
     grid-cellen dras in med navigeringens gutter, så rutans mitt hamnar på
     kolumnens (uppmätt 2026-09-18: kolumnen 354-1214 med mitt 784, rutan 470-970
     med mitt 720). padding och inte left/inset: bakgrunden rörs inte.
     Bundet till has-bottom-nav, eftersom sidor utan navigering (den delade vyn)
     inte har någon gutter att dra ifrån. */
  body.has-bottom-nav .panel-overlay { padding-left: calc(20px + var(--nav-gutter)); }
  /* VYN BÖRJAR EFTER NAVIGERINGEN i stället för att lägga sig över den. Ytan
     blir densamma som med padding, så rutan hamnar på kolumnens mitt precis som
     förut - men sidokolumnen går att trycka på med vyn uppe.
     Gällde bara vyer som sparar direkt till 2026-09-18; nu alla, eftersom ett
     flikklick ur en transaktion går genom vyns fråga (app-back.js). */
  body.has-bottom-nav .edit-view-overlay {
    left: var(--nav-gutter); padding-left: 20px;
  }
  /* KOLUMNEN LIGGER PÅ INNEHÅLLET, inte på vyn. En position:fixed-vy står
     utanför body:s kolumnregel (`body { max-width: var(--col-desktop, ...) }`)
     och mäter sig mot fönstret - så när vyn blev helskärm 2026-09-22 hade
     rubrik och fält annars hamnat i hela fönstrets bredd medan listan bakom
     ligger i 860. Samma fälla som beskrivs vid .edit-view längre upp, och
     skälet till att rutan en gång fick kolumnens bredd.
     BANVYN ÄR UNDANTAGET: dess kropp är en YTA för kartan och inte en spalt -
     kartan ska gå ända ut i kanterna (se course-places.css). */
  .edit-view:not(.edit-view-sheet) > .panel-header,
  .edit-view:not(.edit-view-sheet) > .panel-body:not(.course-edit-body),
  .edit-view:not(.edit-view-sheet) > .edit-view-status,
  .edit-view:not(.edit-view-sheet) > .edit-view-footer {
    width: 100%; max-width: var(--col-desktop, 860px); margin-inline: auto;
  }
  /* DIALOGEN ÄR EN RUTA. Kvar är `#add-panel` (Lägg till bana), som är märkt
     role="dialog" aria-modal="true" och STÄNGS GENOM ETT KLICK UTANFÖR
     (courses.js) - gjordes den helskärm fanns ingen utsida kvar att klicka på,
     och vägen ut hade försvunnit utan att något sagt ifrån.
     Lika bred som listan bakom (Pers önskemål 2026-09-18): rutan stod på 520px
     medan kolumnen var 860 och läste som en liten lapp mitt på sidan. */
  .full-modal:not(.edit-view) {
    position: relative; inset: auto; width: min(var(--col-desktop, 860px), 100%); max-height: min(640px, 85vh);
    border: 1px solid var(--border); border-radius: var(--radius-lg);
    box-shadow: var(--skugga-dialog); transform: scale(0.96);
  }
  .full-modal:not(.edit-view).open { transform: scale(1); }

  /* VYN ÄR HELSKÄRM, också på dator (Pers beslut 2026-09-22). Den var en ruta
     med ram och skugga mitt på skärmen - ett arv från när vytyperna var
     dialoger, inte ett val: klasserna heter panel-overlay och full-modal, och
     skuggan --skugga-dialog.
     MEN INTE ÖVER NAVIGERINGEN. Det var precis vad .page-view gjorde, och den
     togs bort 2026-09-18 på Pers iakttagelse att vyerna betedde sig olika -
     Träningsbanan täckte flikraden medan Redigera bana lät den stå kvar. Vyn
     börjar därför efter sidokolumnen, som fortsätter gå att trycka på. Det är
     samma regel som på mobil, där vyn slutar ovanför flikraden.
     HALVARKET UNDANTAS: det centreras med left: 50 % i sitt eget block längre
     ner, och den här regeln är mer specifik och hade vunnit över den. */
  body.has-bottom-nav .edit-view:not(.edit-view-sheet) { left: var(--nav-gutter); }
}
.panel-header { display: flex; align-items: center; gap: var(--luft-sm); padding: var(--luft-lg); border-bottom: 1px solid var(--border); flex: none; }
.panel-body { flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch; padding: var(--luft-lg); }

/* Leaflets zoomkontroller ar 30px i biblioteket. De ar knappar som alla andra
   och foljer samma matt. */
.leaflet-control-zoom a { width: 44px !important; height: 44px !important;
  line-height: 44px !important; }

/* ── Listrader ───────────────────────────────────────────────────────────
   Tre listtyper, och raden ska ga att LASA som en av dem utan att man
   provtrycker (server/docs/ux-principer.md punkt 13):

     navigationsrad  chevron till hoger, leder vidare
     valrad          valmarkering, valjer nagot
     atgardsrad      knapp, utfor nagot pa plats

   Formen ar densamma for alla tre: rader atskilda av en linje, inte kort
   inuti ett kort. Sex kort i en yta som redan ar ett kort blir ett lager for
   mycket, och linjerna later blicken ga rakt ner genom samma kolumn. Samma
   grepp som akarraden och tavlingsraden redan anvande - enhetslistan pa Profil
   var det enda stallet som ritade sma kort i stallet.

   .course-row nedan ar sin egen sak och inte en av de tre: den fals ut PA
   PLATS, alltsa varken navigering, val eller atgard. */
/* MIN-HOJD OCH INTE BARA PADDING (2026-09-21). Raden var 44px bara sa lange
   titeln rakade vara 17,92px hog - nar texten flyttade till --text-normal
   (15,2) foll Jags fyra navigationsrader till 41-42px, alltsa under det matt en
   tumme traffar. Traffytan far inte hanga pa hur stor texten ar; samma princip
   som favoritstjarnan och distansstegaren redan foljer. */
.list-row {
  display: flex; align-items: center; gap: var(--luft-md); min-height: 44px;
  width: 100%; padding: var(--luft-md) 0; border-top: 1px solid var(--border);
  background: none; border-left: none; border-right: none; border-bottom: none;
  color: inherit; text-align: left; font: inherit;
}
.list-row:first-child { border-top: none; }
/* Bara den som leder eller utfor nagot ska kannas klickbar. */
.list-row-nav { cursor: pointer; }
/* Bara med en riktig pekare: på en telefon fastnar :hover på raden man senast
   tryckte på, och namnet stod kvar grönt (Pers fynd 2026-10-02). */
@media (hover: hover) {
  .list-row-nav:hover .list-row-title { color: var(--accent); }
}
.list-row-nav:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px;
  border-radius: var(--radius-sm); }
.list-row-text { flex: 1; min-width: 0; }
.list-row-title { font-size: var(--text-normal); display: block; font-weight: 600; color: var(--text-heading);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.list-row-meta { display: block; margin-top: 2px; }
/* Chevronen sager "leder vidare" och ritas av chevron() i course-row.js -
   EN pil i appen, inte en inklistrad SVG-strang per stalle. */
.list-row-chevron { flex: none; color: var(--text-muted); display: flex; }
/* KOMPONENTERNA (komponenter.js, 2026-10-09) - det raderna och grupperna
   behöver utöver .list-row. Sidorna bygger dem genom komponenter.js och ritar
   inte om dem. */
/* Värdet till höger (en tid, en placering) - lika tungt som namnet. */
.list-row-varde { flex: none; font-size: var(--text-normal); font-weight: 600; color: var(--text-heading);
  font-variant-numeric: tabular-nums; }
/* RÄKNAREN före pilen (_komponenter.html rad, räknare=): det som väntar där,
   samma siffra som pricken på fliken - raden läser "Följare 2 >". Låg i
   settings.css som .settings-row-badge till 2026-10-09. */
.list-row-raknare { margin-left: auto; min-width: 20px; padding: 0 6px; border-radius: 999px;
  background: var(--accent); color: var(--on-accent); font-size: var(--text-stod);
  font-weight: 700; line-height: 20px; text-align: center; flex: none; }
/* Profilhuvudet överst på Jag: namnet i rubrikstorlek. */
.list-row-stor .list-row-title { font-size: var(--text-rubrik); }
/* LOGGEN (_komponenter.html logg): det som hänt, tätare än en rad som leder
   någonstans. Det som inte setts har en prick i samma färg som den i
   navigeringen - det är samma sak. */
.list-row-logg { align-items: baseline; padding: var(--luft-sm) 0; }
.list-row-loggtext { flex: 1; min-width: 0; }
.list-row-loggtid { flex: none; }
.list-row-logg.ny .list-row-loggtext::before {
  content: ""; display: inline-block; vertical-align: middle;
  width: 7px; height: 7px; margin-right: var(--luft-sm); border-radius: 50%;
  background: var(--red);
}
.list-row-logg:not(.ny) .list-row-loggtext { color: var(--text-muted); }
/* Placeringen till vänster, i linje under varandra. */
.list-row-placering { flex: none; min-width: 1.6em; color: var(--text-muted);
  font-size: var(--text-stod); font-variant-numeric: tabular-nums; }
.list-row-knappar { flex: none; display: flex; flex-wrap: wrap; gap: var(--luft-sm); }
/* Under namnet (en arkiverad bana): luft mot metaraden ovanför. */
.list-row-text > .list-row-knappar { margin-top: var(--luft-sm); align-items: center; }
/* Ett inlägg: metaraden och hela texten, ingen pil. */
.list-row-inlagg { display: block; }
.list-row-brodtext { margin: 2px 0 0; white-space: pre-line; color: var(--text); }
/* En rad som hör till den ovanför: indragen, och utan linje mot den. */
.list-row-under { margin-left: var(--luft-lg); padding-left: var(--luft-md);
  border-left: 2px solid var(--border); width: auto; }
.list-row + .list-row-under, .list-row-under + .list-row-under { border-top: none; }
/* Rubriken med brickor bredvid: namnet krymper, brickorna står kvar. */
.list-row-rubrik { display: flex; align-items: center; gap: var(--luft-sm); min-width: 0; }
.list-row-rubrik .list-row-title { flex: 0 1 auto; min-width: 0; }
/* Den utfällbara raden: linjen sitter på behållaren, så att en öppen rad och
   dess innehåll hör ihop. */
.list-row-utfallbar { border-top: 1px solid var(--border); }
.list-row-utfallbar:first-of-type { border-top: none; }
.list-row-utfallbar > .list-row { border-top: none; }
/* Rubrikraden är en <summary>: webblasarens triangel bort, appens pil vrids. */
summary.list-row { list-style: none; }
summary.list-row::-webkit-details-marker { display: none; }
.list-row-utfallbar[open] > summary .list-row-chevron svg { transform: rotate(90deg); }
.list-row-innehall { padding-bottom: var(--luft-md); }
.list-row-innehall > .hint:first-child { margin-top: 0; }
/* Grupperna: rubriken, och raderna i en egen behållare så att första raden
   inte får en linje under rubriken. */
.grupp + .grupp { margin-top: var(--luft-lg); }
.grupp > .grupprubrik { margin-bottom: var(--luft-xs); }
.grupp.list-section { border-top: none; margin-top: var(--luft-lg); }
.grupp.list-section > .list-section-toggle { padding: var(--luft-xs) 0; min-height: 44px; }

/* ── Banraden och dess verktygsrad ───────────────────────────────────────
   Delad av Hantera banor och banvaljaren pa Planera (course-row.js,
   course-filter.js). De hade var sin kopia - .course-row och .picker-row -
   med samma summeringsrad, samma chevron och samma kartruta.

   Kompakt lista: namn + nyckeltal, som fals ut pa plats vid klick i stallet
   for att navigera bort eller alltid visa hela formularet for varje bana. */
.toolbar { display: flex; gap: var(--luft-sm); margin-bottom: var(--luft-md); }
.toolbar .field-input { flex: 1; min-width: 0; }
/* .popover .radio-row och inte bara .radio-row: `.popover label` ovan ar mer
   specifik och satter display:block, sa raden tappade sin flexlayout nar
   regeln flyttade hit fran courses.css. */
.popover .radio-row { display: flex; align-items: center; gap: var(--luft-sm); font-size: var(--text-normal);
  color: var(--text); margin: var(--luft-sm) 0; }
/* Segmenterad stigande/fallande-valjare i stallet for tva egna radioknappar -
   mindre yta, och tydligt avskild fran nyckel-listan ovanfor sa popovern inte
   blir en enda ostrukturerad stapel. */
.sort-dir-toggle { display: flex; gap: var(--luft-xs); margin-top: 14px; padding-top: var(--luft-efter-linje);
  border-top: 1px solid var(--border); }
.sort-dir-btn { flex: 1; padding: 6px 8px; font-size: var(--text-stod); border-radius: var(--radius-sm);
  border: 1px solid var(--border-input); background: var(--bg); color: var(--text-muted);
  cursor: pointer; }
.sort-dir-btn.active { border-color: var(--accent); color: var(--accent); background: var(--surface); }

.course-row { border-radius: var(--radius-md); border: 1px solid var(--border-input);
  background: var(--surface); margin: var(--luft-sm) 0; overflow: hidden; }
/* RADERNA I ETT KORT (Pers fråga 2026-10-03: "varje bana har ett eget kort -
   är inte det onödigt?"). Banor och Pass hade ett kort per rad; nu står
   raderna i ett gemensamt kort, åtskilda av en linje, som tävlingarnas.
   Banväljaren står utanför .radlista och behåller sina radkort. */
.card.radlista { padding: var(--luft-xs) var(--luft-sm); }
.radlista > .course-row { border: none; border-radius: 0; margin: 0; background: none; }
.radlista > .course-row + .course-row { border-top: 1px solid var(--border); }
.course-row-summary {
  display: flex; align-items: center; justify-content: space-between; gap: var(--luft-sm); width: 100%;
  padding: var(--luft-md); background: none; border: none; color: inherit; text-align: left;
  cursor: pointer; font: inherit;
}
.course-row-summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* Symbolen ar 23px men ytan 44: paddingen vaxer utat och den negativa
   marginalen tar tillbaka utrymmet, sa raden ser likadan ut som forut. */
.course-row-favorite {
  flex: none; background: none; border: none; font-size: 1.3rem; line-height: 1;
  color: var(--text-muted); cursor: pointer;
  min-width: 44px; min-height: 44px; margin: -10px 0 -10px -10px;
  display: flex; align-items: center; justify-content: center;
}
.course-row-favorite.on { color: var(--varning); }
/* Texten tar resten av bredden: utan flex hamnade namnet mitt i raden med en
   lucka mellan stjarnan och sig, vilket blev tydligt fel sa fort miniatyren
   kom dit. Chevron och markning ligger kvar till hoger. */
.course-row-summary-text { flex: 1; min-width: 0; }
.course-row-name { font-size: var(--text-normal); font-weight: 600; color: var(--text-heading); }
.course-row-meta { display: block; margin-top: 2px; }
.course-row-chevron { flex: none; color: var(--text-muted); transition: transform 0.15s; display: flex; }
.course-row.expanded .course-row-chevron { transform: rotate(90deg); }
.course-row-detail { padding: 0 var(--luft-md) var(--luft-md); }
/* isolation:isolate - Leaflet satter position:relative pa kartbehallaren men
   ingen egen z-index, sa dess interna lager (kontroller upp till 1000) lacker
   ut och tavlar med sidans overlays. */
.course-row-map { height: 160px; border-radius: var(--radius-md); overflow: hidden;
  background: var(--bg); margin-bottom: 10px; isolation: isolate; }
.course-row-map:empty { display: none; margin: 0; }
/* Miniatyren: banans form, ritad som en SVG utan kartbakgrund (course-row.js).
   44x44 ar samma matt som en trafflig traffyta - rutan bar alltsa bade
   igenkanningen och en del av radens hojd. Hantera banor OCH tavlingslistan
   (2026-09-06); banvaljaren fals ut och visar en riktig karta i stallet. */
.course-thumb {
  display: block; border: 1px solid var(--border);
  border-radius: var(--radius-sm); background: var(--surface-sunken, var(--surface));
}
.course-thumb svg { width: 100%; height: 100%; display: block; padding: 3px;
  box-sizing: border-box; }
.course-row-thumb { flex: none; width: 44px; height: 44px; }
/* non-scaling-stroke gor att bredden lases i PIXLAR och inte i viewBox-enheter
   - annars maste den anges som 0.0x, och en sadan siffra ar latt att skriva av
   sig pa till nagot osynligt. */
.course-thumb polyline { fill: none; stroke: var(--accent); stroke-width: 2;
  stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke; }
/* Navigationsraden leder vidare och ska kannas klickbar i hela sin bredd. */
.course-row-nav .course-row-summary { cursor: pointer; }
/* Bara med en riktig pekare: på en telefon fastnar :hover på raden man senast
   tryckte på, och namnet stod kvar grönt (Pers fynd 2026-10-02). */
@media (hover: hover) {
  .course-row-nav:hover .course-row-name { color: var(--accent); }
}

.course-row-actions { display: flex; gap: var(--luft-sm); margin-top: 6px; }
.course-row-actions button { flex: 1; }

/* Den bana som galler just nu. Accentram plus en liten etikett - ramen ensam
   ar for svag i en lista dar varje rad redan har en ram, och fargen far inte
   bara betydelsen (raden bar aria-current). */
/* BRICKAN: en egenskap i en rad - tävlingens läge, passets typ. Delad av
   Tävlingar och Aktiviteter; låg i races.css till 2026-10-06. */
.race-badge { flex: none; font-size: var(--text-stod); color: var(--text-muted);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  /* EGET MATT: en bricka ar sa liten den kan vara och anda rymma sin text.
     Avstandsmigreringen rundade 1px 6px -> 4px 8px och gjorde den dubbelt sa
     hog (2026-09-21). En komponents inre padding ar dess FORM, inte luft mellan
     element, och hor darfor inte till luftskalan. */
  padding: 1px 6px; }
/* KLASSNINGENS BRICKA (komponenter.js klassbricka): passets sort i sin färg. */
.klass-chip { color: var(--on-accent); background: var(--klassfarg); border-radius: 999px; padding: 1px 8px;
  font-size: var(--text-stod); white-space: nowrap; }
.cls-distans { --klassfarg: var(--klass-distans); }
.cls-langpass { --klassfarg: var(--klass-langpass); }
.cls-intervall { --klassfarg: var(--klass-intervall); }
.cls-troskel { --klassfarg: var(--klass-troskel); }
.cls-aterhamtning { --klassfarg: var(--klass-aterhamtning); }
.cls-styrka { --klassfarg: var(--klass-styrka); }
.cls-teknik { --klassfarg: var(--klass-teknik); }
.cls-test { --klassfarg: var(--klass-test); }
.cls-default { --klassfarg: var(--klass-ovrigt); }
/* Brickans två toner (komponenter.js bricka()): något att ta ställning till,
   och något som inte blir av. Låg i races.css till 2026-10-09. */
.race-badge-attention { color: var(--accent); border-color: var(--accent); }
.race-badge-cancelled { color: var(--red); border-color: var(--red); }
.course-row.selected { border-color: var(--accent); }
/* Märket på den valda banan är komponentens bricka (komponenter.js) - här
   bara att den står längst till höger. */
.course-row-summary > .race-badge { margin-left: auto; }
/* Chevronen kommer efter etiketten - utan det har hamnar den intill namnet och
   etiketten langst ut, tvartemot ordningen i markupen. */
.course-row.selected .course-row-chevron:not(.course-row-disclosure) { margin-left: var(--luft-sm); }
/* Valet i banvaljarens rad, langst ut till hoger dar "Vald" star pa den bana
   som galler (course-row.js, `välj`). 44 px traffyta; den negativa
   marginalen tar tillbaka hojden, sa raden inte blir hogre an forut. */
.course-row-choose { flex: none; margin: -4px 0 -4px auto; min-height: 44px; padding: 0 var(--luft-lg); }
/* Utfallningspilen star till VANSTER om namnet i en rad som fals ut - hogra
   kanten ar Valj/Vald:s. Den vrids nedat nar raden ar oppen (regeln for
   .course-row.expanded ovan). */
.course-row-disclosure { margin-left: -4px; }

/* ── Toasten ─────────────────────────────────────────────────────────────
   En rad som seglar in over innehallet och sager nagot kort. UTSEENDET star
   har, PLACERINGEN hos den som visar den: kartans nyhetsflash sitter under
   loppvaljaren och lamnar plats for knappstapeln, installationsrutan hanger i
   sidans ovankant. Tva uppsattningar stilar hade glidit isar. */
.toast {
  position: fixed; z-index: 55;
  display: flex; align-items: center; gap: var(--luft-sm);
  background: var(--surface); color: var(--text);
  border-radius: var(--radius-md); box-shadow: var(--skugga-lyft);
  padding: var(--luft-md) var(--luft-md); font-size: var(--text-normal);
  opacity: 0; transform: translateY(-8px);
  transition: opacity .2s ease, transform .2s ease;
}
.toast.visible { opacity: 1; transform: translateY(0); }
/* Knapparna i en toast ar sma - raden ar smal och texten bredvid ar det
   viktiga. */
.toast .btn-primary, .toast .btn-secondary { padding: 6px 12px; font-size: var(--text-stod); }
.toast-text { flex: 1 1 auto; }
.toast-close {
  flex: none; border: none; background: none; cursor: pointer;
  color: var(--text-muted); font-size: 1.1rem; line-height: 1; padding: 4px 6px;
}

/* Installationsrutan: sidans ovankant, over allt utom modalerna. Egen placering
   och inget annat - utseendet kommer fran .toast ovan. */
.install-toast { top: 12px; left: 16px; right: 16px; }
@media (min-width: 541px) {
  .install-toast { left: auto; right: 24px; max-width: 420px; }
}

/* ── Kontrollfragan ──────────────────────────────────────────────────────
   EN dialog i hela appen (static/js/confirm-dialog.js). Den lag i fyra
   skepnader: webblasarens egen ruta, .small-modal pa Hantera banor,
   .confirm-box pa Tavlingar och en inbakad rad i listan pa Delning.

   Rutan anvands pa tva stallen: fritt over sidan (.confirm-overlay) och inuti
   en redigeringsvy, dar fragan galler VYN och inte sidan under
   (.edit-view-confirm). Samma ruta, tva vardar. */
.confirm-overlay {
  position: fixed; inset: 0; z-index: var(--z-fraga);
  display: grid; place-items: center; padding: 24px;
  background: rgba(0,0,0,0.5);
}
.confirm-box {
  width: min(340px, 100%); padding: 20px; border-radius: var(--radius-lg);
  background: var(--surface); box-shadow: var(--skugga-dialog);
}
.confirm-title { margin: 0 0 var(--luft-sm); font-size: var(--text-rubrik); }
/* Forklaringsrutan (static/js/info-dialog.js) ar samma ruta - den BERATTAR
   bara, sa den ar bredare och far luft mellan styckena och en enda vag ut. */
.info-box { width: min(420px, 100%); }
.info-box .confirm-text + .confirm-text { margin-top: 10px; }
.info-box .btn-block { margin-top: var(--luft-lg); }
/* ⓘ efter det varde den forklarar. Ingen knappruta: den ska lasa som en del av
   raden, inte tavla med den. Traffytan ar anda 44 px (padding). */
.info-btn {
  margin-left: 6px; padding: 0 6px;
  border: none; background: none; cursor: pointer;
  font-size: 1rem; line-height: 1; color: var(--text-muted);
}
.info-btn:hover { color: var(--text-heading); }
.confirm-text { margin: 0; color: var(--text-muted); font-size: var(--text-normal); }
/* Statusraden syns bara nar den har nagot att saga - annars ett tomt hal
   mitt i rutan. */
.confirm-box .form-status:empty { display: none; }
/* Vagen ut till vanster, handlingen till hoger. Bada far vaxa och radbryta
   till var sin rad nar etiketterna ar langa ("Stang utan att spara") - en
   knapp vars text kapas sager inte langre vad den gor. */
.confirm-actions { display: flex; flex-wrap: wrap; gap: var(--luft-sm); margin-top: var(--luft-lg); }
.confirm-actions button { flex: 1 1 auto; min-width: 8em; }

/* Varvforslaget efter en import. En INRAMAD ruta och inte bara text: den ar en
   fraga som vantar pa svar, till skillnad fran statusraden ovanfor den som bara
   berattar vad som hant. */
.import-loop-suggestion {
  margin-top: var(--luft-md); padding: var(--luft-md);
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--surface-raised, transparent);
}
.import-loop-suggestion p { margin: 0 0 var(--luft-sm); font-size: var(--text-normal); }
.import-loop-suggestion p:last-of-type { margin-bottom: 0; }
.import-loop-suggestion.error p:first-child { color: var(--red); }
.import-loop-actions { display: flex; flex-wrap: wrap; gap: var(--luft-sm); margin-top: var(--luft-md); }
.import-loop-actions button { flex: 1 1 auto; min-width: 8em; }

/* Sok/sortera/filter-verktygsrad med popover-paneler. */
.toolbar-btn { position: relative; flex: none; }
/* Ett pasatt filter syns aven nar panelen ar stangd, och antalet star pa
   knappen (ux-principer punkt 19). Egen klass och inte .active - den betyder
   "popovern ar oppen". */
.toolbar-btn > button.har-filter { border-color: var(--accent); color: var(--accent); }
.toolbar-btn.active > button { border-color: var(--accent); color: var(--accent); }
.popover {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 40; width: 280px;
  background: var(--surface); border: 1px solid var(--border-input); border-radius: var(--radius-md);
  padding: var(--luft-md); box-shadow: var(--skugga-lyft);
}
.popover label { display: block; font-size: var(--text-stod); color: var(--text-muted); margin: var(--luft-md) 0 var(--luft-xs); }
.popover label:first-child { margin-top: 0; }
/* Synligt "-" mellan min/max istallet for tva fristaende falt pa rad. */
.popover .range-row { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: var(--luft-sm); }
.popover .range-row span { color: var(--text-muted); }
.popover .btn-secondary {
  min-height: 44px; width: 100%; margin-top: var(--luft-md); }
/* Riktiga <button aria-pressed> istallet for kryssrutor - samma visuella
   sprak for alla flerval (Typ/Manad/Favorit). */
.pill-group { display: flex; flex-wrap: wrap; gap: var(--luft-xs); margin-top: var(--luft-xs); }
.pill-btn {
  border: 1px solid var(--border-input); border-radius: var(--radius-sm); padding: 5px 10px;
  background: transparent; color: var(--text); font-size: var(--text-stod); cursor: pointer;
}
.pill-btn[aria-pressed="true"] { border-color: var(--accent); color: var(--accent); background: var(--bg); }

/* hidden-attributet slar ut allt annat. Utan det har vinner en egen
   display-regel (t.ex. .map-fab { display: flex }) over webblasarens
   [hidden] { display: none }, och elementet syns trots att koden sagt at det
   att forsvinna - upptackt pa nyhetsknappen 2026-08-21. */
[hidden] { display: none !important; }

/* ── Akarraden ────────────────────────────────────────────────────────────────
 Delad av infopanelen pa kartan och av topplistan: samma akare ska se likadan
 ut pa bada stallen. Rader atskilda av en linje i stallet for var sitt kort -
 sex kort inuti en yta som redan ar ett kort blir ett lager for mycket, och
 linjerna later blicken ga rakt ner genom samma kolumn hos alla akare. */
.athlete-row { padding: var(--luft-md) 0; }
.athlete-row + .athlete-row { border-top: 1px solid var(--border); }
/* Samma grasgörning som den inaktuella akar-markoren pa kartan (se isStale()) -
   varden andras inte, bara den visuella tydligheten i att de inte ar aktuella. */
.athlete-row.stale { opacity: 0.55; }
.athlete-head { display: flex; align-items: baseline; gap: var(--luft-sm); margin-bottom: 6px; }
/* Samma farg som akarens spar, markor och foljknapp - raden gar att koppla ihop
   med ratt spar pa kartan utan att lasa nagot namn. Fargen ar aldrig ensam
   barare: namnet star bredvid. */
.athlete-chip { flex: none; width: 10px; height: 10px; border-radius: 50%;
  align-self: center; }
.athlete-name { font-size: var(--text-normal); font-weight: 600; color: var(--text-heading);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.athlete-chip.utan-farg { box-sizing: border-box; border: 2px solid var(--border); }
.athlete-lopp { flex: none; font-size: var(--text-stod); color: var(--text-muted);
  white-space: nowrap; }
.athlete-goal { margin-left: auto; font-size: var(--text-stod); color: var(--text-muted);
  white-space: nowrap; font-variant-numeric: tabular-nums; }
.athlete-goal:empty { display: none; }
/* Fem kolumner pa EN rad, aldrig auto-fit: med auto-fit bar pulsen over till en
   egen rad sa fort bredden inte rackte till fem spar, och de fem varden hor
   ihop som en avlasning.

   Kolumnerna ar innehallsbreda, och det som blir over fordelas JAMNT mellan dem
   (space-between). Forr var de fasta brakdelar - 1fr 1fr 1.25fr 1fr 0.85fr -
   satta efter det bredaste tankbara innehallet i varje kolumn. Tid fick mest
   plats for "1:02:33" och behaller den aven nar klockan star pa "12:34", sa
   luckan mellan Tid och Fart blev bred nog att lasa som en avdelare mellan tva
   grupper (anvandarens fynd 2026-08-26). Nagon gang under ett lopp vaxer Tid
   med en timsiffra och kolumnerna flyttar sig en gang - siffrorna i sig rycker
   inte, det ar vad tabular-nums nedan ar till for.

   minmax(0, max-content) och inte max-content: pa en riktigt smal skarm maste
   kolumnerna kunna krympa under sitt innehall i stallet for att spilla ut ur
   panelen. */
.athlete-cells { display: grid;
  /* Sju rutor: varvet finns bara i ett flervarvslopp och stakfrekvensen bara
     nar telefonen mater den (2026-10-08). Doljs de (hidden) faller kolumnerna
     bort och de fem star som forut. */
  grid-template-columns: repeat(7, minmax(0, max-content));
  justify-content: space-between;
  gap: var(--luft-sm) var(--luft-sm); }
.athlete-cell { display: flex; flex-direction: column; gap: var(--luft-xs); min-width: 0; }
.cell-label { font-size: 0.68rem; color: var(--text-muted); }
.cell-value { display: flex; align-items: baseline; gap: var(--luft-xs); min-width: 0; }
/* PULSZONENS TRAPPA (athlete-row.js, Pers beslut 2026-09-25): fem staplar som
   växer, och de till och med zonen fylls i sin zons färg. Zon 0 fyller ingen. */
.puls-trappa { display: inline-flex; align-items: flex-end; gap: 2px; height: 0.95em;
  align-self: center; }
.puls-trappa[hidden] { display: none; }
.puls-trappa i { width: 4px; border-radius: 1px; background: var(--border); }
.puls-trappa i:nth-child(1) { height: 40%; }
.puls-trappa i:nth-child(2) { height: 55%; }
.puls-trappa i:nth-child(3) { height: 70%; }
.puls-trappa i:nth-child(4) { height: 85%; }
.puls-trappa i:nth-child(5) { height: 100%; }
.puls-trappa i[data-zon="1"] { --zonfarg: var(--hr-zone-1); }
.puls-trappa i[data-zon="2"] { --zonfarg: var(--hr-zone-2); }
.puls-trappa i[data-zon="3"] { --zonfarg: var(--hr-zone-3); }
.puls-trappa i[data-zon="4"] { --zonfarg: var(--hr-zone-4); }
.puls-trappa i[data-zon="5"] { --zonfarg: var(--hr-zone-5); }
.puls-trappa[data-zon="1"] i:nth-child(-n+1),
.puls-trappa[data-zon="2"] i:nth-child(-n+2),
.puls-trappa[data-zon="3"] i:nth-child(-n+3),
.puls-trappa[data-zon="4"] i:nth-child(-n+4),
.puls-trappa[data-zon="5"] i:nth-child(-n+5) { background: var(--zonfarg); }
/* tabular-nums: siffrorna skrivs om varje sekund (se tickPanel), och utan fast
   siffbredd rycker hela raden i sidled nar en etta byts mot en atta. */
.cell-number { font-size: var(--text-normal); font-weight: 600; color: var(--text-heading);
  font-variant-numeric: tabular-nums; }
.cell-unit { font-size: 0.68rem; color: var(--text-muted); }
/* Smala telefoner: strama at typografin i stallet for att lata nagot brytas ner
   pa en egen rad. Grasen ar satt sa att 320px - panelens sidpadding fortfarande
   rymmer alla fem. */
@media (max-width: 380px) {
  .athlete-cells { gap: var(--luft-sm) var(--luft-xs); }
  .cell-number { font-size: 0.85rem; }
  .cell-label, .cell-unit { font-size: 0.62rem; }
}

/* Placeringssiffran: bara topplistan har en. Kartans panel staller akarna i
   palettordning, och en siffra dar hade sett ut som en placering utan att vara det. */
.athlete-place { flex: none; min-width: 1.4em; font-size: var(--text-normal); font-weight: 700;
  color: var(--text-muted); font-variant-numeric: tabular-nums; text-align: right; }

/* Redigeringsvyn - det delade skalet (static/js/edit-view.js). Stilarna bor HAR
   och inte i en sidas egen stilmall: vyn ar samma sak overallt, och det ar hela
   poangen med den. */
.edit-view-header { justify-content: space-between; gap: var(--luft-xs); padding: 0 var(--luft-xs); }
/* Kartan i banvyn gar kant till kant och anda upp hit, sa raden far ingen
   egen underkantslinje att skilja sig fran den med. */
.edit-view-header { border-bottom: none; }
/* Rubriken klipps, men ⓘ:t bredvid den gor det inte: en lang rubrik gomde
   knappen helt, och da gick vyn inte att fa forklarad. */
.edit-view-title { flex: 1; min-width: 0; margin: 0; font-size: var(--text-rubrik);
 color: var(--text-heading);
  display: flex; align-items: center; justify-content: center; gap: var(--luft-xs); }
.edit-view-title-text {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* X och Spara ar bada 44px hoga: samma minsta trafferyta som handtaget pa
   infopanelen, och de sitter i overkanten dar tangentbordet aldrig nar dem. */
.edit-view-close {
  flex: none; width: 44px; height: 44px; display: flex; align-items: center; justify-content: center;
  background: none; border: none; color: var(--text); cursor: pointer; padding: 0;
  border-radius: var(--radius-md); -webkit-tap-highlight-color: transparent;
}
/* Spara ar en LANK och inte en fylld knapp: en knapp gjorde rubrikraden onodigt
   hog, och raden ska ta sa lite plats som mojligt fran det man faktiskt
   redigerar. Traffytan ar fortfarande 44px hog - den sitter i paddingen. */
.edit-view-save, .edit-view-balans {
  flex: none; min-height: 44px; padding: 0 var(--luft-md); border: none; background: none;
  color: var(--accent); font-size: var(--text-normal); cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.edit-view-save:active { opacity: 0.6; }
.edit-view-save:disabled { opacity: 0.5; cursor: default; }
/* En vy som sparar direkt har ingen Spara, men platsen behålls så titeln står
   mitt i huvudet (edit-view.js, sparasDirekt). EGEN KLASS och inte ett tillägg
   på .edit-view-save: den skulle annars matcha varje selektor som letar efter
   vyns Spara-knapp - se kommentaren i edit-view.js. */
.edit-view-balans { visibility: hidden; }
.edit-view-status:empty { display: none; }
.edit-view-status { padding: 0 var(--luft-lg) var(--luft-md); }
/* Radera langst ner, med luft over sig: den ska inte ga att trycka pa av bara
   farten nar man siktar pa nagot annat. */
.edit-view-footer { margin-top: 28px; padding-top: var(--luft-efter-linje); border-top: 1px solid var(--border);
  display: flex; justify-content: flex-end; }
/* Kontrollfragan ligger over vyns egen yta - den galler vyn, inte sidan under.
   Sjalva rutan ar .confirm-box, samma som overallt annars; det enda som skiljer
   ar att den ar absolut mot vyn i stallet for fixerad mot fonstret. */
.edit-view-confirm { position: absolute; inset: 0; z-index: 5;
  display: grid; place-items: center; padding: 24px; background: rgba(0,0,0,0.5); }
.edit-view { position: fixed; }

/* Halvarket: samma vy, mindre yta. For nagot man just pekat ut pa en karta -
   hela poangen ar att man ska SE var man klickade, sa vyn far inte ta skarmen.
   Ytan utanfor slapper igenom klick (pointer-events: none) sa kartan gar att
   dra och zooma medan arket ligger uppe; arket sjalvt tar forstas emot dem. */
/* .open och inte bara klassen: .panel-overlay.open sätter pointer-events: auto
   och vinner annars pa specificitet - da fangade en osynlig yta alla klick pa
   kartan, vilket ar precis det halvarket finns for att slippa. */
.edit-view-overlay-sheet.open { background: none; pointer-events: none; }
.edit-view-overlay-sheet .edit-view-sheet {
  pointer-events: auto;
  top: auto; bottom: 0; left: 0; right: 0;
  max-height: 45%;
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  box-shadow: var(--skugga-ark);
  border-top: 1px solid var(--border);
}
/* ARKET ÄR TÄTARE ÄN EN HEL SIDA (Pers fynd 2026-09-20: "den här panelen är för
   luftig och tar för mycket plats"). Ett halvark visar några få fält om något
   man just pekat ut på kartan, och varje pixel det tar är en pixel mindre av
   kartan - medan en helskärmsvy har ytan ändå.
   Bara arket, alltså: helskärmsvyerna behåller sin luft. Måtten kommer ur
   luftstegen i :root, så tätheten går att ändra på ett ställe.

   HUVUDET RÖRS INTE. Här stod först en regel för .panel-header också, och den
   gjorde arket STÖRRE: .edit-view-header har redan padding 0 4px, alltså ingen
   vertikal luft alls, och en mer specifik regel lade tillbaka tolv pixlar upptill
   och nedtill. Uppmätt: arket växte från 36 % av skärmen till 38 %. */
.edit-view-sheet .panel-body { padding: var(--luft-sm) var(--luft-lg) var(--luft-md); }
/* FOTEN TÄTARE I ARKET (Pers fynd 2026-09-20: "dialogen tar fortfarande för
   mycket luft och den tar onödigt stor plats"). Den stod på 28 + 16 px plus en
   linje - alltså 44 px luft ovanför "Lägg till nästa plats", och 28 var
   dessutom ett tal utanför luftstegen.
   På en HELSKÄRMSVY är den luften rätt: foten bär Radera och ska stå tydligt
   ifrån fälten. I ett ark som ligger över kartan är den bara bortkastad yta. */
.edit-view-sheet .edit-view-footer {
  margin-top: var(--luft-md); padding-top: var(--luft-sm);
}
@media (min-width: 541px) {
  /* Pa dator ar arket en ruta i nederkanten av innehallskolumnen, inte en
     remsa tvars over hela fonstret. */
  .edit-view-overlay-sheet { padding: 0; place-items: end center; }
  .edit-view-overlay-sheet .edit-view-sheet {
    position: fixed; width: min(520px, 100%); left: 50%; transform: translateX(-50%);
  }
}

/* En vy med en annan ovanpa sig: knapparna slas av bade i sak (edit-view.js)
   och till utseendet. Halvarket slapper igenom klick utanfor arket, sa
   overkanten GAR att traffa - och en knapp som ser tryckbar ut men inte gor
   nagot ar varre an en som syns vara avstangd. */
.edit-view-covered .edit-view-save,
.edit-view-covered .edit-view-close { opacity: 0.35; cursor: default; }

/* BUGGRAPPORTEN (buggrapport.js) och listan under Utveckling
   (buggrapporter-lista.js), 2026-10-03. */
.bugg-text { width: 100%; resize: vertical; }
.bugg-skarmbild { display: flex; align-items: center; gap: var(--luft-md); margin-top: var(--luft-md); }
.bugg-skarmbild .field-switch { flex: 1; }
.bugg-miniatyr { width: 72px; flex: none; border-radius: var(--radius-sm); border: 1px solid var(--border); }
.bugg-bild-rad { display: flex; align-items: center; gap: var(--luft-md); min-width: 0; }
.bugg-bild-vald { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bugg-status { display: grid; grid-template-columns: auto 1fr; gap: var(--luft-sm);
  align-items: center; margin: var(--luft-sm) 0; }
.bugg-status .meta { grid-column: 1 / -1; }
.bugg-rapport-text { white-space: pre-wrap; }
.bugg-rapport-bild { max-width: 100%; border-radius: var(--radius-sm); }
.bugg-rapport-data { font-size: var(--text-stod); overflow-x: auto; white-space: pre; }

/* Sensorprovet under Utveckling (sensorprov.js): talen i fast bredd så de
   inte hoppar när de ändras. */
.sensor-varden { font-size: var(--text-normal); margin: var(--luft-sm) 0 0; white-space: pre; }
.sensor-prov-lista { margin: var(--luft-sm) 0 0; padding-left: var(--luft-md); }

/* Meddelande till en vän (meddelande.js, 2026-10-05): raden går att trycka på. */
.athlete-row-tryckbar { cursor: pointer; }
@media (hover: hover) { .athlete-row-tryckbar:hover .athlete-name { color: var(--accent); } }
.meddelande-falt { width: 100%; resize: none; }
.meddelande-rad { display: flex; align-items: center; justify-content: space-between; gap: var(--luft-md); margin-top: var(--luft-sm); }
/* TRÄNING UNDER JAG (traning_vy.html): rubriken som Jags vyer
   (.edit-view-header) - pilen till vänster, titeln mitt i. */
body[data-sida="traning"] .header-back { position: relative; justify-content: center; margin-left: 0; }
body[data-sida="traning"] .header-back-icon { position: absolute; left: 0; color: var(--text); }
.bugg-svar { grid-column: 1 / -1; resize: vertical; }
