/* CRM Robertson Digital — style.css
   Satinarkivet: kallvit arbetsyta, lågmäld aluminiumram och lugna
   papperskort. Se crm/DESIGN.md för material, kontrast och avvikelser. */

@font-face {
  font-family: "Manrope";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/static/fonts/Manrope-700-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Manrope";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/static/fonts/Manrope-700-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Manrope";
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url("/static/fonts/Manrope-800-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Manrope";
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url("/static/fonts/Manrope-800-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Public Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/static/fonts/PublicSans-400-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Public Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/static/fonts/PublicSans-400-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Public Sans";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/static/fonts/PublicSans-600-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Public Sans";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/static/fonts/PublicSans-600-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Public Sans";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/static/fonts/PublicSans-700-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Public Sans";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/static/fonts/PublicSans-700-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/static/fonts/IBMPlexMono-500-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/static/fonts/IBMPlexMono-500-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  /* Neutraler (spec §4.1) */
  --bg: #eef1f5;
  --surface: #ffffff;
  --sidebar: #f7f9fc;
  --ink: #18202c;
  --ink-muted: #596474;
  --ink-faint: #9aa0b4;   /* ENDAST dekor: punkter, avskiljare. ALDRIG text. */
  --border: #cbd3dd;
  --border-soft: #e5e9ef;

  /* Arbetsytans glasmorfism (Chris önskemål, live-granskning, andra
     rundan). Rutorna bär en tvålagers glasgradient (samma recept som
     sidopanelens `--glas-*`, fast ljust) plus en ljus innerkant för lyster.
     NEBULOSA (2026-09-26, Chris egna tunade värden ur Stilverkstaden):
     alfavärdena är höjda eftersom korten nu flyter över en nästan svart
     nebulosa i stället för en ljusgrå vägg — kortet ska läsa som ett ljust,
     nästan opakt frostat blad, så att --ink/--ink-muted kan sitta kvar inuti
     utan egen nollställning. Se DESIGN.md "Nebulosa (2026-09-26)". */
  --yta-frost-ljus: rgba(255, 255, 255, 0.95);
  --yta-frost-dis: rgba(255, 255, 255, 0.37);
  --yta-frost-bas: rgba(255, 255, 255, 0.58);
  --yta-frost-kant: rgba(255, 255, 255, 0.98);
  --yta-frost-kant-svag: rgba(255, 255, 255, 0.5);
  --yta-frost-blur: 32px;
  /* GOLVET är en mätt, medveten avvikelse från Stilverkstaden, av samma slag
     som glasets mörkning i ticket 01. `--yta-frost-ljus` (0,95) täcker bara
     radialgradientens övre vänstra 55 % — resten av kortet bär enbart
     `--yta-frost-dis` (0,37). Över den gamla ljusgrå väggen syntes det inte;
     över nebulosan blir samma hörn en blågrå ton där --ink visserligen
     klarar sig på 5,69:1 men --ink-muted faller till 2,08:1, alltså under
     AA. Det är den DÄMPADE texten golvet finns för. Ett nästan opakt
     bottenlager (samma mönster som `.sidopanel-glas`s tredje lager
     `var(--glas-bas)`) lyfter kortets mörkaste punkt till --ink 15,02:1 och
     --ink-muted 5,50:1 mot nebulosans ljusaste punkt. Kvar blir 10 % genomskinlighet, så
     `--yta-frost-blur` fortfarande gör något. */
  --yta-frost-golv: rgba(255, 255, 255, 0.9);

  /* Nebulosan: arbetsytans egen nattgrund (2026-09-26, porterad till
     klot+brus-lager 2026-09-27). `--neb-grund-0` är gradientens LJUSASTE
     stopp och därmed värsta fallet bakom en textrad — alla `--yta-text*`
     mäts mot kompositen (skärmblandning, `mix-blend-mode: screen`) av den,
     molnlagrets ton och båda kloten i tests/test_design_rules.py. */
  --neb-grund-0: #0e1338;
  --neb-grund-1: #060814;
  --neb-grund-2: #020207;
  --neb-1: rgba(70, 90, 220, .30);
  --neb-2: rgba(70, 110, 230, .30);

  /* Text på nebulosan (2026-09-26, mätvärden uppdaterade 2026-09-27 efter
     porteringen till klot+brus). Arbetsytan är den FJÄRDE medvetet mörka
     ytan — Chris eget val, inte ett förval. Värsta fallet är nebulosans
     ljusaste punkt: `--neb-grund-0` skärmblandad med molnlagret (ton
     rgb(70,90,220) vid opacitet 0,30) och båda kloten (`--neb-1`, `--neb-2`,
     0,30 var) = #4359ac. Uppmätt mot den (pytest, 2026-09-27):
     --yta-text-stark 6,44:1, --yta-text 5,91:1, --yta-text-svag 5,37:1,
     --yta-larm 5,12:1, --yta-lank 5,30:1. Alla fem klarar AA för brödtext
     (4,5:1), inte bara för rubriker — `--yta-text-svag` bär dämpad RIKTIG
     text (etiketter, meta) och får därför inte mätas mot 3:1-nivån.
     Fokusringen (samma token som --yta-text-stark) klarar 3:1 med 6,44:1. */
  --yta-text: #f2f5ff;
  --yta-text-stark: #ffffff;
  --yta-text-svag: #e4eaff;
  /* Semantiskt larm som ligger BART på nebulosan (Ekonomins "Förfallet").
     --rose mäter 1,23:1 där och försvinner helt; den här ljusa tonen i samma
     kulör mäter 5,12:1. --rose fortsätter gälla på alla ljusa ytor. */
  --yta-larm: #ffdde2;
  /* Länkfärg som token i stället för `--accent` direkt i `a`-regeln, av
     samma skäl som bläcket: en länk BART på nebulosan (`.pipeline-intro`,
     `.ovriga-relationer`, båda i start.html) mäter 1,61:1 i --accent och
     försvinner. Den här svala tonen mäter 5,30:1 mot värsta fallet. Varje
     ljus yta binder tillbaka --lank till --accent. Länkar i löptext är
     dessutom understrukna av webbläsaren — färgen är aldrig enda signalen
     (SC 1.4.1). Värdet skrivs som hex, inte `var(--accent)`, för att
     kontrastvakten i tests/test_design_rules.py bara kan slå upp hex-tokens
     i `:root` — en indirektion hade gjort `a`-regeln omätbar. */
  --lank: #1e3a8a;
  --yta-lank: #d6ecff;
  /* Fokusringen av samma skäl som länken: 2 px --accent mot nebulosan mäter
     1,70:1 och syns inte (SC 2.4.11/1.4.11 kräver 3:1). Ringen ligger med
     `outline-offset: 2px` UTANFÖR elementet, så ett fält inne i ett ljust
     kort får sin ring på kortet (mörk ring, rätt) medan en bar länk får sin
     på nebulosan (ljus ring, 6,44:1). Därför binds den om per yta, precis som
     bläcket — inte per komponent. */
  --fokus: #1e3a8a;

  /* Leadtavlans kolumnyta (crm-ny-stil ticket 03). Kolumnerna bär ytan
     själva; tavlan har ingen egen ram. Uppmätt mot ytan: --ink 13,58:1,
     --ink-muted 4,97:1, se crm/DESIGN.md. */
  --kol-yta: #e6eaf1;
  /* Rosa TEXT på kolumnytan. --rose mäter bara 4,35:1 mot --kol-yta och
     faller under AA; den här mörkare tonen i samma kulör mäter 6,20:1.
     --rose fortsätter användas som fyllning och som text på vitt. */
  --rose-ink: #a3202f;

  /* "Natt och eld" (2026-09-25, crm-ny-stil ticket 01): accent bytt från
     ljuslågans orange till mockupens mörkblå. Mockupen
     (.scratch/crm-ny-stil/preview-skiss.html) är facit för hela
     konverteringen — se DESIGN.md "Natt och eld (2026-09-25)" för samtliga
     uppmätta kontrastvärden. */
  --accent: #1e3a8a;
  --accent-ink: #ffffff;
  --accent-tint: #e8edfb;
  /* Hover-tillstånd (granskningsfynd runda 2, mönster bevarat genom både
     ljuslåga- och natt-och-eld-omfärgningen): en svag knapps TEXT byter
     till accent-hover på hover, inte bara bakgrunden till
     accent-tint-hover. Ren mörkning av bakgrunden inom accent-tint-hover
     kan aldrig nå 4,5:1 mot en ljusare --accent-text om accentens egen
     luminans är för låg — mörka TEXTEN, inte bara bakgrunden. Se DESIGN.md
     "Kontrast". */
  --accent-hover: #162c6b;
  --accent-tint-hover: #d6def6;

  /* Natt och eld: sidopanelens och inloggningens mörkblå scen. ENDAST de
     två ytorna — arbetsytan är fortsatt ljus, se color-scheme på html
     nedan. (Inga klammerparenteser i kommentarer inuti :root — de bryter
     tokenparsningen i tests/test_design_rules.py.) */
  --navy-0: #070d22;
  --navy-1: #0f1d4a;
  --navy-2: #1f3a86;
  --glow: #e2765c;

  /* Glasets tre lager, uppifrån och ned. Egna tokens i stället för hex
     inbakade i gradienterna, så att kontrasttestet
     test_ljus_text_pa_glaset_klarar_aa_aven_over_tandaste_embern kan räkna
     om kompositen mot scenens
     ljusaste ember — mockupens egna alfavärden (.14/.28/.34) gav bara
     3,03:1 för navtexten där en tänd ember lyste igenom. Mörkare glas är
     alltså en mätt, medveten avvikelse från mockupen, inte en smakfråga.
     Ändra ett värde här och testet räknar om sig självt.
     Nebulosa (2026-09-26): Chris tunade om tre av värdena i Stilverkstaden —
     ljusare glas (0,40/0,48 i stället för 0,48/0,55) och ett starkare
     överlägg på det aktiva navvalet (0,14 i stället för 0,10). Det STARKARE
     ÖVERLÄGGET är infört. Det LJUSARE GLASET är det inte, och av exakt samma
     skäl som mockupens egna värden föll i ticket 01: med 0,40/0,48 hamnar
     kompositen över scenens tändaste ember (#d9e8ff) på #545c71, och det
     aktiva navvalet på #6c7385, där hela --panel-text-familjen mäter
     3,73–4,07:1. Ens rent vit text når bara 4,74:1 där, alltså 0,24 marginal
     — för tunt för en yta som ska hålla i åratal. Glaset stannar därför på
     0,48/0,55 (komposit #454c61, aktivt navval #5f6577) och textfamiljen
     ljusas ett litet steg. Mätt, medveten avvikelse, inte en smakfråga. */
  --glas-ljus: rgba(255, 255, 255, 0.06);
  --glas-dis: rgba(10, 17, 42, 0.48);
  --glas-bas: rgba(5, 9, 26, 0.55);
  --glas-aktiv: rgba(255, 255, 255, 0.14);
  --glas-kant: rgba(255, 255, 255, 0.22);
  --glas-kant-svag: rgba(255, 255, 255, 0.14);
  /* En kant som ensam ska BÄRA en komponents form (inloggningens
     primärknapp: fyllningen mäter 1,16:1 mot glaset) behöver 3:1 enligt
     SC 1.4.11. --glas-kant (0,22) över knappens mörkblå fyllning ger bara
     2,14:1; 0,50 ger 4,40:1. Dekorativa kanter (panelens ytterkant,
     kontoblockets avdelare) fortsätter använda --glas-kant. */
  --glas-kant-stark: rgba(255, 255, 255, 0.5);

  /* Text på glaset. Uppmätta mot glaset ovan över scenens ljusaste ember,
     se DESIGN.md. Nebulosa (2026-09-26): ljusade ett litet steg eftersom
     `--glas-aktiv` gick från 0,10 till 0,14. Mot glaset #454c61 respektive
     det aktiva navvalets #5f6577: --panel-text 7,33:1 / 4,99:1,
     --panel-text-stark 8,54:1 / 5,81:1, --panel-text-svag 7,19:1 / 4,89:1.
     De tre stegen är fortfarande åtskilda — hierarkin i sidopanelen är
     bevarad. */
  --panel-text: #e9edff;
  --panel-text-stark: #ffffff;
  --panel-text-svag: #e6ebff;

  /* Chattbottpanelen (crm-ny-stil ticket 09) — den TREDJE medvetet mörka
     ytan, vid sidan av sidopanelen och inloggningen. Egna tokens av samma
     skäl som glaset ovan: gradientens alfavärden ska gå att räkna om i
     tests/test_design_rules.py utan att någon tolkar linear-gradient.
     Värdena är mockupens egna (0,94/0,97/0,98 över natt-familjens toner) och
     står kvar eftersom mätningen godkände dem — till skillnad från glasets.
     Kanten runt panelen är DEKOR: panelens nästan opaka yta skiljer sig
     redan tydligt från arbetsytan bakom. */
  --bott-topp: rgba(10, 17, 42, 0.94);
  --bott-mitt: rgba(5, 9, 26, 0.97);
  --bott-botten: rgba(4, 7, 20, 0.98);
  --bott-kant: rgba(255, 255, 255, 0.16);
  --bott-bubbla-svar: rgba(255, 255, 255, 0.12);
  /* Textfältets kant BÄR fältets form och måste därför klara 3:1
     (SC 1.4.11). Mockupens rgba vit 0,24 mäter 1,74:1 mot fältytan — samma
     sorts för ljusa alfavärde som föll i ticket 01. Opak i stället för
     genomskinlig, av samma skäl som inloggningens fält: en opak ton går att
     mäta maskinellt och skiftar inte med vad som råkar ligga bakom. */
  --bott-kant-falt: #7f8aa8;
  /* Platshållaren är fältets enda SYNLIGA etikett (den riktiga etiketten är
     skärmläsarsynlig), alltså riktig text med riktigt kontrastkrav. */
  --bott-platshallare: #9aa8c4;

  --metal-hi: #fbfcfe;
  --metal: #d9dfe7;
  --metal-low: #b8c1cc;

  /* Stegfärger — mörkade från konceptets original inom SAMMA kulör tills
     varje par klarade 4.5:1 mot sin egen tint (uppmätt, se DESIGN.md
     "Kontrast"). Tinterna är orörda. */
  --blue: #2267de;      --blue-tint: #e8f0fe;
  --violet: #7a4aeb;    --violet-tint: #f1ebfd;
  --amber: #946407;     --amber-tint: #fbf0dc;
  --green: #147e4c;     --green-tint: #e3f6ec;
  --rose: #cb2d44;      --rose-tint: #fce9ec;
  --sky: #077792;       --sky-tint: #e1f3f6;
  --gray: #666d7a;      --gray-tint: #eef0f4;

  --shadow: 0 1px 2px rgba(31, 36, 48, 0.04), 0 6px 16px -10px rgba(31, 36, 48, 0.14);

  /* Typskala — konceptets faktiska grader i rem (spec §4.2). Basen förblir
     1rem = 16px; komponenterna skalas, inte <body>s font-size. */
  --fs-0: 0.78rem;
  --fs-1: 0.86rem;
  --fs-2: 1rem;
  --fs-3: 1.06rem;
  --fs-4: 1.21rem;
  --fs-5: 1.79rem;

  --rytm-1: 4px;
  --rytm-2: 8px;
  --rytm-3: 12px;
  --rytm-4: 16px;
  --rytm-5: 24px;
  --rytm-6: 32px;
  --rytm-7: 48px;
  --rytm-8: 64px;

  --radie-kort: 14px;
  --radie-liten: 10px;
  --radie-pill: 99px;

  --motion-fast: 120ms;
  --ease-standard: ease-out;
}

/* [data-tema="dag"] — blå himmel med vita moln (crm-tema ticket 01 gav
   mekaniken, ticket 02 den riktiga ytan). Himlen är BARA tokenvärden: samma
   `radial-gradient` i `.nebulosa-grund` målar båda temana, ingen regel
   dupliceras. Lagren ovanpå (kloten, stjärnorna, molnfiltret) kan inte
   uttryckas som tokens och har därför egna skopade regler längre ner, vid
   `.nebulosa-brus`.

   Gradienten har sitt ljusaste stopp i mitten (50% 25%) och mörknar utåt, så
   himlen läser som dagsljus högt uppe och djupare blått mot kanterna.
   `--neb-grund-2` är alltså dagtemats VÄRSTA fall bakom en textrad — motsatt
   natten, där `--neb-grund-0` är det. Mätningen i
   tests/test_design_rules.py vet det av sig själv: den bygger en lista
   kandidatytor per tema och tar den mörkaste för mörk text, den ljusaste för
   ljus text.

   `--neb-1`/`--neb-2` skrivs medvetet INTE om här. Kloten är dolda i
   dagtemat, och ett övertaget alfavärde för ett lager som inte målas hade
   sett ut som en mätbar del av ytan utan att vara det. */
[data-tema="dag"] {
  --neb-grund-0: #eaf6ff;
  --neb-grund-1: #a8d5f5;
  --neb-grund-2: #74b6e4;

  /* MÖRKA toner för dagtemat (ytan är nu ljus) — samma etablerade mörka
     bläck-familj som resten av appen redan använder för text på LJUSA ytor
     (:root --ink/--ink-muted), inte nya påhittade toner. Uppmätt mot himlens
     mörkaste punkt --neb-grund-2 (pytest, 2026-09-27): --yta-text-stark
     8,73:1, --yta-text 7,45:1, --yta-text-svag 5,24:1, --yta-larm 4,78:1,
     --yta-lank 4,71:1. Alla fem klarar AA för brödtext (4,5:1); fokusringen
     (samma token som --yta-text-stark) klarar 3:1 med 8,73:1.

     Två av tonerna är MÖRKARE än :root-familjen de kommer ur, och det är
     mätningen som bestämde det: --yta-text-svag #3d4a5c mätte 3,48:1 mot
     himlen och --yta-larm #8a1f2b 4,13:1. Det är tonerna som rättades, aldrig
     testet. */
  --yta-text: #18202c;
  --yta-text-stark: #0b0f16;
  --yta-text-svag: #2f3a49;
  --yta-larm: #7a1a24;
  --yta-lank: #1e3a8a;
  --fokus: #0b0f16;

  /* Kortkanten på de FROSTADE korten (`.panel`, `.valkort`).
     `--yta-frost-kant-svag` är vit i :root, och det fungerar bara så länge
     kortet svävar över en nästan svart nebulosa: där bär kortytan SJÄLV
     gränsen (vitt glas mot #0e1338, uppmätt 6,16:1) och den vita kanten är
     bara en ljusning i kanten av glaset. Över dagens ljusa himmel gör den
     ingenting alls — vitt på vitt, uppmätt 1,03:1. Kortet syntes bara tack
     vare skuggan, och högst upp på sidan, där himlen är ljusast, höll den på
     att försvinna (uppmätt i dashboard-tema-dag-1280.png: kortytan 1,20:1 mot
     himlen).

     Värdet är `--border`s egen ton skriven i klartext. Alla ANDRA kort på
     arbetsytan (`.uppmarksamhet`, `.omrade-kort`, `.tabell-omslag`,
     `.sammanfattning` …) ritar redan sin kant med `--border`, så det här är
     inte en ny kantfärg utan samma kant som resten — de frostade korten var
     de enda som saknade en synlig gräns i dagtemat. Att skriva `var(--border)`
     här hade gjort tokenet oläsbart för mätningen i test_design_rules.py, som
     läser rgba-tokens ur källan. Natten rör vi inte.
     Mätt av tests/test_design_rules.py::test_frostade_kortet_har_en_synlig_kant_i_dagtemat.

     OBS: hela dagtemats kortgräns ligger därmed runt 1,5:1, inte 3:1. Det är
     ett medvetet avsteg från WCAG 1.4.11 och står namngivet i DESIGN.md. */
  --yta-frost-kant-svag: rgba(203, 211, 221, 1);
}

* {
  box-sizing: border-box;
}

html {
  color-scheme: light;
}

body {
  margin: 0;
  /* Nebulosa (2026-09-26): den borstade metallen är borta. Nattgrunden hör
     till `.innehall`, inte till `<body>` — kroppen omsluter också
     sidopanelen, som har sin egen opaka `--navy-0` och inte får röras.
     `--bg` ligger kvar som botten: den syns bara om en yta någon gång inte
     täcker hela rutan, och en ljus botten är rätt bakom sidopanelens eget
     mörka lager. */
  background: var(--bg);
  color: var(--ink);
  font-family: "Public Sans", ui-sans-serif, system-ui, sans-serif;
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.5;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}

::selection {
  background: var(--accent-tint);
  color: var(--ink);
}

* {
  caret-color: var(--accent);
}

:focus-visible {
  outline: 2px solid var(--fokus);
  outline-offset: 2px;
  border-radius: 4px;
}

@media (prefers-reduced-motion: no-preference) {
  a,
  button,
  input,
  select,
  textarea {
    transition: border-color var(--motion-fast) var(--ease-standard), background-color var(--motion-fast) var(--ease-standard);
  }

  .flik > summary::before {
    transition: transform var(--motion-fast) var(--ease-standard);
  }
}

@media (prefers-reduced-motion: reduce) {
  * {
    transition: none !important;
  }
}

::-webkit-scrollbar {
  width: 12px;
  height: 12px;
}
::-webkit-scrollbar-track {
  background: var(--bg);
}
::-webkit-scrollbar-thumb {
  background-color: var(--border);
  border-radius: 6px;
  border: 3px solid var(--bg);
}
* {
  scrollbar-color: var(--border) var(--bg);
  scrollbar-width: thin;
}

a {
  color: var(--lank);
}

h1,
h2,
h3 {
  font-family: "Manrope", ui-sans-serif, sans-serif;
  font-weight: 800;
  text-wrap: balance;
  margin: 0 0 var(--rytm-3);
  color: var(--ink);
}

h1 {
  font-size: var(--fs-5);
}

h2 {
  font-size: var(--fs-4);
  font-weight: 700;
}

p {
  max-width: 66ch;
}

.synlig-for-skarmlasare {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
  padding: 0;
  margin: -1px;
}

.belopp {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-variant-numeric: tabular-nums;
}

/* ---------- Skal: sidopanel + innehåll ---------- */

.skal {
  display: grid;
  grid-template-columns: 238px 1fr;
  min-height: 100vh;
}

/* Natt och eld (ticket 01): sidopanelen är en mörkblå nattscen med
   glödande embers bakom frostat glas. Scenen (`_scen.html`) ligger som ett
   absolut placerat SVG i `.sidopanel`; `.sidopanel-glas` ligger ovanpå och
   suddar den med `backdrop-filter`. `isolation: isolate` håller suddningens
   bakgrund inne i panelen — utan den suddas hela sidan bakom.
   `background: var(--navy-0)` är inte dekor utan en säkerhetsåtgärd: målas
   inte SVG:n blir ytan ändå mörk, så den ljusa texten aldrig hamnar på
   ljus bakgrund. (Arbetsytan var ljus när det här skrevs; sedan nebulosan
   2026-09-26 är den den fjärde medvetet mörka ytan.) */
.sidopanel {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  overflow: hidden;
  isolation: isolate;
  background: var(--navy-0);
  color: var(--panel-text);
  border-right: 0;
  border-radius: 0 28px 28px 0;
  /* Nebulosans lager är `position: fixed` och täcker hela rutan, även bakom
     panelen. Utan `z-index` här målas `.innehall`s hela stackningskontext
     (lagren med) ÖVER panelen — de är rutnätssyskon med `z-index: auto`, så
     DOM-ordningen avgör, och stjärnorna syntes på panelen. Med `1` ligger
     den opaka panelen över alla lager; hörnurtaget (`border-radius` ovan) är
     genomsläppligt och visar `.nebulosa-grund` i stället för den ljusa
     `body`-bottnen. */
  z-index: 1;
}

.sidopanel .scen {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  display: block;
}

.sidopanel-glas {
  position: relative;
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--rytm-5);
  /* Panelen klipper (overflow: hidden) för rundade hörn och för scenen. På
     ett lågt fönster skulle kontoblocket annars försvinna tyst under
     nederkanten — glaset scrollar i stället. */
  overflow-y: auto;
  padding: var(--rytm-5) var(--rytm-4) 20px;
  border-radius: 0 28px 28px 0;
  border-right: 1px solid var(--glas-kant);
  background:
    radial-gradient(130% 55% at 0% 0%, var(--glas-ljus), rgba(255, 255, 255, 0) 58%),
    linear-gradient(160deg, var(--glas-dis), var(--glas-bas)),
    var(--glas-bas);
  -webkit-backdrop-filter: blur(11px) saturate(180%);
  backdrop-filter: blur(11px) saturate(180%);
  box-shadow: inset 0 1px 0 var(--glas-kant), inset 1px 0 0 var(--glas-kant-svag);
}

.varumarke {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 2px 8px;
}

/* Embers: glödpunkterna i scenen. Glöden är ren dekor och bär ingen
   information — därför ligger animationen ENBART i no-preference-blocket
   och `prefers-reduced-motion: reduce` ger en stillastående scen. */
.sidopanel .ember,
.inlogg-skal .ember {
  transform-origin: center;
}

.sidopanel .ember-gnista,
.inlogg-skal .ember-gnista {
  fill: var(--glow);
}

@media (prefers-reduced-motion: no-preference) {
  .sidopanel .ember,
  .inlogg-skal .ember {
    animation: glod 6s ease-in-out infinite;
  }
  .sidopanel .ember:nth-of-type(2n),
  .inlogg-skal .ember:nth-of-type(2n) {
    animation-duration: 7.5s;
    animation-delay: -2.4s;
  }
  .sidopanel .ember:nth-of-type(3n),
  .inlogg-skal .ember:nth-of-type(3n) {
    animation-duration: 9s;
    animation-delay: -4.6s;
  }
}

@keyframes glod {
  0%,
  100% {
    opacity: 0.75;
  }
  50% {
    opacity: 1;
  }
}

/* Monogrammet är oförändrad medveten platshållare (samma "R", samma
   storlek). På de två mörka ytorna byter brickan håll — vit botten med
   accentens mörkblå bokstav (10,36:1) — eftersom mörkblått på mörkblått
   inte syns (1,86:1 mot --navy-0). */
.sidopanel .varumarke-marke,
.inlogg-kort .varumarke-marke {
  background: var(--panel-text-stark);
  color: var(--accent);
}

.sidopanel .varumarke-namn,
.inlogg-kort .varumarke-namn {
  color: var(--panel-text-stark);
}

.sidopanel .varumarke-tagg,
.inlogg-kort .varumarke-tagg {
  color: var(--panel-text-svag);
}

.varumarke-marke {
  width: 30px;
  height: 30px;
  border-radius: var(--radie-liten);
  flex: none;
  background: var(--accent);
  color: var(--accent-ink);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "Manrope", sans-serif;
  font-weight: 800;
  font-size: var(--fs-2);
}

/* Företagets logga i R-rutans ställe (crm-nova ticket 06). Mått, radie och
   `flex: none` ärvs från basregeln ovan, så raden byter inte höjd när loggan
   kommer eller går. Ingen bakgrund här: den vita brickan kommer från de
   panelskopade reglerna ovan (0,2,0), som vinner över den här (0,1,0) i
   vilken ordning som helst — en mörk logga försvinner annars i nattemat.
   `contain`, aldrig `cover`: en logga får inte beskäras. Paddingen ger
   loggan luft mot brickans kant; `border-box` håller måttet på 30×30. */
.varumarke-marke--logga {
  box-sizing: border-box;
  padding: 2px;
  object-fit: contain;
}

.varumarke-text {
  display: flex;
  flex-direction: column;
  line-height: 1.25;
}

.varumarke-namn {
  font-family: "Manrope", sans-serif;
  font-size: var(--fs-3);
  font-weight: 700;
}

.varumarke-tagg {
  font-size: var(--fs-0);
  color: var(--ink-muted);
}

.sidopanel .nav {
  display: flex;
  flex-direction: column;
  gap: var(--rytm-1);
}

/* Navvalen ligger på glaset: ljus text, ljust överlägg som aktivt/hover-
   tillstånd. Ingen accentfärgad pill längre — mörkblått på mörkblått syns
   inte. 44 px träffyta (WCAG 2.2 SC 2.5.8). */
.navval {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: var(--rytm-2) var(--rytm-3);
  border: 1px solid transparent;
  border-radius: var(--radie-liten);
  color: var(--panel-text);
  font-size: var(--fs-1);
  font-weight: 500;
  text-decoration: none;
}

.navval:hover {
  background: var(--glas-ljus);
  color: var(--panel-text-stark);
}

.navval--aktiv,
.navval--aktiv:hover {
  background: var(--glas-aktiv);
  border-color: var(--glas-kant);
  color: var(--panel-text-stark);
  font-weight: 600;
}

.navval-antal {
  margin-left: auto;
  padding: 3px 9px;
  border-radius: var(--radie-pill);
  background: var(--glas-kant-svag);
  font-family: "IBM Plex Mono", ui-monospace, Consolas, monospace;
  font-size: var(--fs-0);
  color: var(--panel-text-stark);
}

.navval--aktiv .navval-antal {
  color: var(--panel-text-stark);
}

/* ---------- Nebulosa: arbetsytan som fjärde mörka yta (2026-09-26) --------
   Chris eget, uttryckliga val efter runda 31 i Stilverkstaden — inte ett
   förval och inte en tolkning. Arbetsytan var tidigare uttalat ljus "för
   alltid" (crm/CLAUDE.md, punkten om chattbottpanelen); den punkten är
   uppdaterad, inte kringgången.

   Arkitekturen är en OMBINDNING av tokens, inte en färg per element.
   `.innehall` binder om `--ink`/`--ink-muted` till nebulosans ljusa
   textfamilj, och varje LJUS yta inuti (`.panel`, `.lead`, `.tabell-omslag`,
   fälten, flikarna ...) binder tillbaka dem till sina riktiga mörka värden
   för hela sitt underträd. Därför behöver inte ett enda `color:`-anrop inuti
   en ruta skrivas om: `color: var(--ink-muted)` på en etikett betyder ljust
   ute på nebulosan och mörkt inne i ett kort, av sig självt. Stilverkstadens
   egen prototyp löste aldrig det här (dess `.huvud h1`/`p` saknade
   färgändring i Nebulosa-läget) — det är vår tillagda del.

   `color: var(--ink)` måste stå på BÅDA nivåerna: en ombunden token ändrar
   inte ett redan ärvt `color`-värde från `<body>`, så varje nivå som binder
   om tokenen måste också läsa den. */
.innehall {
  padding: 26px 32px 60px;
  min-width: 0;
  position: relative;
  /* Håller nebulosans `z-index: -1` inne i arbetsytan. INTE overflow:
     hidden — kugghjulsmenyerna (`.meny`) är absolut placerade och skulle
     klippas. */
  isolation: isolate;
  /* Säkerhetsåtgärd av samma slag som `.sidopanel`s `--navy-0`: målas inte
     lagren blir ytan ändå mörk, så den ljusa texten aldrig hamnar på ljus
     bakgrund. Bara en platt ton: själva gradienten bor sedan 2026-09-27 i
     `.nebulosa-grund`, som täcker hela rutan och inte bara högerkolumnen.
     Det tog samtidigt bort `background-attachment: fixed` härifrån, som
     tvingade om en ommålning av gradienten vid varje rullningsbildruta. */
  background: var(--neb-grund-0);
  --ink: var(--yta-text-stark);
  --ink-muted: var(--yta-text-svag);
  --lank: var(--yta-lank);
  --fokus: var(--yta-text-stark);
  color: var(--ink);
}

/* Nebulosan ligger fast mot fönstret, inte mot det (godtyckligt höga)
   dokumentet: då stämmer vmax-måtten och fläckarna växer inte med sidans
   längd. `z-index: -1` inuti arbetsytans egen stackningskontext lägger den
   över `.innehall`s grundgradient men under allt innehåll. */
/* Nattgrunden. Låg på `.innehall` fram till 2026-09-27; som eget
   `fixed`-lager täcker den hela rutan, även bakom sidopanelen, så panelens
   rundade hörn visar natt i stället för den ljusa `body`-bottnen. Den ligger
   kvar INUTI `.innehall`s stackningskontext och UNDER kloten (`z-index: -2`),
   så klotens `mix-blend-mode: screen` fortfarande blandas mot den — ett
   omslutande wrapper-lager hade brutit det. */
.nebulosa-grund {
  position: fixed;
  inset: 0;
  z-index: -4;
  pointer-events: none;
  background: radial-gradient(
    ellipse 90% 70% at 50% 25%,
    var(--neb-grund-0) 0%,
    var(--neb-grund-1) 55%,
    var(--neb-grund-2) 100%
  );
}

.nebulosa-stjarnor {
  position: fixed;
  inset: 0;
  z-index: -3;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.nebulosa-stjarnor circle {
  fill: var(--yta-text-stark);
  animation: nebulosa-tvinkla 4s ease-in-out infinite;
}

@keyframes nebulosa-tvinkla {
  0%, 100% { opacity: var(--min, .3); }
  50% { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .nebulosa-stjarnor circle {
    animation: none;
  }
}

/* Stjärnornas variation (nyansen som gör fältet levande: olika bottenopacitet,
   takt och fasförskjutning per stjärna). Prototypen satte dem som
   `style="--min:..."` per cirkel. Det går INTE här: appens CSP är
   `default-src 'self'` UTAN `style-src`, så webbläsaren blockerar all
   inline-stil — både attribut och `<style>`-block — och
   tests/test_tystnadslinje.py vaktar att HTML:en aldrig innehåller `style=`.
   Variationen ligger därför i stilmallen, fördelad på 20 hinkar via
   `:nth-child(20n + k)`. Stjärnornas LÄGEN är redan slumpade i partialen, så
   hinkarna syns inte som ett mönster; värdena är de 20 första stjärnornas
   egna, genererade tal.

   Hinkarna ligger inuti `no-preference` av ren specificitetsanledning:
   `.nebulosa-stjarnor circle:nth-child(...)` väger (0,2,1) och skulle annars
   vinna över `reduce`-blockets `animation: none` (0,1,1) ovan och låta
   stjärnorna blinka vidare för den som bett om lugn rörelse. Samma
   cascade-fälla som en gång gjorde `.valkort` till vit text på vitt kort. */
@media (prefers-reduced-motion: no-preference) {
  .nebulosa-stjarnor circle:nth-child(20n + 1) { --min: 0.42; animation-duration: 2.92s; animation-delay: -0.33s; }
  .nebulosa-stjarnor circle:nth-child(20n + 2) { --min: 0.45; animation-duration: 4.49s; animation-delay: -0.61s; }
  .nebulosa-stjarnor circle:nth-child(20n + 3) { --min: 0.55; animation-duration: 2.78s; animation-delay: -0.06s; }
  .nebulosa-stjarnor circle:nth-child(20n + 4) { --min: 0.28; animation-duration: 3.59s; animation-delay: -3.43s; }
  .nebulosa-stjarnor circle:nth-child(20n + 5) { --min: 0.37; animation-duration: 5.36s; animation-delay: -4.5s; }
  .nebulosa-stjarnor circle:nth-child(20n + 6) { --min: 0.55; animation-duration: 2.59s; animation-delay: -1.9s; }
  .nebulosa-stjarnor circle:nth-child(20n + 7) { --min: 0.47; animation-duration: 4.69s; animation-delay: -0.91s; }
  .nebulosa-stjarnor circle:nth-child(20n + 8) { --min: 0.28; animation-duration: 3.5s; animation-delay: -1.39s; }
  .nebulosa-stjarnor circle:nth-child(20n + 9) { --min: 0.54; animation-duration: 5.48s; animation-delay: -4.33s; }
  .nebulosa-stjarnor circle:nth-child(20n + 10) { --min: 0.37; animation-duration: 4.52s; animation-delay: -0.42s; }
  .nebulosa-stjarnor circle:nth-child(20n + 11) { --min: 0.43; animation-duration: 2.79s; animation-delay: -1.11s; }
  .nebulosa-stjarnor circle:nth-child(20n + 12) { --min: 0.23; animation-duration: 3.86s; animation-delay: -3.09s; }
  .nebulosa-stjarnor circle:nth-child(20n + 13) { --min: 0.2; animation-duration: 2.8s; animation-delay: -2.75s; }
  .nebulosa-stjarnor circle:nth-child(20n + 14) { --min: 0.44; animation-duration: 5.06s; animation-delay: -2.41s; }
  .nebulosa-stjarnor circle:nth-child(20n + 15) { --min: 0.3; animation-duration: 4.34s; animation-delay: -2.76s; }
  .nebulosa-stjarnor circle:nth-child(20n + 16) { --min: 0.44; animation-duration: 4.58s; animation-delay: -4.46s; }
  .nebulosa-stjarnor circle:nth-child(20n + 17) { --min: 0.54; animation-duration: 3.55s; animation-delay: -0.04s; }
  .nebulosa-stjarnor circle:nth-child(20n + 18) { --min: 0.17; animation-duration: 2.87s; animation-delay: -2.48s; }
  .nebulosa-stjarnor circle:nth-child(20n + 19) { --min: 0.23; animation-duration: 4.96s; animation-delay: -1.48s; }
  .nebulosa-stjarnor circle:nth-child(20n + 20) { --min: 0.36; animation-duration: 5.08s; animation-delay: -2.04s; }
}

.nebulosa-klot {
  position: fixed;
  z-index: -2;
  border-radius: 50%;
  pointer-events: none;
  opacity: .95;
  mix-blend-mode: screen;
  filter: blur(70px);
}

.nebulosa-klot--a {
  width: 60vmax;
  height: 60vmax;
  top: -22vmax;
  right: -18vmax;
  background: radial-gradient(circle, var(--neb-1), transparent 70%);
}

.nebulosa-klot--b {
  width: 60vmax;
  height: 60vmax;
  bottom: -20vmax;
  left: -16vmax;
  background: radial-gradient(circle, var(--neb-2), transparent 70%);
}

.nebulosa-brus {
  position: fixed;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
  mix-blend-mode: screen;
}

/* ---------- Dagtemats lager: blå himmel, vita moln (crm-tema ticket 02) ----
   Himlen själv är bara tokenvärden (se `[data-tema="dag"]` högst upp). DE HÄR
   tre reglerna finns för att lagren OVANPÅ himlen inte går att uttrycka som
   tokenvärden — ett blandningsläge, ett `display` och ett filter-id är inga
   färger.

   Alla tre står SENARE i filen än basreglerna ovan OCH väger tyngre
   ([data-tema="dag"] lägger till ett attribut, 0-2-0 mot 0-1-0). Båda delarna
   är avsiktliga: en skopad regel som bara vinner på källordning har fällt den
   här stilmallen tre gånger — senast blev kugghjulet 1,00:1 i öppet läge
   (2026-09-27). Flyttas blocket ändrar sig ingenting.

   Stjärnor och klot DÖLJS i stället för att tonas om. Skälet är mätbarhet,
   inte smak: båda bär `mix-blend-mode: screen`, och screen mot en ljus grund
   blåser ut mot vitt (vaultnoten om skärmblandning). Dolda lager kan inte
   göra himlen ljusare, och då är dagtemats värsta fall bakom en textrad
   himlen själv plus molnen — två lager i stället för fyra. */
[data-tema="dag"] .nebulosa-stjarnor,
[data-tema="dag"] .nebulosa-klot {
  display: none;
}

/* Vita moln ligger PÅ himlen, de adderar inte ljus till den: vanlig
   alfa-komposit, aldrig screen. */
[data-tema="dag"] .nebulosa-brus {
  mix-blend-mode: normal;
}

/* Molnrektangeln byter filter och tak. Båda är presentationsattribut i
   `_nebulosa.html` (specificitet 0), så den här regeln vinner över dem utan
   att mallen behöver veta vilket tema som är valt — partialen är identisk i
   båda lägena. `opacity` 0,65 mot nattens 0,30: ett vitt moln på blå himmel
   ska synas som ett moln, en blå slöja på natthimlen ska knappt synas.
   Kontrastmätningen läser BÅDA talen ur källan. */
[data-tema="dag"] .nebulosa-brus rect {
  filter: url(#neb-moln-dag);
  opacity: .65;
}

/* Varje LJUS yta inuti arbetsytan binder tillbaka bläcket. Listan är
   uttömmande för de ytor som själva målar en ljus bakgrund (`--surface`,
   `--bg`, `--kol-yta`, `--border-soft`, en tint eller frostgradienten) —
   allt annat inuti dem ärver rätt värde. Lägger någon till en NY ljus yta
   måste den in här, annars blir dess text ljus på ljust. */
.band,
.tom-lage pre,
.olastbara-lista li,
.lead,
.tabell-omslag,
tr.rad--dampad,
li.rad--dampad,
.panel,
.meny,
.installningar > summary:hover,
.valkort,
input,
select,
textarea,
.bocka-ruta,
.ny-relation,
.flik,
.sammanfattning,
.pipeline-kolumn,
.omrade-kort,
.omrade-ny-uppgift,
.nova-feedback,
.uppmarksamhet {
  --ink: #18202c;
  --ink-muted: #596474;
  --lank: #1e3a8a;
  --fokus: #1e3a8a;
  color: var(--ink);
}

/* Fokusringen är 2 px `var(--fokus)`. På de här två mörka ytorna skulle
   mörkblått mot mörkblått vara osynligt (1,86:1) — ringen blir vit där.
   Nebulosa (2026-09-26): arbetsytan löser samma sak genom att binda om
   `--fokus`, inte genom en egen `outline-color`-regel, eftersom ringen där
   ska växla tillbaka till mörkblått inuti varje LJUST kort. De här två ytorna
   är enfärgat mörka hela vägen och behöver ingen sådan växling. */
.sidopanel :focus-visible,
.inlogg-skal :focus-visible {
  outline-color: var(--panel-text-stark);
}

/* Fixrunda 1, punkt 3: .meny (kugghjulets utfällda block) ligger inuti
   .sidopanel men målar en LJUS yta (background: var(--surface), vit) —
   regeln ovan band outline-color direkt till --panel-text-stark (vit),
   vilket blir en vit ring på vit botten (1,00:1). .meny binder om --fokus
   till #1e3a8a (den skopade listen för ljusa ytor ovan), men den
   ombindningen når aldrig fram eftersom regeln ovan sätter outline-color
   DIREKT i stället för via var(--fokus). Högre specificitet vinner i
   stället, samma mönster som kugghjulets hover/open-toner längre ner i
   filen. */
.sidopanel .meny :focus-visible {
  outline-color: var(--fokus);
}

@media (max-width: 760px) {
  .skal {
    grid-template-columns: 1fr;
  }
  .sidopanel {
    position: relative;
    height: auto;
    border-radius: 0 0 24px 24px;
  }
  /* Flexföräldern för märke/nav/konto är sedan natt-och-eld-omstylingen
     glaset, inte .sidopanel själv (.sidopanel har ett enda barn: glaset). */
  /* Ticket 02 fixrunda: `flex: none` lät glaset bli så brett som hela
     innehållet på EN rad (1173 px i ett 390 px-fönster) — wrap slog aldrig
     till och kontoraden hamnade utanför skärmen. `flex: 1 1 auto` + basens
     `min-width: 0` låser glaset till panelens bredd så raderna bryts. */
  .sidopanel-glas {
    flex: 1 1 auto;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    padding: 14px 16px;
    gap: 14px;
    border-right: 0;
    border-radius: 0 0 24px 24px;
  }
  .sidopanel .nav {
    flex-direction: row;
    /* Utan wrap blev raden bredare än skärmen och "Ekonomi" klipptes
       (panelens overflow: hidden gjorde den osynligt avklippt). */
    flex-wrap: wrap;
  }
  .innehall {
    padding: 20px 18px 48px;
  }
}

/* ---------- Band: fel och varningar ---------- */

.band {
  border-radius: var(--radie-liten);
  padding: var(--rytm-3) var(--rytm-4);
  margin-bottom: var(--rytm-5);
  border: 1px solid var(--border);
  background: var(--surface);
}

.band.band-fel {
  border-color: var(--rose);
  background: var(--rose-tint);
  color: var(--rose);
}

.band.band-varning {
  border-color: var(--amber);
  background: var(--amber-tint);
  color: var(--amber);
}

.tom-lage {
  margin-top: var(--rytm-7);
  color: var(--ink-muted);
}

.tom-lage pre {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radie-liten);
  padding: var(--rytm-3);
  overflow-x: auto;
  font-family: ui-monospace, "Cascadia Code", monospace;
}

.tom-lage-text {
  color: var(--ink-muted);
}

/* ---------- Pill (stadium) och avatar — spec §4.4 ---------- */

.pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: var(--fs-0);
  font-weight: 700;
  padding: 3px 10px;
  border-radius: var(--radie-pill);
  white-space: nowrap;
}

.pill-punkt {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  flex: none;
}

.avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "Manrope", sans-serif;
  font-weight: 700;
  font-size: var(--fs-0);
}

/* En sluten uppsättning stegfärger (spec §4.4) — bara stadium väljer
   färgen, aldrig fri text i en klass. */
.pill--blue, .avatar--blue { color: var(--blue); background: var(--blue-tint); }
.pill--violet, .avatar--violet { color: var(--violet); background: var(--violet-tint); }
.pill--amber, .avatar--amber { color: var(--amber); background: var(--amber-tint); }
.pill--green, .avatar--green { color: var(--green); background: var(--green-tint); }
.pill--rose, .avatar--rose { color: var(--rose); background: var(--rose-tint); }
.pill--sky, .avatar--sky { color: var(--sky); background: var(--sky-tint); }
.pill--gray, .avatar--gray { color: var(--gray); background: var(--gray-tint); }

.punkt--blue { background: var(--blue); }
.punkt--violet { background: var(--violet); }
.punkt--amber { background: var(--amber); }
.punkt--green { background: var(--green); }
.punkt--rose { background: var(--rose); }
.punkt--sky { background: var(--sky); }
.punkt--gray { background: var(--gray); }

/* ---------- Leadsidan (/) ---------- */

.olastbara-block {
  margin-bottom: var(--rytm-6);
}

.olastbara-lista {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--rytm-2);
}

