/*
|--------------------------------------------------------------------------
| Järvsö Design CRM — formspråket
|--------------------------------------------------------------------------
|
| Luftigt arbetsverktyg: gradientkort, stora siffror, generösa mellanrum.
| Ljust läge är förval, mörkt läge slås om med knappen i topplisten och
| sparas i localStorage.
|
| Färgerna ligger som variabler på :root och [data-theme="dark"] — inte
| utspridda i reglerna — så att paletten kan bytas utan att en enda
| komponentregel rörs.
|
| Filen kommer från den första versionens mockup. Reglerna för vyer som
| aldrig byggdes om städades bort 2026-09-30 (kort #36); mockupen ligger
| arkiverad i jarvsodesign_snapshots/crm.jarvsodesign.se/public_html/
| mockup.2026-09-25-1448/ om en regel behövs igen.
|
*/


/*
|--------------------------------------------------------------------------
| Designtokens — ljust läge
|--------------------------------------------------------------------------
|
| Diagramfärgerna (--series-N) är validerade mot skalan för färgblindhet och
| mot ytan de ritas på. Slot 1 är varumärkets orange rakt ur logotypen; den
| klarade varje grind och behövde inte ersättas. Slot 4 får bara användas i
| staplar och linjer (intilliggande par), aldrig i punktdiagram.
|
*/

:root {
    color-scheme: light;

    /* Ytor */
    --page:           #f3f5f7;   /* sidans botten */
    --surface:        #ffffff;   /* kort och paneler */
    --surface-2:      #f8fafb;   /* nedtonad yta inne i ett kort */
    --surface-hover:  #f2f5f8;

    /* Text */
    --ink:            #1a1d21;
    --ink-2:          #59636e;
    --ink-3:          #8a939d;

    /* Linjer */
    --border:         #e5e9ee;
    --border-strong:  #d3d9e0;

    /* Varumärket */
    --brand:          #df7236;
    --brand-gold:     #e4d349;
    --brand-deep:     #c15f28;
    --graphite:       #373a3e;
    --brand-wash:     #fdf1e9;

    /* Diagramserier */
    --series-1:       #df7236;
    --series-2:       #2a78d6;
    --series-3:       #1baf7a;
    --series-4:       #4a3aa7;
    /* Femte: snabbsökens grupp Sajter (kort #20). Validerad med
       dataviz-skillens validate_palette.js mot #ffffff — godkänd, med
       kontrastvarning som bärs av gruppens textetikett. */
    --series-5:       #e87ba4;

    /* Diagrammets ram */
    --grid-line:      #e9ecf0;
    --axis-line:      #ccd3db;

    /* Status — fasta, aldrig omtemade. Bärs alltid av ikon + text, aldrig
       av färgen ensam: varumärkets orange ligger i samma familj som
       "serious" och de får inte förväxlas. */
    --good:           #0ca30c;
    --warn:           #fab219;
    --serious:        #ec835a;
    --critical:       #d03b3b;
    --good-wash:      #e8f6e8;
    --warn-wash:      #fdf4e1;
    --critical-wash:  #fbeaea;
    --neutral-wash:   #eef1f4;
    /* Text på en wash — mörkare än statusfärgen, för kontrastens skull. */
    --good-ink:       #0a7a0a;
    --warn-ink:       #8a6100;

    /* Kvittensen — vit text på en mättad grund, samma i båda temana. */
    --toast-ok-bg:    #16794f;
    --toast-error-bg: #b02a23;
    --toast-ink:      #ffffff;

    /* Form */
    --radius:         14px;
    --radius-sm:      9px;
    --shadow:         0 1px 2px rgba(23, 28, 33, .04), 0 4px 16px rgba(23, 28, 33, .05);
    --shadow-lift:    0 2px 6px rgba(23, 28, 33, .06), 0 12px 32px rgba(23, 28, 33, .09);

    /* Typsnittet — Plus Jakarta Sans ur assets/fonts/ (se fonts.css).
       Systemstacken är reserven medan filen laddas. */
    --font:           "Plus Jakarta Sans", system-ui, -apple-system, "Segoe UI", sans-serif;

    --sidebar-w:      248px;
    --topbar-h:       68px;
}


/*
|--------------------------------------------------------------------------
| Designtokens — mörkt läge
|--------------------------------------------------------------------------
|
| Egna steg, inte en automatisk invertering. Serierna är omvalda för den
| mörka ytan och validerade mot den, precis som de ljusa mot den vita.
|
*/

[data-theme="dark"] {
    color-scheme: dark;

    --page:           #15181b;
    --surface:        #24282c;
    --surface-2:      #2b3036;
    --surface-hover:  #30363c;

    --ink:            #f1f3f5;
    --ink-2:          #aab3bd;
    --ink-3:          #79828c;

    --border:         #343a41;
    --border-strong:  #454d55;

    --brand:          #e58a51;
    --brand-gold:     #e4d349;
    --brand-deep:     #df7236;
    --graphite:       #1d2023;
    --brand-wash:     #3a2a1e;

    --series-1:       #d95926;
    --series-2:       #3987e5;
    --series-3:       #199e70;
    --series-4:       #9085e9;
    --series-5:       #d55181;

    --grid-line:      #2f353b;
    --axis-line:      #414951;

    --good-wash:      #1c3320;
    --warn-wash:      #3a3018;
    --good-ink:       #8fe3a8;
    --warn-ink:       #fab219;
    --critical-wash:  #3a2020;
    --neutral-wash:   #2e343a;

    --toast-ok-bg:    #1f9463;
    --toast-error-bg: #c9564b;
    --toast-ink:      #ffffff;

    --shadow:         0 1px 2px rgba(0, 0, 0, .3), 0 4px 16px rgba(0, 0, 0, .25);
    --shadow-lift:    0 2px 6px rgba(0, 0, 0, .35), 0 12px 32px rgba(0, 0, 0, .4);
}


/*
|--------------------------------------------------------------------------
| Grund
|--------------------------------------------------------------------------
*/

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

/* hidden-attributet måste vinna över komponenternas egna display-regler.
   Utan detta syns en dold .btn ändå, eftersom `display: inline-flex` i
   klassen slår webbläsarens förvalda `[hidden] { display: none }` — och
   Rensa-knappen står kvar synlig fast inget filter är satt. */
[hidden] { display: none !important; }

/* Platsen för rullningslisten står kvar även när den försvinner. En ruta
   (jdModal) låser rullningen med overflow: hidden, och utan detta hoppade
   hela sidan — topplisten och knapparna — cirka 16 px åt höger. */
html { scrollbar-gutter: stable; }

body {
    margin: 0;
    background: var(--page);
    color: var(--ink);
    font: 15px/1.55 var(--font);
    -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }
/* Formulärfälten får annars webbläsarens eget typsnitt. Bara familjen —
   fälten har egna storlekar, och monospace-fälten skriver över den. */
input, select, textarea { font-family: inherit; }

h1, h2, h3 { margin: 0; font-weight: 650; letter-spacing: -.01em; }
h1 { font-size: 1.5rem; }
h2 { font-size: 1.05rem; }
h3 { font-size: .95rem; }

/* Siffror som ska ligga i pelare — tabellkolumner, axelvärden. Stora
   fristående tal får däremot behålla proportionella siffror. */
.num { font-variant-numeric: tabular-nums; }

::selection { background: var(--brand); color: #fff; }

:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 2px;
    border-radius: 4px;
}


/*
|--------------------------------------------------------------------------
| Skalet — sidomeny, topplist, innehållsyta
|--------------------------------------------------------------------------
*/

.shell { display: flex; min-height: 100vh; }

.sidebar {
    width: var(--sidebar-w);
    flex: 0 0 var(--sidebar-w);
    background: var(--surface);
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
}

.sidebar-head {
    height: var(--topbar-h);
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: 0 1.25rem;
    border-bottom: 1px solid var(--border);
    flex: 0 0 auto;
}

.sidebar-head img { height: 40px; width: auto; }
.sidebar-head .env-badge { margin-left: auto; }

/* overflow-x och nowrap: medan menyn fälls ut eller ihop (ikonraden) får den
   varken en vågrät rullningslist eller etiketter som bryts på två rader. */
.sidebar-scroll { display: flex; flex-direction: column; gap: .15rem; overflow-x: hidden; overflow-y: auto; padding: 1rem .75rem 1.5rem; flex: 1 1 auto; }


.nav-link {
    display: flex;
    align-items: center;
    gap: .7rem;
    padding: .55rem .75rem;
    border-radius: var(--radius-sm);
    color: var(--ink-2);
    font-weight: 500;
    transition: background .12s, color .12s;
}

.nav-link:hover { background: var(--surface-hover); color: var(--ink); }

.nav-link .icon { flex: 0 0 20px; width: 20px; opacity: .8; }

/* Aktiv post: varumärkets gradient. Den enda platsen i menyn där guldet
   får synas — används den på fler ställen tappar den sin signalverkan. */
.nav-link.is-active {
    background: linear-gradient(100deg, var(--brand) 0%, var(--brand-gold) 165%);
    color: #fff;
    font-weight: 600;
    box-shadow: 0 3px 10px rgba(223, 114, 54, .3);
}

.nav-link.is-active .icon { opacity: 1; }

.nav-count {
    margin-left: auto;
    font-size: .72rem;
    font-weight: 700;
    padding: .1rem .42rem;
    border-radius: 20px;
    background: var(--critical-wash);
    color: var(--critical);
}

.nav-link.is-active .nav-count { background: rgba(255, 255, 255, .25); color: #fff; }

/* I mörkt läge räcker inte en tvätt: röd text på mörkröd botten mot en
   mörk sidomeny blir tre lager av nästan samma valör, och siffran syns
   knappt. Full mättnad med vit text i stället — brickan är en larmsignal
   och ska läsas på avstånd. */
[data-theme="dark"] .nav-count {
    background: var(--critical);
    color: #fff;
}

.sidebar-foot { padding: .75rem; border-top: 1px solid var(--border); flex: 0 0 auto; }

.main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }

.topbar {
    height: var(--topbar-h);
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0 1.75rem;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    position: sticky;
    top: 0;
    z-index: 20;
}

/*
|--------------------------------------------------------------------------
| Snabbsöken i topplisten
|--------------------------------------------------------------------------
|
| Fältet, och panelen som search.js fyller mot /search/. Varje grupp bär
| sin färg som --group-color, satt av skriptet ur registret i
| helpers/search.php (en --series-token) — en ny grupp ändrar inte CSS:en.
| Färgen blandas med rubrikens textfärg, så att etiketten läses i båda
| temana. Se docs/crm.md#snabbsök.
|
*/

.search {
    position: relative;
    flex: 0 1 340px;
    min-width: 0;
}

.search-input {
    width: 100%;
    padding: .5rem 3.6rem .5rem 2.2rem;
    border: 1px solid var(--border);
    border-radius: 20px;
    background: var(--surface-2);
    color: var(--ink);
    font: inherit;
    font-size: .88rem;
}

.search-input::placeholder { color: var(--ink-3); }
.search-input:focus { outline: 0; border-color: var(--brand); background: var(--surface); box-shadow: 0 0 0 3px var(--brand-wash); }
/* Webbläsarens eget kryss visas bara när markören står i fältet — då är
   Ctrl K dold, och de två krockar inte. Det är enda sättet att tömma fältet
   på en telefon; Esc stänger panelen och tömmer inte. */
.search-input:not(:focus)::-webkit-search-cancel-button { display: none; }
.search-input::-webkit-search-cancel-button { cursor: pointer; }
.search-input:focus { padding-right: .9rem; }

.search-icon {
    position: absolute; left: .8rem; top: 50%; transform: translateY(-50%);
    display: grid; place-items: center;
    color: var(--ink-3);
    pointer-events: none;
}

.search-kbd {
    position: absolute; right: .8rem; top: 50%; transform: translateY(-50%);
    font: inherit; font-size: .68rem; font-weight: 600;
    color: var(--ink-3);
    background: transparent; border: 0; padding: 0;
    pointer-events: none;
}
.search-input:focus ~ .search-kbd { display: none; }

.search-panel {
    position: absolute; top: calc(100% + 8px); left: 0; z-index: 30;
    width: max(100%, 460px);
    max-height: min(70vh, 520px);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: .4rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-lift);
}
.search-panel[hidden] { display: none; }

.search-group {
    --group-color: var(--ink-3);
    border-left: 2px solid color-mix(in srgb, var(--group-color) 60%, transparent);
    border-radius: 3px;
    padding-left: .3rem;
}
.search-group + .search-group { margin-top: .5rem; }

.search-group-label {
    display: flex; align-items: center; gap: .4rem;
    padding: .4rem .6rem .2rem;
    font-size: .64rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
    color: color-mix(in srgb, var(--group-color) 75%, var(--ink));
}
[data-theme="dark"] .search-group-label { color: color-mix(in srgb, var(--group-color) 60%, var(--ink)); }

.search-row {
    display: block;
    padding: .4rem .6rem;
    border-radius: 7px;
    color: var(--ink);
    text-decoration: none;
}
.search-row:hover, .search-row.is-active { background: var(--surface-hover); }
.search-row.is-active { outline: 2px solid var(--brand); outline-offset: -2px; }
.search-row-title { font-size: .88rem; font-weight: 600; overflow-wrap: anywhere; }
.search-row-meta, .search-row-match { font-size: .76rem; color: var(--ink-2); overflow-wrap: anywhere; }
.search-row-more .search-row-meta { color: var(--ink-2); font-weight: 600; }
.search-row mark { background: color-mix(in srgb, var(--brand) 22%, transparent); color: var(--ink); padding: 0 1px; border-radius: 2px; }
[data-theme="dark"] .search-row mark { background: color-mix(in srgb, var(--brand) 38%, transparent); }

/* Tomt svar och fel står i panelen — en toast per tecken skulle fylla skärmen. */
.search-note { padding: .6rem .6rem; font-size: .82rem; color: var(--ink-2); }

.topbar-right { margin-left: auto; display: flex; align-items: center; gap: .4rem; }

.icon-btn {
    width: 36px; height: 36px;
    display: grid; place-items: center;
    border: 1px solid transparent;
    border-radius: 50%;
    background: transparent;
    color: var(--ink-2);
    cursor: pointer;
}

.icon-btn:hover { background: var(--surface-hover); color: var(--ink); }

.user {
    display: flex; align-items: center; gap: .6rem;
    padding: .3rem .7rem .3rem .35rem;
    border-radius: 22px;
    cursor: pointer;
}
.user:hover { background: var(--surface-hover); }

.avatar {
    width: 30px; height: 30px; border-radius: 50%;
    display: grid; place-items: center;
    background: linear-gradient(135deg, var(--brand), var(--brand-gold));
    color: #fff; font-weight: 700; font-size: .78rem;
}

.content { padding: 1.75rem; flex: 1 1 auto; }


/*
|--------------------------------------------------------------------------
| Mobil — utfällbar meny
|--------------------------------------------------------------------------
|
| Under 820 px får sidomenyn inte plats bredvid innehållet. Den skjuts ut
| till vänster och fälls in över sidan med hamburgaren i topplisten, med
| ett skymmande lager bakom som stänger vid klick.
|
| Menyn TAS INTE BORT ur dokumentet — den ligger kvar och är fokuserbar,
| så att tangentbord och skärmläsare når den; det är transformen som
| flyttar den ur bild.
|
*/

.nav-toggle { display: none; }

@media (max-width: 820px) {
    .nav-toggle { display: grid; }

    .sidebar {
        position: fixed;
        top: 0; left: 0; bottom: 0;
        z-index: 50;
        transform: translateX(-100%);
        transition: transform .22s ease;
    }

    .sidebar.is-open { transform: translateX(0); box-shadow: var(--shadow-lift); }

    .scrim {
        position: fixed; inset: 0;
        z-index: 40;
        background: rgba(12, 15, 18, .45);
        opacity: 0;
        pointer-events: none;
        transition: opacity .22s;
    }
    .scrim.is-open { opacity: 1; pointer-events: auto; }

    .topbar { padding: 0 1rem; gap: .5rem; }
    .search { flex: 1 1 auto; }
    /* Ingen tangentbordsgenväg på en telefon — och namnet får ge plats åt
       fältet; avataren leder fortfarande till Mitt konto. */
    .search-kbd { display: none; }
    .search-input { padding-right: .9rem; }
    .topbar .user .strong { display: none; }
    .topbar .user { padding: 7px; }
    /* Panelen följer skärmen, inte fältet, som är för smalt för en träff. */
    .search-panel {
        position: fixed;
        top: calc(var(--topbar-h) + 4px); left: .5rem; right: .5rem;
        width: auto;
        max-height: calc(100dvh - var(--topbar-h) - 1rem);
    }
    .search-row { min-height: 44px; padding-top: .55rem; padding-bottom: .55rem; }
    .content { padding: 1rem; }
    .page-head .actions { margin-left: 0; width: 100%; }

    /* Träffytor. 44 px är gränsen där ett finger träffar rätt — under den
       blir varje knapp en chansning. Gäller riktiga kontroller; ett
       statusmärke är text och inget man siktar på. */
    .btn, .icon-btn, .pill, .facet-btn { min-height: 44px; min-width: 44px; }
    .btn.sm { padding: .5rem .8rem; }
    /* Plus Jakarta Sans är bredare än systemtypsnittet: med den vanliga
       luften bröts Fakturors sex pills på tre rader i 390 px. Selektorn
       är skarpare än .pill, som står längre ned i filen. */
    .pills .pill { padding-left: .7rem; padding-right: .7rem; }
    .field input, .field select, .field textarea,
    .search input, .filter-search input { min-height: 44px; }

    /* Kryssrutan i sig får aldrig bli 44 px — den skulle se sönderdragen
       ut. Träffytan är hela raden: .choice är en <label>, och ett klick var
       som helst på den kryssar i rutan. Rutan förstoras bara så pass att
       läget syns på en telefon. */
    .choice { min-height: 44px; }
    .choice input[type="checkbox"] { width: 20px; height: 20px; flex: 0 0 20px; }

    /* Fakturaradens benämning redigeras i en ramlös input rakt i tabellen.
       Den ärver ingen fältstil och blir därför för låg att träffa. */
    table.data-table input { min-height: 44px; }

    /* Ett statusmärke som är en LÄNK är en kontroll och behöver träffyta;
       ett märke som bara är text gör det inte. */
    a.status { min-height: 44px; padding-left: .8rem; padding-right: .8rem; }

}

