/* Bambatjänst — globalt formspråk (Fas 7).
   Ersätter den handskrivna Material Design 3-stilen (m3.css) helt.

   Färgtokens delas med Tailwind (laddas som CDN-script i base.html) via
   tailwind.config — se base.html. Den här filen täcker det Tailwind-
   utility-klasser inte når utan att ändra forms.py/vyerna: råa
   <button>/<input>/<select>/<textarea> från Djangos formulärrendering
   ({{ form.as_p }} m.fl.) och några återanvända komponentklasser (kort,
   chip, lista, dialog …). Medvetet ljust — inget mörkt läge, se
   konversationen om kortomdesignen.

   OBS specificitet: Tailwinds CDN-script injicerar sin "preflight"-reset
   (button/input/h1-h3/a m.fl. nollställda) som ett eget <style>-element
   SENARE i dokumentet än den här filens <link> — även med
   corePlugins.preflight satt till false i tailwind.config (Play CDN
   respekterar inte det tillförlitligt). Vid lika specificitet vinner
   senare källordning, så Tailwinds reset skulle annars tysta våra rena
   taggselektorer. Lösningen: alla taggselektorer nedan som konkurrerar med
   preflight är prefixade med "body" för en högre specificitetsnivå — INTE
   kosmetiskt, ta inte bort prefixet. Klasselektorer (.btn, .card, …) är
   redan högre specificitet än preflightens taggselektorer och behöver det
   inte. */

:root {
    --layout-max-width: 1350px;

    --surface: #FFFFFF;
    --surface-soft: #F7F8F5;
    --primary: #16A34A;
    --primary-strong: #15803D;
    --on-primary: #FFFFFF;
    --primary-tint: #DCFCE7;
    --on-primary-tint: #166534;
    --ink: #1C1917;
    --ink-soft: #57534E;
    --ink-faint: #A8A29E;
    --line: #E7E5E4;
    --line-soft: #F2F1F0;
    --error: #DC2626;
    --error-tint: #FEE2E2;
    --on-error-tint: #991B1B;

    --shadow-1: 0 1px 2px rgba(28, 25, 23, .06), 0 1px 3px rgba(28, 25, 23, .08);
    --shadow-2: 0 1px 3px rgba(28, 25, 23, .1), 0 8px 20px -6px rgba(28, 25, 23, .18);
}

/* --- Bas --- */

* { box-sizing: border-box; }

html { color-scheme: light; }

body {
    margin: 0;
    font-family: "Plus Jakarta Sans", system-ui, -apple-system, 'Segoe UI', sans-serif;
    font-size: 16px;
    line-height: 1.5;
    background: var(--surface);
    color: var(--ink);
}

body h1, body h2, body h3 { font-weight: 700; line-height: 1.25; margin: 0 0 .75rem; }
body h1 { font-size: 1.75rem; }
body h2 { font-size: 1.25rem; margin-top: 2rem; }
body h3 { font-size: 1.05rem; }

body a { color: var(--primary-strong); }
body a:visited { color: var(--primary-strong); }

.container {
    max-width: var(--layout-max-width);
    margin: 0 auto;
    padding: 1rem 1rem 3rem;
}

/* --- Knappar --- */

/* .btn-outline/.btn-text delas in i basregeln också — annars saknar en
   <a class="btn-outline"/"btn-text"> (utan .btn också) padding/rundade
   hörn, som annars bara kommer från "button"-elementselektorn eller .btn. */
body button,
.btn,
.btn-outline,
.btn-text {
    font-family: inherit;
    font-size: .875rem;
    font-weight: 700;
    border-radius: 999px;
    padding: .625rem 1.5rem;
    /* border-width (inte "border: none") — annars nollställs även
       border-style, som Tailwinds .border/.border-* utility-klasser
       (bara bredd/färg) förlitar sig på att preflight satt till "solid";
       en knapp som bara har Tailwind-klasser (ingen .btn-outline) och
       vill ha en synlig kant tappar den annars trots border-width/color. */
    border-width: 0;
    border-style: solid;
    cursor: pointer;
    background: var(--primary);
    color: var(--on-primary);
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    text-decoration: none;
    line-height: 1.2;
}