.olastbara-lista li {
  background: var(--rose-tint);
  border: 1px solid var(--rose);
  border-radius: var(--radie-liten);
  padding: var(--rytm-3) var(--rytm-4);
}

.olastbara-lista a {
  font-weight: 700;
  color: var(--ink);
}

.rad-fel {
  margin: var(--rytm-1) 0 0;
  color: var(--rose);
  font-size: var(--fs-0);
}

.stegrad {
  display: flex;
  flex-wrap: wrap;
  gap: var(--rytm-3);
  margin-bottom: var(--rytm-6);
}

.steg-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--fs-0);
  font-weight: 600;
  color: var(--ink-muted);
}

.steg-chip-punkt {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex: none;
}

.steg-chip-antal {
  color: var(--ink-muted);
}

.lead-lista {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--rytm-4);
}

.lead {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radie-kort);
  box-shadow: var(--shadow);
  padding: var(--rytm-4) var(--rytm-5);
}

.lead-topp {
  display: flex;
  align-items: flex-start;
  gap: var(--rytm-3);
}

.lead-namnrad {
  flex: 1;
  min-width: 0;
}

.lead-namn {
  display: block;
  font-family: "Manrope", sans-serif;
  font-weight: 700;
  font-size: var(--fs-3);
  color: var(--ink);
  text-decoration: none;
}