/* Respektera den som stängt av rörelse i systemet. */
@media (prefers-reduced-motion: reduce) {
    .sidebar, .scrim { transition: none; }
}

.page-head {
    display: flex; align-items: flex-start; gap: 1rem;
    flex-wrap: wrap; margin-bottom: 1.35rem;
}
.page-head .lead { margin: .3rem 0 0; color: var(--ink-2); font-size: .9rem; }
.page-head .actions { margin-left: auto; display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; justify-content: flex-end; }

/* Rubrikens spalt tar den plats som blir över, så att knapparna bredvid
   står på en rad så länge de får plats i stället för att brytas en och en. */
.page-head > div:first-child { flex: 1 1 320px; min-width: 0; }
.page-head .filter-search { margin-left: 0; flex: 0 1 250px; }
@media (min-width: 821px) { .page-head .actions { flex-wrap: nowrap; } }
.facet-btn { white-space: nowrap; }


/*
|--------------------------------------------------------------------------
| Kort och rutnät
|--------------------------------------------------------------------------
*/

.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}

.card-head {
    display: flex; align-items: center; gap: .75rem;
    padding: 1.1rem 1.35rem;
    border-bottom: 1px solid var(--border);
}
.card-head .right { margin-left: auto; display: flex; align-items: center; gap: .5rem; }
.card-body { padding: 1.35rem; }
.card-foot { padding: .85rem 1.35rem; border-top: 1px solid var(--border); color: var(--ink-2); font-size: .85rem; }

.grid { display: grid; gap: 1.25rem; }
.grid.cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid.cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid.cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid.cols-2-1 { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
/*
| Luft mellan sidans block.
|
| Regeln stod tidigare bara som `.grid + .grid`, och då fick ett kort som
| följde direkt på ett rutnät ingen marginal alls — nyckeltalsraden satt
| ihop med filterkortet under sig på Kunder, Abonnemang, Fakturor och
| Sajter. Kombinationerna räknas därför upp.
|
| Scopat till direkta barn av .content: kort INNE i ett rutnät är
| rutnätsceller, och en marginal på dem skulle bryta layouten i stället
| för att skapa luft.
*/
.content > .grid + .grid,
.content > .grid + .card,
.content > .card + .grid,
.content > .card + .card,
.content > .card + .note,
.content > .grid + .note { margin-top: 1.25rem; }

@media (max-width: 1200px) {
    .grid.cols-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .grid.cols-3, .grid.cols-2-1 { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 820px) {
    .grid.cols-2, .grid.cols-4 { grid-template-columns: minmax(0, 1fr); }
}


/*
|--------------------------------------------------------------------------
| Nyckeltal
|--------------------------------------------------------------------------
|
| En stat-ruta, inte ett diagram med en stapel. Värdet är stort och i
| textfärg — aldrig i seriefärgen; en färgad prick bär identiteten om
| rutan behöver en.
|
*/

.stat .label {
    font-size: .78rem; font-weight: 600; letter-spacing: .04em;
    text-transform: uppercase; color: var(--ink-3);
}
.stat .value { font-size: 1.95rem; font-weight: 680; line-height: 1.15; margin-top: .35rem; }
.stat .value .unit { font-size: .95rem; font-weight: 600; color: var(--ink-3); margin-left: .2rem; }
.stat .delta { display: inline-flex; align-items: center; gap: .3rem; font-size: .83rem; font-weight: 600; margin-top: .45rem; }
.stat .delta.up { color: var(--good); }
.stat .delta.down { color: var(--critical); }
.stat .delta .since { color: var(--ink-3); font-weight: 500; }

/* Hjältesiffran: en enda per sida, den siffra vyn handlar om. */
.hero { font-size: 3rem; font-weight: 700; line-height: 1.05; letter-spacing: -.02em; }
.hero-sub { color: var(--ink-2); margin-top: .3rem; }


/*
|--------------------------------------------------------------------------
| Knappar
|--------------------------------------------------------------------------
*/

.btn {
    display: inline-flex; align-items: center; gap: .45rem;
    padding: .5rem .95rem;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--ink);
    font-weight: 550; font-size: .9rem;
    cursor: pointer;
    white-space: nowrap;
    transition: background .12s, border-color .12s;
}
.btn:hover { background: var(--surface-hover); }

.btn.primary {
    background: linear-gradient(100deg, var(--brand), var(--brand-deep));
    border-color: transparent; color: #fff;
    box-shadow: 0 2px 8px rgba(223, 114, 54, .28);
}
.btn.primary:hover { filter: brightness(1.06); }

.btn.ghost { border-color: transparent; background: transparent; color: var(--ink-2); }
.btn.ghost:hover { background: var(--surface-hover); color: var(--ink); }

.btn.sm { padding: .32rem .65rem; font-size: .83rem; }
.btn.danger { color: var(--critical); border-color: var(--critical-wash); }


/*
|--------------------------------------------------------------------------
| Filterrad
|--------------------------------------------------------------------------
|
| Samma uppsättning som CRM-listorna i LeadFactory: statuspills till
| vänster, fasettknappar med antalsbricka, sökruta med fördröjning, och en
| Rensa-knapp som bara syns när något är satt. Allt i EN rad ovanför
| tabellen — filter under rubriken, aldrig inuti diagrammet.
|
*/

.filter-bar {
    display: flex; align-items: center; gap: .5rem;
    flex-wrap: wrap;
    padding: .85rem 1.35rem;
    border-bottom: 1px solid var(--border);
}

.pills { display: flex; gap: .3rem; flex-wrap: wrap; }

.pill {
    padding: .34rem .8rem;
    border-radius: 20px;
    border: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--ink-2);
    font-size: .85rem; font-weight: 550;
    cursor: pointer;
}
.pill:hover { background: var(--surface-hover); color: var(--ink); }
.pill.is-active { background: var(--graphite); border-color: var(--graphite); color: #fff; }
[data-theme="dark"] .pill.is-active { background: var(--brand-deep); border-color: var(--brand-deep); }
.pill .count { opacity: .65; margin-left: .3rem; font-variant-numeric: tabular-nums; }

.filter-search { position: relative; margin-left: auto; flex: 0 1 240px; }
.filter-search input {
    width: 100%;
    padding: .4rem .7rem .4rem 2rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    color: var(--ink);
    font-size: .88rem;
}
.filter-search .icon { position: absolute; left: .6rem; top: 50%; transform: translateY(-50%); color: var(--ink-3); }

.facet { position: relative; }
.facet-btn {
    display: inline-flex; align-items: center; gap: .4rem;
    padding: .38rem .7rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    color: var(--ink-2);
    font-size: .87rem; cursor: pointer;
}
.facet-btn:hover { background: var(--surface-hover); }
.facet-btn.is-set { border-color: var(--brand); color: var(--ink); background: var(--brand-wash); }
.facet-btn .facet-badge { font-weight: 700; color: var(--brand-deep); }

.facet-menu {
    position: absolute; z-index: 30; top: calc(100% + .35rem); left: 0;
    min-width: 210px; padding: .45rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-lift);
}
.facet-menu[hidden] { display: none; }
.facet-menu label {
    display: flex; align-items: center; gap: .55rem;
    padding: .38rem .5rem; border-radius: 6px; cursor: pointer; font-size: .88rem;
}
.facet-menu label:hover { background: var(--surface-hover); }


/*
|--------------------------------------------------------------------------
| Tabeller
|--------------------------------------------------------------------------
*/

.table-wrap { overflow-x: auto; }

/*
| TABELLER I EN HALV SPALT
|
| Översiktens "Kräver åtgärd" och "Förnyas" ligger i ett tvåspaltigt
| rutnät och har ändå fyra kolumner, varav den sista är en knapp. Med
| full cellpadding fick de sidoscroll redan på en bred skärm, och
| knappen — det enda i raden man ska trycka på — hamnade utanför kanten.
|
| Regeln gäller bara tabeller som ligger i ett tvåspaltigt rutnät.
| Listsidorna har hela bredden och rörs inte: en tabell som är
| luftigare där den får plats och tätare där den inte får det är rätt,
| samma mått överallt är det inte.
|
| I mobilbredd tar kortlayouten längre ned över, och då gäller den i
| stället.
*/
@media (min-width: 821px) {
    .grid.cols-2 > .card table.data-table th,
    .grid.cols-2 > .card table.data-table td,
    .grid.cols-2-1 > div:last-child table.data-table th,
    .grid.cols-2-1 > div:last-child table.data-table td { padding-left: .7rem; padding-right: .7rem; }

    .grid.cols-2 > .card table.data-table th:first-child,
    .grid.cols-2 > .card table.data-table td:first-child,
    .grid.cols-2-1 > div:last-child table.data-table th:first-child,
    .grid.cols-2-1 > div:last-child table.data-table td:first-child { padding-left: 1.35rem; }

    .grid.cols-2 > .card table.data-table th:last-child,
    .grid.cols-2 > .card table.data-table td:last-child,
    .grid.cols-2-1 > div:last-child table.data-table th:last-child,
    .grid.cols-2-1 > div:last-child table.data-table td:last-child { padding-right: 1.35rem; }

    /* Etiketten får brytas här. Ett pill som tvingar fram sidoscroll
       kostar mer än ett pill på två rader. */
    .grid.cols-2 > .card table.data-table .status,
    .grid.cols-2-1 > div:last-child table.data-table .status { white-space: normal; }

    /* E-postadresser är långa och har inga mellanslag. Utan brytpunkt
       sätter de tabellens minsta bredd, och kontaktkortet fick
       sidoscroll av en adress som ändå går att läsa bruten. */
    .grid.cols-2-1 > div:last-child table.data-table td { overflow-wrap: anywhere; }
}

table.data-table { width: 100%; border-collapse: collapse; font-size: .9rem; }

table.data-table th {
    text-align: left;
    font-size: .72rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
    color: var(--ink-3);
    padding: .7rem 1.35rem;
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}

table.data-table td {
    padding: .8rem 1.35rem;
    border-bottom: 1px solid var(--border);
}

/* Förvalet står för sig, utan "table" i selektorn: en lista med rader på
   flera rader text sätter sin egen justering (.invoices-table td), och
   den regeln ska väga lika tungt som förvalet och vinna på att stå senare. */
.data-table td { vertical-align: middle; }

/* En lista som står mot överkanten säger det med --cell-top: 1 bredvid
   vertical-align: top. En knapp är högre än en textrad (.9rem × 1.55) och
   skulle då hamna under texten och göra raden tung upptill. I en rad med
   knapp får cellerna därför halva skillnaden som luft överst, och knappen
   lyfts lika mycket: texten och knappen står i linje, och en rad på en
   rad text ser ut som när den stod mot mitten. I en lista som står mot
   mitten, och på telefon, blir lyftet noll. */
.data-table tr:has(td .btn.sm) { --row-control: 2.025rem; }
.data-table tr:has(td .icon-btn) { --row-control: 36px; }
table.data-table td {
    --control-rise: calc(var(--cell-top, 0) * (var(--row-control, 1.395rem) - 1.395rem) / 2);
    padding-top: calc(.8rem + var(--control-rise));
}
.data-table td .icon-btn,
.data-table td .btn.sm { margin-top: calc(-1 * var(--control-rise)); }

table.data-table tbody tr:last-child td { border-bottom: 0; }
table.data-table tbody tr[data-row-href],
table.data-table.products-table tbody tr { cursor: pointer; }
table.data-table tbody tr:hover { background: var(--surface-2); }

.right { text-align: right; }

/* Belopp och datum får aldrig radbrytas. "2 400 kr" som blir "2 400" på en
   rad och "kr" på nästa läses som två olika saker. */
td.right, th.right { text-align: right; white-space: nowrap; }
/* Rubriken över en högerställd kolumn linjerar med sina värden.
   table.data-table th ovan är skarpare än th.right och vann annars. */
table.data-table th.right { text-align: right; }

.strong { font-weight: 600; }
.muted { color: var(--ink-2); }
.sm { font-size: .82rem; }
.empty-value { color: var(--ink-3); }

.empty { padding: 3rem 1.35rem; text-align: center; color: var(--ink-2); }
.empty .icon { color: var(--ink-3); margin-bottom: .6rem; }


/*
|--------------------------------------------------------------------------
| Tabeller i mobilbredd — en rad blir ett kort
|--------------------------------------------------------------------------
|
| En tabell med åtta kolumner får aldrig plats på 390 px. Alternativet är
| att låta den sidoscrolla i sin hylsa, och då hamnar kolumnrubrikerna
| utanför bild samtidigt som värdena — man scrollar fram ett tal utan att
| se vad det är ett tal PÅ.
|
| Raden bryts därför upp: rubrikraden döljs, varje rad blir ett kort och
| varje cell får sin kolumnrubrik till vänster om värdet. Rubriken kommer
| ur `data-label`, som sätts av labelTableCells() i shell.js — den läser
| <th>-texterna, så att en ny kolumn får sin etikett utan att någon
| behöver komma ihåg att skriva den en andra gång.
|
| Första cellen är radens namn och behåller ingen etikett: den ÄR
| rubriken.
|
*/

@media (max-width: 700px) {

    .table-wrap { overflow-x: visible; }

    table.data-table thead { display: none; }

    table.data-table,
    table.data-table tbody,
    table.data-table tr,
    table.data-table td { display: block; width: auto; }

    table.data-table tr {
        padding: .9rem 1.1rem;
        border-bottom: 1px solid var(--border);
    }

    table.data-table tbody tr:hover { background: transparent; }

    /* Cellen förblir ett BLOCK, inte en flexrad. En cell kan innehålla
       flera saker — ett namn plus en underrad, ett märke plus ett datum —
       och som flexobjekt hamnar de bredvid varandra och spräcker bredden.
       Etiketten läggs därför ovanför värdet i vanligt flöde. */
    table.data-table td {
        padding: .3rem 0;
        border: 0;
        text-align: left;
        --cell-top: 0;
    }

    /* Höger-ställda tal ska ligga i samma pelare som allt annat när raden
       blivit ett kort — annars hoppar värdena i sidled mellan raderna. */
    td.right { text-align: left; white-space: normal; }

    table.data-table td::before {
        content: attr(data-label);
        display: block;
        font-size: .68rem;
        font-weight: 700;
        letter-spacing: .05em;
        text-transform: uppercase;
        color: var(--ink-3);
        margin-bottom: .1rem;
    }

    /* Första cellen är radens rubrik: ingen etikett, större text, egen
       luft under sig. */
    table.data-table td:first-child {
        display: block;
        font-size: 1rem;
        margin-bottom: .5rem;
    }
    table.data-table td:first-child::before { content: none; }

    /* En cell utan innehåll (åtgärdskolumnen sist) ska inte lämna en
       ensam etikett efter sig. */
    table.data-table td:empty { display: none; }
}


/*
|--------------------------------------------------------------------------
| Statusmärken
|--------------------------------------------------------------------------
|
| Alltid ikon + text. Färgen är en förstärkning, aldrig bäraren — dels för
| färgblindhet, dels för att varumärkets orange bor i samma hörn av
| färgrymden som statusfärgen för "förfaller snart".
|
*/

.status {
    display: inline-flex; align-items: center; gap: .35rem;
    padding: .2rem .55rem;
    border-radius: 20px;
    font-size: .78rem; font-weight: 600;
    background: var(--neutral-wash);
    color: var(--ink-2);
    white-space: nowrap;
}
.status .dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: 0 0 7px; }
.status.good     { background: var(--good-wash);     color: var(--good-ink); }
.status.warn     { background: var(--warn-wash);     color: var(--warn-ink); }
.status.critical { background: var(--critical-wash); color: var(--critical); }
[data-theme="dark"] .status.good { color: var(--good); }
[data-theme="dark"] .status.warn { color: var(--warn); }