/* En <a class="btn"> som redan besökts blev GRÖN TEXT PÅ GRÖN BOTTEN.
   Orsak: `body a:visited` ovan har specificitet (0,1,1) — `:visited`
   räknas i klass-kolumnen — och slår därför .btn (0,1,0). Det drabbade
   VARJE knapp-liknande länk i appen så fort man klickat på den en gång,
   vilket är varför det såg slumpmässigt ut.

   Regler med :visited här ger (0,2,0) och vinner tillbaka. Lägg till
   samma :visited-variant om en ny knappklass tillkommer. */
.btn:visited { color: var(--on-primary); }
.btn-outline:visited { color: var(--ink-soft); }
.btn-text:visited { color: var(--primary-strong); }
.btn-danger:visited { color: #fff; }

body button:hover, .btn:hover { box-shadow: var(--shadow-1); }
body button:disabled { opacity: .5; cursor: default; box-shadow: none; }

.btn-outline {
    background: transparent;
    color: var(--ink-soft);
    border: 1px solid var(--line);
}
.btn-outline:hover { background: var(--surface-soft); box-shadow: none; }

.btn-text {
    background: transparent;
    color: var(--primary-strong);
    padding: .625rem .75rem;
}
.btn-text:hover { box-shadow: none; text-decoration: underline; }

.btn-danger { background: var(--error); color: #fff; }

/* Tangentbordsfokus i appens egen färg. Utan den här regeln ritar
   webbläsaren sin egen ring — i Chrome en blå — vilket syntes tydligast
   på guidens ✕, eftersom en <dialog> ger fokus till sitt första
   fokuserbara element när den öppnas. :focus-visible, inte :focus, så
   ringen bara dyker upp vid tangentbordsnavigering och inte vid musklick. */
:focus-visible {
    outline: 2px solid var(--primary-strong);
    outline-offset: 2px;
    border-radius: 4px;
}

/* --- Planeringsläget: kort på tonad yta ---------------------------
   Planeraren är en riktig sida (?planera=1) — egen adress, bakåtknapp,
   överlever omladdning — men ramas in som ett kort så den känns som ett
   eget läge. Appens topprad står kvar oskymd ovanför.

   Se planerings-prototypens variant E för hur valet gjordes, och varför
   telefonen får kant i kant i stället för 16 px tonad kant. */
.plan-stage {
    background: rgba(28, 25, 23, .38);
    min-height: calc(100vh - 57px); /* 57px = toppradens höjd i base.html */
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem 1rem;
}
.plan-card {
    background: var(--surface);
    border-radius: 20px;
    box-shadow: var(--shadow-2);
    width: min(1100px, 100%);
    max-height: calc(100vh - 57px - 3rem);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.plan-card-head {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: .875rem 1.25rem;
    border-bottom: 1px solid var(--line);
    flex: 0 0 auto;
}
.plan-card-body {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 1.25rem;
}
.plan-head-short { display: none; }

@media (max-width: 640px) {
    /* Kant i kant. 16 px tonad bakgrund runt kortet ser inte ut som ett
       kort, det ser ut som ett misstag — och bredden behövs bättre till
       innehållet. */
    .plan-stage { padding: 0; align-items: stretch; background: var(--surface); }
    .plan-card {
        border-radius: 0;
        box-shadow: none;
        width: 100%;
        max-height: none;
        flex: 1 1 auto;
    }
    .plan-card-body { padding: 1rem; }
    /* "Planerar vecka 41" radbryter till två rader på 390 px och gör
       rubriken 21 px högre för ingenting. */
    .plan-head-long { display: none; }
    .plan-head-short { display: inline; }
}

/* AI-kommentarens hopfällda rad: alltid två rader hög, oavsett om den är
   tom, kort eller lång. Kortet ska ha samma höjd före och efter ett
   förslag — annars hoppar allt under det när kommentaren kommer in.
   Hela texten syns när man fäller ut kortet. */
.ai-comment-summary {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    min-height: 3em;
}
details[open] .ai-comment-summary { -webkit-line-clamp: unset; }

/* Bara för skärmläsare — notisbubblan är en färgad prick utan text, och
   en prick säger ingenting den vägen. */
.sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border-width: 0;
}

/* Notisbubbla på en flik/rubrik: "det finns något att göra där borta".
   Föräldern måste vara position: relative. */
.notif-dot {
    position: absolute;
    top: -.125rem;
    right: -.125rem;
    width: .5rem;
    height: .5rem;
    border-radius: 999px;
    background: var(--error);
    box-shadow: 0 0 0 2px var(--surface);
}

/* --- Inköpslistan ---
   Rader man bockar av stående i en butik: hela raden är tappytan (minst
   44 px hög), och den kan dras åt vänster för att tas bort (se
   static/js/shopping-list.js). `overflow: hidden` på raden håller
   dragningen innanför panelens kant. */
.shopping-row {
    position: relative;
    display: flex;
    align-items: center;
    gap: .25rem;
    border-bottom: 1px solid var(--line-soft);
    overflow: hidden;
    transition: transform .18s ease;
    background: var(--surface);
}
.shopping-row:last-child { border-bottom: 0; }

body .shopping-row-toggle {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: flex-start;
    gap: .625rem;
    text-align: left;
    background: transparent;
    color: var(--ink);
    font-weight: 400;
    font-size: .9375rem;
    border-width: 0;
    border-radius: .5rem;
    padding: .6875rem .5rem;
    min-height: 44px;
    cursor: pointer;
}
body .shopping-row-toggle:hover { box-shadow: none; background: var(--surface-soft); }

/* Rutan är ritad i CSS, inte en <input type=checkbox> — hela raden är
   knappen, och en riktig kryssruta inuti en knapp hade tagit emot sitt
   eget klick och togglat två gånger. */
.shopping-check {
    flex: 0 0 auto;
    width: 1.25rem;
    height: 1.25rem;
    margin-top: .0625rem;
    border: 2px solid var(--line);
    border-radius: 999px;
    position: relative;
}
.shopping-row.is-checked .shopping-check {
    background: var(--primary);
    border-color: var(--primary);
}
.shopping-row.is-checked .shopping-check::after {
    content: '';
    position: absolute;
    left: .3125rem; top: .0625rem;
    width: .3125rem; height: .625rem;
    border: solid var(--on-primary);
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}
.shopping-row.is-checked .shopping-row-text {
    text-decoration: line-through;
    color: var(--ink-faint);
}

body .shopping-row-delete {
    flex: 0 0 auto;
    background: transparent;
    color: var(--ink-faint);
    border-width: 0;
    border-radius: 999px;
    padding: 0;
    width: 36px;
    min-height: 44px;
    font-size: .875rem;
    cursor: pointer;
}
body .shopping-row-delete:hover { box-shadow: none; background: var(--surface-soft); color: var(--error); }

/* "Ändra"-läget: markeringsruta och draghandtag finns bara då, och raden
   slutar bete sig som en avbockningsknapp (se shopping-list.js). */
.shopping-row-select,
.shopping-row-handle { display: none; }
#shopping-list-root.editing .shopping-row-select { display: inline-block; margin-left: .5rem; }
#shopping-list-root.editing .shopping-row-handle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    min-height: 44px;
    color: var(--ink-faint);
    cursor: grab;
    user-select: none;
}
#shopping-list-root.editing .shopping-row-delete { display: none; }
#shopping-list-root.editing .shopping-row-toggle { cursor: default; }
#shopping-list-root.editing .shopping-check { opacity: .35; }
.shopping-row.is-dragging { opacity: .4; }

/* "body button" ger display: inline-flex, som vinner över webbläsarens
   [hidden] vid lika specificitet — samma fälla som #toast-undo. */
#shopping-clear-checked[hidden], #shopping-delete-selected[hidden] { display: none; }

/* --- Stjärnbetyg ---
   Egen regel eftersom "body button" ovan ger VARJE knapp den gröna,
   fyllda pillerformen — en stjärna måste nollställa bakgrund, padding
   och radie själv. Tappytan är minst 44 px hög (samma mått som
   dragreglagen i veckoplaneraren) trots att glyfen är liten. */
.star-row { display: inline-flex; align-items: center; gap: .125rem; }
body .star-btn {
    background: transparent;
    border-width: 0;
    padding: 0 .125rem;
    min-width: 32px;
    min-height: 44px;
    border-radius: .5rem;
    font-size: 1.5rem;
    line-height: 1;
    color: var(--line);
    cursor: pointer;
}
body .star-btn:hover { box-shadow: none; background: var(--surface-soft); }
body .star-btn.filled { color: #E8A33D; }

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

body label { font-size: .875rem; color: var(--ink-soft); }

body input[type=text], body input[type=number], body input[type=url], body input[type=password],
body input[type=email], body textarea, body select {
    font-family: inherit;
    font-size: 1rem;
    color: var(--ink);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 8px;
    padding: .625rem .75rem;
    width: 100%;
    max-width: 100%;
}

body input:focus, body textarea:focus, body select:focus {
    outline: 2px solid var(--primary);
    outline-offset: -1px;
}

body textarea { resize: vertical; }

body input[type=checkbox], body input[type=radio] {
    width: 1.15rem;
    height: 1.15rem;
    accent-color: var(--primary);
    vertical-align: middle;
}

form p, #cell-editor-fields p { margin: 0 0 1rem; }
form p > label, #cell-editor-fields p > label { display: block; margin-bottom: .25rem; }

.helptext { display: block; font-size: .75rem; color: var(--ink-faint); margin-top: .25rem; }
.errorlist { list-style: none; padding: 0; margin: .25rem 0; color: var(--error); font-size: .8125rem; }

/* Litet rensa-kryss inuti receptfältet (cell-editor-recipe-clear). En
   <button> som ska vara dold via [hidden] tills fältet har ett värde —
   måste ha en egen [hidden]-override, se kommentaren vid .toast[hidden]
   nedan om varför (body button ovan sätter display: inline-flex som
   author-CSS, vilket annars trumfar [hidden] oavsett specificitet). */
.recipe-field-clear {
    position: absolute;
    top: 50%;
    right: .25rem;
    transform: translateY(-50%);
    width: 1.5rem;
    height: 1.5rem;
    padding: 0;
    background: transparent;
    color: var(--ink-soft);
    border-radius: 50%;
    font-size: .9rem;
    line-height: 1;
}
.recipe-field-clear:hover { background: var(--surface-soft); box-shadow: none; }
.recipe-field-clear[hidden] { display: none; }

/* --- Kort --- */

.card {
    background: var(--surface-soft);
    border-radius: 16px;
    padding: 1rem 1.25rem;
    margin-bottom: .75rem;
}

.card-outlined {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 16px;
    padding: 1rem 1.25rem;
    margin-bottom: .75rem;
}

/* --- Chips (taggar, filter, badges) --- */

.chip {
    display: inline-flex;
    align-items: center;
    padding: .25rem .75rem;
    border-radius: 999px;
    background: var(--surface-soft);
    color: var(--ink-soft);
    font-size: .8125rem;
    font-weight: 600;
    margin: 0 .25rem .25rem 0;
    text-decoration: none;
    border: none;
    cursor: default;
}
button.chip { cursor: pointer; }
a.chip { cursor: pointer; }
.chip.active { background: var(--primary); color: var(--on-primary); }

/* Samma :visited-fälla som .btn ovan, och av exakt samma skäl: receptlistans
   kategorifilter är <a class="chip">, och `body a:visited` (0,1,1) slår .chip
   (0,1,0) — en kategori man klickat en gång hade annars bytt till grön text.
   .chip.active (0,2,0) vinner redan över :visited av sig själv, men står med
   för att den inte ska gå sönder om basregeln någonsin får en klass till. */
.chip:visited { color: var(--ink-soft); }
.chip.active:visited { color: var(--on-primary); }

/* --- Meddelanden --- */

.messages { list-style: none; padding: 0; margin: 0 0 1rem; }
.messages li {
    padding: .75rem 1rem;
    border-radius: 8px;
    margin-bottom: .5rem;
    background: var(--primary-tint);
    color: var(--on-primary-tint);
}
.messages li.error { background: var(--error-tint); color: var(--on-error-tint); }

/* --- Listor --- */

.list { list-style: none; padding: 0; margin: 0; }
.list-item {
    display: flex;
    align-items: flex-start;
    gap: .75rem;
    padding: .75rem;
    border-bottom: 1px solid var(--line-soft);
}
.list-item:last-child { border-bottom: none; }
.list-item.selected { background: var(--primary-tint); color: var(--on-primary-tint); font-weight: 600; }

/* --- Receptbläddraren (delad av veckoplanerarens redigeringsdialog och
   sök-dropdownen) --- */

/* Måste ha position: relative — .recipe-field-clear (rensa-krysset)
   positioneras absolut inuti fältet. #recipe-quick-dropdown positioneras
   INTE mot den här (se kommentar i weekly_plan.html om varför — den är
   position: fixed med koordinater satta i JS istället). */
.recipe-quick-search { position: relative; }

.browser-filters { display: flex; flex-wrap: wrap; gap: .375rem; margin-bottom: .75rem; }
.browser-result { cursor: pointer; }
.browser-result:hover { background: var(--surface-soft); }
.browser-result.add-new { color: var(--primary-strong); font-style: italic; border-top: 1px dashed var(--line); }

/* --- Dialog --- */

body dialog {
    border: none;
    border-radius: 16px;
    padding: 1.5rem;
    background: var(--surface);
    color: var(--ink);
    box-shadow: var(--shadow-2);
    max-width: 420px;
    width: calc(100% - 2rem);
}
body dialog::backdrop { background: rgba(28, 25, 23, .45); }

#recipe-browse-dialog { max-width: 560px; max-height: calc(100vh - 4rem); overflow-y: auto; }
/* Introduktionen är bredare än de andra dialogerna: skärm 2 visar en hel
   veckoplan i två kolumner, och den blir obegriplig hoptryckt. */
#tutorial-dialog { max-width: 720px; width: calc(100% - 2rem); max-height: calc(100vh - 3rem); overflow-y: auto; }
/* Knappraden byter innehåll per skärm, och [hidden] räcker INTE: reglerna
   ovan ger varje button/.btn-* ett eget display, som vinner över
   webbläsarens [hidden] vid lika specificitet. Samma fälla som
   .recipe-field-clear[hidden] och #board[hidden] redan löser — den syntes
   här som alla fyra knapparna samtidigt på skärm 2. */
#tutorial-back[hidden], #tutorial-next[hidden],
#tutorial-store[hidden], #tutorial-done[hidden] { display: none; }

/* Butiksväljaren i guiden: bubblan har Tailwinds .inline-flex och
   kedjeraden .flex, som båda sätter display och därmed vinner över
   webbläsarens [hidden]. Samma fälla som resten av filen redan löser. */
#tutorial-store-chosen[hidden], #tutorial-store-provider[hidden] { display: none; }
/* Samma fälla en gång till: raderna i dela-dialogen har display via en
   inline-stil respektive Tailwinds .flex, som båda vinner över
   webbläsarens [hidden]. Utan det här syntes länkfältet även när veckan
   inte delades. */
#share-week-toggle-row[hidden], #share-week-link-row[hidden] { display: none; }

/* Samma fälla en gång till: "body button" ovan ger knappen
   display: inline-flex, som vinner över webbläsarens [hidden]. */
#week-rating-expand[hidden], .week-rating-expand[hidden] { display: none; }
#willys-dialog { max-width: 640px; max-height: calc(100vh - 4rem); overflow-y: auto; }

/* Sidopaneler (#shopping-list-panel, #willys-offers-panel i
   weekly_plan.html) — INTE <dialog>-element, egenbyggda "slide-in"-paneler
   via Tailwinds position: fixed-klasser. Behöver ett eget dolt
   standardläge: elementen ligger alltid i DOM:en (se mallkommentarerna om
   varför de inte gatas på "plan"/butiksval) och behöver därför en riktig
   av/på-övergång istället för att bara lita på .open att göra NÅGOT — utan
   den här regeln var #shopping-list-panel permanent synlig och "Stäng"
   hade ingen effekt alls (upptäckt en gång, se historiken ovan i filen —
   #willys-offers-panel fick samma regel direkt den här gången). */
#shopping-list-panel,
#willys-offers-panel {
    transform: translateX(100%);
    transition: transform .2s ease-out;
}
#shopping-list-panel.open,
#willys-offers-panel.open { transform: translateX(0); }

/* --- Formset-rader (recept-inline, ingredienser) --- */

.formset-row {
    background: var(--surface-soft);
    border-radius: 12px;
    padding: .75rem;
    margin-bottom: .5rem;
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    align-items: flex-end;
}
.formset-row label { display: flex; flex-direction: column; gap: .25rem; font-size: .75rem; flex: 1 1 120px; }

/* --- Enkel spinner för progress-indikatorer på knappar/länkar --- */

.spinner {
    display: inline-block;
    width: .875em;
    height: .875em;
    margin-right: .375rem;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    vertical-align: -.15em;
    animation: app-spin .6s linear infinite;
}
@keyframes app-spin { to { transform: rotate(360deg); } }

/* --- Ångra-toast (autosparning i veckoplaneraren) --- */

.toast {
    position: fixed;
    left: 50%;
    bottom: calc(1.5rem + env(safe-area-inset-bottom, 0px));
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    gap: .5rem;
    background: var(--ink);
    color: var(--surface);
    border-radius: 12px;
    box-shadow: var(--shadow-2);
    padding: .75rem 1rem;
    max-width: calc(100% - 2rem);
    z-index: 900;
}
.toast[hidden] { display: none; } /* se progress-overlay-kommentaren nedan om varför */
.toast #toast-message { font-size: .875rem; }
.toast .btn-text { color: var(--surface); }
#toast-undo[hidden] { display: none; } /* body button ovan sätter display: inline-flex — samma fälla som .recipe-field-clear ovan */

/* --- Helskärmsoverlay för långsamma anrop (10-20+ sekunder) — en liten
   spinner i en knapp är lätt att missa eller scrolla bort ifrån. Blockerar
   sidan tydligt och visar att arbete pågår tills nästa sida hunnit ladda. --- */

.progress-overlay {
    position: fixed;
    inset: 0;
    background: rgba(28, 25, 23, .45);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
}
/* [hidden] i webbläsarens standard-stilmall räcker inte ensam — den tävlar
   mot .progress-overlay:s "display: flex" ovan (author-CSS vinner alltid
   över UA-stilmallen oavsett specificitet) och skulle annars visa overlayn
   direkt vid sidladdning trots hidden-attributet. Högre specificitet här
   (klass + attribut) vinner tillbaka det. */
.progress-overlay[hidden] { display: none; }

.progress-overlay-card {
    background: var(--surface);
    color: var(--ink);
    border-radius: 16px;
    box-shadow: var(--shadow-2);
    padding: 2rem 2.5rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
    text-align: center;
    /* Bredd (inte bara max-bredd) — annars ändrar sig kortets storlek
       märkbart mellan meddelanden, t.ex. när "Det här kan ta upp till en
       minut"s cyklande "."/".."/"..."-svans (se showProgressOverlay i
       base.html) råkar knuffa texten till en extra rad vid vissa
       punktantal men inte andra. calc(...)-fallbacken håller den smalare
       än viewporten på mycket smala skärmar. */
    width: 22rem;
    max-width: calc(100% - 2rem);
}

.progress-overlay-spinner {
    display: inline-block;
    width: 2.5rem;
    height: 2.5rem;
    border: 4px solid var(--line);
    border-right-color: var(--primary);
    border-radius: 50%;
    animation: app-spin .8s linear infinite;
}

.progress-overlay-text { font-weight: 700; }

/* Lista över det som FAKTISKT blivit klart under väntan (kontrollerade
   receptkandidater, se addProgressOverlayItem i base.html). Fylls på
   uppifrån och ned; max-height + overflow så kortet aldrig växer förbi
   skärmen när en lång sökrunda hittar många kandidater — den fasta
   bredden på kortet ovan gäller fortfarande, därför bryts långa titlar
   istället för att tvinga fram en horisontell scroll. */
.progress-overlay-list {
    list-style: none;
    margin: 0;
    padding: .75rem 0 0;
    border-top: 1px solid var(--line);
    width: 100%;
    max-height: 9.5rem;
    overflow-y: auto;
    text-align: left;
    font-size: .8125rem;
    line-height: 1.45;
    overflow-wrap: anywhere;
}
.progress-overlay-list[hidden] { display: none; }
.progress-overlay-list li { color: var(--ink); }
/* Kontrollerad men bortvald kandidat — dämpad, inte dold: den förklarar
   varför sökrundan tar tid. */
.progress-overlay-list li.rejected { color: var(--ink-faint); }

/* --- Cellernas väntelägen medan ett AI-förslag hämtas/sparas ---
   Båda klasserna sätts från weekly_plan.html. Knapparna är `disabled`
   hela tiden (man ska inte kunna redigera en cell mitt i en omgång), och
   `body button:disabled` ovan ger dem `opacity: .5` — det gjorde ÄVEN de
   celler som redan hade en läsbar förhandsvisad titel bleka och
   "utgråade" (Ludwigs observation). Därför skiljer vi på de två lägena:
   ett tomt skelett ska se ut att ladda, en förhandsvisning ska synas. */

.cell-summary-button.skeleton {
    /* Pulserar mjukt istället för att bara stå blank och halvgenomskinlig. */
    animation: app-skeleton-pulse 1.2s ease-in-out infinite;
    min-height: 3.25rem;
    border-radius: 10px;
    opacity: 1;
}
.cell-summary-button.cell-preview:disabled {
    /* Har riktigt innehåll att visa — ska inte dimmas som ett tomt
       skelett. Den streckade dagskortkanten (.day-unplanned) räcker som
       "ännu inte sparat"-signal. */
    opacity: 1;
}
@keyframes app-skeleton-pulse {
    0%, 100% { background: var(--line-soft); }
    50% { background: var(--line); }
}

/* Delrubrik i ett recept (t.ex. "Potatismos") över ingredienser/steg. */
.recipe-part-heading {
    margin: 1rem 0 .25rem;
    font-size: .9375rem;
    font-weight: 700;
    color: var(--primary-strong);
}
.recipe-part-heading:first-child { margin-top: 0; }

/* Prompt-rutans rubrikrad (#ai-prompt-details > summary): hopfälld visar
   den din senaste prompt, utfälld en statisk rubrik. Utan det här stod
   samma text två gånger — i rubriken och i textrutan direkt under. */
#ai-prompt-details[open] .prompt-summary-collapsed { display: none; }
#ai-prompt-details:not([open]) .prompt-summary-open { display: none; }