.lead-namn:hover {
  color: var(--accent);
}

.lead-kontakt {
  margin: 2px 0 0;
  font-size: var(--fs-0);
  color: var(--ink-muted);
}

.lead-nasta-steg {
  margin: var(--rytm-4) 0;
}

.etikett {
  display: block;
  font-size: var(--fs-0);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-bottom: var(--rytm-1);
}

.lead-nasta-steg-text {
  margin: 0;
  font-size: var(--fs-4);
  font-weight: 600;
  color: var(--ink);
}

.lead-nasta-steg-text--tom {
  color: var(--amber);
}

.lead-nasta-steg-datum {
  display: inline-block;
  margin-top: 2px;
  font-size: var(--fs-0);
}

.lead-nasta-steg-datum--rose { color: var(--rose); font-weight: 600; }
.lead-nasta-steg-datum--amber { color: var(--amber); font-weight: 600; }
.lead-nasta-steg-datum--muted { color: var(--ink-muted); }

.markor {
  display: inline-block;
  margin-top: var(--rytm-1);
  font-size: var(--fs-0);
  font-weight: 600;
}

.markor--amber {
  color: var(--amber);
}

.lead-tystnadsrad {
  display: flex;
  align-items: center;
  gap: var(--rytm-3);
  margin: var(--rytm-3) 0;
}

.tystnadslinje {
  height: 2px;
  border-radius: 1px;
  background: var(--border);
  flex: 0 0 auto;
}

/* STEG_MAX diskreta bredd-steg i stället för ett inline style="width: ...px".
   CSP:ns default-src 'self'-fallback saknar style-src, vilket blockerar
   inline style i en riktig webbläsare (granskningsfynd 2026-09-15). Ren
   extern CSS-klass kringgår det utan att CSP:n behöver försvagas.
   96 steg (Chris beslut, granskningsrunda 3): höjt från 20 eftersom
   Burlöv/Idrottsfabriken (8/9 dagars tystnad) kolliderade i samma steg —
   se app/sortering.py::STEG_MAX för uträkningen (minimum 91 för att
   skilja alla dagspar 0-30 åt). Bredderna är linjärt genererade 6-240px. */
.tystnadslinje--w1 { width: 6px; }
.tystnadslinje--w2 { width: 8px; }
.tystnadslinje--w3 { width: 11px; }
.tystnadslinje--w4 { width: 13px; }
.tystnadslinje--w5 { width: 16px; }
.tystnadslinje--w6 { width: 18px; }
.tystnadslinje--w7 { width: 21px; }
.tystnadslinje--w8 { width: 23px; }
.tystnadslinje--w9 { width: 26px; }
.tystnadslinje--w10 { width: 28px; }
.tystnadslinje--w11 { width: 31px; }
.tystnadslinje--w12 { width: 33px; }
.tystnadslinje--w13 { width: 36px; }
.tystnadslinje--w14 { width: 38px; }
.tystnadslinje--w15 { width: 40px; }
.tystnadslinje--w16 { width: 43px; }
.tystnadslinje--w17 { width: 45px; }
.tystnadslinje--w18 { width: 48px; }
.tystnadslinje--w19 { width: 50px; }
.tystnadslinje--w20 { width: 53px; }
.tystnadslinje--w21 { width: 55px; }
.tystnadslinje--w22 { width: 58px; }
.tystnadslinje--w23 { width: 60px; }
.tystnadslinje--w24 { width: 63px; }
.tystnadslinje--w25 { width: 65px; }
.tystnadslinje--w26 { width: 68px; }
.tystnadslinje--w27 { width: 70px; }
.tystnadslinje--w28 { width: 73px; }
.tystnadslinje--w29 { width: 75px; }
.tystnadslinje--w30 { width: 77px; }
.tystnadslinje--w31 { width: 80px; }
.tystnadslinje--w32 { width: 82px; }
.tystnadslinje--w33 { width: 85px; }
.tystnadslinje--w34 { width: 87px; }
.tystnadslinje--w35 { width: 90px; }
.tystnadslinje--w36 { width: 92px; }
.tystnadslinje--w37 { width: 95px; }
.tystnadslinje--w38 { width: 97px; }
.tystnadslinje--w39 { width: 100px; }
.tystnadslinje--w40 { width: 102px; }
.tystnadslinje--w41 { width: 105px; }
.tystnadslinje--w42 { width: 107px; }
.tystnadslinje--w43 { width: 109px; }
.tystnadslinje--w44 { width: 112px; }
.tystnadslinje--w45 { width: 114px; }
.tystnadslinje--w46 { width: 117px; }
.tystnadslinje--w47 { width: 119px; }
.tystnadslinje--w48 { width: 122px; }
.tystnadslinje--w49 { width: 124px; }
.tystnadslinje--w50 { width: 127px; }
.tystnadslinje--w51 { width: 129px; }
.tystnadslinje--w52 { width: 132px; }
.tystnadslinje--w53 { width: 134px; }
.tystnadslinje--w54 { width: 137px; }
.tystnadslinje--w55 { width: 139px; }
.tystnadslinje--w56 { width: 141px; }
.tystnadslinje--w57 { width: 144px; }
.tystnadslinje--w58 { width: 146px; }
.tystnadslinje--w59 { width: 149px; }
.tystnadslinje--w60 { width: 151px; }
.tystnadslinje--w61 { width: 154px; }
.tystnadslinje--w62 { width: 156px; }
.tystnadslinje--w63 { width: 159px; }
.tystnadslinje--w64 { width: 161px; }
.tystnadslinje--w65 { width: 164px; }
.tystnadslinje--w66 { width: 166px; }
.tystnadslinje--w67 { width: 169px; }
.tystnadslinje--w68 { width: 171px; }
.tystnadslinje--w69 { width: 173px; }
.tystnadslinje--w70 { width: 176px; }
.tystnadslinje--w71 { width: 178px; }
.tystnadslinje--w72 { width: 181px; }
.tystnadslinje--w73 { width: 183px; }
.tystnadslinje--w74 { width: 186px; }
.tystnadslinje--w75 { width: 188px; }
.tystnadslinje--w76 { width: 191px; }
.tystnadslinje--w77 { width: 193px; }
.tystnadslinje--w78 { width: 196px; }
.tystnadslinje--w79 { width: 198px; }
.tystnadslinje--w80 { width: 201px; }
.tystnadslinje--w81 { width: 203px; }
.tystnadslinje--w82 { width: 206px; }
.tystnadslinje--w83 { width: 208px; }
.tystnadslinje--w84 { width: 210px; }
.tystnadslinje--w85 { width: 213px; }
.tystnadslinje--w86 { width: 215px; }
.tystnadslinje--w87 { width: 218px; }
.tystnadslinje--w88 { width: 220px; }
.tystnadslinje--w89 { width: 223px; }
.tystnadslinje--w90 { width: 225px; }
.tystnadslinje--w91 { width: 228px; }
.tystnadslinje--w92 { width: 230px; }
.tystnadslinje--w93 { width: 233px; }
.tystnadslinje--w94 { width: 235px; }
.tystnadslinje--w95 { width: 238px; }
.tystnadslinje--w96 { width: 240px; }


/* Tystnadslinjen ritas i relationens stadiumfärg (spec §3, "Signatur") —
   tystnad och steg läses i samma ögonkast. */
.tystnadslinje--blue { background: var(--blue); }
.tystnadslinje--violet { background: var(--violet); }
.tystnadslinje--amber { background: var(--amber); }
.tystnadslinje--green { background: var(--green); }
.tystnadslinje--rose { background: var(--rose); }
.tystnadslinje--sky { background: var(--sky); }
.tystnadslinje--gray { background: var(--gray); }

.lead-uppgiftsrad {
  margin: var(--rytm-3) 0 0;
}

.lead-uppgiftslank {
  display: inline-flex;
  align-items: center;
  gap: var(--rytm-2);
  min-height: 44px;
  padding: var(--rytm-2) var(--rytm-4);
  border-radius: var(--radie-pill);
  font-size: var(--fs-0);
  font-weight: 700;
  text-decoration: none;
  color: var(--accent);
  background: var(--accent-tint);
}

.lead-uppgiftslank:hover {
  color: var(--accent-hover);
  background: var(--accent-tint-hover);
}

.ovriga-relationer {
  margin-top: var(--rytm-6);
  color: var(--ink-muted);
  font-size: var(--fs-1);
}

/* ---------- Relationer (/kunder) ---------- */

.tabell-omslag {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--radie-kort);
  background: var(--surface);
}

table.tabell {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}

table.tabell th,
table.tabell td {
  text-align: left;
  padding: var(--rytm-3) var(--rytm-4);
  border-bottom: 1px solid var(--border-soft);
  font-size: var(--fs-1);
  vertical-align: middle;
}