/*
|--------------------------------------------------------------------------
| Formulär
|--------------------------------------------------------------------------
*/

.field { margin-bottom: 1rem; }
.field label { display: block; font-size: .82rem; font-weight: 600; color: var(--ink-2); margin-bottom: .3rem; }
.field input, .field select, .field textarea {
    width: 100%;
    padding: .5rem .7rem;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--ink);
    font: inherit;
}
/*
| Platshållaren måste vara dämpad.
|
| Utan regeln ärver den fältets egen färg och blir lika svart som riktig
| text — ett tomt formulär såg då ifyllt ut, och exempelvärdet
| "Mackes Gräv AB" i rutan för ny kund lästes som att kunden redan var
| skriven. Sökrutan i topplisten hade regeln, formulärfälten inte.
*/
.field input::placeholder,
.field textarea::placeholder { color: var(--ink-3); opacity: 1; }

/*
| Val (.choice) inuti ett .field — svaren och kontaktsätten på demosidan.
| Reglerna ovan gjorde etiketten till ett block och knappen fullbredd, så
| att radioknappen hamnade mitt i rutan och texten på en egen rad under.
*/
.field label.choice { display: flex; margin-bottom: 0; font-size: inherit; font-weight: inherit; color: inherit; }
.field .choice input[type="radio"],
.field .choice input[type="checkbox"] { width: auto; flex: 0 0 auto; padding: 0; margin: 0; }

.field .hint { font-size: .8rem; color: var(--ink-3); margin-top: .25rem; }
.field-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }


/*
|--------------------------------------------------------------------------
| Notis — förklarande ruta
|--------------------------------------------------------------------------
|
| Gul kant, syns tydligt. För det som ska läsas innan man gör något på
| sidan — t.ex. Backups besked om vilken miljö den körs mot.
|
*/

.note {
    display: flex; gap: .7rem;
    padding: .8rem 1rem;
    border-left: 3px solid var(--brand-gold);
    background: var(--surface-2);
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
    font-size: .87rem; color: var(--ink-2);
    margin-bottom: 1.25rem;
}
.note .icon { color: var(--brand); flex: 0 0 auto; }
/* En lång sökväg i <code> får brytas — annars trycker den ut sidan i sidled. */
.note > div { min-width: 0; overflow-wrap: anywhere; }
.note b { color: var(--ink); }


/*
|--------------------------------------------------------------------------
| Modal
|--------------------------------------------------------------------------
|
| Byggd på <dialog> och inte på en egen overlay-div. Webbläsaren ger då
| fokusfälla, Escape-stängning, inert bakgrund och rätt roll för
| skärmläsare — fyra saker som är lätta att skriva fel för hand och som
| ingen märker är fel förrän någon navigerar med tangentbord.
|
| ::backdrop kan inte läsa CSS-variabler från :root i alla motorer, så
| skuggan bakom sätts som en rå färg.
|
*/

dialog.modal {
    width: min(920px, calc(100vw - 2rem));
    max-height: calc(100vh - 3rem);
    padding: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--ink);
    box-shadow: var(--shadow-lift);
    overflow: hidden;
}

dialog.modal::backdrop { background: rgba(12, 15, 18, .5); }

dialog.modal[open] { display: flex; flex-direction: column; }

.modal-head {
    display: flex; align-items: center; gap: .75rem;
    padding: 1.1rem 1.35rem;
    border-bottom: 1px solid var(--border);
    flex: 0 0 auto;
}
.modal-head .right { margin-left: auto; display: flex; align-items: center; gap: .5rem; }

/* Kroppen rullar, inte hela dialogen — huvudet och fotens knappar ska
   stå kvar när innehållet är långt. */
.modal-body { padding: 1.35rem; overflow-y: auto; flex: 1 1 auto; }

.modal-foot {
    display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
    padding: .9rem 1.35rem;
    border-top: 1px solid var(--border);
    background: var(--surface-2);
    flex: 0 0 auto;
}

@media (max-width: 820px) {
    dialog.modal {
        width: 100vw; max-width: 100vw;
        height: 100dvh; max-height: 100dvh;
        border-radius: 0; border: 0;
        margin: 0;
    }
}


/*
|--------------------------------------------------------------------------
| Utvecklingstavlan
|--------------------------------------------------------------------------
|
| Tavlan, kortet, snabbtitten och uppgiftssidan. Byggd 2026-09-25 efter
| LeadFactorys tavla — samma delar och samma beteende, i CRM:ets
| formspråk.
|
*/

/*
| Kolumnerna flyter i sidled och scrollar när de inte får plats. Ett golv
| på 200 px håller ett kort läsbart; färre påslagna kolumner breder ut sig.
| grid-auto-flow: column räknar inte kolumner, så en ny status behöver
| ingen ändring här.
*/
.kanban {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(200px, 1fr);
    gap: .85rem;
    overflow-x: auto;
    padding-bottom: .5rem;
    align-items: start;
}

.kanban-column {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: .6rem;
}
.kanban-column.is-hidden { display: none; }

.kanban-column-head {
    display: flex; align-items: center; gap: .45rem;
    padding: .15rem .3rem .6rem;
    font-size: .78rem; font-weight: 700;
    letter-spacing: .04em; text-transform: uppercase;
    color: var(--ink-2);
}
.kanban-column-head .count {
    margin-left: auto;
    background: var(--surface); border: 1px solid var(--border);
    border-radius: 20px; padding: 0 .45rem;
    font-size: .74rem; font-variant-numeric: tabular-nums;
}
.kanban-column-head .help { color: var(--ink-3); cursor: help; display: inline-flex; }

.kanban-list { min-height: 3rem; display: flex; flex-direction: column; gap: .5rem; }

/* Kortet. Prioriteten Hög och Akut bär en färgstapel till vänster; Låg och
   Normal är utan, så att det brådskande syns i en blick. */
.kanban-card {
    position: relative;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow);
    overflow: hidden;
    cursor: grab;
}
.kanban-card:hover { border-color: var(--border-strong); }
.kanban-card:active { cursor: grabbing; }
.kanban-card.prio-high::before,
.kanban-card.prio-urgent::before {
    content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
}
.kanban-card.prio-high::before   { background: var(--warn); }
.kanban-card.prio-urgent::before { background: var(--critical); }

/* Nyss skapat eller sparat — markeras och scrollas fram av todo.js. */
.kanban-card.is-new { outline: 2px solid var(--brand); outline-offset: 2px; }

.kanban-cat {
    padding: .22rem .75rem;
    font-size: .7rem; font-weight: 700; letter-spacing: .03em;
    background: var(--cat-bg); color: var(--cat-fg);
}
.kanban-card.prio-high .kanban-cat,
.kanban-card.prio-urgent .kanban-cat { padding-left: 1rem; }

.kanban-card-body { padding: .6rem .75rem; }
.kanban-card.prio-high .kanban-card-body,
.kanban-card.prio-urgent .kanban-card-body { padding-left: 1rem; }

.kanban-card-title {
    display: block;
    font-size: .86rem; font-weight: 600; line-height: 1.4;
    color: var(--ink);
}
.kanban-card-title:hover { text-decoration: underline; }

/* Tre rader av beskrivningen. Hela texten står i snabbtitten. */
.kanban-card-desc {
    margin: .3rem 0 0;
    font-size: .8rem; line-height: 1.45; color: var(--ink-2);
    display: -webkit-box; -webkit-line-clamp: 3; line-clamp: 3; -webkit-box-orient: vertical;
    overflow: hidden;
    white-space: pre-line;
}

.kanban-card-meta {
    display: flex; align-items: center; gap: .75rem;
    margin-top: .5rem;
    font-size: .78rem; color: var(--ink-3);
}
.kanban-card-meta .is-complete { color: var(--good); }

/* Ikonknapparna på kortet: snabbtitt och kopiera startprompt. */
.kanban-icon {
    display: inline-flex; align-items: center; justify-content: center;
    padding: .15rem; border: 0; background: none;
    color: var(--ink-3); cursor: pointer; border-radius: 4px;
}
.kanban-icon:hover { color: var(--ink); }
.kanban-icon.is-copied { color: var(--good); }
.kanban-icon.push { margin-left: auto; }

/* Brickor: kategori i snabbtitten och Gäller på kort och sidor. */
.chip {
    display: inline-flex; align-items: center;
    padding: .1rem .45rem; border-radius: 5px;
    font-size: .7rem; font-weight: 600;
    background: var(--neutral-wash); color: var(--ink-2);
}
.chips { display: flex; flex-wrap: wrap; gap: .3rem; }
.kanban-card .chips { margin-top: .45rem; }

/* Sortable under dragningen. */
.kanban-ghost { opacity: .4; border-style: dashed; }
.kanban-chosen { box-shadow: var(--shadow-lift); }

.search-empty { margin-bottom: 1rem; }


/*
| Snabbtitten — läsvy i en modal.
*/
.peek-meta { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; margin-bottom: 1rem; }
.peek-meta .stamp { margin-left: auto; font-size: .8rem; color: var(--ink-3); }
.peek-desc { white-space: pre-wrap; overflow-wrap: anywhere; font-size: .9rem; line-height: 1.55; margin: 0 0 1.25rem; }
.peek-heading {
    display: flex; align-items: center; gap: .45rem;
    font-size: .8rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
    color: var(--ink-2); margin: 0 0 .5rem;
}
.peek-heading .count { font-weight: 500; color: var(--ink-3); }
.peek-check { list-style: none; margin: 0 0 1.25rem; padding: 0; }
.peek-check li { display: flex; gap: .55rem; align-items: baseline; padding: .15rem 0; font-size: .88rem; }
.peek-check li .icon { color: var(--ink-3); flex: 0 0 auto; position: relative; top: .15rem; }
.peek-check li.is-done span { text-decoration: line-through; color: var(--ink-3); }
.peek-check li.is-done .icon { color: var(--good); }

/* Anteckningarna hopfällda: en snabbtitt ska gå att överblicka. */
.peek-comment { border: 1px solid var(--border); border-radius: var(--radius-sm); margin-bottom: .4rem; }
.peek-comment summary {
    display: flex; flex-wrap: wrap; gap: .15rem .5rem;
    padding: .55rem .75rem; cursor: pointer; font-size: .84rem;
    list-style: none;
}
.peek-comment summary::-webkit-details-marker { display: none; }
.peek-comment summary .preview { flex: 1 1 100%; color: var(--ink-3); font-size: .8rem; }
.peek-comment[open] summary { background: var(--surface-2); }
.peek-comment[open] summary .preview { display: none; }
.peek-comment .body { padding: .6rem .75rem; white-space: pre-wrap; overflow-wrap: anywhere; font-size: .86rem; border-top: 1px solid var(--border); }


/*
| Uppgiftssidan: fälten till vänster, checklista, bilagor, startprompt och
| farozon till höger.
*/
.task-layout {
    display: grid;
    grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
    gap: 1.25rem;
    align-items: start;
}
.task-layout > div { display: flex; flex-direction: column; gap: 1.25rem; min-width: 0; }
@media (max-width: 1100px) { .task-layout { grid-template-columns: minmax(0, 1fr); } }

.backlink {
    display: inline-flex; align-items: center; gap: .4rem;
    font-size: .85rem; color: var(--ink-2); margin-bottom: .75rem;
}
.backlink:hover { color: var(--ink); }
/* 44 px träffyta på telefon, som alla kontroller i mobilbredd. */
@media (max-width: 820px) { .backlink { min-height: 44px; } }

.form-bar {
    display: flex; justify-content: flex-end; gap: .5rem;
    padding: .85rem 1.35rem; border-top: 1px solid var(--border); background: var(--surface-2);
}

.btn.success { background: var(--good); border-color: transparent; color: #fff; }
.btn.success:hover { filter: brightness(1.06); }
.btn.full { width: 100%; justify-content: center; }

/* Segmentväljaren: status, prioritet och kategori. Radioknappar under,
   så att formuläret fungerar utan skript och går att tabba i. */
.segmented {
    display: inline-flex; flex-wrap: wrap; gap: .2rem;
    padding: .2rem; border-radius: var(--radius-sm);
    background: var(--surface-2); border: 1px solid var(--border);
}
.segmented input { position: absolute; opacity: 0; width: 0; height: 0; }
.segmented label {
    display: inline-flex; align-items: center; gap: .4rem;
    padding: .32rem .7rem; border-radius: 6px;
    font-size: .84rem; font-weight: 550; color: var(--ink-2); cursor: pointer;
}
.segmented label:hover { color: var(--ink); }
.segmented input:checked + label { background: var(--surface); color: var(--ink); box-shadow: var(--shadow); }
.segmented input:focus-visible + label { outline: 2px solid var(--brand); outline-offset: 1px; }
.segmented .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--dot, var(--border-strong)); }

.field .label-text { display: block; font-size: .82rem; font-weight: 600; color: var(--ink-2); margin-bottom: .3rem; }

/* Gäller: flerval som brickor. Rutan får inte ärva .field inputs
   width: 100% — då sträcktes den ut och texten hamnade långt ifrån. */
.check-grid { display: flex; flex-wrap: wrap; gap: .4rem; }
.field .check-grid label {
    display: inline-flex; align-items: center; gap: .45rem;
    margin: 0; padding: .35rem .75rem .35rem .6rem;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface);
    font-size: .84rem; font-weight: 550; color: var(--ink-2); cursor: pointer;
}
.field .check-grid label:hover { background: var(--surface-hover); color: var(--ink); }
.field .check-grid label:has(input:checked) { border-color: var(--brand); background: var(--brand-wash); color: var(--ink); }
.field .check-grid input {
    width: 16px; height: 16px; flex: 0 0 16px;
    margin: 0; padding: 0; accent-color: var(--brand);
}
@media (max-width: 820px) {
    .field .check-grid label { min-height: 44px; }
    .field .check-grid input { min-height: 0; width: 18px; height: 18px; flex-basis: 18px; }
}

/* Checklistan. Draghandtaget syns när musen är över raden. */
.checklist { list-style: none; margin: 0 0 .9rem; padding: 0; }
.check-row { display: flex; align-items: center; gap: .45rem; padding: .2rem 0; }
.check-row .grip { color: transparent; cursor: grab; display: inline-flex; flex: 0 0 auto; }
.check-row:hover .grip { color: var(--ink-3); }
.check-row label.text { flex: 1 1 auto; min-width: 0; display: flex; gap: .5rem; align-items: baseline; font-size: .88rem; cursor: pointer; overflow-wrap: anywhere; }
.check-row label.text input { flex: 0 0 auto; position: relative; top: .1rem; }
.check-row.is-done label.text span { text-decoration: line-through; color: var(--ink-3); }
.check-row .row-actions { display: flex; gap: .1rem; flex: 0 0 auto; opacity: 0; }
.check-row:hover .row-actions,
.check-row:focus-within .row-actions { opacity: 1; }
.check-row input.edit { flex: 1 1 auto; }
.check-ghost { opacity: .4; }
.check-chosen { background: var(--surface-2); border-radius: 6px; }
@media (hover: none) { .check-row .row-actions { opacity: 1; } }

.add-row { display: flex; gap: .5rem; }
.add-row input { flex: 1 1 auto; }

input.text-input, textarea.text-input {
    width: 100%;
    padding: .5rem .7rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--ink);
    font: inherit; font-size: .9rem;
}

/* Lanseringslistan på sajtsidan (kort #66): tavlans checklista, med en
   hjälprad under varje steg och brickan eller länken till höger. */
.launch-list .check-row { align-items: flex-start; padding: .45rem 0; border-top: 1px solid var(--border); }
.launch-list .check-row:first-child { border-top: 0; }
.launch-list .check-row label.text,
.launch-list .check-row .text { flex: 1 1 auto; min-width: 0; display: flex; gap: .5rem; align-items: flex-start; font-size: .88rem; }
.launch-list .launch-text { display: flex; flex-direction: column; gap: .1rem; }
.launch-list .launch-help { font-size: .8rem; color: var(--ink-3); }
.launch-list .launch-title { display: flex; flex-wrap: wrap; align-items: center; gap: .2rem .45rem; }
.launch-list .launch-auto { gap: .25rem; font-size: .7rem; padding-block: .05rem; }
/* Bara stegets namn stryks; en överstrykning på föräldern går inte att ta bort på barnet. */
.launch-list .check-row.is-done label.text span { text-decoration: none; color: inherit; }
.launch-list .check-row.is-done label.text .launch-label { text-decoration: line-through; color: var(--ink-3); }
.launch-list .check-row.is-done label.text .launch-help { color: var(--ink-3); }
.launch-list .launch-meta { flex: 0 0 auto; align-self: center; }
.launch-list .check-row > .btn,
.launch-list .check-row > .status { flex: 0 0 auto; align-self: center; }
@media (max-width: 40rem) {
    .launch-list .check-row { flex-wrap: wrap; }
    .launch-list .launch-meta,
    .launch-list .check-row > .btn { margin-left: 1.6rem; }
}

/* Tunn framstegsstapel för checklistan. */
.meter { height: 4px; border-radius: 99px; background: var(--border); overflow: hidden; margin-bottom: .9rem; }
.meter span { display: block; height: 100%; background: var(--good); transition: width .2s; }

.icon-btn.danger:hover { color: var(--critical); }

/* Kommentarerna. */
.comment { padding-bottom: .9rem; margin-bottom: .9rem; border-bottom: 1px solid var(--border); }
.comment-head { display: flex; align-items: flex-start; gap: .5rem; font-size: .8rem; color: var(--ink-3); }
.comment-head strong { color: var(--ink-2); }
.comment-head .row-actions { margin-left: auto; display: flex; gap: .1rem; }
.comment-body { margin-top: .3rem; font-size: .88rem; white-space: pre-wrap; overflow-wrap: anywhere; }
.comment-editor .bar { display: flex; gap: .4rem; margin-top: .5rem; }

/* Bilagorna. */
.attachments { list-style: none; margin: 0 0 .9rem; padding: 0; }
.attachment-row { display: flex; align-items: center; gap: .7rem; padding: .5rem 0; border-bottom: 1px solid var(--border); }
.attachment-row:last-child { border-bottom: 0; }
.attachment-thumb {
    width: 42px; height: 42px; flex: 0 0 42px;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 6px; background: var(--surface-2); border: 1px solid var(--border);
    overflow: hidden; color: var(--ink-3);
}
.attachment-thumb img { width: 100%; height: 100%; object-fit: cover; }
.attachment-row .info { flex: 1 1 auto; min-width: 0; }
.attachment-row .name { font-size: .86rem; font-weight: 550; overflow-wrap: anywhere; }
.attachment-row .meta { font-size: .76rem; color: var(--ink-3); }
.upload-status { font-size: .82rem; color: var(--ink-2); margin-bottom: .6rem; }
.upload-status.is-error { color: var(--critical); }

/* Startprompten i sin helhet. Ett pre-block: radbrytningarna bär
   betydelse, och titeln kan vara allt från fyra ord till fyra rader. */
.prompt-box {
    margin: 0;
    padding: .75rem .9rem;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-size: .8rem; line-height: 1.55;
    white-space: pre-wrap; overflow-wrap: anywhere;
}

.danger-zone { border-color: var(--critical-wash); }
.danger-zone .card-head h2 { color: var(--critical); }

.muted-note { font-size: .8rem; color: var(--ink-3); margin: .5rem 0 0; }


/*
| Kvittensen mitt i nederkanten — jdToast() i shell.js. En pill som glider
| upp, grön eller röd med vit text; felet har ett kryss och står kvar.
*/
.toast-stack {
    position: fixed; left: 50%; bottom: 0; transform: translateX(-50%);
    z-index: 100; width: min(30rem, 100%);
    padding: 0 1rem calc(1.25rem + env(safe-area-inset-bottom, 0px));
    display: flex; flex-direction: column; gap: .5rem;
    pointer-events: none;
}
.toast {
    display: flex; align-items: center; gap: .75rem;
    padding: .9rem 1.4rem;
    border-radius: 999px;
    background: var(--toast-ok-bg); color: var(--toast-ink);
    box-shadow: 0 6px 24px rgba(23, 28, 33, .24);
    opacity: 0; transform: translateY(1.25rem); pointer-events: auto;
    transition: opacity .22s ease, transform .22s ease;
}
.toast.is-visible { opacity: 1; transform: translateY(0); }
.toast.is-leaving { opacity: 0; transform: translateY(1.25rem); }
.toast.is-error { background: var(--toast-error-bg); }
.toast-icon { flex: none; font-size: 1.35rem; }
.toast-body { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.toast-body strong {
    font-size: .95rem; font-weight: 700; line-height: 1.2;
    letter-spacing: .04em; text-transform: uppercase;
}
.toast-body span { font-size: .82rem; line-height: 1.35; opacity: .92; overflow-wrap: anywhere; }
.toast-close {
    flex: none; margin-left: auto; padding: .35rem; line-height: 1;
    background: none; border: 0; border-radius: 999px;
    color: inherit; opacity: .8; cursor: pointer;
}
.toast-close:hover, .toast-close:focus-visible { opacity: 1; }
.toast-close:focus-visible { outline: 2px solid currentColor; outline-offset: 1px; }

@media (max-width: 767.98px) {
    .toast { border-radius: var(--radius); }
    .toast-close { display: inline-flex; align-items: center; justify-content: center; min-width: 44px; min-height: 44px; }
}

@media (prefers-reduced-motion: reduce) {
    .toast, .toast.is-leaving { transform: none; transition: opacity .22s ease; }
}

/*
|--------------------------------------------------------------------------
| Framsteg — backupkörningen
|--------------------------------------------------------------------------
*/

.progress { height: 10px; border-radius: 20px; background: var(--border); overflow: hidden; }
.progress.is-done span  { background: var(--good); }
.progress.is-error span { background: var(--critical); }

/* Rubriken över mapp- och fillistan på backupsidan. */
.field-caption {
    font-size: .78rem; font-weight: 600; letter-spacing: .04em;
    text-transform: uppercase; color: var(--ink-3);
    margin-bottom: .4rem;
}

.backup-patterns { font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; font-size: .85rem; }

/* Historiken: en tbody per körning, med innehållet på en egen rad under
   datum, status och knappar. Som egen kolumn blev innehållet en smal
   pelare med ett ord per rad. Strecket går mellan körningarna, inte
   mellan raderna i en körning, och hela körningen markeras vid hovring. */
.backup-history .backup-run tr:first-child:not(:last-child) td { border-bottom: 0; padding-bottom: .35rem; }
.backup-history .backup-detail td { padding-top: 0; }
.backup-history .backup-run:not(:last-child) tr:last-child td { border-bottom: 1px solid var(--border); }
.backup-history .backup-run tr:hover { background: transparent; }
.backup-history .backup-run:hover { background: var(--surface-2); }
.backup-history .backup-filename { word-break: break-all; }
.backup-history .backup-error { margin-top: .3rem; white-space: normal; }
.backup-history .backup-actions { display: inline-flex; align-items: center; gap: .35rem; }

@media (max-width: 700px) {
    .backup-history .backup-run { display: block; border-bottom: 1px solid var(--border); }
    .backup-history .backup-run:last-child { border-bottom: 0; }
    .backup-history .backup-run:hover { background: transparent; }
    .backup-history .backup-run tr { border-bottom: 0; }
    .backup-history .backup-run tr:first-child:not(:last-child) { padding-bottom: 0; }
    .backup-history .backup-detail { padding-top: 0; }
    .backup-history .backup-run td { border-bottom: 0 !important; }
    /* Innehållsraden är ingen rubrik, fast den är radens första cell. */
    .backup-history .backup-detail td:first-child { font-size: .82rem; margin-bottom: 0; }
}
.progress span {
    display: block; height: 100%;
    background: linear-gradient(90deg, var(--brand), var(--brand-gold));
    transition: width .3s;
}

.choice {
    display: flex; align-items: center; gap: .65rem;
    padding: .5rem .6rem; border-radius: var(--radius-sm); cursor: pointer;
}
.choice:hover { background: var(--surface-hover); }

/* Ett val som inte går att göra ska se ut som ett besked, inte som ett
   erbjudande — nedtonat och utan pekare. */
.choice.is-locked,
.choice.is-locked:hover { cursor: default; background: transparent; opacity: .6; }

/* Backupens mappar och filer: en ruta per val, med storleken på en egen
   rad under namnet. Som högerkolumn sköts storleken ut över kortets kant
   av ett långt mappnamn, och förklaringen på den låsta mappen trängdes
   ihop bredvid den. */
.backup-choices { display: grid; gap: .4rem; }
.backup-choices .choice {
    border: 1px solid var(--border);
    padding: .55rem .8rem;
}
.backup-choices .choice-text { display: block; flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.backup-choices .choice-name { display: block; font-weight: 600; }
.backup-choices .choice-meta { display: block; margin-top: .1rem; color: var(--ink-3); font-size: .82rem; }
.backup-choices .choice .chip { margin-left: .3rem; vertical-align: middle; }

/* Rutan Schema: databasen och filerna var för sig, med en linje emellan. */
.backup-schedule + .backup-schedule { border-top: 1px solid var(--border); padding-top: 1rem; }
.backup-schedule { margin-bottom: 1rem; }
.backup-schedule .field-pair { gap: .75rem; }
.backup-schedule .settings-unit input { width: 6rem; }
.backup-next { margin: -.4rem 0 0; }
.backup-cron-link { font-weight: 600; text-decoration: underline; text-underline-offset: 2px; }
.backup-cron-link:hover { color: var(--brand); }

/* Sorten bredvid statusen i historiken: Allt, Databasen, Filerna. */
.backup-history .backup-kind { margin-left: .35rem; vertical-align: middle; }

/* Valet bredvid Kör backup nu — lika högt som knappen på telefon. */
@media (max-width: 820px) {
    #backup-kind { min-height: 44px; }
}

/* Backup är två sidor: Backuper och Inställningar. Flikarna står under
   sidhuvudet och ser ut som en del av sidan, inte som en meny. */
.page-tabs {
    display: flex; gap: .25rem; flex-wrap: wrap;
    border-bottom: 1px solid var(--border);
    margin: -.35rem 0 1.25rem;
}
.page-tab {
    padding: .55rem .9rem; margin-bottom: -1px;
    border-bottom: 2px solid transparent;
    color: var(--ink-2); font-weight: 600; font-size: .92rem;
}
.page-tab:hover { color: var(--ink); }
.page-tab.is-active { color: var(--ink); border-bottom-color: var(--brand); }
@media (max-width: 820px) {
    .page-tab { min-height: 44px; display: inline-flex; align-items: center; }
}

/* Backuper: förloppet (bara medan en körning pågår), läget i tre delar och
   historiken, i den ordningen med samma luft emellan. */
.backup-running, .backup-status { margin-bottom: 1.25rem; }
.backup-scope { margin: 0 0 .8rem; }
.backup-status {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1px;
    background: var(--border); border: 1px solid var(--border);
    border-radius: var(--radius); overflow: hidden;
}
.backup-status-item {
    display: flex; flex-direction: column; gap: .15rem;
    padding: .85rem 1.1rem; background: var(--surface); min-width: 0;
}
.backup-status-label {
    font-size: .75rem; font-weight: 600; letter-spacing: .04em;
    text-transform: uppercase; color: var(--ink-3);
}
.backup-status-link { margin-top: .25rem; color: var(--ink-2); text-decoration: underline; text-underline-offset: 2px; align-self: flex-start; }
.backup-status-link:hover { color: var(--brand); }
@media (max-width: 820px) {
    .backup-status { grid-template-columns: minmax(0, 1fr); }
    .backup-status-link { min-height: 44px; display: inline-flex; align-items: center; margin-top: 0; }
}

/* Inställningar: kundsajterna som en hopfälld grupp med sökning. */
.backup-group { margin-top: 1rem; border: 1px solid var(--border); border-radius: var(--radius-sm); }
.backup-group summary {
    display: flex; align-items: baseline; justify-content: space-between; gap: .75rem;
    padding: .7rem .8rem; cursor: pointer; list-style: none;
}
.backup-group summary::-webkit-details-marker { display: none; }
.backup-group summary .field-caption { margin: 0; }
.backup-group summary::after { content: "▾"; color: var(--ink-3); }
.backup-group[open] summary::after { content: "▴"; }
.backup-group summary [data-backup-group-count] { margin-left: auto; }
.backup-group > .backup-choices, .backup-group > .backup-group-tools, .backup-group > .backup-group-empty { margin: 0 .8rem .8rem; }
.backup-group-tools { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }
.backup-group-search {
    flex: 1 1 12rem; min-width: 0; padding: .45rem .7rem;
    border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--ink); font: inherit;
}
.backup-group .choice[hidden] { display: none; }
@media (max-width: 820px) {
    .backup-group summary, .backup-group-search, .backup-group-tools .btn { min-height: 44px; }
}

/* Den gemensamma Spara-raden: syns när något ändrats och stannar längst
   ned i fönstret medan man rullar. */
.save-bar {
    position: sticky; bottom: 1rem; z-index: 20;
    display: flex; align-items: center; justify-content: space-between; gap: .75rem; flex-wrap: wrap;
    margin-top: 1.25rem; padding: .75rem 1rem;
    background: var(--surface); border: 1px solid var(--brand);
    border-radius: var(--radius); box-shadow: 0 6px 24px rgba(0, 0, 0, .18);
}
/* Ett fält som webbläsaren rullar fram (ett ogiltigt värde, Tab) ska inte
   hamna bakom raden. */
html:has(.save-bar:not([hidden])) { scroll-padding-bottom: 7rem; }
.save-bar-text { display: inline-flex; align-items: center; gap: .5rem; font-weight: 600; color: var(--ink); }
.save-bar-text .icon { color: var(--brand); }
.save-bar-actions { display: flex; gap: .5rem; margin-left: auto; }
@media (max-width: 820px) {
    .save-bar { bottom: .5rem; }
    .save-bar-actions { width: 100%; }
    .save-bar-actions .btn { flex: 1 1 0; justify-content: center; min-height: 44px; }
}


/*
|--------------------------------------------------------------------------
| Inloggning
|--------------------------------------------------------------------------
|
| Egen sida utan skal — det finns ingen meny att visa för den som inte är
| inloggad. Delar tokens med resten av CRM:et, så mörkt läge följer med
| utan en enda extra regel.
|
| Kortet är smalt med flit. En inloggning har ett fält och en knapp, och
| ett brett kort får ögat att leta efter något mer.
|
*/

.login-page {
    min-height: 100vh;
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    gap: 1.25rem;
    padding: 2rem 1.25rem;
    background: var(--page);
}

.login-brand { margin-bottom: .25rem; }
.login-brand img { height: 46px; width: auto; display: block; }

.login-card {
    width: 100%; max-width: 400px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lift);
    padding: 1.85rem;
}

.login-card h1 {
    margin: 0 0 .4rem;
    font-size: 1.4rem; font-weight: 650; letter-spacing: -.02em;
    color: var(--ink);
}
.login-card .lead { margin: 0 0 1.35rem; color: var(--ink-2); font-size: .9rem; line-height: 1.5; }
.login-card .field { margin-bottom: 1.15rem; }
.login-card .btn.primary { width: 100%; justify-content: center; padding: .6rem 1rem; }

/* Symbolen ovanför rubriken i de lägen som rapporterar ett utfall —
   länken skickad, länken utgången. Färgen bärs aldrig ensam: under den
   står alltid en rubrik som säger samma sak i ord. */
.login-mark {
    width: 52px; height: 52px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 50%;
    margin-bottom: 1.1rem;
    background: var(--brand-wash); color: var(--brand);
}
.login-mark.warn { background: var(--warn-wash); color: var(--warn-ink); }

.login-remember {
    display: flex; align-items: flex-start; gap: .55rem;
    margin: 0 0 1.25rem;
    font-size: .87rem; color: var(--ink-2);
}
.login-remember input { margin: .15rem 0 0; flex: 0 0 auto; width: 16px; height: 16px; }
.login-remember .hint { display: block; font-size: .78rem; color: var(--ink-3); margin-top: .15rem; }

.login-alt {
    margin: 1.25rem 0 -.6rem; padding-top: 1.1rem;
    border-top: 1px solid var(--border);
    font-size: .85rem; color: var(--ink-2);
    text-align: center;
}
.login-alt a {
    display: inline-flex; align-items: center; justify-content: center;
    min-height: 44px; padding: 0 .5rem;
    color: var(--brand); text-decoration: none; font-weight: 600;
}
.login-alt a:hover { text-decoration: underline; }

.login-sent { font-size: .9rem; color: var(--ink-2); line-height: 1.55; margin: 0 0 1.35rem; }
.login-sent b { color: var(--ink); }

.login-foot { font-size: .8rem; color: var(--ink-3); text-align: center; }

@media (max-width: 480px) {
    .login-page { justify-content: flex-start; padding-top: 3rem; }
    .login-card { padding: 1.35rem; }
}


/*
|--------------------------------------------------------------------------
| Skalet i PHP — tillägg 2026-09-25
|--------------------------------------------------------------------------
*/

/* En modul som inte är byggd än: syns i menyn så att strukturen går att
   bedöma, men är ingen länk. */
.nav-link.is-soon,
.nav-link.is-soon:hover {
    cursor: default;
    background: transparent;
    color: var(--ink-3);
}
.nav-link.is-soon .icon { opacity: .5; }
.nav-soon {
    margin-left: auto;
    font-size: .68rem; font-weight: 600;
    letter-spacing: .04em; text-transform: uppercase;
    color: var(--ink-3);
}