table.tabell tbody tr:last-child td {
  border-bottom: none;
}

table.tabell th {
  font-size: var(--fs-0);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-muted);
  font-weight: 700;
}

table.tabell td.belopp,
table.tabell th.belopp {
  text-align: right;
}

.cell-dampad {
  color: var(--ink-muted);
}

.cell-nasta-steg {
  color: var(--ink);
  font-weight: 600;
}

/* Avslutade stadier (Förlorad/Pausad) dämpas via en ljus bakgrundston, inte
   via opacity — opacity skulle blekt VARJE textfärg proportionellt
   (länken, pillen, cell-dampad) under 4,5:1 mot vitt, uppmätt med axe-core
   i en riktig webbläsare (Pass 6). Varje textfärg i raden är redan dämpad
   i sig (--ink-muted, stegfärgens pill) — bakgrundstonen räcker för att
   ögat ska läsa raden som mindre viktig. */
tr.rad--dampad,
li.rad--dampad {
  background: var(--bg);
}

/* ---------- Relationer (/kunder): grupperad lista, ticket 04 --------------
   Tabellen är ersatt av en grupp per stadium. `.huvud` och `.panel` kommer
   från mockupen (.scratch/crm-ny-stil/preview-skiss.html) och är NYA i
   style.css här — de fanns bara i artefakten före ticket 04. OBS:
   `--panel-text*` hör till sidopanelens MÖRKA glas och används inte av
   `.panel`, som är en ljus yta på arbetsytan. Uppmätta kontrastpar står i
   crm/DESIGN.md, "Relationer (crm-ny-stil ticket 04)". */

.huvud {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--rytm-4);
  margin-bottom: var(--rytm-5);
}

.huvud h1 {
  margin: 0 0 var(--rytm-1);
}

.huvud p {
  margin: 0;
  color: var(--ink-muted);
  max-width: 65ch;
}

.panel {
  background:
    radial-gradient(120% 60% at 0% 0%, var(--yta-frost-ljus), transparent 55%),
    linear-gradient(165deg, var(--yta-frost-dis), var(--yta-frost-bas)),
    var(--yta-frost-golv);
  -webkit-backdrop-filter: blur(var(--yta-frost-blur)) saturate(160%);
  backdrop-filter: blur(var(--yta-frost-blur)) saturate(160%);
  border: 1px solid var(--yta-frost-kant-svag);
  border-radius: var(--radie-kort);
  box-shadow: var(--shadow), inset 0 1px 0 var(--yta-frost-kant);
  margin-bottom: var(--rytm-5);
  overflow: hidden;
}

.panel-rubrik {
  display: flex;
  align-items: center;
  gap: var(--rytm-2);
  margin: 0;
  padding: var(--rytm-3) var(--rytm-4);
  border-bottom: 1px solid var(--border-soft);
  font-size: var(--fs-3);
  font-weight: 600;
}

.grupp-antal {
  color: var(--ink-muted);
  background: var(--bg);
  border-radius: var(--radie-pill);
  padding: 2px var(--rytm-2);
  font-size: var(--fs-0);
  font-weight: 700;
}

.rel-lista {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Avdelaren sitter mellan raderna, inte ovanpå den första: ingen
   `:first-child`-nollställning behövs och gruppens rubrikkant blir inte
   dubbel. */
.rel-lista > li + li {
  border-top: 1px solid var(--border-soft);
}

.rel-rad {
  display: flex;
  align-items: center;
  gap: var(--rytm-3);
  padding: var(--rytm-3) var(--rytm-4);
  min-height: 56px;
  color: inherit;
  text-decoration: none;
}

/* Hovern använder --kol-yta, inte --bg: en avslutad rad (li.rad--dampad)
   ligger redan på --bg och hade annars inte reagerat alls på musen. */
.rel-rad:hover,
.rel-rad:focus-visible {
  background: var(--kol-yta);
}

.rel-namn {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 2 1 200px;
  min-width: 0;
}

.rel-namn b {
  font-weight: 600;
}

.rel-meta {
  color: var(--ink-muted);
  font-size: var(--fs-1);
}

/* Fast bredd, inte `auto`: annars bestämmer pillens egen textlängd var
   stadiekolumnen börjar och både pillarna och nästa steg-texten hamnar på
   olika x-position i varje rad. Ögat läser en kolumn, inte en trappa. */
.rel-stadium {
  flex: 0 0 160px;
}

.rel-nasta {
  flex: 2 1 180px;
  min-width: 0;
  color: var(--ink-muted);
  font-size: var(--fs-1);
}

.rel-datum {
  flex: 0 0 104px;
  color: var(--ink-muted);
  font-size: var(--fs-1);
}

.rel-varde {
  flex: 0 0 96px;
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-1);
}

.rel-pil {
  flex: 0 0 auto;
  color: var(--ink-muted);
}

.relationsfilter {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--rytm-3);
  margin-bottom: var(--rytm-3);
}

.relationsfilter-falt {
  display: flex;
  flex-direction: column;
  gap: var(--rytm-1);
}

.relationsfilter-falt label {
  margin-bottom: 0;
  font-weight: 600;
}

/* 44px träffyta (WCAG 2.2 SC 2.5.8) skopat till filterraden, så att inga
   andra fält eller knappar i appen får en höjdändring de inte bad om. */
.relationsfilter input,
.relationsfilter select,
.relationsfilter .knapp {
  min-height: 44px;
}

.relationsfilter-knappar {
  display: flex;
  align-items: center;
  gap: var(--rytm-3);
}

.relationsfilter-rensa {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: var(--fs-1);
}

.relationsfilter-antal {
  margin: 0 0 var(--rytm-4);
  color: var(--ink-muted);
  font-size: var(--fs-1);
}

@media (max-width: 760px) {
  /* Datum och värde är det första som får vika på en telefon — namn,
     stadium och nästa steg är det Chris letar efter. */
  .rel-datum,
  .rel-varde {
    display: none;
  }

  .rel-rad {
    flex-wrap: wrap;
  }

  /* Två fasta rader i stället för att låta varje posts textlängd avgöra
     var brytningen hamnar: namn + typ · kontakt överst, sedan stadium och
     nästa steg. Utan detta hoppar pillen mellan rad ett och rad två från
     post till post. */
  .rel-namn {
    flex: 1 1 100%;
  }

  /* Den fasta stadiekolumnen är till för att rada upp pillarna på en bred
     skärm. På en telefon radbryter raden ändå och 160 px blir bara ett hål. */
  .rel-stadium {
    flex: 0 0 auto;
  }

  .relationsfilter {
    flex-direction: column;
    align-items: stretch;
  }

  .relationsfilter-falt {
    width: 100%;
  }

  .relationsfilter input,
  .relationsfilter select {
    width: 100%;
  }
}

.status-forfallen {
  color: var(--rose);
  font-weight: 600;
}

/* ---------- Kundsidan (crm-ny-stil ticket 05) ----------
   Tvåkolumnsrutnät: arbetet (Nästa steg, Uppgifter, Historik, Anteckningar)
   till vänster, fakta (Kontaktuppgifter, Fakturor, Löpande, Övriga fält) till
   höger. Administrationen av posten (byta stadium, radera) ligger bakom
   kugghjulet i sidhuvudet.

   .installningar och .meny är skrivna GENERISKT, inte kundsidespecifikt:
   ticket 06 (Internt) ska återanvända exakt samma regler.

   FÄLLA: .panel har overflow: hidden. Kugghjulet ligger i .huvud, aldrig i
   en .panel — en absolut positionerad meny inuti en panel klipps bort.
   Modifierarna nedan ligger med flit EFTER sina basregler .huvud och .panel
   (samma specificitet, källordningen avgör).
   -------------------------------------------------------------------- */

.kund-rutnat {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  gap: var(--rytm-5);
  align-items: start;
}

/* Samma brytpunkt som resten av appen (760 px), inte mockupens egen. */
@media (max-width: 760px) {
  .kund-rutnat {
    grid-template-columns: 1fr;
  }
}

.stack {
  display: flex;
  flex-direction: column;
  gap: var(--rytm-4);
}

/* .panel bär margin-bottom: var(--rytm-5) och .flik var(--rytm-3) för sina
   egna, ostaplade sammanhang. I en stack med gap skulle de dubbla avståndet. */
.stack > .panel,
.stack > .flik {
  margin-bottom: 0;
}

.panel-kropp {
  padding: var(--rytm-3) var(--rytm-4);
}

.panel--nasta {
  background: var(--accent-tint);
  border: 1px solid var(--accent);
}

.panel--nasta .etikett {
  color: var(--accent);
}

.panel--nasta .fran-projektet {
  margin: var(--rytm-2) 0 0;
}

.huvud--med-meny {
  position: relative;
  padding-right: 56px;
}

.huvud-aktioner {
  display: flex;
  align-items: center;
  gap: var(--rytm-2);
  flex-wrap: wrap;
}

.kund-typrad {
  display: flex;
  align-items: center;
  gap: var(--rytm-2);
  flex-wrap: wrap;
  margin: 0;
}

.installningar {
  position: absolute;
  top: 0;
  right: 0;
}

/* 44 px, inte mockupens 36 px: appens klickytor följer WCAG 2.2 SC 2.5.8. */
.installningar > summary {
  list-style: none;
  width: 44px;
  height: 44px;
  border-radius: 10px;
  display: grid;
  place-items: center;
  cursor: pointer;
  color: var(--ink-muted);
}

.installningar > summary::-webkit-details-marker {
  display: none;
}

.installningar > summary:hover {
  background: var(--border-soft);
  color: var(--ink);
}

.installningar[open] > summary {
  background: var(--accent-tint);
  color: var(--accent);
}

.meny {
  position: absolute;
  top: 48px;
  right: 0;
  min-width: 240px;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  box-shadow: var(--shadow);
  padding: var(--rytm-3);
  display: flex;
  flex-direction: column;
  gap: var(--rytm-2);
  z-index: 5;
}

.meny-formular {
  display: flex;
  flex-direction: column;
  gap: var(--rytm-2);
}

.meny-formular .faltrad {
  margin-bottom: 0;
}

.meny-formular select {
  width: 100%;
}

.meny hr {
  border: 0;
  border-top: 1px solid var(--border-soft);
  margin: var(--rytm-2) 0;
  width: 100%;
}

.meny-fara {
  color: var(--rose-ink);
  min-height: 44px;
  display: flex;
  align-items: center;
  padding: 0 var(--rytm-2);
  border-radius: 8px;
  text-decoration: none;
}

.meny-fara:hover {
  background: var(--bg);
}

.kund-typ {
  color: var(--ink-muted);
}

.nasta-steg-text {
  margin: 0;
  font-size: var(--fs-4);
  line-height: 1.5;
  font-weight: 600;
  color: var(--ink);
}

.nasta-steg-text--tom {
  color: var(--ink-muted);
  font-weight: 400;
}

.fran-projektet {
  margin: 0 0 var(--rytm-6);
  color: var(--ink-muted);
  font-size: var(--fs-1);
}

/* Faktalistan ärvde typografin från den borttagna `.faktablock`-asiden
   (ticket 05): egen klass i stället för `.panel-kropp dl`, så att ticket 06:s
   paneler inte tyst får en versal beskrivningslista de inte bett om. */
.faktalista {
  margin: 0;
}

.faktalista dt {
  font-size: var(--fs-0);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-top: var(--rytm-3);
}

.faktalista dt:first-child {
  margin-top: 0;
}

.faktalista dd {
  margin: 0;
  color: var(--ink);
}

section.block {
  margin-bottom: var(--rytm-7);
}

section.block h2 {
  border-bottom: 1px solid var(--border);
  padding-bottom: var(--rytm-2);
}

ul.uppgiftslista {
  list-style: none;
  margin: 0;
  padding: 0;
}

ul.uppgiftslista li {
  padding: var(--rytm-2) 0;
  border-bottom: 1px solid var(--border-soft);
  display: flex;
  gap: var(--rytm-3);
  align-items: baseline;
}

ul.uppgiftslista li.klar {
  color: var(--ink-muted);
  text-decoration: line-through;
}

ul.uppgiftslista .uppgift-datum {
  color: var(--ink-muted);
  white-space: nowrap;
}

/* Kundsidans uppgiftsrad: Ändra-fliken får en egen rad under uppgiften
   (radera/redigera, ticket 04). Hemvisten flyttade från `.kund-huvud` till
   `.panel-kropp` i ticket 05 när kolumnen blev ett rutnät av paneler — utan
   den bryter raden illa på mobil. */
.panel-kropp ul.uppgiftslista li { flex-wrap: wrap; }
.panel-kropp ul.uppgiftslista li > .uppgift-text { flex: 1 1 0; min-width: 0; }
.panel-kropp ul.uppgiftslista li > .uppgift-detaljer { flex-basis: 100%; }

form.statusrad {
  display: flex;
  align-items: center;
  gap: var(--rytm-2);
}

form.statusrad select {
  padding: var(--rytm-1) var(--rytm-2);
}

ul.historik {
  list-style: none;
  margin: 0;
  padding: 0;
}

ul.historik li {
  padding: var(--rytm-3) 0;
  border-bottom: 1px solid var(--border-soft);
}

ul.historik .historik-datum {
  display: block;
  font-weight: 600;
  margin-bottom: var(--rytm-1);
}

.anteckningar {
  max-width: 66ch;
  white-space: pre-wrap;
}

.ovriga-falt {
  margin-top: var(--rytm-5);
  font-size: var(--fs-1);
  color: var(--ink-muted);
}

/* ---------- Ekonomisidan: ett enda tal ---------- */

.stor-siffra {
  font-family: "Manrope", sans-serif;
  font-size: clamp(var(--fs-5), 8vw, 2.6rem);
  font-weight: 800;
  margin: var(--rytm-5) 0 var(--rytm-2);
}

.stor-siffra-etikett {
  font-size: var(--fs-0);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.delsummor {
  display: flex;
  gap: var(--rytm-6);
  flex-wrap: wrap;
  margin: var(--rytm-6) 0 var(--rytm-7);
  padding-top: var(--rytm-4);
  border-top: 1px solid var(--border);
}

.delsumma dt {
  font-size: var(--fs-0);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.delsumma dd {
  margin: var(--rytm-1) 0 0;
  font-size: var(--fs-3);
  font-weight: 700;
}

/* Ligger BART på nebulosan (Snabböversikten har ingen ruta): --rose mäter
   1,23:1 där. Ljus ton i samma kulör, 5,12:1 (2026-09-26, mätvärde uppdaterat
   2026-09-27 efter porteringen till klot+brus). */
.delsumma.forfallet dd {
  color: var(--yta-larm);
}

/* Ekonomimenyns valkort (crm-ny-stil ticket 07). Egna, plattare kort: de
   lånar INTE .omrade-kort:s hålslagsremsa (den hör till interna områden) och
   inte .panel:s overflow. De ska vinna genom yta och hovring, aldrig genom
   färg — fokalpunkten på sidan är fortfarande .stor-siffra ovanför. */
.valkort-lista {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--rytm-4);
  margin-bottom: var(--rytm-5);
}

.valkort {
  display: flex;
  flex-direction: column;
  gap: var(--rytm-2);
  padding: var(--rytm-4);
  background:
    radial-gradient(120% 60% at 0% 0%, var(--yta-frost-ljus), transparent 55%),
    linear-gradient(165deg, var(--yta-frost-dis), var(--yta-frost-bas)),
    var(--yta-frost-golv);
  -webkit-backdrop-filter: blur(var(--yta-frost-blur)) saturate(160%);
  backdrop-filter: blur(var(--yta-frost-blur)) saturate(160%);
  border: 1px solid var(--yta-frost-kant-svag);
  border-radius: var(--radie-kort);
  box-shadow: var(--shadow), inset 0 1px 0 var(--yta-frost-kant);
  /* Nebulosa (2026-09-27, bevisrundan): var `color: inherit` innan denna
     kommentar skrevs — på arbetsytans nya ljusa ambienta text vann det över
     återställningsblockets `color: var(--ink)` ovan (samma specificitet,
     senare i filen), så kortets titel blev ljus text på det nästan vita
     frostade kortet, 1:1. `.valkort` är redan en av de återställda ytorna
     (se blocket ovan där `--ink` binds om för just detta klassnamn) — den
     ska alltså läsa sin egen `--ink`, inte ärva arbetsytans. */
  color: var(--ink);
  text-decoration: none;
}

/* Samma hovringsspråk som .rel-rad: ytan byter till --kol-yta, texten
   behålls. Uppmätt mot --kol-yta: --ink 13,58:1, --ink-muted 4,97:1. */
.valkort:hover,
.valkort:focus-visible {
  background: var(--kol-yta);
}

.valkort-under {
  color: var(--ink-muted);
  font-size: var(--fs-0);
}

/* Platshållarmodifieraren för Skatteverket-kortet togs bort i ticket 08:
   båda valkorten är riktiga länkar nu och inget använder den längre. */

/* Kategorisumman i Utgifter-flikens summary: skjuts ut till höger och håller
   siffrorna i kolumn med tabellsiffror. */
.utgift-kategori-summa {
  margin-left: auto;
  font-variant-numeric: tabular-nums;
}

/* Delradens formulär ligger helt inom EN <td> (ett <form> får aldrig korsa
   en <tr>/<td>-gräns). Radbryter på smal skärm i stället för att pressa
   fälten. */
.utgift-delform {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--rytm-2);
}

/* ---------- Formulär ---------- */

label {
  display: block;
  font-size: var(--fs-0);
  color: var(--ink-muted);
  margin-bottom: var(--rytm-1);
}

input,
select,
textarea {
  font-family: inherit;
  font-size: 1rem;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radie-liten);
  padding: var(--rytm-2) var(--rytm-3);
}

input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  border-color: var(--accent);
}

input:disabled,
select:disabled,
textarea:disabled,
button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

button,
.knapp,
.knapp-svag {
  /* Granskningsfynd runda 1: .knapp-svag hade bara sina EGNA color/
     background/box-shadow-rader (nedan) och ärvde ALDRIG basformen —
     `<a class="knapp-svag">` (sidopanelens "+ Ny relation") blev 24px
     hög, 0 padding, 0 radie, vikt 400: den enda ostylade ytan i hela
     sidopanelen. `.knapp-svag`s egna färgregler nedan har samma
     specificitet och matchas senare i filen, så de vinner fortfarande
     över den fyllda bakgrunden/texten här — bara box-modellen delas. */
  font-family: inherit;
  font-size: var(--fs-1);
  font-weight: 700;
  color: var(--accent-ink);
  background: var(--accent);
  border: none;
  border-radius: var(--radie-liten);
  padding: var(--rytm-2) var(--rytm-4);
  cursor: pointer;
  box-shadow: var(--shadow);
}