/* Miljömärket i sidomenyns fot. Syns bara i beta, så att en flik mot den
   lokala databasen aldrig förväxlas med driften. */
.env-badge {
    display: inline-block;
    padding: .15rem .5rem;
    border-radius: 20px;
    font-size: .72rem; font-weight: 700;
    letter-spacing: .06em; text-transform: uppercase;
    background: var(--warn-wash); color: var(--warn-ink);
}
[data-theme="dark"] .env-badge { color: var(--warn); }

/* Formulär som bara är en knapp — utloggningen i topplisten, återkalla
   en enhet. Formuläret ska inte ta egen plats i raden. */
.inline-form { display: inline; margin: 0; }

/* Utfall av en åtgärd: fel, klart eller bara besked. Alltid ikon + text —
   färgen är en förstärkning, aldrig bäraren. */
.alert {
    display: flex; gap: .6rem; align-items: flex-start;
    padding: .75rem .9rem;
    border-radius: var(--radius-sm);
    font-size: .88rem; line-height: 1.45;
    margin-bottom: 1.1rem;
    background: var(--neutral-wash); color: var(--ink);
}
.alert .icon { flex: 0 0 auto; margin-top: .05rem; }
.alert.error   { background: var(--critical-wash); }
.alert.error .icon   { color: var(--critical); }
.alert.success { background: var(--good-wash); }
.alert.success .icon { color: var(--good); }
.alert.info .icon { color: var(--brand); }

/* Inloggningskortet har två vägar in. Den andra knappen står under den
   första, lika bred, så att valet syns direkt. */
.login-card .btn.full { width: 100%; justify-content: center; padding: .6rem 1rem; }
.login-or {
    display: flex; align-items: center; gap: .75rem;
    margin: 1rem 0;
    font-size: .78rem; color: var(--ink-3);
}
.login-or::before, .login-or::after { content: ""; flex: 1 1 auto; height: 1px; background: var(--border); }

/* Inloggningens två lägen. Kortets data-mode avgör vilka delar som syns;
   länken är förvalet och lösenordet öppnas med knappen under. */
.login-card[data-mode="link"] .when-password,
.login-card[data-mode="password"] .when-link { display: none; }
.login-card .btn .when-link,
.login-card .btn .when-password { display: inline-flex; align-items: center; gap: .45rem; }
.login-card[data-mode="link"] .btn .when-password,
.login-card[data-mode="password"] .btn .when-link { display: none; }

/* Frågetecknet bredvid en sidrubrik, länk till en guide. */
.help-link { color: var(--ink-3); display: inline-flex; vertical-align: middle; margin-left: .3rem; }
.help-link:hover { color: var(--brand); }

/* Räknarbricka i ett korthuvud. */
.count-badge {
    display: inline-block; min-width: 1.6rem; text-align: center;
    padding: .05rem .45rem; border-radius: 20px;
    background: var(--neutral-wash); color: var(--ink-2);
    font-size: .76rem; font-weight: 700; font-variant-numeric: tabular-nums;
}

/* Guiden till /todo. Ren läsning: kortare rader och mer luft än
   arbetsytorna. */
.guide { max-width: 880px; display: flex; flex-direction: column; gap: 1.1rem; }
.guide p { line-height: 1.65; }
.guide .card-body > p:first-child { margin-top: 0; }
.guide code, .page-head h1 code {
    background: var(--surface-2); border-radius: 5px; padding: .05rem .35rem;
    font-size: .88em; color: var(--brand-deep);
}
[data-theme="dark"] .guide code, [data-theme="dark"] .page-head h1 code { color: var(--brand); }
.guide .data-table td { white-space: normal; vertical-align: top; --cell-top: 1; line-height: 1.55; }
.guide-kicker { margin: .6rem 0 -.3rem; font-size: .74rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); }
.guide-when { font-size: .7rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3); }
.guide-ex { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: .75rem .95rem; }
.guide-ex p { margin: 0 0 .5rem; font-size: .87rem; }
.guide-ex p:last-child { margin-bottom: 0; }
.guide-ex .you::before { content: "Du: "; font-weight: 700; color: var(--brand-deep); }
.guide-ex .me::before { content: "Claude: "; font-weight: 700; color: var(--ink-3); }

/*
|--------------------------------------------------------------------------
| Felsökning
|--------------------------------------------------------------------------
*/

/* Rullgardin i en filterrad — samma form som sökrutan bredvid. */
.select {
    padding: .4rem .6rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    color: var(--ink);
    font: inherit; font-size: .87rem;
}

.debug-table td { vertical-align: top; --cell-top: 1; }
.debug-message { min-width: 280px; overflow-wrap: anywhere; }
.debug-json { margin-top: .35rem; }
.debug-json summary { cursor: pointer; color: var(--ink-3); }
.debug-json pre {
    margin: .4rem 0 0; padding: .6rem .75rem;
    background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm);
    font-size: .74rem; line-height: 1.5;
    white-space: pre-wrap; overflow-wrap: anywhere; max-height: 360px; overflow: auto;
}

/*
|--------------------------------------------------------------------------
| Verktyg — vänstermenyn på Verktygs sidor
|--------------------------------------------------------------------------
|
| Samma rytm som huvudmenyn, men aktiv post utan varumärkets gradient: den
| hör till huvudmenyn och tappar sin signalverkan om den syns på två ställen.
| Under 1100 px lägger sig menyn som en rad kort ovanför innehållet.
|
*/

.tools-layout {
    display: grid;
    grid-template-columns: 200px minmax(0, 1fr);
    gap: 1.75rem;
    align-items: start;
}

.tools-nav { position: sticky; top: calc(var(--topbar-h) + 1.25rem); }
.tools-nav-group + .tools-nav-group { margin-top: 1rem; }

.tools-nav-heading {
    font-size: .72rem; font-weight: 600; letter-spacing: .06em;
    text-transform: uppercase; color: var(--ink-3);
    padding: 0 .7rem; margin-bottom: .3rem;
}

.tools-nav-link {
    display: flex; align-items: center; gap: .6rem;
    padding: .5rem .7rem;
    border-radius: var(--radius-sm);
    color: var(--ink-2); font-weight: 500; font-size: .92rem;
}
.tools-nav-link:hover { background: var(--surface-hover); color: var(--ink); }
.tools-nav-link .icon { flex: 0 0 16px; opacity: .8; }
.tools-nav-link.is-active { background: var(--surface-2); color: var(--ink); font-weight: 600; box-shadow: inset 3px 0 0 var(--brand); }
.tools-nav-link.is-active .icon { opacity: 1; color: var(--brand); }

.tools-body { min-width: 0; }

/* Kortknappen på en platshållare bär kortets titel, som kan vara lång —
   den får brytas i stället för att trycka ut sidan i sidled. */
.tools-soon-task { white-space: normal; text-align: left; max-width: 100%; height: auto; }

@media (max-width: 1100px) {
    .tools-layout { grid-template-columns: minmax(0, 1fr); gap: 1rem; }
    .tools-nav { position: static; display: flex; flex-wrap: wrap; gap: .4rem; }
    .tools-nav-group { display: contents; }
    .tools-nav-heading { display: none; }
    .tools-nav-link { border: 1px solid var(--border); background: var(--surface); padding: .55rem .8rem; min-height: 44px; }
    .tools-nav-link.is-active { box-shadow: none; border-color: var(--brand); }
    .tools-nav-link .nav-soon { margin-left: .35rem; }
}


/*
|--------------------------------------------------------------------------
| Ikoner — Font Awesome
|--------------------------------------------------------------------------
|
| icon() ritar <i class="icon fa-…"> med storleken som font-size. Ikonen
| centreras i sin egen ruta, så att en smal och en bred ikon står i samma
| linje i en meny.
|
*/

.icon { display: inline-block; flex-shrink: 0; line-height: 1; text-align: center; }


/*
|--------------------------------------------------------------------------
| Sidomenyn — dragspel och ikonrad
|--------------------------------------------------------------------------
|
| Byggd 2026-09-25 efter LeadFactorys sidomeny. Grupperna (Kunder, Affär)
| är själva menyposter; bara en är öppen åt gången, och den som bär sidan
| man står på är öppen vid laddning. Öppnandet är CSS — grid-raden går från
| 0fr till 1fr — och shell.js byter bara klassen.
|
| På desktop kan menyn fällas ihop till en ikonrad (html.nav-collapsed, satt
| i <head> ur localStorage). Där rullar menyn inte: undermenyer och
| tooltips ligger då bredvid sin post utan att deras läge räknas ut i JS.
| Menyn är kort nog att alltid rymmas på en desktopskärm.
|
*/

.sidebar-mark { display: none; }
.nav-label { white-space: nowrap; }

.nav-divider { border: 0; border-top: 1px solid var(--border); margin: .6rem .5rem; }

.nav-group-toggle,
.nav-collapse {
    width: 100%;
    border: 0;
    background: transparent;
    cursor: pointer;
    text-align: left;
    font: inherit;
}

.nav-caret { opacity: .5; transition: transform .2s ease; }
.nav-section.is-open .nav-caret { transform: rotate(90deg); }
.nav-section.has-active > .nav-group-toggle { color: var(--ink); font-weight: 600; }

/* Summan står bara när gruppen är stängd — öppen syns varje sidas egen. */
.nav-section.is-open .nav-count-sum { display: none; }

.nav-sub { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .25s ease; }
.nav-section.is-open > .nav-sub { grid-template-rows: 1fr; }
.nav-sub-inner { overflow: hidden; min-height: 0; display: flex; flex-direction: column; gap: .15rem; }
.nav-section.is-open .nav-sub-inner { padding: .15rem 0 .35rem; }

.nav-sublink { padding-left: 1.55rem; font-size: .93rem; }
.nav-flyout-title { display: none; }

.nav-collapse .icon { transition: transform .2s ease; }

@media (max-width: 820px) {
    /* Ikonraden finns bara på desktop — på telefonen är menyn en utskjutbar panel. */
    .sidebar-foot { display: none; }
}

@media (min-width: 821px) {

    /* sticky skapar en egen stapelkontext — utan z-index hamnar menyerna åt
       sidan under innehållets egna sticky-element, som Verktygs vänstermeny. */
    .sidebar { z-index: 30; transition: width .2s ease, flex-basis .2s ease; }

    html.nav-collapsed { --sidebar-w: 72px; }

    html.nav-collapsed .sidebar-head { padding: 0; justify-content: center; }
    html.nav-collapsed .sidebar-logo,
    html.nav-collapsed .sidebar-head .env-badge { display: none; }

    /* Symbolen utan ordbilden, assets/img/logomark.svg. */
    html.nav-collapsed .sidebar-mark { display: block; }
    html.nav-collapsed .sidebar-mark img { display: block; height: 38px; width: auto; }

    html.nav-collapsed .sidebar-scroll { overflow: visible; padding: 1rem .65rem; }

    html.nav-collapsed .nav-top { justify-content: center; padding: .6rem; position: relative; }
    html.nav-collapsed .nav-top > .nav-label,
    html.nav-collapsed .nav-top > .nav-soon,
    html.nav-collapsed .nav-top > .nav-caret { display: none; }

    html.nav-collapsed .nav-top > .nav-count {
        position: absolute; top: 1px; right: 1px;
        font-size: .62rem; padding: 0 .3rem; line-height: 1.45;
    }
    html.nav-collapsed .nav-section.is-open .nav-count-sum { display: inline-block; }

    /* Gruppen som bär sidan man står på får samma markering som en aktiv
       post — i ikonraden syns inte sidan under den. */
    html.nav-collapsed .nav-section.has-active > .nav-group-toggle {
        background: linear-gradient(100deg, var(--brand) 0%, var(--brand-gold) 165%);
        color: #fff;
    }

    /* Gruppens sidor öppnas åt sidan. */
    html.nav-collapsed .nav-section { position: relative; }
    html.nav-collapsed .nav-section > .nav-sub { display: none; }
    html.nav-collapsed .nav-section.is-flyout > .nav-sub {
        display: block;
        position: absolute; left: calc(100% + .65rem); top: 0; z-index: 60;
        min-width: 220px;
        background: var(--surface);
        border: 1px solid var(--border);
        border-radius: var(--radius-sm);
        box-shadow: var(--shadow-lift);
        padding: .4rem;
    }
    /* En osynlig brygga över glipan, så att menyn inte stängs när pekaren
       går från ikonen till den. */
    html.nav-collapsed .nav-section.is-flyout > .nav-sub::before {
        content: ""; position: absolute; top: 0; bottom: 0; left: -.75rem; width: .75rem;
    }
    html.nav-collapsed .is-flyout .nav-sub-inner { overflow: visible; padding: 0; }
    html.nav-collapsed .is-flyout .nav-flyout-title {
        display: block;
        font-size: .72rem; font-weight: 700; letter-spacing: .06em;
        text-transform: uppercase; color: var(--ink-3);
        padding: .35rem .6rem .45rem;
    }
    html.nav-collapsed .is-flyout .nav-sublink { padding-left: .75rem; }

    /* Tooltip med postens namn. */
    html.nav-collapsed .nav-top[data-tip]:hover::after,
    html.nav-collapsed .nav-top[data-tip]:focus-visible::after {
        content: attr(data-tip);
        position: absolute; left: calc(100% + .65rem); top: 50%; transform: translateY(-50%);
        z-index: 70; pointer-events: none; white-space: nowrap;
        background: var(--ink); color: var(--surface);
        font-size: .8rem; font-weight: 500;
        padding: .3rem .55rem; border-radius: 6px;
    }

    html.nav-collapsed .nav-collapse .icon { transform: rotate(180deg); }
}

@media (prefers-reduced-motion: reduce) {
    .sidebar, .nav-sub, .nav-caret, .nav-collapse .icon { transition: none; }
}

/*
|--------------------------------------------------------------------------
| Formulärfel och Verktyg → Inställningar
|--------------------------------------------------------------------------
*/

/* Ett fält som inte gick igenom: röd ram och texten direkt under. */
.field.has-error input,
.field.has-error select,
.field.has-error textarea { border-color: var(--critical); }
.field-error { font-size: .82rem; color: var(--critical); margin-top: .3rem; font-weight: 500; }

/* Talfält med enheten bredvid: "30 dagar", "8 %". */
.settings-unit { display: flex; align-items: center; gap: .55rem; }
.settings-unit input, .settings-unit select { width: 8rem; flex: 0 0 auto; }
/* Talen och momsvalet är korta — samma smala bredd med eller utan enhet. */
.settings-form .settings-number, .settings-form select { max-width: 8rem; }
.settings-row { margin-bottom: 0; }
.settings-check { margin: -.2rem 0 1rem; }

/* Två fält i bredd blir ett på smal skärm — annars trängs etiketterna. */
@media (max-width: 1100px) {
    .settings-form .field-pair { grid-template-columns: minmax(0, 1fr); gap: 0; }
}


/*
|--------------------------------------------------------------------------
| Verktyg → Systemstatus
|--------------------------------------------------------------------------
*/

.critical-text { color: var(--critical); }
.good-text     { color: var(--good); }

/* Driftlägets och serverns tabeller: märket längst till höger, förklaringen
   under namnet. */
.status-table td { vertical-align: top; --cell-top: 1; }
.status-table td.right { white-space: nowrap; }

.status-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .7rem; }
.status-list li { display: flex; gap: .6rem; align-items: flex-start; }
.status-list li > .icon { margin-top: .2rem; }

.status-facts { display: grid; grid-template-columns: minmax(10rem, max-content) minmax(0, 1fr); gap: .5rem 1.25rem; margin: 0; }
.status-facts dt { color: var(--ink-3); font-size: .87rem; }
.status-facts dd { margin: 0; overflow-wrap: anywhere; }

@media (max-width: 820px) {
    .status-facts { grid-template-columns: minmax(0, 1fr); gap: .15rem; }
    .status-facts dd { margin-bottom: .6rem; }
}

/* Verktygs platshållare (Cron, E-postlogg): brödtexten under rubriken. */
.tools-soon-body { max-width: 34rem; margin: .4rem auto 1rem; }


/*
|--------------------------------------------------------------------------
| Reglage
|--------------------------------------------------------------------------
|
| Ett av/på-val som verkställs direkt: jobben i Cron, tystnadslarmet och
| valen i en filtermeny. En riktig <input type="checkbox" role="switch">
| i en <label> — tangentbord, skärmläsare och klick på hela raden kommer
| gratis. Spåret ritas med tokens, aldrig som en bild.
|
*/

.switch {
    display: inline-flex; align-items: center; gap: .6rem;
    cursor: pointer; position: relative;
}
.switch input {
    position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0;
}
.switch-track {
    position: relative; flex: 0 0 auto;
    width: 36px; height: 20px; border-radius: 99px;
    background: var(--border-strong);
    transition: background .15s ease;
}
.switch-track::after {
    content: ''; position: absolute; top: 2px; left: 2px;
    width: 16px; height: 16px; border-radius: 50%;
    background: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, .25);
    transition: transform .15s ease;
}
.switch input:checked + .switch-track { background: var(--brand); }
.switch input:checked + .switch-track::after { transform: translateX(16px); }
.switch input:focus-visible + .switch-track { outline: 2px solid var(--brand); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
    .switch-track, .switch-track::after { transition: none; }
}


/*
|--------------------------------------------------------------------------
| Filterknappar i en listas filterrad
|--------------------------------------------------------------------------
|
| Formen från docs/crm.md#utseendet. Streckad ram när inget är valt —
| knappen är ett erbjudande. Hel ram i varumärkesfärg och "· N" när filtret
| är på. Bara inuti .filter-bar: tavlans Kolumner-knapp är ett visningsval,
| inget filter, och behåller sin form.
|
*/

.filter-bar .facet-btn {
    border: 1px dashed var(--border-strong);
    border-radius: 99px;
    background: transparent;
    color: var(--ink-2);
    font-size: .8rem; font-weight: 600;
    padding: .34rem .8rem;
    text-decoration: none;
}
.filter-bar .facet-btn:hover { background: var(--surface-hover); color: var(--ink); }
.filter-bar .facet-btn.is-set {
    border-style: solid; border-color: var(--brand);
    background: var(--brand-wash); color: var(--brand-deep);
}
[data-theme="dark"] .filter-bar .facet-btn.is-set { color: var(--brand); }
.filter-bar .facet-btn[hidden] { display: none; }

.filter-bar .facet-menu {
    min-width: 260px; max-height: 280px; overflow-y: auto;
    padding: .45rem;
}
.facet-option {
    display: flex; width: 100%;
    padding: .45rem .5rem; border-radius: 6px; font-size: .88rem;
}
.facet-option:hover { background: var(--surface-hover); }
.facet-option .facet-n { color: var(--ink-3); font-variant-numeric: tabular-nums; }
.facet-option.is-zero { opacity: .5; }
.facet-hint { margin: .35rem .5rem .2rem; font-size: .76rem; color: var(--ink-3); }

/* Lägena som reglage direkt i filterraden (Sajter, Demos —
   crm_state_switches()). Ett läge som är på skrivs i full färg, ett utan
   träffar tonas ned. */
.state-switches {
    display: flex; flex-wrap: wrap; align-items: center;
    gap: .35rem 1.1rem;
}
.state-switch { font-size: .85rem; font-weight: 550; color: var(--ink-2); gap: .45rem; }
.state-switch:hover, .state-switch:has(input:checked) { color: var(--ink); }
.state-switch .switch-track { width: 30px; height: 17px; }
.state-switch .switch-track::after { width: 13px; height: 13px; }
.state-switch input:checked + .switch-track::after { transform: translateX(13px); }
.state-switch .switch-n { color: var(--ink-3); font-weight: 500; margin-left: .1rem; font-variant-numeric: tabular-nums; }
.state-switch.is-zero { opacity: .5; }

/* På telefon blir menyn lika bred som raden i stället för att sticka ut:
   den placeras mot filterraden, inte mot knappen. */
@media (max-width: 820px) {
    .filter-bar { position: relative; }
    .filter-bar .facet { position: static; }
    .filter-bar .facet-menu { left: 1rem; right: 1rem; min-width: 0; }
    .facet-option { min-height: 44px; }

    /* Reglaget är 20 px högt — träffytan är hela etiketten. */
    .switch { min-height: 44px; min-width: 44px; }

    /* Lägena i två spalter i full bredd, så att nio reglage inte blir en
       trasig rad. */
    .state-switches { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 .75rem; width: 100%; }
    .pager .select { min-height: 44px; }
}


/*
|--------------------------------------------------------------------------
| Sidfot med sidnumrering
|--------------------------------------------------------------------------
*/

.pager {
    display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
    padding: .85rem 1.35rem;
    border-top: 1px solid var(--border);
}
.pager-size { margin-left: auto; }


/*
|--------------------------------------------------------------------------
| Verktyg → Cron
|--------------------------------------------------------------------------
*/

.cron-jobs td { vertical-align: top; --cell-top: 1; }
.cron-job { min-width: 220px; }
.cron-job .muted { max-width: 32rem; }
.cron-last { min-width: 200px; }
.cron-last .chip { margin-left: .3rem; }
.cron-last .sm + .sm { margin-top: .15rem; }

.cron-expected { margin-top: 1.1rem; padding-top: 1rem; border-top: 1px solid var(--border); }
.cron-expected p { margin: .45rem 0 0; }

.cron-url { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.cron-url code { overflow-wrap: anywhere; }
.cron-steps { margin: .3rem 0 0; padding-left: 1.1rem; }
.cron-steps li + li { margin-top: .3rem; }
.cron-command {
    margin: .4rem 0; padding: .6rem .75rem;
    background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm);
    font-size: .8rem; white-space: pre-wrap; overflow-wrap: anywhere;
}

.cron-runs td { vertical-align: top; --cell-top: 1; }
.cron-summary { min-width: 260px; overflow-wrap: anywhere; }
.cron-output { margin-top: .35rem; }
.cron-output summary { cursor: pointer; color: var(--ink-3); }
.cron-output pre {
    margin: .4rem 0 0; padding: .6rem .75rem;
    background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm);
    font-size: .74rem; line-height: 1.5;
    white-space: pre-wrap; overflow-wrap: anywhere; max-height: 360px; overflow: auto;
}

@media (max-width: 700px) {
    .cron-job, .cron-last, .cron-summary { min-width: 0; }
    .cron-output summary { display: flex; align-items: center; min-height: 44px; }
}


/*
|--------------------------------------------------------------------------
| Filtermenyns radioknappar — ett av flera
|--------------------------------------------------------------------------
|
| Samma rad och träffyta som reglagen (.facet-option), men en radioknapp:
| ett val utesluter de andra. Byggt 2026-09-26 med Produkternas Dolda.
|
*/

.facet-radio { align-items: center; gap: .6rem; cursor: pointer; }
.facet-radio input { margin: 0; width: 16px; height: 16px; flex: 0 0 auto; accent-color: var(--brand); }

/* På telefon hamnar sökrutan på en egen rad i full bredd överst, och
   knapparna bryts under den (docs/crm.md#utseendet). */
@media (max-width: 820px) {
    .filter-bar .filter-search { order: -1; flex: 1 1 100%; margin-left: 0; }
}


/*
|--------------------------------------------------------------------------
| Produkter
|--------------------------------------------------------------------------
*/

.products-table td { vertical-align: top; --cell-top: 1; }
.products-name { min-width: 220px; }
.products-name .chip { gap: .25rem; margin-left: .4rem; vertical-align: 1px; }
.products-description { margin-top: .15rem; max-width: 46ch; white-space: pre-line; }

/* En dold produkt finns kvar men säljs inte — nedtonad, pennan i full färg. */
.products-table .is-hidden-row td:not(:last-child) { opacity: .6; }


/* Greppet till vänster om namnet: raden dras inom sitt slag
   (products/reorder/). Hela namnet flyttas in, så att beskrivningen
   under står i linje med det. */
.products-table td.products-name { position: relative; padding-left: 2.6rem; }
.products-grip {
    /* Samma luft överst som cellen — se --control-rise vid table.data-table td. */
    position: absolute; left: 1rem; top: calc(.8rem + var(--control-rise, 0px));
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.1rem; height: 1.3rem;
    color: var(--ink-3); cursor: grab; touch-action: none;
}
.products-grip:hover { color: var(--ink); }
.products-grip:focus-visible { color: var(--ink); outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 4px; }
.products-table tr.products-ghost { opacity: .4; }
.products-table tr.products-chosen { background: var(--surface-2); box-shadow: var(--shadow-lift); }
.products-table tr.products-chosen .products-grip { cursor: grabbing; }

.products-vat { max-width: 8rem; }
.products-hidden { margin: .25rem -.6rem 0; }
/* Frågan om abonnemangens namn, under namnfältet när namnet ändrats. */
.field label.products-rename { margin: .6rem 0 0; background: var(--brand-wash); }
.field label.products-rename:hover { background: var(--brand-wash); }

@media (max-width: 700px) {
    .products-name { min-width: 0; padding-right: 3rem !important; }
    /* Greppet är en knapp (tangentbordet) och får en hel träffyta, 44 px,
       som delvis ligger i kortets vänstermarginal. */
    .products-table td.products-name { padding-left: 2.2rem; }
    .products-grip { left: -.6rem; top: -.55rem; width: 2.75rem; height: 2.75rem; }

    /* Pennan i kortets övre högra hörn i stället för ensam sist. */
    .products-table tr { position: relative; }
    .products-table td:last-child { position: absolute; top: .55rem; right: .6rem; padding: 0; }

    /* Kompakt kort: namnet överst, slag, period och moms bredvid varandra
       på en rad, och priset under — i stället för fyra etiketter i en
       stapel, där sex produkter blev sex skärmar. */
    table.data-table.products-table tr {
        display: grid;
        grid-template-columns: repeat(3, minmax(0, 1fr));
        column-gap: .75rem;
    }
    .products-table td.products-name { grid-column: 1 / -1; }
    .products-table td.products-vat-cell { order: 1; }
    .products-table td.products-price-cell { order: 2; grid-column: 1 / -1; }
    .products-table td:last-child { order: 3; }
}


/*
|--------------------------------------------------------------------------
| Kunder
|--------------------------------------------------------------------------
*/

.customers-table td,
.contacts-table td { vertical-align: top; --cell-top: 1; }
/* Sökningen går i fler fält än produkternas — platshållaren ska få plats. */
.customers-filter .filter-search { flex-basis: 340px; }
.customers-name { color: var(--ink); text-decoration: none; }
.customers-name:hover { text-decoration: underline; }
.customers-email,
.contacts-email { overflow-wrap: anywhere; }

/* Postnumret är fem siffror — orten får resten av raden. */
.field-pair.customers-postal { grid-template-columns: minmax(0, 8rem) minmax(0, 1fr); }

/* Adresserna: postadressen står alltid öppen, besöks- och fakturaadressen
   fälls ut när de behövs. */
.customers-group { border: 0; padding: 0; margin: 0 0 1rem; min-width: 0; }
.customers-group legend,
.customers-group summary { font-size: .92rem; font-weight: 700; color: var(--ink); margin-bottom: .5rem; padding: 0; }
.customers-group > .hint { font-size: .8rem; color: var(--ink-3); margin: 0; }
.customers-group .field { margin-bottom: .5rem; }
.customers-optional { border-top: 1px solid var(--border); padding-top: .75rem; }
.customers-optional summary { cursor: pointer; margin-bottom: 0; min-height: 28px; display: list-item; }
.customers-optional[open] summary { margin-bottom: .5rem; }
.customers-optional summary .muted { font-weight: 400; }
/* "— samma som postadressen" gäller bara så länge gruppen är hopfälld: utfälld fylls den i. */
.customers-optional[open] summary .muted { display: none; }

/* Avtalsvillkoren: version och tidpunkt hör ihop och står under en rubrik. */
.customers-terms { border: 0; padding: 0; margin: 0 0 1rem; min-width: 0; }
.customers-terms legend { font-size: .82rem; font-weight: 600; color: var(--ink-2); margin-bottom: .35rem; padding: 0; }
.customers-terms .field { margin-bottom: .25rem; }
.customers-terms > .hint { font-size: .8rem; color: var(--ink-3); margin: 0; }

.contacts-billing { gap: .25rem; margin-left: .4rem; vertical-align: 1px; background: var(--brand-wash); color: var(--brand-deep); }
[data-theme="dark"] .contacts-billing { color: var(--brand); }
.contacts-actions { white-space: nowrap; }
.contacts-actions > .icon-btn,
.contacts-actions form { display: inline-flex; vertical-align: middle; }

.customer-note { white-space: pre-line; overflow-wrap: anywhere; }
/* Högerspalten är smal: rubriken ovanför värdet i stället för bredvid. */
.status-facts.customer-facts { grid-template-columns: minmax(0, 1fr); gap: .1rem; }
.customer-facts dd { line-height: 1.5; }
.customer-facts dd + dt { margin-top: .8rem; }

@media (max-width: 700px) {
    /* Kompakt kort: företaget överst, sedan två värden per rad — ort och
       antal kontaktpersoner, fakturareferens och abonnemang — i stället för
       fyra etiketter i en stapel, där 50 kunder blev över tjugo skärmar. */
    table.data-table.customers-table tr {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        column-gap: .75rem;
    }
    .customers-table td:first-child { grid-column: 1 / -1; }
    .customers-table td:nth-child(2) { order: 1; }
    .customers-table td:nth-child(5) { order: 2; }
    .customers-table td:nth-child(3) { order: 3; }
    .customers-table td:nth-child(4) { order: 4; }

    /* Pennan och papperskorgen i kortets övre högra hörn, som i Produkter. */
    .contacts-table tr { position: relative; }
    .contacts-table td:first-child { padding-right: 6rem; }
    .contacts-table td.contacts-actions { position: absolute; top: .55rem; right: .6rem; padding: 0; }
    .contacts-table td.contacts-actions::before { content: none; }
}

/* Sökrutan i en filtermeny med många val (list-filter.js). Den döljer bara
   rader i menyn — ett dolt val måste därför slå igenom mot display: flex. */
.facet-menu-search {
    width: 100%; margin-bottom: .35rem;
    padding: .4rem .6rem;
    border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--ink); font: inherit; font-size: .85rem;
}
.facet-menu-search::placeholder { color: var(--ink-3); opacity: 1; }
.facet-option[hidden] { display: none; }

/* Kundkortets spalter: korten staplas med samma avstånd som rutnätet. */
/* Spalterna på en sida med kort i två kolumner: korten staplas med samma
   luft som mellan sidans egna kort. En ny sida med .grid.cols-2-1 och
   flera kort per spalt ska ha klassen här — annars ligger korten kant i
   kant (Demosidan 2026-10-07, se docs/webblasargranskning.md). */
.customer-layout,
.demo-layout,
.sites-layout,
.backup-settings-grid { align-items: start; }
.customer-layout > div,
.demo-layout > div,
.sites-layout > div,
.backup-settings-grid > div { display: flex; flex-direction: column; gap: 1.25rem; min-width: 0; }

/* Fakturakopian och telefonnumren i kontaktpersonernas lista. */
.contacts-copy { gap: .25rem; margin-left: .4rem; vertical-align: 1px; }
.contacts-phones { white-space: nowrap; }

/* Kort för en modul som inte är byggd (customers_render_soon_card()):
   formen syns, men nedtonad — det finns ingenting att klicka på än. */
.customers-soon .card-head .chip { margin-left: .6rem; }
.customers-soon .table-wrap { opacity: .65; }
.customers-soon-table td { padding-top: 1rem; padding-bottom: 1rem; }
@media (max-width: 700px) {
    .customers-soon-table td::before { content: none; }
}
.customers-soon .btn:disabled { opacity: .5; cursor: not-allowed; box-shadow: none; }
.customers-soon .card-head .chip { white-space: nowrap; }
@media (max-width: 700px) {
    /* Rubrik, märke och knapp får inte plats på en rad — knappen bryts under. */
    .customers-soon .card-head { flex-wrap: wrap; row-gap: .6rem; }
    .customers-soon .card-head .right { margin-left: 0; flex-basis: 100%; }
}


/*
|--------------------------------------------------------------------------
| Abonnemang
|--------------------------------------------------------------------------
*/

.subscriptions-table td,
.subscriptions-due-table td { vertical-align: top; --cell-top: 1; }
.subscriptions-name { min-width: 200px; }
.subscriptions-name .status,
.subscriptions-name .chip { margin-left: .4rem; vertical-align: 1px; }
.subscriptions-name .status { padding: .1rem .45rem; font-size: .7rem; }
.subscriptions-discount { gap: .25rem; }
.subscriptions-reference { overflow-wrap: anywhere; }
.subscriptions-next { min-width: 150px; }
.subscriptions-filter .filter-search { flex-basis: 320px; }
.subscriptions-due-table .status { margin-top: .25rem; padding: .1rem .45rem; font-size: .7rem; }
.subscriptions-due-action form { display: inline-flex; }
.subscriptions-due-action .btn { white-space: nowrap; }
.subscriptions-due-note { padding: 0 1.35rem 1rem; margin: .75rem 0 0; }

/* Återkommande intäkt: siffrorna till vänster, produkterna till höger. */
.subscriptions-recurring-body {
    display: grid; grid-template-columns: minmax(14rem, 1fr) minmax(0, 2fr);
    gap: 1.25rem 2rem; align-items: start;
}
.subscriptions-recurring-figures { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; }
.subscriptions-recurring-figures .hero-sub { grid-column: 1 / -1; margin: 0; }@media (max-width: 900px) {
    .subscriptions-recurring-body { grid-template-columns: minmax(0, 1fr); }
}