/* En <a> är i formen efter samma .knapp/.knapp-svag-klasser som en
   <button> (spec crm-ny-relation §5, tomma lägets knapp + sidopanelens
   "+ Ny relation") — bara layoutegenskaper som en <button> redan har
   gratis via sitt element, inga nya färger eller radier. */
a.knapp,
a.knapp-svag {
  display: inline-block;
  text-decoration: none;
}

button:hover:not(:disabled),
a.knapp:hover {
  background: var(--accent-hover);
}

.knapp-svag {
  color: var(--accent);
  background: var(--accent-tint);
  box-shadow: none;
}

.knapp-svag:hover:not(:disabled) {
  /* Granskningsfynd runda 2: accent (#5850EC) på accent-tint-hover mätte
     4,29:1, under 4,5:1 — accents egen luminans är för låg för att någon
     mörkning av bakgrunden ensam kan rädda paret (se :root-kommentaren).
     Texten byter till accent-hover här, samma mörkare indigo som redan
     används för primärknappens hover-bakgrund — samma kulör, bara mörkare.
     `:not(:disabled)` är en no-op på en <a> (disabled finns inte där) —
     ofarligt, hover gäller ändå. */
  color: var(--accent-hover);
  background: var(--accent-tint-hover);
}

.knapp-liten {
  padding: var(--rytm-1) var(--rytm-3);
  font-size: var(--fs-0);
  white-space: nowrap;
}

/* Uppgiftsradens "bocka av/upp" (ticket: ruta i stället för textknapp).
   En <button role="checkbox"> — CSP tillåter inget <input type=checkbox>
   utan skript (progressiv JS-regeln, se CLAUDE.md), så det måste förbli ett
   riktigt POST-formulär styliserat som en kryssruta. Ikonen ritas med
   border-linjer, inte text/färg, så kontrastvakten (som bara läser
   color/background-par) inte behöver ett nytt par att bedöma — den
   verkliga kontrasten återanvänder samma accent/accent-ink-par som
   redan är uppmätt för basknappen ovan. */
.bocka-ruta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  background: var(--surface);
  border: 2px solid var(--ink-muted);
  border-radius: var(--radie-liten);
  box-shadow: none;
  cursor: pointer;
  flex: none;
}

.bocka-ruta::after {
  content: "";
  width: 12px;
  height: 7px;
  border-left: 2px solid var(--accent-ink);
  border-bottom: 2px solid var(--accent-ink);
  transform: rotate(-45deg) translateY(-1px);
  opacity: 0;
}

.bocka-ruta:hover:not(:disabled) {
  background: var(--surface);
  border-color: var(--accent);
}

.bocka-ruta:focus-visible {
  outline: 2px solid var(--fokus);
  outline-offset: 2px;
}

.bocka-ruta[aria-checked="true"] {
  background: var(--accent);
  border-color: var(--accent);
}

.bocka-ruta[aria-checked="true"]::after {
  opacity: 1;
}

.bocka-ruta[aria-checked="true"]:hover:not(:disabled) {
  background: var(--accent-hover);
  border-color: var(--accent-hover);
}

.sidopanel-ny {
  /* Granskningsfynd runda 1: träffytan var 24px hög (under 44px-kravet i
     _system/UI_KONVENTIONER_2026.md §1/§6) innan basformen ovan
     applicerades. `var(--rytm-4)` (16px) på båda sidor i stället för
     basens `var(--rytm-2)` (8px) — samma spacing-skala, ingen ny token —
     ger tillräcklig höjd. `display: inline-block` (från `a.knapp-svag`
     ovan, högre specificitet än den här klassen) respekterar vertikal
     padding för klickytans höjd precis som `block` hade gjort. */
  text-align: center;
  padding-top: var(--rytm-4);
  padding-bottom: var(--rytm-4);
  /* På glaset byter den svaga knappen håll: vit yta med accentens mörkblå
     text (10,36:1), samma som mockupens `.ny`. Accent-tinten hade blivit en
     nästan osynlig ljusblå fläck på den mörka panelen. */
  background: var(--panel-text-stark);
  color: var(--accent);
}

/* Granskningsfynd runda 3: som `.sidopanel-ny:hover` (0,2,0) förlorade den
   här regeln specificitetsstriden mot `.knapp-svag:hover:not(:disabled)`
   (0,3,0) ovan och målades aldrig — hovringen gav den vanliga svaga
   knappens ljusblå tint i stället för den vita knappens. Elementet är
   `<a class="knapp-svag sidopanel-ny">`, så `a.knapp-svag.sidopanel-ny:hover`
   (0,3,1) beskriver samma element och vinner. Mekaniserat i
   test_scopade_knappoverskrivningar_vinner_faktiskt. */
a.knapp-svag.sidopanel-ny:hover {
  background: var(--accent-tint);
  color: var(--accent-hover);
}

.faltrad {
  margin-bottom: var(--rytm-3);
}

.formularrad {
  display: flex;
  gap: var(--rytm-3);
  align-items: end;
  flex-wrap: wrap;
}

/* ---------- /ny: "Lägg till ny relation" (spec crm-ny-relation §5) ---------- */

.ny-relation {
  max-width: 480px;
  padding: var(--rytm-5);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radie-kort);
  box-shadow: var(--shadow);
}

.ny-relation-huvud {
  max-width: 480px;
  margin-bottom: var(--rytm-5);
}

.ny-relation-huvud h1 {
  margin-bottom: var(--rytm-1);
}

.ny-relation-huvud p {
  margin: 0;
  color: var(--ink-muted);
}

.faltgrupp {
  margin-top: var(--rytm-5);
  padding-top: var(--rytm-4);
  border-top: 1px solid var(--border);
}

.faltgrupp-rubrik {
  /* Medvetet UTAN versaler (spec §5): "Kan fyllas i senare" är en dämpad
     hänvisning, inte en sektionsetikett som .etikett (som ÄR versal). */
  font-size: var(--fs-0);
  font-weight: 600;
  color: var(--ink-muted);
  margin: 0 0 var(--rytm-3);
}

.falt-hjalp {
  font-size: var(--fs-0);
  color: var(--ink-muted);
  margin: calc(var(--rytm-1) * -1) 0 var(--rytm-3);
}

/* ---------- Flik: <details>/<summary> (spec crm-lugnare-vy §5) ---------- */

.flik {
  border: 1px solid var(--border);
  border-radius: var(--radie-liten);
  background: var(--surface);
  margin-bottom: var(--rytm-3);
}

.flik > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: var(--rytm-2);
  min-height: 44px;
  padding: var(--rytm-2) var(--rytm-4);
  color: var(--ink);
  background: var(--surface);
  border-radius: var(--radie-liten);
}

.flik > summary::-webkit-details-marker {
  display: none;
}

.flik > summary::before {
  content: "";
  flex: none;
  width: 7px;
  height: 7px;
  border: solid var(--accent);
  border-width: 0 2px 2px 0;
  transform: rotate(-45deg);
}

.flik[open] > summary::before {
  transform: rotate(45deg);
}

.flik > summary:hover {
  background: var(--border-soft);
}

.flik-rubrik {
  margin: 0;
  border: none;
  padding: 0;
  font-size: var(--fs-1);
  font-weight: 700;
}

.flik-antal,
.block-antal {
  font-family: "Public Sans", ui-sans-serif, system-ui, sans-serif;
  font-size: var(--fs-1);
  font-weight: 400;
  color: var(--ink-muted);
}

.flik-innehall {
  padding: 0 var(--rytm-4) var(--rytm-4);
}

.flik-innehall > .formularrad,
.flik-innehall > .tabell-omslag + .formularrad {
  margin-top: var(--rytm-4);
}

/* Redigera-fliken sitter sist i kontaktpanelen och bär panelens sista rad
   (ticket 05: `.faktablock`-asiden blev en `.panel`). Ingen egen ram och
   ingen rundning — den ska läsas som panelens fot, inte som ett eget kort. */
.panel > .flik {
  margin: 0;
  border: 0;
  border-top: 1px solid var(--border-soft);
  border-radius: 0;
}

@media (max-width: 760px) {
  .knapp-liten {
    min-height: 44px;
    min-width: 44px;
  }

  .ny-relation {
    padding: var(--rytm-4);
  }
}

/* ---------- Inloggning (ticket 03) — egen minimal layout, ingen
   sidopanel: _inlogg_bas.html ärver INTE base.html. Basstilarna (margin,
   bakgrund, textfärg, typsnitt) kommer redan från den generella `body`-
   regeln ovan — ingen egen klassad body-regel för inloggningen behövs
   (åtgärdsrunda ticket 11, punkt 8: en tidigare sådan regel dubblerade
   den byte för byte). ---------- */

/* Åtgärdsrunda ticket 11, punkt 1: kortet ska INTE flyta centrerat i
   viewporten med en svävande skugga — det ska ligga uppe till vänster i
   samma rytm som `.innehall` (samma padding-skala), utan sidopanel att
   dela grid med (ingen finns före inloggning). Ingen `box-shadow`, en
   `border` i den metallgrå tonen `--metal-low` i stället för den vanliga
   kort-ramen. (Hänvisningen till pipelinets delade ram togs bort i ticket
   03: tavlan har ingen egen ram längre, kolumnerna bär ytan själva.) */
/* Natt och eld (ticket 01): inloggningen är den andra — och enda andra —
   ytan som bär den mörkblå scenen. Kortet ligger fortfarande uppe till
   vänster i samma rytm som `.innehall`, inte centrerat och utan svävande
   skugga (åtgärdsrunda ticket 11, punkt 1 gäller oförändrat) — det är BARA
   ytan som bytt från vitt papper till glas över natt. */
.inlogg-skal {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  min-height: 100vh;
  padding: 26px 32px 60px;
  background: var(--navy-0);
  color: var(--panel-text);
}

.inlogg-skal .scen {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  display: block;
}

@media (max-width: 760px) {
  .inlogg-skal {
    padding: 20px 18px 48px;
  }
}

.inlogg-kort {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 360px;
  padding: var(--rytm-6);
  /* Samma glas som sidopanelen, samma mätta alfavärden (se :root). Ingen
     slagskugga: kortet ska inte sväva (åtgärdsrunda ticket 11, punkt 1,
     mekaniserad i test_inlogg_skal_ar_inte_centrerad_med_flytande_skugga —
     som läser den här regelkroppen som text, kommentarer inkluderade). */
  background:
    radial-gradient(130% 55% at 0% 0%, var(--glas-ljus), rgba(255, 255, 255, 0) 58%),
    linear-gradient(160deg, var(--glas-dis), var(--glas-bas)),
    var(--glas-bas);
  -webkit-backdrop-filter: blur(11px) saturate(180%);
  backdrop-filter: blur(11px) saturate(180%);
  border: 1px solid var(--glas-kant);
  border-radius: 22px;
  color: var(--panel-text);
}

.inlogg-titel {
  margin: var(--rytm-5) 0 var(--rytm-4);
  color: var(--panel-text-stark);
}

.inlogg-kort label {
  color: var(--panel-text-stark);
  font-size: var(--fs-1);
  font-weight: 600;
}

/* Fälten är solid --navy-1 i stället för mockupens genomskinliga
   rgba(255,255,255,.08): en opak ton går att mäta maskinellt (vit text på
   #0f1d4a = 16,22:1, med i den generella kontrastsvepningen) och ett
   inmatningsfält ska inte skifta i läsbarhet beroende på vilken ember som
   råkar lysa bakom det. */
.inlogg-kort input {
  background: var(--navy-1);
  border-color: var(--glas-kant);
  color: var(--panel-text-stark);
  caret-color: var(--panel-text-stark);
}

.inlogg-kort input:focus-visible {
  border-color: var(--panel-text-stark);
}

/* Primärknappen är accentens mörkblå (vit text, 10,36:1). På den mörka
   ytan behöver den en ljus kant för att formen ska synas alls
   (SC 1.4.11, icke-textkontrast) — knappfyllningen själv mäter bara 1,16:1
   mot glaset över den tändaste embern, så kanten ÄR knappens form.

   Granskningsfynd runda 3 (samma buggklass som runda 1 och 2 ovan): den
   här regeln hade bara `border-color`, och basregeln `button, .knapp,
   .knapp-svag` sätter `border: none` — en ensam `border-color` mot
   `border-style: none` ritar ingenting, kanten fanns bara i koden.
   Shorthanden nedan ritar den på riktigt. Kulören är `--glas-kant-stark`
   (vit 0,50), inte `--glas-kant` (0,22): en halvgenomskinlig kant blandas
   med knappens EGEN mörkblå fyllning under sig (background-clip är
   border-box), och 0,22 gav bara 2,14:1 mot glaset — under 3:1. 0,50 ger
   4,40:1 mot glaset över embern och 3,80:1 mot fyllningen inuti.
   Mekaniserat i test_ingen_border_color_utan_border_style. */
.inlogg-kort .knapp {
  border: 1px solid var(--glas-kant-stark);
}

.inlogg-falt {
  margin-bottom: var(--rytm-4);
}

/* Åtgärdsrunda ticket 11, punkt 5: steg två visar kodfältet ensamt på
   sidan med användarnamnet som en liten överrad direkt ovanför fältet,
   inte som ett eget etiketterat formulärfält. */
.inlogg-anvandarnamn-rad {
  margin: 0 0 var(--rytm-2);
  font-size: var(--fs-0);
  /* Var --ink-muted (grafitgrå) — omätbart svag på det mörka glaset. */
  color: var(--panel-text-svag);
}

.inlogg-falt input {
  width: 100%;
  min-height: 44px;
}

.inlogg-fel {
  margin: 0 0 var(--rytm-4);
  padding: var(--rytm-3) var(--rytm-4);
  border-radius: var(--radie-liten);
  border: 1px solid var(--rose);
  background: var(--rose-tint);
  color: var(--rose);
  font-size: var(--fs-1);
}

/* Ticket 06: besked om VARFÖR en session gick ut (`?skal=...`) — samma form
   som .inlogg-fel men amber i stället för rose, eftersom det inte är ett
   fel Chris gjorde, bara ett förklarat utloggat läge. */
.inlogg-besked {
  margin: 0 0 var(--rytm-4);
  padding: var(--rytm-3) var(--rytm-4);
  border-radius: var(--radie-liten);
  border: 1px solid var(--amber);
  background: var(--amber-tint);
  color: var(--amber);
  font-size: var(--fs-1);
}

.inlogg-knapp {
  width: 100%;
  min-height: 44px;
}

/* ---------- Sidopanelens kontoblock (ticket 03) ---------- */

.sidopanel-konto {
  margin-top: auto;
  padding-top: var(--rytm-4);
  border-top: 1px solid var(--glas-kant);
  display: flex;
  flex-direction: column;
  gap: var(--rytm-2);
  /* Kontoraden (ticket 02) ankrar kugghjulets summary absolut mot RADEN,
     inte mot hela panelen — se .kontorad och .sidopanel-konto .installningar
     > summary nedan. */
  position: relative;
}

.sidopanel-namn {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: var(--fs-1);
  font-weight: 600;
  color: var(--panel-text-stark);
  text-decoration: none;
  /* Kontoraden (ticket 02): namnet delar grid-facket med en fast bredd på
     var sida (bilden, kugghjulet) och måste kunna krympa under sin egen
     innehållsbredd för att ellipsen ska få effekt, annars trycker ett långt
     namn ut kugghjulet ur panelen. */
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sidopanel-namn:hover,
.sidopanel-namn:focus-visible {
  /* Var --accent tidigare. På glaset skulle mörkblått försvinna — hover
     markeras med understrykning i stället för med färg. */
  color: var(--panel-text-stark);
  text-decoration: underline;
}

.sidopanel-utlogg .knapp-svag {
  background: transparent;
  border: 1px solid var(--glas-kant);
  color: var(--panel-text-stark);
}

.sidopanel-utlogg .knapp-svag:hover {
  background: var(--glas-aktiv);
  color: var(--panel-text-stark);
}

.sidopanel-utlogg {
  margin: 0;
}

.sidopanel-utlogg .knapp-svag {
  width: 100%;
  min-height: 44px;
}

/* Kontoraden (ticket 02): bild, namn och kugghjul på EN rad i stället för
   tre. Grid i stället för flex — bilden och kugghjulet har fasta bredder
   (32px respektive 44px, kugghjulets träffyta), namnet får resten
   (minmax(0, 1fr) så det kan krympa till ellipsen i .sidopanel-namn ovan).
   `<details class="installningar">` ligger som tredje grid-barn, men får
   (fixrunda 1, punkt 1+2) `grid-column: 1 / -1` på sig (se regeln längre
   ner) — den begär då alla tre kolumnerna, får inte plats i rad 1 (redan
   upptagen av bild och namn) och hamnar automatiskt i en egen, implicit
   rad 2 som spänner hela bredden. `.meny` (position: static) är
   `<details>`s enda in-flow-innehåll och får därför hela panelens bredd att
   flyta i i stället för det tidigare 44px-facket, och `.kontorad`s egen rad
   (bild + namn) delar inte längre gridspår med menyn — kontoradens höjd
   ändras alltså aldrig av att menyn fälls ut. */
/* row-gap: 0 är avsiktligt. `summary` är absolutpositionerad och alltså ur
   flödet, så med stängd meny har `<details>` noll in-flow-innehåll och rad 2
   blir 0px hög — ett radgap hade då lagt 12px dött utrymme under kontoraden i
   standardläget. Med row-gap: 0 är stängt läge exakt 44px och menyn fäller ut
   fäst under kugghjulet, vilket är normal dropdown-geometri. */
.kontorad {
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr) 44px;
  align-items: center;
  column-gap: var(--rytm-3);
  row-gap: 0;
}

/* Samma mått som profilbilden (ticket 05) sedan får, så layouten inte
   hoppar när en bild läggs till. */
.kontobild {
  width: 32px;
  height: 32px;
  border-radius: 50%;
}

/* Initialrutan (ingen bild uppladdad än). Bakgrund och text är samma
   redan uppmätta par som `.sidopanel-utlogg .knapp-svag:hover` använder
   (`--glas-aktiv` + `--panel-text-stark`) — ingen ny token. */
.kontobild--initial {
  display: grid;
  place-items: center;
  background: var(--glas-aktiv);
  color: var(--panel-text-stark);
  font-size: var(--fs-0);
  font-weight: 600;
}

/* Den uppladdade profilbilden (crm-nova ticket 05c). Måtten och radien
   ärvs från `.kontobild` ovan, så bilden tar exakt initialrutans plats.
   `object-fit: cover` beskär en avlång bild till cirkeln i stället för att
   trycka ihop den; `display: block` tar bort baslinjeglappet under en
   inline-bild. Ingen width/height här: då skulle den här regelns högre
   specificitet slå ut `.kontobild--stor` nedan. */
img.kontobild {
  display: block;
  object-fit: cover;
}