/* Ett avslutat abonnemang står kvar i listan, men nedtonat — pennan är full. */
.subscriptions-table .is-ended-row td:not(:last-child) { opacity: .6; }

/* Rutan: lägesraden överst och åtgärderna sist. */
.subscriptions-form-status {
    margin: 0 0 1rem; padding: .55rem .75rem;
    border-radius: var(--radius-sm); background: var(--surface-2); color: var(--ink-2);
}
.subscriptions-discount-value { margin-top: .5rem; }
.subscriptions-form-actions {
    display: flex; flex-wrap: wrap; gap: 1rem 1.5rem; justify-content: space-between;
    margin-top: 1.25rem; padding-top: 1rem; border-top: 1px solid var(--border);
}
.subscriptions-form-actions > div { flex: 1 1 14rem; }
.subscriptions-form-actions .hint { margin: .35rem 0 0; font-size: .8rem; color: var(--ink-3); }

@media (max-width: 700px) {
    /* Kompakt kort: kunden och abonnemanget överst i full bredd, sedan två
       värden per rad, och pennan i kortets övre högra hörn som i Produkter. */
    table.data-table.subscriptions-table tr,
    table.data-table.subscriptions-due-table tr {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        column-gap: .75rem;
        position: relative;
    }
    .subscriptions-table td:first-child,
    .subscriptions-table td.subscriptions-name,
    .subscriptions-due-table td:first-child,
    .subscriptions-due-table td.subscriptions-name { grid-column: 1 / -1; }
    .subscriptions-table td:first-child { padding-right: 3rem; }
    .subscriptions-table td:last-child { position: absolute; top: .55rem; right: .6rem; padding: 0; }
    .subscriptions-table td:last-child::before { content: none; }
    .subscriptions-name { min-width: 0; }

    /* Knappen i full bredd under raden — ett klick som flyttar ett datum ska vara lätt att träffa. */
    .subscriptions-due-table td.subscriptions-due-action { grid-column: 1 / -1; }
    .subscriptions-due-table td.subscriptions-due-action::before { content: none; }
    .subscriptions-due-action form,
    .subscriptions-due-action .btn { width: 100%; justify-content: center; min-height: 44px; }
}


/*
|--------------------------------------------------------------------------
| Fakturor
|--------------------------------------------------------------------------
*/

.invoices-table td { vertical-align: top; --cell-top: 1; }
.invoices-filter .filter-search { flex-basis: 300px; }
.page-head h1 .status,
.page-head h1 .chip { vertical-align: middle; margin-left: .5rem; font-size: .75rem; }

/* Editorn: huvudet, raderna, summeringen och knapparna. */
.invoice-editor > .grid,
.invoice-editor > .card { margin-bottom: 1.25rem; }
.invoice-editor-head,
.invoice-editor-foot { align-items: start; }
/* Datum och villkor sida vid sida också i 390 px: kolumnerna får krympa och
   villkorsfältet är kort — annars sköt "dagar" ut och sidan rullade i sidled. */
.invoice-editor-head .field-pair { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.invoice-editor-head .settings-unit input { width: 5.5rem; }
.invoice-recipient { margin: 0; }
.invoice-recipient summary .muted { font-weight: 400; }
.invoice-recipient[open] summary .muted { display: none; }
.invoice-recipient > .hint { font-size: .8rem; color: var(--ink-3); margin: .25rem 0 0; }

.invoice-lines input,
.invoice-lines select {
    width: 100%; min-width: 0;
    padding: .45rem .6rem;
    border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--ink); font: inherit; font-size: .9rem;
}
.invoice-lines input::placeholder { color: var(--ink-3); opacity: 1; }
.invoice-lines .has-error input,
.invoice-lines .has-error select { border-color: var(--critical); }

/* En rad: benämning, antal, enhet, à-pris, moms, belopp och knapparna. */
.invoice-lines-head,
.invoice-line-main {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 5.5rem 5.5rem 7rem 6rem 7.5rem 4.5rem;
    gap: .6rem; align-items: start;
}
.invoice-lines-head {
    padding: .6rem 1.35rem;
    font-size: .68rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-3);
    border-bottom: 1px solid var(--border);
}
.invoice-line { padding: .75rem 1.35rem; border-bottom: 1px solid var(--border); }
.invoice-line.is-subscription { background: var(--surface-2); }
.invoice-cell-label { display: none; }
.invoice-cell-amount { text-align: right; padding-top: .45rem; font-weight: 600; white-space: nowrap; }
.invoice-cell-actions { display: flex; justify-content: flex-end; gap: .15rem; }
.invoice-cell .field-error { font-size: .78rem; }
.invoice-cell .hint { font-size: .78rem; color: var(--ink-3); margin-top: .2rem; }
.modal .invoice-number-input { max-width: 10rem; }
.invoice-line-details {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .6rem 1.25rem;
    margin-top: .6rem; padding-top: .6rem; border-top: 1px dashed var(--border);
}
.invoice-line-details[hidden] { display: none; }
.invoice-detail-label { display: block; font-size: .78rem; font-weight: 600; color: var(--ink-2); margin-bottom: .25rem; }
.invoice-discount { display: flex; gap: .5rem; }
.invoice-discount select { flex: 1 1 auto; }
.invoice-discount input { flex: 0 0 7rem; }
.invoice-period { display: flex; align-items: center; gap: .5rem; }
.invoice-line-note { margin-top: .35rem; display: flex; align-items: center; gap: .35rem; }
.invoice-line-note[hidden] { display: none; }
.invoice-lines-empty { padding: 1rem 1.35rem 0; margin: 0; }
.invoice-lines-add { display: flex; flex-wrap: wrap; gap: .6rem; padding: 1rem 1.35rem; }
.invoice-lines-add .select { max-width: 22rem; }

/* Summeringen: beloppen till höger, att betala i varumärkets ton. */
.invoice-totals-list { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: .35rem 1rem; margin: 0 0 .75rem; font-size: .9rem; }
.invoice-totals-list dt { color: var(--ink-2); }
.invoice-totals-list dd { margin: 0; text-align: right; white-space: nowrap; }
.invoice-total-row {
    display: flex; justify-content: space-between; align-items: baseline; gap: 1rem;
    padding: .7rem .9rem; border-radius: var(--radius-sm);
    background: var(--brand-wash); border-left: 4px solid var(--brand);
    font-weight: 600;
}
.invoice-total-row b { font-size: 1.25rem; font-weight: 800; white-space: nowrap; }

.invoice-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; margin-bottom: 1.25rem; }
.invoice-actions form { display: inline-flex; }
.invoice-actions .invoice-delete { margin-left: auto; }
.invoice-actions .is-disabled { opacity: .5; pointer-events: none; }
.invoice-side { display: flex; flex-direction: column; gap: 1.25rem; min-width: 0; }
.invoice-view-lines td { vertical-align: top; --cell-top: 1; }
.invoice-sent-to { overflow-wrap: anywhere; }
.invoice-send-modal { width: min(640px, calc(100vw - 2rem)); }
.invoice-ledger-link { color: var(--ink-2); text-decoration: underline; text-underline-offset: 2px; }
.invoice-ledger-link:hover { color: var(--ink); }

@media (max-width: 900px) {
    .invoice-lines-head { display: none; }
    /* Raden blir ett kort: benämningen överst i full bredd, sedan två fält per rad. */
    .invoice-line-main { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .invoice-cell-label { display: block; font-size: .72rem; font-weight: 600; color: var(--ink-2); margin-bottom: .2rem; }
    .invoice-cell-description { grid-column: 1 / -1; }
    .invoice-cell-amount { text-align: left; padding-top: 0; }
    .invoice-cell-actions { align-items: end; }
    .invoice-line-details { grid-template-columns: minmax(0, 1fr); }
    .invoice-lines input, .invoice-lines select, .invoice-lines-add .select, .invoice-lines-add .btn { min-height: 44px; }
    .invoice-cell-actions .icon-btn { width: 44px; height: 44px; }
}

@media (max-width: 700px) {
    table.data-table.invoices-table tr {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        column-gap: .75rem;
    }
    .invoices-table td:first-child { grid-column: 1 / -1; }
    .invoice-actions .btn { flex: 1 1 auto; justify-content: center; min-height: 44px; }
    .invoice-actions .invoice-delete { margin-left: 0; }
}

@media (max-width: 700px) {
    /* Läsvyns rader: benämningen överst, sedan antal, à-pris, moms och belopp två och två. */
    table.data-table.invoice-view-lines tr {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        column-gap: .75rem;
    }
    .invoice-view-lines td:first-child { grid-column: 1 / -1; }
}


/*
|--------------------------------------------------------------------------
| Ekonomi
|--------------------------------------------------------------------------
|
| Året i sidhuvudet styr hela sidan. Nyckeltalen och månaderna är små
| tabeller som förblir tabeller också på telefon — fyra kolumner tal får
| plats, och tolv månader som tolv kort vore tolv skärmar. Raderna under
| är en vanlig lista som blir kort.
|
*/

.ledger-years { margin: -.25rem 0 1.25rem; }
.ledger-years .pill { font-variant-numeric: tabular-nums; }

.ledger-top { margin-bottom: 1.25rem; align-items: start; }
.ledger-side { display: flex; flex-direction: column; gap: 1.25rem; min-width: 0; }
.ledger-months-card { margin-bottom: 1.25rem; }

.ledger-figures,
.ledger-months { width: 100%; border-collapse: collapse; font-size: .9rem; }
.ledger-figures th,
.ledger-figures td,
.ledger-months th,
.ledger-months td { padding: .55rem 1.35rem; border-bottom: 1px solid var(--border); }
.ledger-figures thead th,
.ledger-months thead th {
    font-size: .72rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
    color: var(--ink-3); background: var(--surface-2); white-space: nowrap; text-align: left;
}
.ledger-figures thead th.right,
.ledger-months thead th.right { text-align: right; }
.ledger-figures tbody th { text-align: left; font-weight: 500; color: var(--ink-2); }
/* Tabellerna förblir tabeller på telefon — talen står kvar till höger, trots
   att td.right vänsterställs där för listorna som blir kort. */
.ledger-figures td.right,
.ledger-months td.right { text-align: right; white-space: nowrap; }
.ledger-figures tbody tr:last-child th,
.ledger-figures tbody tr:last-child td { border-bottom: 0; }
.ledger-figures .is-strong th,
.ledger-figures .is-strong td { font-weight: 700; color: var(--ink); background: var(--brand-wash); }

.ledger-months tbody tr.is-upcoming td { color: var(--ink-3); }
.ledger-months tfoot td { border-bottom: 0; }
.ledger-months tfoot .is-strong td { font-weight: 700; border-top: 2px solid var(--border-strong); }
.ledger-control td { font-size: .82rem; color: var(--ink-2); }
.ledger-control .status { margin-left: .4rem; font-size: .72rem; vertical-align: 1px; }

.ledger-facts { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: .4rem 1rem; margin: 1rem 0 0; font-size: .9rem; }
.card-body > .ledger-facts:first-child { margin-top: 0; }
.ledger-facts dt { color: var(--ink-2); }
.ledger-facts dd { margin: 0; text-align: right; white-space: nowrap; }
.ledger-side .hint { font-size: .8rem; color: var(--ink-3); margin: .75rem 0 0; }
.ledger-side .stat .hero { margin-top: .35rem; }

/* Listan: kommande poster nedtonade, pennan eller låset i full färg. */
.ledger-table td { vertical-align: top; --cell-top: 1; }
.ledger-date { white-space: nowrap; }
.ledger-description { min-width: 200px; }
.ledger-description .chip { gap: .25rem; margin-left: .4rem; vertical-align: 1px; }
.ledger-invoice-chip { text-decoration: none; }
.ledger-invoice-chip:hover { color: var(--ink); border-color: var(--border-strong); }
.ledger-table .is-upcoming td:not(:last-child) { opacity: .6; }
.ledger-table .icon-btn.is-locked { color: var(--ink-3); cursor: default; }
.ledger-table .icon-btn.is-locked:hover { background: transparent; }
.ledger-filter .filter-search { flex-basis: 280px; }
/* Snabbsökens träff leder hit (#ledger-filters) — listan ska inte hamna under topplisten. */
.ledger-filter { scroll-margin-top: calc(var(--topbar-h) + 1rem); }

/* Typen som bricka med ikon — färgen förstärker, texten bär. Intäkt i
   det gröna, utgift neutral, uttag i varumärkets ton. */
.ledger-type {
    display: inline-flex; align-items: center; gap: .35rem;
    padding: .18rem .55rem; border-radius: 20px;
    font-size: .75rem; font-weight: 650; white-space: nowrap;
    background: var(--neutral-wash); color: var(--ink-2);
}
.ledger-type-income  { background: var(--good-wash);  color: var(--good-ink); }
/* Återbetalning: en negativ intäkt, neutral som en utgift — pengarna gick ut. */
.ledger-type-refund  { background: var(--neutral-wash); color: var(--ink-2); }
.ledger-type-drawing { background: var(--brand-wash); color: var(--brand-deep); }
[data-theme="dark"] .ledger-type-drawing { color: var(--brand); }

/* Beloppet bär riktningen: +in i grönt, −ut i textfärg. */
.ledger-amount.is-in b { color: var(--good-ink); }

/* Diagrammen: fast höjd, bredden följer kortet. Tabellerna under är facit. */
.ledger-chart { position: relative; height: 260px; padding: 1rem 1.35rem .5rem; }
.ledger-yoy-card { margin-bottom: 1.25rem; }
.ledger-yoy-head { border-top: 1px solid var(--border); }
.ledger-years-table tbody tr.is-current td { color: var(--ink-2); }

/* Rutan: momsens snabbval och upprepningen. */
.ledger-rate-btn {
    padding: 0; border: 0; background: none; font: inherit; color: var(--ink-2); font-weight: 600;
    text-decoration: underline; text-underline-offset: 2px; cursor: pointer;
}
.ledger-rate-btn:hover { color: var(--ink); }
.ledger-repeat { margin-top: .25rem; }
.ledger-repeat .choice { margin: 0 -.6rem; }
.ledger-repeat .field { margin: .5rem 0 0; }
.ledger-repeat .field select { max-width: 16rem; }

/* En kolumn: hjältesiffran först, den är det sidan handlar om. */
@media (max-width: 1200px) {
    .ledger-top .ledger-side { order: -1; }
}

@media (max-width: 820px) {
    .ledger-chart { height: 220px; padding: .75rem .6rem .25rem; }
    .ledger-figures th, .ledger-figures td,
    .ledger-months th, .ledger-months td { padding-left: .9rem; padding-right: .9rem; }
    .ledger-years { overflow-x: auto; flex-wrap: nowrap; padding-bottom: .25rem; }
    .ledger-years .pill { min-height: 44px; display: inline-flex; align-items: center; }
    .ledger-rate-btn { min-height: 32px; }
}

@media (max-width: 480px) {
    .ledger-figures, .ledger-months { font-size: .82rem; }
    .ledger-figures th, .ledger-figures td,
    .ledger-months th, .ledger-months td { padding-left: .6rem; padding-right: .6rem; }
    .ledger-figures thead th, .ledger-months thead th { font-size: .64rem; letter-spacing: .03em; white-space: normal; }
    /* Sexsiffriga årsbelopp ("117 684,60 kr") i tre kolumner: tätare, så att
       tabellen ryms i 390 px — .table-wrap rullar inte i sidled på telefon. */
    .ledger-months { font-size: .74rem; }
    .ledger-months th, .ledger-months td { padding-left: .35rem; padding-right: .35rem; }
    .ledger-months th:first-child, .ledger-months td:first-child { padding-left: .6rem; }
    .ledger-months th:last-child, .ledger-months td:last-child { padding-right: .6rem; }
    /* Årstabellen har en kolumn till: ännu tätare, och årets not under året. */
    .ledger-years-table { font-size: .7rem; }
    .ledger-years-table th, .ledger-years-table td { padding-left: .25rem; padding-right: .25rem; }
    .ledger-years-table td:first-child .muted { display: block; }
}

@media (max-width: 700px) {
    /* Kompakt kort: benämningen överst, sedan datum och typ, belopp och
       moms två och två, och pennan i hörnet. Datumet står först i tabellen
       men får sin etikett tillbaka — rubriken är benämningen. */
    table.data-table.ledger-table tr {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        column-gap: .75rem;
        position: relative;
    }
    .ledger-table td.ledger-description { order: -1; grid-column: 1 / -1; font-size: 1rem; margin-bottom: .5rem; min-width: 0; padding-right: 3rem; }
    .ledger-table td.ledger-description::before { content: none; }
    table.data-table.ledger-table td.ledger-date { font-size: .82rem; margin-bottom: 0; white-space: normal; }
    table.data-table.ledger-table td.ledger-date::before { content: attr(data-label); }
    .ledger-table td:last-child { position: absolute; top: .55rem; right: .6rem; padding: 0; }
    .ledger-table td:last-child::before { content: none; }
    /* Fakturans chip är en länk — en hel träffyta på telefon. */
    .ledger-description .ledger-invoice-chip { min-height: 44px; margin: .35rem 0 0; }
    .ledger-description b { display: block; }
    .ledger-description .chip { margin: .35rem .4rem 0 0; }
}


/*
|--------------------------------------------------------------------------
| Översikten
|--------------------------------------------------------------------------
|
| Startsidan (kort #11): nyckeltalen som stat-rutor, korten för det som
| väntar och prognosen. Prognostabellen lånar Ekonomis månadstabell
| (.ledger-months) och förblir en tabell på telefon.
|
*/
/* Nyckeltalsrutorna fyller radens höjd, och helåret står längst ned i dem
   alla, i linje med Netto-rutans botten. */
.overview-stats .stat { display: flex; flex-direction: column; }
.overview-stats .stat .card-body { flex: 1; display: flex; flex-direction: column; }

/* Raderna i rutorna bär etiketter som "Totalt (nu + inkommande)" (Excels
   egna ord) och "Helår inkl. kommande", som inte får brytas på två rader:
   ett belopp bredvid en halv etikett läses fel. Därför får Netto-rutan mer
   bredd än de tre andra, raderna är något mindre, och fyra rutor i bredd
   kräver 1401 px — därunder står de två och två, och under 820 px en och
   en (samma gräns som .grid.cols-4). */
@media (min-width: 1401px) {
    .grid.cols-4.overview-stats { grid-template-columns: repeat(3, minmax(0, 1fr)) minmax(0, 1.2fr); }
}
@media (max-width: 1400px) {
    .grid.cols-4.overview-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 820px) {
    .grid.cols-4.overview-stats { grid-template-columns: minmax(0, 1fr); }
}
.overview-stats .ledger-facts { font-size: .8rem; gap: .4rem .6rem; }
.overview-year { margin-top: auto; padding-top: 1rem; }
.overview-net .ledger-facts { margin-top: .9rem; }
.overview-more {
    display: inline-flex; align-items: center; gap: .3rem; align-self: flex-start;
    margin-top: auto; padding-top: .9rem;
    font-size: .85rem; font-weight: 600;
}

/* Prognosens ruta behåller sin egen höjd bredvid den långa tabellen. */
.overview-forecast { align-items: start; }
.overview-recurring .overview-more { display: flex; width: max-content; margin-top: 0; }

.overview-recurring .hero { margin-top: .35rem; }
.overview-recurring .hero .unit { font-size: 1.2rem; font-weight: 600; color: var(--ink-3); margin-left: .25rem; }
.overview-recurring .hint { font-size: .8rem; color: var(--ink-3); margin: .75rem 0 0; }

.overview-waiting { align-items: start; }
.overview-empty { padding: 1.75rem 1.35rem; }
.overview-table td { vertical-align: top; --cell-top: 1; }
.overview-table .status { margin-top: .25rem; }
.overview-table tfoot td { border-bottom: 0; font-weight: 600; }

.overview-forecast-table tbody tr.is-empty td { color: var(--ink-3); }

/* Ett fel i en del: luft runt larmet, som runt ett kort. */
.content > .overview-error { margin: 1.25rem 0; }

@media (max-width: 700px) {
    /* Länkarna i rutorna är hela träffytor på telefon. */
    .overview-more { min-height: 44px; padding-top: .4rem; }
}


/*
|--------------------------------------------------------------------------
| E-postmallar (Verktyg)
|--------------------------------------------------------------------------
*/

.email-templates {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 340px), 1fr));
    gap: 1.25rem;
}
.email-template-card h2 a { color: inherit; }
.email-template-description { margin: 0 0 1rem; }