/* Samma bild i större format överst i #profilbild på kontosidan. 96px är
   tre gånger sidopanelens 32px. */
.kontobild--stor {
  width: 96px;
  height: 96px;
  margin: 0 0 var(--rytm-3);
}

/* Granskningsfynd M1 (crm-nova 05c): Spara och Ta bort låg kant i kant och
   under 44×44px-träffytan. Ta bort raderar utan bekräftelse, så formulären
   får luft emellan. Skopat som `.konto-utlogg .knapp-svag`. */
#foretagslogga .formularrad + .formularrad,
#profilbild .formularrad + .formularrad {
  margin-top: var(--rytm-3);
}

#foretagslogga .knapp-svag,
#profilbild .knapp-svag {
  min-height: 44px;
  min-width: 44px;
}

/* Den stora loggan i #foretagslogga (crm-nova ticket 06) återanvänder
   `.kontobild--stor`s 96×96, men en logga är inte ett ansikte: `contain` i
   stället för profilbildens `cover`, rundad ruta i stället för cirkel, och
   samma vita bricka som i sidopanelen — arbetsytan bakom är mörk i nattemat.
   Id-skopningen (1,1,0) slår `img.kontobild` och `.kontobild`. */
#foretagslogga .kontobild--stor {
  box-sizing: border-box;
  padding: var(--rytm-2);
  border-radius: var(--radie-liten);
  background: var(--panel-text-stark);
  object-fit: contain;
}

/* Dagtemat: den vita brickan mätte bara 1,24–1,57:1 mot den ljusa himlen
   (bevisrunda 06), så en logga med vit botten flöt ihop med sidan. En tunn
   kant i dagtemats --yta-text-svag ger brickan en gräns: 5,24:1 mot himlens
   mörkaste punkt, 10,49:1 mot den ljusaste, 11,52:1 mot brickan (--ink-muted
   föll på 2,73:1 mot den mörkaste). border-box håller 96×96. Nattemat
   behöver ingen kant. */
[data-tema="dag"] #foretagslogga .kontobild--stor {
  border: 1px solid var(--yta-text-svag);
}

/* Länken till "Mitt konto" i menyn. Ingen egen färg: `.meny` har alltid
   ljus bakgrund (`--surface`, se basregeln), och husets globala `a`-regel
   (`color: var(--lank)`) räcker — samma konvention som resten av huset.
   Fixrunda 1, punkt 8: padding, border-radius och hover speglar nu
   `.meny-fara` (utloggningslänken längre ner i menyn) så de två länkarna
   känns som samma komponent i stället för att bara `.meny-fara` hade en
   tydlig träffyta och hover-bakgrund. */
.menyval {
  min-height: 44px;
  display: flex;
  align-items: center;
  padding: 0 var(--rytm-2);
  border-radius: 8px;
  text-decoration: none;
}

.menyval:hover {
  background: var(--bg);
}

/* ---------- Temaväljaren i kontoblocket (crm-tema ticket 01) ----------
   Skopade modifierare. Basreglerna .installningar och .meny (kundsidan,
   Internt) är oförändrade och ligger FÖRE dessa, precis som modifierarna på
   kundsidan; selektorerna vinner dessutom på specificitet.

   Kontoraden (ticket 02, Alternativ A) bygger vidare på samma två fixar:

   1. Basregeln är position: absolute med top och right noll — den skulle
      lyfta HELA <details> ur flödet. `.sidopanel-konto .installningar`
      nollar det till position: static, plus `grid-column: 1 / -1`
      (fixrunda 1, punkt 1+2): <details> begär då alla tre kolumnerna, får
      inte plats i rad 1 (redan upptagen av bild och namn) och hamnar
      automatiskt i en egen implicit rad 2 som spänner hela bredden — inte
      längre bara det tredje facket. Det är BARA <details> som är static —
      dess `summary` får en EGEN `position: absolute` (se regeln några
      rader ner) ankrad mot `.sidopanel-konto` (nu `position: relative`),
      så kugghjulet visuellt hamnar i radens tredje fack i stället för att
      uppta hela fackets höjd som </details> annars skulle göra. Fördelen
      med den egna raden: `.meny` (position: static, min-width: 0) är
      `<details>`s enda in-flow-innehåll och fick tidigare ärva det tredje
      fackets 44px-bredd rakt av (menyn kollapsade till en 44px-smal
      kolumn); nu får den hela panelens bredd. Kontoradens egen rad
      (bild + namn) delar heller inte längre gridspår med menyn, så
      kontoradens höjd/position påverkas aldrig av om menyn är öppen eller
      stängd.
   2. Panelen klipper (overflow: hidden) och glaset inuti den rullar
      (overflow-y: auto). En absolut placerad .meny klipps därför bort
      oavsett top- och right-värden — exakt fällan kommentaren vid
      .kund-rutnat varnar för. `.sidopanel-konto .meny` är därför fortsatt
      position: static: menyn fäller ut som ett vanligt block UNDER
      kontoraden, ovanför utloggningsknappen, aldrig en svävande popup.
      Panelen är 238px bred, så basregelns min-width på 240px måste nollas
      här, annars sticker menyn ut i kanten som klipper. Glasets egen
      overflow-y: auto gör att kontoblocket följer med även på ett lågt
      fönster. */
.sidopanel-konto .installningar {
  position: static;
  grid-column: 1 / -1;
}

.sidopanel-konto .meny {
  position: static;
  min-width: 0;
}

/* Kugghjulet självt. Basregeln målar det i --ink-muted, arbetsytans dämpade
   bläck, som ger kvoten 1,42 mot glasets ljusaste punkt (kravet är 4,5) —
   ikonen var i praktiken osynlig på den mörka panelen. Panelens egen ljusa
   ton mäts mekaniskt i tests/test_design_rules.py, samma vakt som för resten
   av den ljusa texten på glaset. Hover och öppet läge byter till en LJUS
   bricka i basreglerna och behöver därför varsin EGEN mörk ton här nedan —
   basreglernas egna toner når aldrig fram (se kommentaren vid regeln).
   Ticket 02 (Alternativ A): samma regel bär nu även positioneringen som
   ankrar `summary` (44×44, kugghjulets fasta 44px-fack) mot RADEN
   (`.sidopanel-konto`), inte mot hela panelen — `top` matchar panelens
   `padding-top` (`--rytm-4`) så ikonen hamnar i linje med radens topp. */
.sidopanel-konto .installningar > summary {
  color: var(--panel-text);
  position: absolute;
  top: var(--rytm-4);
  right: 0;
  width: 44px;
  height: 44px;
}

/* Hovrat och öppet läge behöver en EGEN ton, tvärtemot vad kommentaren ovan
   påstod fram till åtgärdsrunda 3. Basreglerna (:1743, :1748) målar en ljus
   bricka OCH byter till en mörk ton, men den skopade regeln precis ovanför
   har samma specificitet som `.installningar[open] > summary` och står
   SENARE i filen — alltså vann panelens ljusa ton, medan basens ljusa bricka
   stod kvar. Uppmätt i webbläsaren: 1,00:1 i öppet läge (#e9edff på
   #e8edfb) och 1,05:1 i hovrat. Ikonen var bokstavligen osynlig så fort man
   rörde musen över den eller fällde ut menyn — vilket ingen märkte, eftersom
   axe-core aldrig hovrar (se vaultnoten om den blinda fläcken). Tonerna här
   är basreglernas egna, nu uttryckligen skrivna med HÖGRE specificitet så
   att regelordningen inte längre avgör. Mäts i tests/test_design_rules.py,
   samma test som viloläget. */
.sidopanel-konto .installningar > summary:hover {
  color: var(--ink);
}

.sidopanel-konto .installningar[open] > summary {
  color: var(--accent);
}

/* Radioknapparna. Det är husets FÖRSTA radioknappar, så formulär-CSS:en
   skrevs utan dem: den globala label-regeln är display: block med en
   bottenmarginal, vilket lade "Natt" på egen rad UNDER sin egen knapp och
   direkt OVANFÖR nästa — två val lästes som fyra staplade element. Träffytan
   var dessutom knappens egna ~13px, mot husets 44px-standard (WCAG 2.2
   SC 2.5.8, samma krav som .sidopanel-namn och .konto-utlogg .knapp-svag;
   mätt i tests/test_design_rules.py). Knapp och etikett läggs på samma rad
   och raden får 44px höjd, så hela raden blir träffytan via etikettens for.
   Skopat till .sidopanel-konto — resten av husets formulär rörs inte. */
.sidopanel-konto .faltrad {
  display: flex;
  align-items: center;
  gap: var(--rytm-2);
  min-height: 44px;
}

/* Etiketten sträcker sig genom hela raden i BÅDA riktningarna, inte bara
   `display: inline`. Med en inline-etikett är radens 44px bara radens, medan
   den KLICKBARA boxen (etikett + radio) blir radhöjd ~20px respektive ~13px —
   44px på pappret, under kravet i praktiken. `align-self: stretch` plus
   `flex: 1` gör etikettboxen 44px hög och hela raden bred, så var som helst
   på raden väljer alternativet. (Omgranskning runda 2, mindre fynd 1.) */
.sidopanel-konto .faltrad label {
  display: flex;
  align-items: center;
  align-self: stretch;
  flex: 1;
  margin-bottom: 0;
}

@media (max-width: 760px) {
  /* Åtgärdsrunda ticket 11, punkt 2: kontoblocket satt i SAMMA rad som
     märket + navigeringen + "+ Ny relation", en rad med `overflow-x: auto`
     — på 390px sköts namnet och "Logga ut" utanför skärmen, synliga bara
     efter horisontell scroll. `flex-basis: 100%` (kombinerat med
     `flex-wrap: wrap` på `.sidopanel` ovan) tvingar kontoblocket till en
     EGEN rad under den scrollbara navigeringsraden i stället — synligt
     utan scroll.

     Ticket 02: `flex-direction: row` + `justify-content: space-between`
     är BORTTAGNA här — det var 390px-buggen där kugghjulet hamnade bredvid
     "Logga ut" i stället för under kontoraden. Kontoraden är sedan ticket 02
     ett eget grid (`.kontorad`) som redan ser likadan ut på mobil som på
     desktop; `.sidopanel-konto` självt ska förbli en kolumn (kontorad ovanpå,
     "Logga ut" under) i alla bredder, bara `flex-basis: 100%` skiljer
     mobilen från desktop. */
  .sidopanel-konto {
    flex-basis: 100%;
    margin-left: 0;
  }
}

/* ---------- Kontosidan (ticket 06) ---------- */

.konto-uppgifter {
  margin: 0;
}

.konto-uppgifter dt {
  font-size: var(--fs-0);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-top: var(--rytm-3);
}

/* Varje dt ligger i en egen <div> (konto.html) — dt är därför ALLTID
   :first-child i sin egen div, oavsett rad. Måste skopas till den FÖRSTA
   div:en, inte till dt:ns egen position (granskningsfynd m3, ticket 06
   åtgärdsrunda). */
.konto-uppgifter > div:first-child dt {
  margin-top: 0;
}

.konto-uppgifter dd {
  margin: 0;
  color: var(--ink);
}

ul.konto-lista {
  list-style: none;
  margin: 0 0 var(--rytm-5);
  padding: 0;
}

.konto-rad {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--rytm-3);
  padding: var(--rytm-3) 0;
  border-bottom: 1px solid var(--border-soft);
}

.konto-enhet {
  color: var(--ink);
  font-weight: 600;
}

.konto-tid {
  color: var(--ink-muted);
  font-size: var(--fs-0);
  font-variant-numeric: tabular-nums;
}

/* Reservkoder kvar (ticket 08) — samma lugna ton som .konto-tid, ingen röd
   varning (DESIGN.md: Operate, inte Persuade). */
.konto-reservkoder {
  margin: 0 0 var(--rytm-4);
  font-variant-numeric: tabular-nums;
}

.konto-reservkoder .konto-reservkoder-lugn {
  color: var(--ink-muted);
  font-size: var(--fs-0);
}

/* Åtgärdsrunda ticket 11, punkt 3: "Logga ut överallt" ärvde bara
   .knapp-svags basform (padding var(--rytm-2), ~33px hög) — under
   44×44px-träffytan (_system/UI_KONVENTIONER_2026.md §1/§6). Skopat till
   den här formen, samma mönster som `.sidopanel-utlogg .knapp-svag`
   ovan, så att inga andra `.knapp-svag`-förekomster (kund.html,
   _komponenter.html) påverkas. */
.konto-utlogg .knapp-svag {
  min-height: 44px;
  min-width: 44px;
}

/* Bygge C ("bokningslänk"): samma lugna förklarande ton som
   .konto-reservkoder-lugn ovan. */
.konto-forklaring {
  margin: 0 0 var(--rytm-3);
  color: var(--ink-muted);
  font-size: var(--fs-0);
}

/* ---------- Affärspipeline: kolumnyta + papperskort ---------- */
/* Omskriven i crm-ny-stil ticket 03 efter mockupen
   (.scratch/crm-ny-stil/preview-skiss.html). Klassnamnen är oförändrade —
   app/static/pipeline.js hänger på dem — men satinmetallramen runt tavlan är
   borta: varje kolumn bär sin egen rundade yta, och stadiumfärgen bärs av en
   prick i kolumnrubriken i stället för en färgad överkant. */

/* Fyrtalsraden ovanför tavlan. Låg, lugn sifferrad: den ska aldrig vinna
   över kolumnerna i storlek eller kontrast (designbrief: fokalpunkten är
   tavlan). */
.sammanfattning {
  display: flex;
  flex-wrap: wrap;
  gap: 28px;
  margin: 0 0 var(--rytm-5);
  padding: 14px 18px;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: var(--radie-kort);
  box-shadow: var(--shadow);
}

.sammanfattning > div {
  display: flex;
  flex-direction: column;
}

.sammanfattning-etikett {
  color: var(--ink-muted);
  font-size: var(--fs-0);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.sammanfattning-tal {
  margin: 0;
  color: var(--ink);
  font-family: "Manrope", ui-sans-serif, sans-serif;
  font-size: var(--fs-4);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* MÅSTE stå efter .sammanfattning-tal: samma specificitet, källordningen
   avgör (kaskadfälla 2 i planen). --rose mäter 5,25:1 mot --surface. */
.sammanfattning-tal--forsenat {
  color: var(--rose);
}

/* Förklaring under Viktat värde när vokabulären saknar sannolikheter.
   Ett andra dd i samma par, giltigt i HTML5. */
.sammanfattning-not {
  margin: 0;
  color: var(--ink-muted);
  font-size: var(--fs-0);
}

.pipeline-verktygsrad {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--rytm-5);
  margin-bottom: var(--rytm-5);
}

.pipeline-verktygsrad h1 {
  margin-bottom: var(--rytm-1);
}

.pipeline-verktygsrad p,
.pipeline-intro,
.ovriga-relationer {
  margin: 0;
  color: var(--ink-muted);
}

.pipeline-status {
  min-height: 1.5em;
  margin: 0 0 var(--rytm-2);
  color: var(--ink-muted);
  font-size: var(--fs-1);
}

.pipeline {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(232px, 1fr);
  gap: 12px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  max-width: 100%;
}

.pipeline-kolumn {
  --stadium: var(--gray);
  --stadium-tint: var(--gray-tint);
  display: flex;
  flex-direction: column;
  gap: 10px;
  scroll-snap-align: start;
  min-width: 0;
  min-height: 260px;
  padding: 10px;
  background: var(--kol-yta);
  border-radius: var(--radie-kort);
}

.pipeline-kolumn--blue { --stadium: var(--blue); --stadium-tint: var(--blue-tint); }
.pipeline-kolumn--violet { --stadium: var(--violet); --stadium-tint: var(--violet-tint); }
.pipeline-kolumn--amber { --stadium: var(--amber); --stadium-tint: var(--amber-tint); }
.pipeline-kolumn--green { --stadium: var(--green); --stadium-tint: var(--green-tint); }
.pipeline-kolumn--rose { --stadium: var(--rose); --stadium-tint: var(--rose-tint); }
.pipeline-kolumn--sky { --stadium: var(--sky); --stadium-tint: var(--sky-tint); }
.pipeline-kolumn--gray { --stadium: var(--gray); --stadium-tint: var(--gray-tint); }

/* Rubriken är fortsatt sticky (tavlan blir hög med många kort) och måste
   därför vara OPAK — en genomskinlig sticky rubrik får korten att rulla
   synligt under texten. Den bär kolumnens EGEN yta i stället för den gamla
   satinmetallbanden, så bandet är borta men rubriken är fortfarande läsbar. */
.pipeline-kolumn-huvud {
  position: sticky;
  top: 0;
  z-index: 1;
  margin: 0;
  padding: 4px 4px 2px;
  background: var(--kol-yta);
}

.pipeline-kolumn-titelrad {
  display: flex;
  align-items: center;
  gap: var(--rytm-2);
}

.pipeline-kolumn-titelrad h2 {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1;
  margin: 0;
  font-size: var(--fs-1);
  font-weight: 700;
  line-height: 1.3;
}

/* Stadiumfärgen bärs av pricken, inte av en färgad kolumnkant. Ren
   dekoration (aria-hidden i mallen), så kontrastkravet gäller den inte. */
.pipeline-kolumn-prick {
  flex: none;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--stadium);
}

.pipeline-antal {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  min-height: 24px;
  padding: 0 7px;
  border-radius: var(--radie-pill);
  color: var(--stadium);
  background: var(--stadium-tint);
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: var(--fs-0);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.pipeline-summa,
.pipeline-okant {
  margin: 0 0 0 4px;
  color: var(--ink-muted);
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: var(--fs-0);
  font-variant-numeric: tabular-nums;
}

/* --rose faller till 4,35:1 mot --kol-yta. Samma kulör, mörkare ton:
   --rose-ink mäter 6,20:1. Se crm/DESIGN.md. */
.pipeline-okant {
  color: var(--rose-ink);
  font-family: inherit;
  font-weight: 700;
}

.pipeline-kortlista {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.pipeline-kort {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px 14px;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  box-shadow: var(--shadow);
  cursor: grab;
}

/* Shorthanden, inte en ensam border-color: en ensam border-color ritar
   ingenting om stilen inte redan är satt (kaskadfälla 1, mekaniserad i
   tests/test_design_rules.py::test_ingen_border_color_utan_border_style). */
.pipeline-kort:hover {
  border: 1px solid var(--accent);
  box-shadow: 0 2px 4px rgba(24, 32, 44, 0.1), 0 14px 24px -18px rgba(24, 32, 44, 0.58);
}

.pipeline-kort:active {
  cursor: grabbing;
}

.pipeline-kort.dras {
  opacity: 0.62;
  transform: translateY(-2px);
  box-shadow: 0 8px 18px -12px rgba(24, 32, 44, 0.72);
}

.pipeline-kort[aria-busy="true"] {
  pointer-events: none;
  opacity: 0.68;
}

.pipeline-kolumn.är-mål {
  background: var(--stadium-tint);
  box-shadow: inset 0 0 0 2px var(--stadium);
}

.pipeline-kort-huvud {
  display: flex;
  align-items: flex-start;
  gap: var(--rytm-2);
}

.pipeline-kort-namn {
  flex: 1;
  min-width: 0;
  color: var(--ink);
  font-family: "Manrope", ui-sans-serif, sans-serif;
  font-size: var(--fs-3);
  font-weight: 800;
  line-height: 1.3;
  text-decoration: none;
}

.pipeline-kort-namn:hover {
  color: var(--accent-hover);
}

.pipeline-draghandtag {
  flex: none;
  color: var(--ink-muted);
}

.pipeline-draghandtag circle {
  fill: currentColor;
}

/* Kortet är en flex-kolumn med `gap: 6px` sedan ticket 03 — barnens egna
   marginaler nollas, annars adderas gammal marginal till den nya gapen. */
.pipeline-kontakt {
  margin: 0;
  color: var(--ink-muted);
  font-size: var(--fs-0);
}

/* Tystnadslinjens bredder (6-240px, app/sortering.py::STEG_MAX) skrevs för
   den gamla breda leadlistan. I en 232px-kolumn får linje och text inte
   dela rad: 240px-steget (ingen historik alls) sköt texten ut ur kortet och
   lade den över grannkolumnen — axe rapporterade "background could not be
   determined because it is overlapped by another element". Linjen får därför
   en egen rad och kapas till kortets bredd; skalan och stegen är oförändrade
   (steg över ~50 dagars tystnad landar visuellt i samma längd). */
.pipeline-kort .lead-tystnadsrad {
  flex-direction: column;
  align-items: flex-start;
  gap: var(--rytm-1);
  margin: 0;
}

.pipeline-kort .tystnadslinje {
  max-width: 100%;
}

.pipeline-tystnadstext {
  color: var(--ink-muted);
  font-size: var(--fs-0);
}

.pipeline-nasta {
  margin: 0;
  padding-top: var(--rytm-3);
  border-top: 1px solid var(--border-soft);
}

.pipeline-nasta-text {
  margin: 0;
  color: var(--ink);
  font-size: var(--fs-1);
  font-weight: 600;
}

.pipeline-nasta-text--tom,
.pipeline-datum--forfallet {
  color: var(--amber);
}

.pipeline-datum {
  display: inline-block;
  margin-top: var(--rytm-1);
  color: var(--ink-muted);
  font-size: var(--fs-0);
}

.pipeline-datum--forfallet {
  font-weight: 700;
}

.pipeline-kort-fakta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* Kolumnen är 232px i den nya tavlan: utan wrap bryts "120 000 kr" och
     "2 öppna uppgifter" mitt i värdet i stället för mellan dem. */
  flex-wrap: wrap;
  gap: var(--rytm-1) var(--rytm-3);
  color: var(--ink-muted);
  font-size: var(--fs-0);
}

.pipeline-varde {
  color: var(--ink);
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.pipeline-uppgifter {
  color: var(--accent-hover);
  font-weight: 600;
}

.pipeline-uppgifter--tom {
  color: var(--ink-muted);
  font-weight: 400;
}

.pipeline-flytta {
  margin: 0;
  padding-top: var(--rytm-3);
  border-top: 1px solid var(--border-soft);
}

.pipeline-flytta-rad {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--rytm-2);
}

.pipeline-flytta select,
.pipeline-flytta button {
  min-height: 44px;
}

.pipeline-flytta select {
  min-width: 0;
  width: 100%;
  font-size: var(--fs-0);
}

.pipeline-tom {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 92px;
  padding: var(--rytm-4);
  color: var(--ink-muted);
  border: 1.5px dashed var(--border);
  border-radius: 12px;
  font-size: var(--fs-0);
  text-align: center;
}

.pipeline-tom[hidden] {
  display: none;
}

.ovriga-relationer {
  margin-top: var(--rytm-5);
  font-size: var(--fs-1);
}

@media (prefers-reduced-motion: no-preference) {
  .pipeline-kort {
    transition: border-color var(--motion-fast) var(--ease-standard), box-shadow var(--motion-fast) var(--ease-standard), opacity var(--motion-fast) var(--ease-standard), transform var(--motion-fast) var(--ease-standard);
  }
}

@media (max-width: 760px) {
  .pipeline-verktygsrad {
    align-items: flex-start;
  }

  .pipeline {
    grid-auto-columns: min(84vw, 300px);
    scroll-snap-type: x mandatory;
  }
}

@media (max-width: 760px) {
  .pipeline-verktygsrad .knapp {
    /* Granskningsfynd: låg bara under 430px, så 431-760px fick .knapps
       ostyrda ~36px — samma breddgräns som resten av sidans tap-target-
       regler (.knapp-liten, .sidopanel-utlogg .knapp-svag m.fl.). */
    min-height: 44px;
  }
}

@media (max-width: 430px) {
  .pipeline-verktygsrad {
    flex-direction: column;
  }
}

/* ---------- Internt (/internt): whiteboarden i arkivskåpet (ticket 03) ----
   Tystare än pipelinen: ingen stadiumkulör, ingen KPI-siffra, brådska visas
   som ordningsföljd — bara grafit, pappersvitt och indigo för handling. */

.internt-huvud {
  margin-bottom: var(--rytm-5);
}

.internt-huvud h1 {
  margin-bottom: var(--rytm-1);
}

.internt-huvud p {
  margin: 0;
  color: var(--ink-muted);
}

.omrade-lista {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--rytm-4);
}

/* Signatur: hålslagsremsan — en smal vänstermarginal med två svaga runda
   urtag i --metal-low, som ett blad i en pärm. Ren CSS, ingen bild. */
.omrade-kort {
  position: relative;
  padding: var(--rytm-5);
  /* 24 px luft + 20 px hålslagsremsa. Bokstavligt värde, inte calc(var()):
     Impeccable-detektorn kan inte läsa calc() med var() och flaggar då
     `cramped-padding` (uppmätt i webbläsaren: 24/24/24/44 px). */
  padding-left: 44px;
  background:
    radial-gradient(120% 60% at 0% 0%, var(--yta-frost-ljus), transparent 55%),
    linear-gradient(165deg, var(--yta-frost-dis), var(--yta-frost-bas)),
    var(--yta-frost-golv);
  -webkit-backdrop-filter: blur(var(--yta-frost-blur)) saturate(160%);
  backdrop-filter: blur(var(--yta-frost-blur)) saturate(160%);
  border: 1px solid var(--border);
  border-radius: var(--radie-kort);
  box-shadow: inset 0 1px 0 var(--yta-frost-kant);
}

.omrade-kort::before,
.omrade-kort::after {
  content: "";
  position: absolute;
  left: var(--rytm-3);
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--metal-low);
}

.omrade-kort::before {
  top: 30px;
}

.omrade-kort::after {
  bottom: 30px;
}

/* Kugghjulet ankras i kortets eget hörn, innanför kortets 24 px luft.
   Basregeln .installningar sitter i hörnet (top 0, right 0), vilket på ett
   kort med ram och padding klistrar 44 px-ytan i innerhörnet. Skopad till
   .omrade-kort: kundsidans meny delar samma basregel och rörs inte. */
.omrade-kort > .installningar {
  top: var(--rytm-3);
  right: var(--rytm-3);
}

.omrade-huvud {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--rytm-3);
  margin-bottom: var(--rytm-3);
}

/* Modifierare, aldrig en ändring i basregeln: .omrade-huvud delas med
   områdessidan, Dashboardens uppmärksamhetslista och /mitt-arbete. Plats
   för kugghjulet (12 px + 44 px) så att läget aldrig hamnar under det. */
.omrade-huvud--med-meny {
  padding-right: 56px;
}

.omrade-namn {
  margin: 0;
  font-size: var(--fs-3);
}

.omrade-lage {
  flex: none;
  font-size: var(--fs-0);
  font-weight: 600;
  color: var(--ink-muted);
}

/* Plusknapp för "Lägg till uppgift" (2026-09-24, Chris efterfrågan):
   stängd som standard igen, en rund 44x44 px plusknapp fäller ut
   formuläret. Ersätter ticket 04:s "alltid öppen"-beslut (spec §2 punkt 3)
   för just den här fliken — Chris bytte medvetet till en kompakt plus-UI. */
.omrade-ny-uppgift {
  border: 1px solid var(--border);
  border-radius: var(--radie-liten);
  background: var(--surface);
  margin-bottom: var(--rytm-3);
}

/* Granskningsfynd (ljuslåga-batchen): stängd var boxen full bredd med
   ett tomt utseende runt den runda 44x44-knappen (.flik:s fullbredds-
   ramkort ärvdes rakt av). Krymp till knappens egen bredd när den är
   stängd; öppen får den fortfarande fylla kortet som formuläret behöver. */
.omrade-ny-uppgift:not([open]) {
  width: max-content;
}

.omrade-ny-uppgift > summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  min-width: 44px;
  min-height: 44px;
  margin: var(--rytm-3) var(--rytm-4);
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--accent);
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1;
}

.omrade-ny-uppgift > summary::-webkit-details-marker {
  display: none;
}

.omrade-ny-uppgift > summary:hover {
  /* Ljuslåga (2026-09-24): dåvarande orange accent mot --border-soft mätte
     4,25:1, under 4,5:1 — samma mönster som accent-tint-hover: texten
     mörkas till accent-hover i stället för att röra bakgrundstokenen.
     Natt och eld (2026-09-25): mönstret behålls. Med mörkblå accent mäter
     paret 10,73:1 (accent-hover) respektive 8,50:1 (accent) mot
     --border-soft, så det är inte längre den enda möjliga lösningen — men
     samma mönster överallt är värt mer än en rad mindre CSS. */
  color: var(--accent-hover);
  background: var(--border-soft);
}

/* Enhetlig uppgiftsrad (ansvarig + anteckning): ersätter det tidigare
   .omrade-fokus/-ovriga-särskiljandet av den första öppna uppgiften — alla
   uppgifter (öppna och klara) visas nu likvärdigt via _uppgift_rad.html,
   med en egen Detaljer-flik per rad. Högre specificitet än
   `ul.uppgiftslista li` (baseline/rad-layout) krävs för att vinna över den. */
ul.uppgiftslista.uppgiftslista-internt li {
  align-items: flex-start;
  flex-direction: column;
  gap: var(--rytm-1);
}

.uppgiftslista-internt .uppgift-huvud {
  display: flex;
  align-items: baseline;
  gap: var(--rytm-3);
  width: 100%;
}

.uppgiftslista-internt .uppgift-huvud form {
  margin-left: auto;
  align-self: center;
  flex: none;
}

.uppgiftslista-internt .uppgift-text {
  flex: 1 1 auto;
  min-width: 0;
}

/* Inte en stadiumfärg (spec §4.4 stänger den uppsättningen till Stadium) —
   ansvarig är ett namn, så badgen återanvänder bara .pill:s form, med
   neutrala toner. */
.uppgift-ansvarig {
  color: var(--ink-muted);
  background: var(--border-soft);
  flex: none;
}

.uppgift-anteckning {
  margin: 0;
  color: var(--ink-muted);
  font-size: var(--fs-0);
  max-width: 66ch;
}

.uppgift-detaljer {
  width: 100%;
}

.uppgift-detaljer > summary {
  color: var(--ink-muted);
  font-size: var(--fs-0);
  cursor: pointer;
  list-style: none;
}

.uppgift-detaljer > summary::-webkit-details-marker {
  display: none;
}

.uppgift-detaljer .formularrad {
  margin-top: var(--rytm-2);
}

.omrade-klara {
  /* Ingen margin-bottom här: .flik ger --rytm-3 mellan Klart och nästa flik.
     Ett tidigare `margin-bottom: 0` slog ut den och lät två ramar stöta ihop. */
  margin-top: var(--rytm-3);
}

/* ---------- Områdessida (/internt/<slug>, ticket 05) ----------------------
   Ett enda registerblad med samma hålslagsremsa som områdeskortet; sidans
   namn är h1, alltså större än kortets h2. Flikarna (klart, ny uppgift,
   historik, anteckningar, om området) ligger INUTI bladet men varje
   formulär ligger helt inom sin egen <details>. */

.omrade-tillbaka {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin-bottom: var(--rytm-2);
  color: var(--ink-muted);
  font-size: var(--fs-1);
}

.omrade-sida .omrade-namn {
  font-size: var(--fs-5);
}

.omrade-sida .omrade-huvud {
  margin-bottom: var(--rytm-4);
}

.omrade-sida > .flik:last-child {
  margin-bottom: 0;
}

.omrade-sida .anteckningar {
  margin: 0;
  white-space: pre-line;
  max-width: 65ch;
}

.omrade-sida .omrade-klara {
  margin-bottom: var(--rytm-3);
}

/* Smal mobil: datumet får en egen rad över uppgiftstexten i "övriga"-listan.
   Annars är datum + text + Bocka av bredare än raden och knappen sköt ~10 px
   förbi avskiljarlinjen. */
@media (max-width: 430px) {
  .omrade-ovriga li {
    flex-wrap: wrap;
    row-gap: var(--rytm-1);
  }

  .omrade-ovriga .uppgift-datum {
    flex: 0 0 100%;
  }

  .omrade-ovriga li > span:not(.uppgift-datum) {
    flex: 1 1 0;
    min-width: 0;
  }
}

/* ---------- Dashboard: "Kräver uppmärksamhet" (ticket 02, crm-ny-stil) ----
   EN lista, två slags rader (intern uppgift, tyst lead). Ingen omstyling av
   tavlan och ingen sammanfattningsrad här — det hör till nästa ticket. Bara
   befintliga tokens; raderna lånar kortets yta och ram från samma familj som
   .omrade-kort så att sidan inte blir en ny visuell dialekt.

   En liten prick först i raden kodar brådskan i FORM, inte bara i ord.
   Ingen färgad vänsterkant: UI-konventionerna (avsnitt 10) förbjuder färgad
   border-left över 1 px. --ink-faint är dekor och aldrig text, se :root. */

.uppmarksamhet {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radie-kort);
  padding: var(--rytm-5);
}

.uppmarksamhet .omrade-huvud {
  margin-bottom: var(--rytm-4);
}

.uppmarksamhet-lista {
  list-style: none;
  margin: 0;
  padding: 0;
}

.uppmarksamhet-rad {
  display: flex;
  align-items: baseline;
  gap: var(--rytm-3);
  padding: var(--rytm-3);
  border-bottom: 1px solid var(--border-soft);
}

/* Brådskeprick: dekor som förstärker ordningen (listan är redan sorterad
   på brådska), därför aria-lös ::before utan text. */
.uppmarksamhet-rad::before {
  content: "";
  flex: 0 0 auto;
  align-self: center;
  width: var(--rytm-2);
  height: var(--rytm-2);
  border-radius: 50%;
  background: var(--border);
}

.uppmarksamhet-rad:last-child {
  border-bottom: 1px solid transparent;
}

/* Brådskan i pricken: förfallet och tystnad är samma allvar (de sorteras i
   samma grupp, se app/dashboard.py::BRADSKA_GRUPP), snart är en påminnelse,
   planerat och odaterat är neutrala. */
.uppmarksamhet-rad--forfallet::before,
.uppmarksamhet-rad--tyst::before {
  background: var(--accent);
}

.uppmarksamhet-rad--snart::before {
  background: var(--metal-low);
}

.uppmarksamhet-lank {
  flex: 0 0 auto;
  font-weight: 600;
}

.uppmarksamhet-slag {
  flex: 0 0 auto;
  font-size: var(--fs-0);
  font-weight: 600;
  color: var(--ink-muted);
}

.uppmarksamhet-text {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--ink);
}

.uppmarksamhet-datum {
  flex: 0 0 auto;
  font-size: var(--fs-1);
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}

/* Smal mobil: namn + slag på första raden, text och datum under — annars
   trängs fyra kolumner ihop och datumet bryter över kanten. */
@media (max-width: 560px) {
  .uppmarksamhet-rad {
    flex-wrap: wrap;
    row-gap: var(--rytm-1);
  }

  .uppmarksamhet-text {
    flex: 1 1 100%;
  }
}

/* ---------- Chattbotten (crm-ny-stil ticket 09) --------------------------
   Den TREDJE medvetet mörka ytan, vid sidan av sidopanelen och
   inloggningen. Chris tillfrågades uttryckligen om just den konflikten och
   valde mörkt två gånger; se crm/DESIGN.md och mesh-beslutet. "Två ytor,
   inga fler" gäller fortfarande för alla ANDRA nya ytor, och vaktas av
   tests/test_design_rules.py.

   Ingen scen, inga embers, ingen backdrop-filter: panelen ligger över en
   rullande arbetsyta, och ett frostat glas hade gjort texten olika läsbar
   beroende på vad som råkar ligga bakom just då. Gradienten är nästan opak,
   och det är hela poängen. Alla klasser har bott-prefix och INGEN av dem
   heter glas, scen eller ember. */

.bott {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 30;
}

/* En summary, inte en button: öppningen sker utan skript. Markören måste
   bort i båda familjerna, annars ritas en triangel i cirkeln. */
.bott-knapp {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--accent-ink);
  border: 1px solid var(--accent);
  box-shadow: 0 14px 30px -12px rgba(0, 0, 0, 0.5);
  cursor: pointer;
  display: grid;
  place-items: center;
  list-style: none;
}

.bott-knapp::-webkit-details-marker {
  display: none;
}

.bott-knapp:hover {
  background: var(--accent-hover);
}

.bott-panel {
  position: fixed;
  right: 20px;
  bottom: 88px;
  width: min(360px, calc(100vw - 40px));
  max-height: min(520px, calc(100vh - 140px));
  background: linear-gradient(160deg, var(--bott-topp), var(--bott-mitt) 55%, var(--bott-botten));
  border: 1px solid var(--bott-kant);
  border-radius: var(--radie-kort);
  box-shadow: 0 30px 60px -24px rgba(0, 0, 0, 0.6);
  display: flex;
  flex-direction: column;
  /* Panelen är en kolumn med flera FASTA rader (huvud, genvägar, hattar,
     felrad, skrivfält) och en enda som får krympa (.bott-meddelanden). På en
     liggande telefon (568x320) är max-height 180px, medan raderna med hatt,
     historik OCH felrad mäter 288px — de går inte att pressa in, hur snålt
     paddingen än sätts (uträkningen står i media-regeln längst ned i filen).
     Med `overflow: hidden` betydde det inte att något klipptes bort nedtill:
     skrivfältet har `autofocus`, så webbläsaren rullade panelen 110px för att
     få fältet i vy, och huvudraden och hattraden hamnade UTANFÖR panelen utan
     något sätt att rulla tillbaka. Mätt 2026-09-27, se
     `.scratch/crm-reflektion/bevis/kor-bevis-reflektion.py` (skottet
     `panel-varstfall-fel-568x320`). `overflow-y: auto` gör det som inte får
     plats nåbart i stället för borta; `overflow-x: hidden` står kvar för de
     rundade hörnen. */
  overflow-x: hidden;
  overflow-y: auto;
  z-index: 30;
  color: var(--panel-text);
}