/* Etikett och värde i två spalter — listans kort och förhandsvisningen. */
.email-template-facts, .email-log-facts {
    display: grid; grid-template-columns: max-content minmax(0, 1fr);
    gap: .35rem 1rem; margin: 0 0 1rem; font-size: .88rem;
}
.email-template-facts dt, .email-log-facts dt { color: var(--ink-3); }
.email-template-facts dd, .email-log-facts dd { margin: 0; overflow-wrap: anywhere; }
.email-log-facts { margin: 0; }
/* Länkar ärver färgen i CRM:et — i en faktaruta måste de synas som länkar. */
.email-log-facts a { text-decoration: underline; text-underline-offset: 2px; }

/* Mallen till vänster, förhandsvisningen till höger — under varandra på smal skärm. */
.email-template-editor {
    display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
    gap: 1.25rem; align-items: start;
}
@media (max-width: 1100px) { .email-template-editor { grid-template-columns: minmax(0, 1fr); } }

.field textarea.email-template-body { min-height: 18rem; resize: vertical; line-height: 1.5; font-size: .9rem; }

.email-template-placeholders h3 { margin: 0 0 .2rem; font-size: .82rem; font-weight: 600; color: var(--ink-2); }
.email-template-placeholders > p { margin: 0 0 .6rem; }
.email-template-placeholders ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .4rem; }
.email-template-placeholders li { display: flex; align-items: baseline; gap: .6rem; }
.placeholder-token {
    flex: 0 0 auto;
    padding: .15rem .5rem; border-radius: 6px;
    border: 1px dashed var(--border-strong); background: var(--surface-2);
    font: inherit; font-size: .8rem; font-weight: 600; color: var(--ink);
    cursor: pointer;
}
.placeholder-token:hover, .placeholder-token:focus-visible { border-color: var(--brand); border-style: solid; background: var(--brand-wash); }

.email-template-actions { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: 1.35rem; }

.email-template-preview-body, .email-log-text {
    margin: 0; padding: 1rem;
    white-space: pre-wrap; overflow-wrap: anywhere;
    font: inherit; font-size: .9rem; line-height: 1.55; color: var(--ink);
    background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.email-template-preview-issue { margin: .75rem 0 0; font-size: .85rem; color: var(--critical); }
.email-template-preview-note { margin: .75rem 0 0; }

@media (max-width: 820px) {
    /* 44 px träffyta på telefon. */
    .placeholder-token { min-height: 44px; padding: .4rem .7rem; }
    .email-template-placeholders li { flex-direction: column; align-items: flex-start; gap: .15rem; }
}

/* Förhandsvisningen: mejlet i en iframe på vit botten — ett mejl är ljust
   hos mottagaren oavsett CRM:ets tema. Textversionen på en egen flik. */
.email-template-preview-tabs, .email-log-tabs { margin-bottom: .75rem; }
.email-template-preview-frame, .email-log-frame {
    display: block; width: 100%; min-height: 160px;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: #fff;
}

/* E-postloggen: listan och ett utskick. */
.email-log-table td { vertical-align: top; --cell-top: 1; }
.email-log-recipient, .email-log-subject { overflow-wrap: anywhere; }
.email-log-recipient { min-width: 240px; }
.email-log-subject { min-width: 200px; }
.email-log-error { color: var(--critical); }
.email-log-acknowledged { margin-top: .2rem; }
.email-log-acknowledge { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; margin-top: 1rem; }
.email-log-title { overflow-wrap: anywhere; }

@media (max-width: 700px) {
    .email-log-recipient, .email-log-subject { min-width: 0; }

    /* Kortets rubrik är ämnet, inte tidpunkten: raden läggs om, och
       tidpunkten får sin etikett tillbaka. */
    table.email-log-table tr { display: flex; flex-direction: column; }
    table.email-log-table td.email-log-subject { order: -1; font-size: 1rem; margin-bottom: .5rem; }
    table.email-log-table td.email-log-subject::before { content: none; }
    table.email-log-table td:first-child { font-size: inherit; margin-bottom: 0; }
    table.email-log-table td:first-child::before { content: attr(data-label); }
}

/* TinyMCE i ett formulärfält: samma kant som fälten runt om. */
.field .tox.tox-tinymce { border: 1px solid var(--border-strong); border-radius: var(--radius-sm); }
.field.has-error .tox.tox-tinymce { border-color: var(--critical); }


/*
|--------------------------------------------------------------------------
| Demos
|--------------------------------------------------------------------------
*/

.demos-table td { vertical-align: top; --cell-top: 1; }
.demos-company { min-width: 200px; }
.demos-filter .filter-search { flex-basis: 320px; }
.demos-response .chip { margin-left: .3rem; gap: .25rem; }
.demos-signals .chip { gap: .25rem; margin-top: .25rem; }
.demos-table .is-ended-row td { opacity: .6; }

.demos-actions form { display: inline-flex; }
.page-head .lead .nowrap { white-space: nowrap; }
/* Tre små tal: bredvid varandra även på en telefon. */
.demo-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1rem; margin-bottom: 1rem; }
.demo-stats .value.demo-stat-date { font-size: 1.25rem; }
.demo-pages { margin-top: .5rem; }
.demo-forms { margin-top: 1rem; }
.demo-mail-table td { vertical-align: top; --cell-top: 1; overflow-wrap: anywhere; }
/* Kontaktad personligen (#75) — överst i Utskick, före mejlen. */
.demo-contacted { display: flex; flex-direction: column; gap: .6rem; }
.demo-contacted + .table-wrap { border-top: 1px solid var(--border); }
.demo-contacted-head { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem .75rem; }
.demo-contacted-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.demo-contacted-actions form { display: inline-flex; }
.demos-remind { margin-top: .25rem; padding: .1rem .45rem; font-size: .7rem; }
.demo-sources { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .7rem; }
.demo-sources a { display: inline-flex; align-items: center; gap: .35rem; overflow-wrap: anywhere; }
.demo-sources .demo-source-place { font-size: .85rem; overflow-wrap: anywhere; }
.demos-responses { border: 0; padding: 0; margin: 0 0 .75rem; }
.demos-responses .choice { padding: .35rem .6rem; }

/* Översiktens Pipeline: två grupper bredvid varandra, under varandra på smal skärm. */
.overview-pipeline-groups { gap: 0; }
.overview-pipeline-group { min-width: 0; padding-bottom: .5rem; }
.overview-pipeline-group + .overview-pipeline-group { border-left: 1px solid var(--border); }
.overview-pipeline-title { font-size: .9rem; margin: 1rem 1.35rem .5rem; }
.overview-pipeline-empty { margin: 0 1.35rem 1rem; }

@media (max-width: 820px) {
    .overview-pipeline-group + .overview-pipeline-group { border-left: 0; border-top: 1px solid var(--border); }
}

@media (max-width: 700px) {
    /* Kompakt kort: företaget överst i full bredd, sedan två värden per rad. */
    table.data-table.demos-table tr {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        column-gap: .75rem;
    }
    .demos-table td:first-child { grid-column: 1 / -1; }
    .demo-stats { gap: .5rem; }
    .demo-stats .stat .value { font-size: 1.4rem; }
    .demo-stats .stat .value.demo-stat-date { font-size: .95rem; }
    .demo-stats .stat .label { font-size: .68rem; }
}


/*
|--------------------------------------------------------------------------
| Sajter
|--------------------------------------------------------------------------
*/

.sites-table td { vertical-align: top; --cell-top: 1; }
.sites-name { min-width: 200px; }
.sites-name a { overflow-wrap: anywhere; }
.sites-filter .filter-search { flex-basis: 320px; }
.sites-customer .chip { gap: .25rem; }
.sites-table .is-ended-row td { opacity: .6; }

/* Trenden bredvid besöken: samma färger som stat-rutornas delta. */
.sites-trend { font-weight: 600; color: var(--ink-3); margin-left: .25rem; }
.sites-trend.up { color: var(--good); }
.sites-trend.down { color: var(--critical); }

.sites-periods { margin-bottom: 1rem; }
/* Luften mellan korten i spalterna ger .sites-layout (regeln vid .customer-layout). */

.sites-table-details { padding: 0 1.35rem 1rem; }
.sites-table-details summary { cursor: pointer; color: var(--ink-2); padding: .75rem 0; }
.sites-stats .stat .label { hyphens: manual; }
.sites-table-details .table-wrap { margin: .5rem -1.35rem 0; }

/* Staplar i listform: etikett och värde på en rad, banan under. */
.sites-bars { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .8rem; }
.sites-bars li { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: .3rem .75rem; align-items: baseline; }
.sites-bars-label { font-size: .88rem; overflow-wrap: anywhere; }
.sites-bars-value { font-size: .88rem; font-weight: 650; }
.sites-bars-track { grid-column: 1 / -1; height: 6px; border-radius: 3px; background: var(--grid-line); overflow: hidden; }
.sites-bars-fill { display: block; height: 100%; border-radius: 3px; background: var(--series-1); }

.sites-customer-table td form { display: inline-flex; }

/* Head-kod och cookies (kort #19). Verifieringen är ett långt ord utan mellanslag. */
.sites-head-token { font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: .82rem; overflow-wrap: anywhere; }
.sites-head-code { font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: .85rem; }
.sites-head-grid { gap: 0 1rem; }

/* Meddelanden (kort #17): en rad per svar som fälls ut. */
.sites-forms { list-style: none; margin: 0; padding: 0; }
.sites-forms li + li { border-top: 1px solid var(--border); }
.sites-forms summary { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: .25rem 1rem; padding: .85rem 1.35rem; cursor: pointer; min-height: 44px; }
.sites-forms summary:hover { background: var(--surface-2); }
.sites-forms-who { min-width: 0; overflow-wrap: anywhere; }
.sites-forms-body { padding: 0 1.35rem 1.1rem; }
.sites-forms-message { margin-top: .75rem; white-space: pre-wrap; }
.sites-forms-files { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .75rem; }
.sites-forms-files img { display: block; width: 120px; height: 90px; object-fit: cover; border-radius: var(--radius-sm); border: 1px solid var(--border); }

@media (max-width: 700px) {
    /* Kompakt kort: sajten överst i full bredd, sedan två värden per rad. */
    table.data-table.sites-table tr {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        column-gap: .75rem;
    }
    .sites-table td:first-child { grid-column: 1 / -1; }
    .sites-table td.right { text-align: left; }

    /* Fyra små tal: två och två även på en telefon. */
    .grid.cols-4.sites-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .6rem; }
    .sites-stats .stat .value { font-size: 1.4rem; }
    .sites-stats .stat .label { font-size: .68rem; }
    .sites-stats .stat .delta { font-size: .75rem; }
}


/*
|--------------------------------------------------------------------------
| Demo-mallar (Verktyg, kort #91)
|--------------------------------------------------------------------------
|
| Ett rutnät med kort: skärmdumpen överst, sedan adressen, branscherna,
| anteckningen och sajterna som använt mallen.
|
*/

.demo-templates-missing { align-items: center; margin-bottom: 1.25rem; }
.demo-templates-missing .btn { margin-left: auto; flex: 0 0 auto; }

.demo-templates-grid {
    list-style: none; margin: 0; padding: 1.1rem 1.35rem 1.35rem;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
    gap: 1.1rem;
}
.demo-template {
    display: flex; flex-direction: column; min-width: 0;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface); overflow: hidden;
}
.demo-template.is-hidden-row .demo-template-shot,
.demo-template.is-hidden-row .demo-template-notes { opacity: .55; }

.demo-template-shot {
    display: block; aspect-ratio: 1440 / 1000;
    background: var(--surface-2); border-bottom: 1px solid var(--border);
}
.demo-template-shot img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: top; }
.demo-template-noshot {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: .4rem; height: 100%; color: var(--ink-3);
}

.demo-template-body { display: flex; flex-direction: column; gap: .55rem; padding: .25rem .85rem .9rem; min-width: 0; }
.demo-template-head { display: flex; align-items: center; gap: .5rem; margin-right: -.4rem; }
/* Hela raden är länken (44 px hög); en lång adress kortas med … och ikonen står kvar. */
.demo-template-url {
    flex: 1 1 auto; min-width: 0; min-height: 44px;
    display: flex; align-items: center; gap: .3rem;
    font-weight: 600; color: var(--ink);
}
.demo-template-url-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.demo-template-url .icon { flex: 0 0 auto; color: var(--ink-3); }
.demo-template-url:hover { color: var(--brand-deep); }
.demo-template-all { background: transparent; border: 1px dashed var(--border-strong); }

/* Anteckningen på högst tre rader — hela texten står i rutan. */
.demo-template-notes {
    margin: 0; color: var(--ink-2);
    display: -webkit-box; -webkit-line-clamp: 3; line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.demo-template-uses { margin-top: auto; line-height: 1.7; overflow-wrap: anywhere; }
.demo-template-use .chip { font-size: .65rem; vertical-align: 1px; }

/* Rutan: branscherna som kryssrutor i tre spalter. */
.demo-templates-industries-field { border: 0; margin: 0 0 1rem; padding: 0; min-width: 0; }
.demo-templates-industries-field legend { padding: 0; margin-bottom: .4rem; }
.demo-templates-industries {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: .1rem .75rem;
}

@media (max-width: 700px) {
    .demo-templates-grid { padding: .9rem; }
    .demo-templates-industries { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .demo-templates-missing { flex-wrap: wrap; }
    .demo-templates-missing .btn { margin-left: 0; }
}