/* Samma skäl som på sidopanelen och inloggningen: mörkblå fokusring mot
   mörkblå yta vore osynlig. */
.bott-panel :focus-visible {
  outline-color: var(--panel-text-stark);
}

.bott-huvud {
  display: flex;
  align-items: center;
  gap: var(--rytm-2);
  padding: var(--rytm-3) var(--rytm-4);
  border-bottom: 1px solid var(--bott-kant);
  flex: none;
}

.bott-huvud b {
  font-size: var(--fs-2);
  color: var(--panel-text-stark);
}

/* Genvägarna i panelen (2026-09-27). EGEN klass, inte .formularrad: raden
   behöver `flex: none`, och .formularrad är en formulärklass som inte ska
   bära panelbeteende. Alla fem målen ska SYNAS — en rad som rullar i sidled
   döljer de sista två för den som har mus och ingen svepgest — så raden
   bryts i stället. Priset är höjd, och höjd är dyrt just här: panelen ovan
   har en FAST max-height, så allt som tar höjd högst upp tar det ur
   .bott-meddelanden. Sedan 2026-09-27 rullar panelen (`overflow-y: auto`) och
   skrivfältet klibbar mot nederkanten (`position: sticky` i .bott-form), så
   den här raden kan inte längre trycka bort fältet — men den kan pressa ihop
   samtalet till ingenting. Därför `flex: none` (raden äter aldrig ur
   .bott-meddelanden, som är det enda som ska krympa) plus media-regeln längst
   ned i filen som viker raden när fönstret är för lågt.
   Paddingen är samma par som .bott-huvud: utan den går pillren kant i kant
   med panelens rundade hörn, till skillnad från allt annat i panelen. */
.bott-genvagar {
  display: flex;
  flex: none;
  flex-wrap: wrap;
  gap: var(--rytm-2);
  padding: var(--rytm-3) var(--rytm-4);
  border-bottom: 1px solid var(--bott-kant);
}

/* Flexbarn krymper som standard. Utan detta pressas pillren ihop på en
   smal panel i stället för att bryta till nästa rad, och .knapp-litens
   white-space: nowrap skjuter då texten utanför sin egen knapp. */
.bott-genvagar > a {
  flex: none;
}

.bott-meddelanden {
  flex: 1 1 auto;
  /* Flexbarn har min-height: auto, alltså "krymp aldrig under ditt innehåll".
     Utan den här raden växer listan i stället för att rulla, och listan är
     det enda i panelen som ska ge vika: de fasta raderna ovanför (huvud,
     genvägar, hattar) ska ALLTID få plats. Ta den inte bort. */
  min-height: 0;
  overflow-y: auto;
  margin: 0;
  padding: var(--rytm-3) var(--rytm-4);
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--rytm-3);
}

.bott-bubbla {
  max-width: 85%;
  padding: var(--rytm-2) var(--rytm-3);
  border-radius: var(--radie-liten);
  font-size: var(--fs-1);
  line-height: 1.45;
}

.bott-bubbla--svar {
  align-self: flex-start;
  background: var(--bott-bubbla-svar);
  color: var(--panel-text);
  border-bottom-left-radius: 4px;
}

.bott-bubbla--fraga {
  align-self: flex-end;
  background: var(--accent);
  color: var(--panel-text-stark);
  border-bottom-right-radius: 4px;
}

.bott-form {
  display: flex;
  /* Ärende 23: skrivfältets ram (.bott-falt) tar en egen hel rad, så
     formuläret måste få radbryta. */
  flex-wrap: wrap;
  gap: var(--rytm-2);
  padding: var(--rytm-3);
  border-top: 1px solid var(--bott-kant);
  flex: none;
  /* Skrivfältet är det enda i panelen som aldrig får hamna utanför synfältet,
     så det KLIBBAR mot panelens nederkant i stället för att bara ligga sist i
     kolumnen. Panelen rullar (`overflow-y: auto` ovan), och utan detta kan
     raderna över fältet trycka ned det under nederkanten: mätt 2026-09-27 på
     568x320 i värstfallet hatt + historik + felrad låg fältet 13px under
     kanten, nåbart men inte synligt, och det första man mötte var felraden i
     stället för fältet man skulle skriva i. Med `sticky` är det strukturellt
     omöjligt — vad som än läggs till högst upp i panelen. Bakgrunden är inte
     kosmetisk: utan den rullar bubblorna synligt under fältets text. Samma
     färg som gradientens sista stopp i .bott-panel. */
  position: sticky;
  bottom: 0;
  background: var(--bott-botten);
}

.bott-form input {
  flex: 1;
  min-width: 0;
  min-height: 44px;
  padding: 0 var(--rytm-3);
  border-radius: var(--radie-liten);
  border: 1px solid var(--bott-kant-falt);
  background: var(--navy-1);
  color: var(--panel-text-stark);
  caret-color: var(--panel-text-stark);
  font-family: inherit;
  font-size: var(--fs-1);
}

/* opacity: 1 — annars dämpar Firefox platshållaren till ~54 % och den
   uppmätta kontrasten nedan gäller inte längre. */
.bott-form input::placeholder {
  color: var(--bott-platshallare);
  opacity: 1;
}

.bott-form input:focus-visible {
  border-color: var(--panel-text-stark);
}

.bott-form .knapp {
  min-height: 44px;
  padding: 0 var(--rytm-3);
  background: var(--panel-text-stark);
  color: var(--accent);
  box-shadow: none;
  flex: none;
}

.bott-form .knapp:hover {
  background: var(--accent-tint);
}

/* Ärende 23 (A2, Mr. Robertsons val 2026-10-04): fältet och Skicka i en ram
   som tar hela raden UNDER övriga knappar. Uppmätt före: fältet fick 21-28 %
   av raden på 390 px, resten gick till knapparna. DOM-ordningen är orörd
   (fält, Skicka, Förslag) så Enter skickar fortfarande frågan; bara den
   visuella ordningen byts med `order`. Skicka är en 34 px cirkel inne i
   fältets högra kant, träffytan hålls på 44 px av ::after (inset -5px). */
.bott-falt {
  order: 2;
  flex: 1 1 100%;
  position: relative;
  display: block;
  min-width: 0;
}

.bott-falt > :is(input, textarea) {
  display: block;
  width: 100%;
}

.bott-falt > input {
  padding-right: 52px;
}

.bott-falt > .bott-skicka {
  position: absolute;
  right: 5px;
  top: 50%;
  transform: translateY(-50%);
  width: 34px;
  height: 34px;
  min-width: 0;
  min-height: 0;
  padding: 0;
  margin: 0;
  display: grid;
  place-items: center;
  border-radius: 999px;
}

.bott-falt > .bott-skicka::after {
  content: "";
  position: absolute;
  inset: -5px;
  border-radius: 999px;
}

.bott-falt > .bott-skicka svg {
  width: 18px;
  height: 18px;
  display: block;
}

/* Förslagsknappen fick sina 44 px av att stå bredvid Skicka; ensam krymper den. */
.bott-form > button {
  min-height: 44px;
}

/* Högkontrastläge: cirkelns bakgrund tvättas bort, så den får en kant i
   systemfärg. Pilen ritas med currentColor och följer knapptexten. */
@media (forced-colors: active) {
  .bott-falt > .bott-skicka {
    border: 1px solid ButtonText;
  }
}

/* Genvägsraden i chattbottpanelen kostar höjd (upp till tre brutna rader à
   44px på mobil). Under 560px fönsterhöjd räcker panelens max-height
   (100vh - 140px) då inte till både genvägar, meddelanden och skrivfält —
   en liggande telefon, eller ett lågt fönster. Då viker GENVÄGARNA, inte
   inmatningen: exakt samma fem mål står kvar i sidopanelens huvudmeny, medan
   ett bortklippt skrivfält gör hela panelen meningslös. */
@media (max-height: 560px) {
  .bott-genvagar {
    display: none;
  }
}

/* --- Hattarna och anteckningarna i chattbottpanelen (2026-09-27) ---------
   Reflektionen flyttade in i panelen (Chris val); /reflektion finns inte
   längre. Hattraden är ett LÄGESVAL för fältet längst ned, inte navigering.
   Samma `flex: none` och samma padding som .bott-genvagar, av exakt samma
   skäl: raden får aldrig äta höjd ur .bott-meddelanden. */
/* EN rad, aldrig två. `flex-wrap: wrap` här var ett direkt brott mot
   mesh-gotchan om #bott-panel: panelen är en flexkolumn med
   `max-height: min(520px, calc(100vh - 140px))` och `overflow: hidden`, så
   varje extra radhöjd överst betalas av `.bott-form` längst ned — skrivfältet
   försvinner tyst, och inget test ser det eftersom HTML:en finns kvar i
   svaret. På en liggande telefon (100vh ~ 320px) hade fyra knappar som
   wrappade till tre rader à 44px räckt för att klippa bort inmatningen.
   `nowrap` + `overflow-x: auto` gör raden horisontellt rullbar i stället för
   högre, vilket är vad gotchan föreskriver. */
.bott-hattar {
  display: flex;
  flex: none;
  flex-wrap: nowrap;
  overflow-x: auto;
  gap: var(--rytm-2);
  padding: var(--rytm-3) var(--rytm-4);
  border-bottom: 1px solid var(--bott-kant);
}

.bott-hattar > button {
  flex: none;
}

/* "Rensa" sitter i huvudraden, skjuten åt höger. Egen form-tagg (den POSTar),
   så marginalen nollas — annars ärver den formulärens normala luft. */
.bott-rensa {
  margin: 0 0 0 auto;
}

/* Anteckningen är användarens egen text, inte bottens svar: egen bubbla med
   hattens namn överst, och `pre-wrap` så styckena överlever (sanera_anteckning
   i app/bott.py behåller radbrytningarna just för det här). */
.bott-bubbla--anteckning {
  align-self: stretch;
  background: var(--bott-bubbla-svar);
  white-space: pre-wrap;
}

.bott-hattnamn {
  display: block;
  margin-bottom: var(--rytm-1);
  color: var(--panel-text-stark);
  font-size: var(--fs-0);
}

.bott-fel {
  flex: none;
  margin: 0;
  padding: var(--rytm-2) var(--rytm-4);
  color: var(--panel-text-stark);
  font-size: var(--fs-0);
}

/* Textarean i anteckningsläget. Samma yta som textfältet bredvid den, men
   den får växa i höjd — därför `resize: vertical` och ingen fast höjd. */
.bott-form textarea {
  flex: 1;
  min-width: 0;
  resize: vertical;
  font: inherit;
  padding: var(--rytm-2) var(--rytm-3);
  border-radius: var(--radie-liten);
  border: 1px solid var(--bott-kant-falt);
  background: var(--navy-1);
  color: var(--panel-text-stark);
}

/* opacity: 1 — annars dämpar Firefox platshållaren till ~54 % och den
   uppmätta kontrasten nedan gäller inte längre. */
.bott-form textarea::placeholder {
  color: var(--bott-platshallare);
  opacity: 1;
}

/* Snålare rader på en låg viewport. EGET @media-block, placerat EFTER alla
   .bott-*-regler: `.bott-hattar` och `.bott-form textarea` definieras längre
   upp i filen än det första @media-blocket, och med samma specificitet vinner
   den regel som står sist — ett block högre upp hade alltså inte bitit på
   dem. Mätt 2026-09-27 på 568x320 med hatt vald och en sparad anteckning:

     .bott-huvud        69px   (44px knapphöjd + 12+12 padding + 1px kant)
     .bott-hattar       69px   (samma)
     .bott-meddelanden  24px   (min-height: 0, men paddingen kvarstår)
     .bott-form         91px   (textarea rows="2")
     ------------------------
     summa             253px   mot panelens max-height 180px

   Bara .bott-meddelanden får krympa, så de 73px som fattas finns inte att ta
   någonstans. Panelen rullade i stället, och med `overflow: hidden` blev
   huvudraden och hattraden onåbara (se .bott-panel längre upp). Därför två
   åtgärder: panelen rullar numera, så inget blir borta, OCH raderna blir
   snålare just här så att det vanliga fallet slipper rulla alls. Bara LODRÄT
   padding ändras — den vågräta hör till panelens rundade hörn. Med felraden
   inne (+35px) räcker det ändå inte, och då är rullningen det som gör resten
   nåbar. Beviset körs av .scratch/crm-reflektion/bevis/kor-bevis-reflektion.py
   (`kravIngenRullning` för de vanliga fallen, `kravNaddbar` för värstfallet). */
@media (max-height: 560px) {
  .bott-huvud,
  .bott-hattar,
  .bott-meddelanden {
    padding-top: var(--rytm-1);
    padding-bottom: var(--rytm-1);
  }

  .bott-form {
    padding: var(--rytm-2);
  }

  /* Anteckningsfältet får samma höjd som frågefältet här. `resize: vertical`
     står kvar, så den som verkligen vill skriva ett stycke på en liggande
     telefon kan dra ut det själv. */
  .bott-form textarea {
    height: 44px;
    min-height: 44px;
  }

  /* Ärende 15 (Mr. Robertsons val 2026-10-04): i ett lågt fönster står
     panelen BREDVID den runda knappen och tar nästan hela fönsterhöjden, i
     stället för att ligga ovanför knappen. Ovanför gav max-height 180px vid
     568x320, mot fasta rader på minst 267px, så panelen rullade och det
     klistrade skrivfältet låg över lägesraden och startfrågorna. right 80px =
     knappens right 20 + bredd 48 + 12 luft, så knappen (som också stänger
     panelen) syns och går att trycka på. 48 är Nova-knappens bredd här:
     nova.css gör pillen rund i lågt liggande fönster (beslut 2), annars hade
     panelen täckt pillens mitt. Bredden lämnar 20px till vänster kant
     (80 + 20 = 100), så ett smalt och lågt fönster inte skjuter panelen
     utanför. Låst i tests/test_bott_lag_hojd.py. */
  .bott-panel {
    right: 80px;
    bottom: 8px;
    width: min(360px, calc(100vw - 100px));
    max-height: calc(100vh - 16px);
  }
}

/* Ärende 15: en STÅENDE telefon med låg synlig höjd (t.ex. 375x548 med
   webbläsarens verktygsfält) har plats ovanför knappen och behåller dagens
   placering. Värdena är exakt grundregeln för .bott-panel ovan; testet
   jämför dem så att de inte glider isär. */
@media (max-height: 560px) and (orientation: portrait) {
  .bott-panel {
    right: 20px;
    bottom: 88px;
    width: min(360px, calc(100vw - 40px));
    max-height: min(520px, calc(100vh - 140px));
  }
}
/* Arbete inline editing: incumbent neutral list surface in both themes. */
.nova .nova-arbetslista .nova-inline-rad{display:grid;grid-template-columns:minmax(120px,1fr) minmax(44px,1fr) 156px 132px 144px;gap:16px;align-items:center}
.nova .nova-inline-rad>*{min-width:0;grid-column:auto;grid-row:auto}
.nova .nova-inline-rad .dashboard-handling{grid-column:1}
.nova .nova-inline-rad .dashboard-handling>span{display:block;font-size:13px;color:#45566d}
.nova .nova-inline-rad .dashboard-oppna{grid-column:5;grid-row:auto}
.nova .nova-inline-rad form{margin:0}
.nova .nova-inline-rad :is(input:not([type=hidden]),button,summary){min-height:44px;max-width:100%;color:#18202c}
.nova .nova-inline-rad input:not([type=radio]):not([type=hidden]){width:100%;min-width:0;background:#fff;border:1px solid #667085;font-size:14px;padding:8px;border-radius:6px}
.nova .nova-inline-rad :is(label,legend){color:#45566d;font-size:12px;font-weight:600;text-align:center;display:block;margin-bottom:4px}
.nova .nova-inline-priority fieldset{padding:0;margin:0;border:0;min-width:0}
.nova .nova-inline-priority legend{float:none;width:100%;padding:0}
.nova .nova-inline-stars{display:flex;gap:0}
.nova .nova-inline-stars label{position:relative;display:grid;place-items:center;width:44px;height:44px;margin:0;cursor:pointer}
.nova .nova-inline-stars input{position:absolute;opacity:0;width:44px;height:44px;margin:0;inset:0;cursor:pointer}
.nova .nova-inline-stars svg{fill:#1e3a8a;stroke:#1e3a8a;stroke-width:1.5}
.nova .nova-inline-stars label:has(input:checked)~label svg{fill:none}
.nova .nova-inline-stars label:has(input:focus-visible){outline:3px solid #1e3a8a;outline-offset:2px;border-radius:4px}
.nova .nova-inline-rad :is(summary,input,button):focus-visible{outline:3px solid #1e3a8a;outline-offset:3px}
.nova .nova-inline-note>summary{display:flex;align-items:center;justify-content:flex-start;list-style:none;cursor:pointer;padding:8px;color:#45566d;overflow-wrap:anywhere;font-size:13px}
.nova .nova-inline-note>summary::-webkit-details-marker{display:none}
.nova .nova-inline-note[data-has-note] [data-note-icon]{display:none}
.nova .nova-inline-note[open]>summary{display:none}
.nova .nova-inline-note form{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.nova .nova-inline-note button{font-size:12px;padding:8px}
.nova .nova-inline-rad .nova-inline-error{grid-column:1 / -1;color:#8b2335;font-size:13px;line-height:1.5;margin:0;overflow-wrap:anywhere}
.nova .nova-inline-error a{color:#1e3a8a;text-decoration:underline}
.nova-js .nova-inline-rad [data-native-save]{display:none}
.nova-js .nova-inline-rad [data-save-error] [data-native-save]{display:inline-flex}
.nova .nova-inline-rad [hidden]{display:none}
@media(max-width:1200px){.nova .nova-arbetslista .nova-inline-rad{grid-template-columns:minmax(120px,1fr) minmax(44px,1fr) 156px 132px}.nova .nova-inline-rad .dashboard-oppna{grid-column:1 / -1;justify-self:end}}
@media(max-width:760px){.nova .nova-arbetslista .nova-inline-rad{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:12px}.nova .nova-inline-rad .dashboard-handling,.nova .nova-inline-note{grid-column:1 / -1}.nova .nova-inline-rad .nova-inline-priority{justify-self:end}.nova .nova-inline-rad .dashboard-oppna{grid-column:1 / -1}.nova .nova-inline-note form{flex-wrap:wrap}}
