/* KIND 2.0 patient-portal overrides
 *
 * Owner: frontend-web (per docs/contracts/file-ownership.md).
 * Scope: patient surface only. Loaded after kind.css via the
 *        {% block per_domain_css %} hook in base.html.
 * Why a separate file: patient surface skews older + lower-vision than
 *        the average user. Larger body type by default, more whitespace,
 *        warmer surfaces. Admin gets its own override in W2-14.
 */

.kind-body--patient {
  --kind-font-base: 1.125rem;            /* 18px, one tick larger than admin */
  /* Classic+ (ADR-065 §D1, CP-02): the patient surface carries the SAME cool
     clinical bearing surfaces as the rest of the product. The warm blush that
     used to sit here came from hue-matching the MARKETPLACE (www.kind.app), not
     the product; see the long note in kind.css §1 Tokens before changing it back.
     What is NOT changed: the larger 18px body and the 1.6 line-height. The
     patient surface skews older and lower-vision, and ADR-065 §D4 reads the
     brief's "16px body" as a FLOOR, never a ceiling, so no existing floor is
     lowered on the surface where that would do the most harm. */
  --kind-color-bg: #F5F7FA;
  --kind-color-surface: #FFFFFF;
  --kind-color-surface-muted: #EBEFF4;
  --kind-line-height: 1.6;
}

/* CP-03 (issue #88, ADR-065 §D6.1): attribute, not media query. The body-level
   re-declaration is still needed even though kind.css sets the same tokens on
   <html>: a declaration on the BODY wins for the body subtree by inheritance,
   so without this the patient surface would keep its light bearing surfaces
   inside a dark page. See the long note in kind.css §1a. */
html[data-kind-theme="dark"] .kind-body--patient {
  /* Classic+ DARK bearing surfaces, identical to kind.css §1a. The values are
     repeated rather than referenced because a CSS custom property cannot be
     re-declared by reference to its own <html>-level value from a body-level
     rule; the drift-guard is the matrix generator's control 8, which parses
     BOTH files and fails if these three ever diverge from the dark set. */
  --kind-color-bg: #12161B;
  --kind-color-surface: #1A2028;
  --kind-color-surface-muted: #232B34;
}

/* ----------------------------------------------------------------------------
 * Patient bottom tab bar (iOS chat-native pivot, 2026-06-24)
 *
 * Matches the real KIND iOS app: exactly 3 tabs (Meddelanden / Bibliotek / Mer)
 * fixed to the bottom of the viewport, icon over label, active tab in the
 * accent colour. Rendered in base.html for nav_role=='patient', replacing the
 * old top nav + "Mer" dropdown.
 *
 * A11y (WCAG 2.2 AA):
 *  - each tab is a min 56px-tall link (well over 2.5.8 24px + the patient 48px
 *    floor; the older/lower-vision patient surface);
 *  - label is ALWAYS visible text under the icon (never icon-only -> 4.1.2 ok);
 *  - active tab carries aria-current="page" (set in base.html) AND a visible
 *    accent colour + top accent rule, so state is not colour-only;
 *  - visible focus ring (2.4.7); the icon inherits the link colour (currentColor)
 *    so it goes accent when active and on focus.
 * -------------------------------------------------------------------------- */
.kind-tabbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 200;
  background: var(--kind-color-surface);
  border-top: 1px solid var(--kind-color-border-soft);
  /* lift above the iOS home indicator / Android gesture bar on real devices */
  padding-bottom: env(safe-area-inset-bottom, 0px);
  box-shadow: 0 -2px 12px rgba(16, 20, 26, 0.06);
}
.kind-tabbar__list {
  list-style: none;
  margin: 0 auto;
  padding: 0;
  max-width: var(--kind-container-max);
  display: flex;
}
.kind-tabbar__item {
  flex: 1 1 0;
  min-width: 0;
}
/* F-2 (a11y-granskning docs/reviews/aktiviteter-a11y-2026-07-17.md, P2): vid
 * 320px gav den jämna fyrdelningen (basis 0) varje flik 80px, dvs 72px
 * etikettyta, medan "Meddelanden" mäter 86px vid default 13px/600, så
 * etiketten ellipsis-klipptes redan vid default; vid xxlarge (etikett 19.5px)
 * klipptes alla fyra ("Medd...", "Bibl...", "Akti...", "Om..."). Fix i två
 * delar, flexibel layout först (minne feedback-locale-scope-css-compaction):
 *
 * 1. Innehållsstyrda flikbredder på smala viewports: flex-basis: auto låter
 *    "Meddelanden" ta det den behöver och "Om mig" lämna ifrån sig; grow 1
 *    delar överskottet lika och shrink håller ihop EN rad. min-width: 44px
 *    ersätter min-width: 0 som explicit target-golv (2.5.8 + patientgolvet).
 *    Vid 320px default ryms alla fyra etiketterna obrutna (summa min-content
 *    ~295px, CSS-math i tests/test_patient_tabbar_labels_css.py).
 *
 * 2. Etiketten pinnas till sin kompakta defaultstorlek (13px = 0.8125rem vid
 *    root 16px, alltså en no-op vid default) så att font-scale inte kan trycka
 *    ut etiketterna ur 320px-raden: opinnat behöver de fyra 366px + padding
 *    vid xxlarge, mot 320 tillgängliga. Rapportens variant B (clamp med
 *    13px-golvet respekterat); radbrytnings-varianten förkastades i CSS-math,
 *    "Meddelanden" är ETT ord utan brytpunkt (white-space: normal bryter inget
 *    utan avstavningsordbok) OCH en tvåradig bar skulle växa förbi de statiska
 *    56/57px-reserverna (UAT-01B-chattskalet, .kind-main--patient). Ikonerna
 *    (24px) och sidtexten skalar oförändrat; webbläsarzoom (1.4.4-mekanismen)
 *    skalar även px, så etiketterna växer fortfarande under zoom.
 *
 * Brytpunkten 440px gäller fortsatt vid normal textskala. Den äldre
 * tröskeln ~414px summerade olika innehållsbredder, men ovanför brytpunkten
 * får varje flik en fjärdedel av raden. Därför behöver xxlarge en egen
 * innehållsstyrd förlängning (#606), se regeln nedan. */
@media (max-width: 440px) {
  .kind-tabbar__item {
    flex-basis: auto;
    min-width: 44px;
  }
  .kind-tabbar__label {
    font-size: 13px;
  }
}
/* #606: vid xxlarge mäter "Meddelanden" 129.30px i lokal Inter (19.5px).
 * Jämna kolumner behöver 4 * (129.30px + 2 * 6px padding) = 565.20px,
 * avrundat uppåt till 566px. Att mäta enbart li missar länkens padding.
 * Låt innehållet styra fram till dess. Över 440px behålls den förstorade
 * etiketten och därmed barens höjd; normalregeln är orörd (desktopnavet som
 * nämndes här togs bort med #212).
 * Härledning och etikettvakt: tests/test_patient_tabbar_labels_css.py. */
@media (max-width: 566px) {
  html[data-kind-font-scale="xxlarge"] .kind-tabbar__item {
    flex-basis: auto;
    min-width: 44px;
  }
}
.kind-tabbar__link {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  min-height: 56px;
  padding: var(--kind-space-2) var(--kind-space-1);
  color: var(--kind-color-text-muted);   /* inactive: muted, 5.87:1 on bg */
  text-decoration: none;
  font-size: 0.8125rem;                   /* 13px label, compact tab footprint */
  font-weight: 600;
  line-height: 1.1;
  text-align: center;
}
.kind-tabbar__icon {
  display: inline-flex;
  flex: 0 0 auto;
  /* Positioneringskontext för notifieringsbadgen nedan. */
  position: relative;
}
/* PIXELBUDGET 2026-07-26 (docs/contracts/chat-pixel-budget.md): badgen som
   ERSÄTTER .kind-todo-chip i chatt-tråden ("Din vårdresa, N att göra", 44px +
   12px marginal i den fasta rälsen ovanför konversationen).

   position:absolute är LOAD-BEARING, inte kosmetik: tabbarens höjd är en
   budgetkonstant på hela patientytan (--kind-tabbar-reserve = 57px, som
   chattskalets height, min-height och textarea-tak alla räknar mot, se
   tests/test_chat_zoned_layout_css.py). En badge i flödet hade växt raden och
   tyst ätit upp exakt den plats den här omgången frigör. Ovanpå ikonen kostar
   den noll höjd.

   Färg: bakgrund = accent, text = sidbakgrunden. Den inversionen följer temat
   automatiskt och ger 4.90:1 i ljust läge (--kind-color-accent mot
   --kind-color-bg), över WCAG 2.2 AA:s 4.5:1 för brödtext. Mörkt läge mäts om
   i CP-03 (#88), dess tokenuppsättning är ännu omätt.
   Siffran är REDUNDANT information: den ligger inuti den aria-hidden-märkta
   ikon-spanen, och antalet bärs i klartext av flikens aria-label, så inget
   hänger på att kunna läsa en liten siffra (1.4.1 använd inte enbart form). */
.kind-tabbar__badge {
  position: absolute;
  top: -6px;
  inset-inline-start: 55%;
  min-width: 18px;
  height: 18px;
  padding-inline: 5px;
  border-radius: var(--kind-radius-pill);
  background: var(--kind-color-accent);
  color: var(--kind-color-bg);
  /* 13px är husets absoluta textgolv (CP-04, ADR-065 §D4). Siffran är visuellt
     redundant (aria-hidden, antalet står i klartext i flikens aria-label), men
     en SEENDE användare läser just den här siffran och ingenting annat, så
     redundans för skärmläsare är inte ett skäl att lägga den under golvet.
     Geometrin är oförändrad: line-height 18px = den fasta pillerhöjden, och
     13 x 1.0 ryms i 18px utan att växa lådan. */
  font-size: 0.8125rem;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}
.kind-tabbar__label {
  display: block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kind-tabbar__link:hover {
  color: var(--kind-color-text);
}
/* Active tab: accent colour for both icon (currentColor) and label, plus a top
   accent rule so the state reads without relying on colour alone. */
.kind-tabbar__link[aria-current="page"] {
  color: var(--kind-color-accent);        /* 5.34:1 on white, 8.36:1 in dark */
  box-shadow: inset 0 2px 0 0 var(--kind-color-accent);
}
/* SAMMA RAKNING SOM `.kind-vardnav__link:focus-visible` i kind_admin.css, och
   den star har for att mekanismen ar DELAD och inte for att felet rapporterades
   har. Aktiv flik bar en insatt accentmarkor, 2px i ovankant pa bottenraden.
   Ringen ar 3px och har SAMMA hexvarde som accenten, sa vid -3px maladas ringen
   pa markoren: uppmatt 170 av 914 ringpixlar OSYNLIGA pa bottenraden. -5px
   racker for bottenraden; talet -6px harleddes 2026-08 ur #164:s sidospalt
   (3px markor, 3 + 3 = 6) och uppmattes da till 0 osynliga i bada lagena.
   Sidospalten ar borttagen sedan #212 (bottenband pa alla bredder), och -6px
   star kvar eftersom det ar uppmatt rent pa bottenraden och en andring av
   talet vore en separat a11y-andring, inte en del av #212. */
.kind-tabbar__link:focus-visible {
  outline: var(--kind-focus-ring);
  outline-offset: -6px;
  border-radius: var(--kind-radius);
}

/* Rendered height of the sticky patient header (.kind-header__inner--patient:
   min-height 44px + 2x --kind-space-3 padding (0.75rem each) + 1px border). Used
   as the scroll-margin-top reserve for a focused element in the thread log
   (.kind-chat__log-list :focus-visible below) so it clears the sticky app
   header. Defined on the root (html) so it inherits to <body> (custom properties
   inherit downward; a var read on html cannot see a body-scoped value). It is
   only consumed by patient CSS, so defining it at root is harmless elsewhere.
   Grounded in the header box (inner min-height 44px + 2x --kind-space-3 padding
   + 1px border), not a magic number. (V6: the old "Att göra nu" tray sticky
   `top` + the html:has(.kind-fastplats) scroll-padding reserve that also read
   this token are retired, the tray now scrolls inside the log.) */
html {
  --kind-header-height: calc(44px + (2 * var(--kind-space-3)) + 1px);  /* ~69px */
}

/* ===================== ISSUE #183: SC 2.4.11 Focus Not Obscured ============
 *
 * MÄTT, INTE HÄRLETT. Issuen ber uttryckligen om att fokusläget mäts med
 * tangentbord i stället för att antas ur tokennamnet, och om att skilja HELT
 * skymt (SC 2.4.11 Minimum brutet) från DELVIS skymt (användbarhetsdefekt).
 * Uppmätt 2026-08-16 på `/patient/profil` i tyngsta rimliga datatillstånd med
 * riktiga Tab-tryck och `elementFromPoint` över ett rutnät (e2e/a11y816-sond.mjs):
 *
 *   390x664 normal    button.kind-btn--ghost "Logga ut"   0 av 15 provpunkter
 *                     rect 616..664, tabbraden täcker 53px   HELT SKYMT
 *   390x664 xxlarge   button.kind-btn--ghost "Logga ut"   0 av 15 provpunkter
 *                     rect 594..664, tabbraden täcker 65px   HELT SKYMT
 *   390x664 xxlarge   button.m207-dragspel "Konto"       10 av 15 provpunkter
 *                                                           DELVIS SKYMT
 *
 * NOLL av 15 träffar betyder att INGEN punkt i knappens egen rect returnerar
 * knappen; `.kind-tabbar` vinner överallt. Det är alltså ett verkligt brott mot
 * WCAG 2.2 AA SC 2.4.11 (Minimum), inte en användbarhetsanmärkning.
 *
 * BÄRAREN ÄR INTE DEN ISSUEN NAMNGER, och det är värt att skriva ut. #183
 * rapporterar "den fjärde snabblänken" ur rekonen och gissar att utfallet
 * troligen blir DELVIS skymt, alltså ingen WCAG-överträdelse. Observationen
 * (något på Mer skyms av den fixerade raden vid 390x664) reproduceras, men
 * bäraren är utloggningsknappen och utfallet är HELT skymt på BÅDA
 * textskalorna, alltså allvarligare än rapporten förutsåg. Rapportens
 * observation, dess diagnos och dess föreslagna åtgärd är tre olika
 * evidensnivåer (regel 38 korollarium). Ytan är dessutom ombaslinjerad efter
 * att #206:s ångerväg landat i samma mall, så issuens mätning är äldre än koden.
 *
 * MEKANISMEN. Chromium rullar mycket riktigt den fokuserade knappen in i
 * viewporten, till `rect 616..664` i en 664px hög viewport, alltså med
 * underkanten exakt vid viewportens underkant. Men den fixerade tabbraden
 * ligger 607..664 och ritas ovanpå, och webbläsaren räknar inte in en fixerad
 * överliggare när den avgör vad "i vy" betyder. `scroll-padding-block-end` är
 * just den egenskap som säger åt rullningen att lämna plats.
 *
 * VARFÖR DEN HÄR EGENSKAPEN FUNGERAR HÄR MEN INTE I #184. I #184 (fokus utanför
 * tabellportens sidled) visade mätningen att fokus inte initierar NÅGON
 * rullning alls när elementet är delvis synligt, så varje `scroll-*`-egenskap
 * var inert och fixen fick bli en JS-avslöjare. Här SKER en rullning, den
 * hamnar bara fel, och då är `scroll-padding` rätt verktyg. Samma issuefamilj,
 * två olika mekanismer, två olika åtgärder. Det är exakt därför bägge mättes i
 * stället för att lösas med samma recept.
 *
 * KONSTANTEN DELAS NU, i stället för att varje yta bär sin egen. #183 ber om
 * att `--kind-tabbar-reserve` appliceras och att varje konsument sveps.
 * Konstanten fanns bara på `.kind-body--chat`, alltså existerade den inte alls
 * på Mer-ytan, och tokennamnet var därför inget bevis på beteendet någonstans
 * utanför chatten. Den hissas hit till `html` så att alla konsumenter läser ETT
 * tal. `.kind-body--chat` sätter fortfarande sitt EGET värde på body-elementet
 * och skuggar därmed det här för chattskalet, så UAT-01B-matematiken och
 * dess invariant-test är oförändrade.
 *
 * SVEP AV KONSUMENTER (regel 27 korollarium 2). En lokal work-around är ett
 * FYND och inte ett avbockat ärende: `.kind-aktivitet__card` bär redan en egen
 * `scroll-margin-bottom` med en kommentar som stavar ut precis den här
 * mekanismen ("keep a tab-focused card clear of the sticky header (top) and the
 * fixed bottom bar"). Någon förstod alltså mekanismen och tillämpade den på EN
 * komponent. Rotreserven nedan täcker varje fokuserbart element på ytan i ett
 * enda uttalande; kortets egen regel lämnas kvar eftersom den är strängare
 * (den reserverar även mot den sticky headern uppåt) och inte i konflikt.
 *
 * `:has()` SJÄLVSKOPAR till sidor som faktiskt renderar raden, samma resonemang
 * som fotens `.kind-tabbar ~ .kind-footer`-scoping några rader ned. En tidigare
 * `html:has(.kind-fastplats)`-reserv RETIRERADES med V6, och det är INTE ett
 * argument mot mönstret: den retirerades för att chattytan är höjdlåst med
 * `overflow: hidden` och därför inte kan dokumentskrolla alls, alltså var
 * reserven inert där. Mer-ytan dokumentskrollar (uppmätt scrollHeight 1741px
 * vid normal, 2280px vid xxlarge i en 664px viewport), så den är verksam här.
 *
 * FOKUSRINGENS 5px INGÅR (3px outline + 2px offset). Det är #166:s lärdom:
 * navets inline-vaddring var 4px mot ringens 5px, alltså klipptes ringen medan
 * border-boxen såg rätt ut, och en mätning som bara läser elementets rect ser
 * ingenting.
 *
 * HISTORIK, EN ENDA DESKTOPBRYTPUNKT (#164 till #212). Nollställningen över
 * brytpunkten låg då i #164:s desktopfråga längre ned, och
 * `tests/test_patient_desktopnav_css.py` pinnade att filen hade exakt EN sådan
 * fråga. Sedan #212 finns varken frågan eller nollställningen: reserven ovan
 * gäller på alla bredder, och vakten fäller i stället varje villkorat block som
 * gör navet till en spalt. Ett första utkast under #164 lade en egen
 * fråga här och fällde den dåvarande vakten, vilket var vad den fanns för. Vakten
 * mjukades INTE upp (regel 41), regeln flyttades. */
html:has(.kind-tabbar) {
  --kind-tabbar-reserve: calc(57px + env(safe-area-inset-bottom, 0px));
  scroll-padding-block-end: calc(var(--kind-tabbar-reserve) + 5px);
}

/* The bottom bar is fixed, so patient page content needs bottom padding equal to
   the bar height (56px) + the safe-area inset so the last element + the sticky
   composer are never hidden behind it. Hook applied to <main> in base.html.
   #207 C3 (godkand mock): luften utover reserven trimmad space-4 -> space-2
   (72px -> 64px totalt vid inset 0). 56px-reserven + safe-area RORS INTE,
   det ar den tests/test_patient_snabbknapp_clears_tabbar.py vaktar. */
.kind-main--patient {
  padding-bottom: calc(56px + env(safe-area-inset-bottom, 0px) + var(--kind-space-2));
}

/* Issue #45 (footer surface). The .kind-main--patient reserve above only covers
   <main>; the shared .kind-footer (base.html) is a SIBLING that renders AFTER
   <main>, so it gets no reserve. On patient pages the fixed .kind-tabbar (56px +
   safe-area, z 200, bottom:0) therefore parks over the footer's trailing lines,
   permanently hiding the copyright line at every width, and more of the footer
   (version, then the patientdatalagen/GDPR legal line) as it wraps to more rows
   at large a11y font-scale. Deployed-browser geometry (Chromium, pod 2.1.9,
   2026-07-13): at 320x568 the .kind-footer__copy rect [492..536] sat behind the
   tabbar [511..568] at max scroll (elementFromPoint -> kind-tabbar__link), i.e.
   unscrollable-clear; same at 375x812 (copy [736..780] vs bar [755..812]).
   Reserve the SAME real tabbar footprint (56px + safe-area, matching the
   .kind-main--patient + .kind-snabbknapp reserves so all three stay in step) on
   the footer's content box, on top of its existing --kind-space-6 breathing, so
   every footer line clears the bar regardless of line count / font-scale. The
   general-sibling combinator self-scopes this to pages that actually render the
   tabbar (a .kind-tabbar must precede the footer, i.e. nav_role=='patient'); and
   kind_patient.css is only loaded on patient surfaces, so admin/public footers
   are untouched. On the chat surface the footer is display:none
   (.kind-body--chat .kind-footer), so this is a no-op there. */
.kind-tabbar ~ .kind-footer .kind-footer__inner {
  padding-bottom: calc(56px + env(safe-area-inset-bottom, 0px) + var(--kind-space-6));
}


/* ----------------------------------------------------------------------------
 * Patient header (iOS chat-native pivot, 2026-06-24): minimal, the mottagning
 * name centered, no wordmark, no top nav. The a11y trigger sits at the right
 * edge as a compact icon-only control (its visible label is sr-only here; the
 * aria-label carries the full name).
 * -------------------------------------------------------------------------- */
.kind-header__inner--patient {
  justify-content: center;
  position: relative;
  flex-wrap: nowrap;
  min-height: 44px;
}
.kind-header__mottagning {
  color: var(--kind-color-text);
  text-decoration: none;
  font-family: var(--kind-font-serif);
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  text-align: center;
  /* keep the centered title clear of the right-edge a11y trigger */
  padding: 0 var(--kind-space-7);
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kind-header__mottagning:hover { color: var(--kind-color-text); }
.kind-a11y-trigger--patient {
  position: absolute;
  right: var(--kind-space-4);
  top: 50%;
  transform: translateY(-50%);
  min-width: 44px;
  min-height: 44px;
  justify-content: center;
}

/* #49 Fas 1 cluster B: the compact 112/1177 emergency row lives INSIDE the sticky
   patient header (base.html), as a full-width second row under the mottagning
   name. .kind-header is already position:sticky; top:0 (kind.css), so this row
   inherits the stickiness and is ALWAYS VISIBLE, never scrolled away, never
   dismissible, and (being at the TOP) never covered by the composer or the
   on-screen keyboard (which push up from the bottom). The .kind-header__inner
   above it is padded + centered; this row spans the full header width. The visual
   look (light-yellow, border-top, contrast) is defined by .kind-safety--kompakt in
   kind.css. */
.kind-header--patient .kind-safety--kompakt {
  width: 100%;
  max-width: none;
}

/* P3 (UAT 2026-07-02): at narrow phone widths the patient header must stay
   materially under 100px so the thread owns the 320x800 screen. The top row
   drops its block padding from --kind-space-3 (12px) to --kind-space-1 (4px):
   44px inner min-height (contains the 44px a11y trigger exactly) + 2 x 4px +
   1px border ~ 53px, and with the compact one-line safety row (~38-40px, see
   kind.css .kind-safety--kompakt) the whole header is ~92px. The
   --kind-header-height derivation (top-row height, used for the Fästplats
   sticky offset + scroll reserves) moves WITH the padding change in the same
   query so the offsets stay in sync (its semantic is unchanged: the top row,
   not the safety row). */
@media (max-width: 360px) {
  html {
    --kind-header-height: calc(44px + (2 * var(--kind-space-1)) + 1px);  /* ~53px */
  }
  .kind-header__inner--patient {
    padding-top: var(--kind-space-1);
    padding-bottom: var(--kind-space-1);
  }
}
/* W1-UTTAGET (compliance-tillagg W, 2026-08-07, FE-2c delmoment 8).
   Itemiseringen av patient-sidhuvudets icke-kliniska krom vid 375-412 xxlarge
   (e2e/diag-w1-sidhuvud.mjs, bokford i docs/design/bibliotek-cp09-cp10.md
   paragraf 4.3): header 215.2 = innerrad 84 + akutrad-aside 130.2 + kant 1,
   dar innerraden bar 18+18px padding-block (rem-skalad space-3) kring en rad
   vars innehall ar 48-49.6px. FRITT tomrum 35.4px, alltsa over W1:s
   24px-troskel: uttaget gors HAR, akutraden rors INTE och W-fragan forfaller
   (W0/W1). Samma parning som 360-blocket ovan: paddingen trimmas till space-1
   OCH den harledda --kind-header-height foljer med i SAMMA regel, annars
   drifter chattens scroll-reserv fran den faktiska headerhojden.
   Skalvillkorat ar tillatet har (W7-analogen: padding ar krom, inte innehall,
   1.4.4 rors inte); normal skala ar pixel-identisk. Globalt pa ALLA
   patientytor per W6:s agarskapslinje, sidhuvudet ar delad patientkrom och
   regeln ligger pa den delade klassen. Aa-knappen (44/49.6px) forblir radens
   hojddrivare, sa traffytegolvet paverkas inte. */
html[data-kind-font-scale="xlarge"],
html[data-kind-font-scale="xxlarge"] {
  --kind-header-height: calc(44px + (2 * var(--kind-space-1)) + 1px);
}
html[data-kind-font-scale="xlarge"] .kind-header__inner--patient,
html[data-kind-font-scale="xxlarge"] .kind-header__inner--patient {
  padding-top: var(--kind-space-1);
  padding-bottom: var(--kind-space-1);
}

/* Respect reduced-motion: the only transform here is the static centering of the
   a11y trigger, nothing animated, declared for future-proofing. */
@media (prefers-reduced-motion: reduce) {
  .kind-tabbar__link { transition: none; }
}

/* Patient dashboard sections read as discrete cards (NIGHT-PASS 2026-06-04).
 * Same surface + hairline + radius + padding + elevation as .kind-card, applied
 * to the existing section class so NO template change is needed for carding.
 * The section--tint modifiers below swap only the background; everything else
 * (hairline, radius, padding, shadow) is inherited from here. */
.kind-patient-dashboard__section {
  background: var(--kind-color-surface);
  border: 1px solid var(--kind-color-border-soft);
  border-radius: var(--kind-radius);
  padding: var(--kind-space-5);
  box-shadow: var(--kind-shadow-sm);
}
.kind-patient-dashboard__section + .kind-patient-dashboard__section {
  margin-top: 0;   /* the grid gap now owns inter-card spacing */
}

/* Patient dashboard grid (NIGHT-PASS 2026-06-04). Two-up on desktop, collapses
 * to one column under ~720px so the patient surface (older / lower-vision, 18px
 * base, may run at 150% font-scale) never side-scrolls. auto-fit + minmax means
 * it is content-driven, not a hard 2-col, so a single remaining card fills the
 * row and the layout reflows cleanly under the a11y font-scale (WCAG 1.4.10).
 * min(100%, 320px) is the reflow-safe form: a bare 320px track can force a
 * column wider than a narrow viewport under 150% scale and reintroduce
 * horizontal scroll, the one thing the patient surface must never do. */
.kind-patient-dashboard__grid {
  display: grid;
  gap: var(--kind-space-5);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
}

/* Section-tint modifiers (NIGHT-PASS 2026-06-04). BACKGROUND ONLY: they swap the
 * white card surface for a pale decorative wash. Ink text (--kind-color-text) on
 * every tint is >=14.7:1 (measured). Hairline + radius + padding + shadow inherit
 * from the base .kind-patient-dashboard__section rule above. The .kind-list__item
 * rows inside keep their own white surface (kind.css), so body text always sits
 * on white at max contrast; only the section wash is tinted. */
.kind-patient-dashboard__section--mint     { background: var(--kind-tint-mint); }
.kind-patient-dashboard__section--lavender { background: var(--kind-tint-lavender); }
.kind-patient-dashboard__section--butter   { background: var(--kind-tint-butter); }
.kind-patient-dashboard__section--blush    { background: var(--kind-tint-blush); }

/* A11y fix (NIGHT-PASS 2026-06-04, contrast sweep): the in-card section-title
 * links ("Se alla ...") are accent-coloured by default, and --kind-color-accent on
 * the pastel washes measures 4.43:1 on lavender (FAIL 1.4.3) and 4.50:1 on blush
 * (at the floor). On a tinted section render those links as INK + underline
 * instead (ink-on-tint >=14.7:1, comfortably AA). The accent stays everywhere it
 * is already AA: buttons, and links on the white .kind-list__item chips. Only the
 * title-row link directly on the pastel changes. Underline preserves the link
 * affordance once colour is no longer the sole signal. */
.kind-patient-dashboard__section--mint .kind-section__title a,
.kind-patient-dashboard__section--lavender .kind-section__title a,
.kind-patient-dashboard__section--butter .kind-section__title a,
.kind-patient-dashboard__section--blush .kind-section__title a {
  color: var(--kind-color-text);
  text-decoration: underline;
}
.kind-patient-dashboard__section--mint .kind-section__title a:hover,
.kind-patient-dashboard__section--mint .kind-section__title a:focus-visible,
.kind-patient-dashboard__section--lavender .kind-section__title a:hover,
.kind-patient-dashboard__section--lavender .kind-section__title a:focus-visible,
.kind-patient-dashboard__section--butter .kind-section__title a:hover,
.kind-patient-dashboard__section--butter .kind-section__title a:focus-visible,
.kind-patient-dashboard__section--blush .kind-section__title a:hover,
.kind-patient-dashboard__section--blush .kind-section__title a:focus-visible {
  color: var(--kind-color-accent-hover);
}

.kind-patient-hero {
  background: var(--kind-color-accent-bg);
  border-radius: var(--kind-radius);
  padding: var(--kind-space-5) var(--kind-space-5);
  margin-bottom: var(--kind-space-6);
}
.kind-patient-hero__greeting {
  font-family: var(--kind-font-serif);
  /* CP-04-1 (#99), tredje fyndet i samma svep: 28px vid alla bredder. Det ligger
     i mobilbandets TOPP (24 till 28) men 2px under desktopgolvet (30 till 34),
     alltså samma defekt som de två andra, bara mindre. Yta: /patient/dashboard. */
  font-size: var(--kind-font-h1);
  margin: 0;
}
/* `.kind-patient-hero__lede` BORTTAGEN 2026-08-11 (#171). Ingressen raknade upp
   sidans egna sektionsrubriker en rad ovanfor sektionerna sjalva. */

/* Fästplats "Att göra nu" tray-card styles. RETIRED from the rendered chat in V6
 * (chatt-fönster-restfix 2026-07-14, spec §G1 + consultant decision Alternativ 1,
 * reviewer CHANGE-REQUIRED, rule 36): patient/chatt.html no longer emits the
 * in-thread tray card. It scrolled out of view once the log lands at the newest
 * message on load, so the care-journey "Att göra" surface moved first to a slim
 * chip in the fixed header and, since the pixel budget 2026-07-26, to the
 * notification badge on the Aktiviteter tab (.kind-tabbar__badge in base.html).
 * These rules therefore style NO rendered element on any current surface (the
 * Aktiviteter tab uses its own .kind-aktivitet* classes, not these); they are
 * kept only pending a follow-up dead-CSS cleanup, which this targeted fix-round
 * intentionally defers to bound the blast radius. The chip's own rules ARE gone
 * (see the note further down). */
.kind-fastplats {
  background: var(--kind-color-accent-bg);    /* blush wash; dark text 15.70:1 */
  border: 1px solid var(--kind-color-border-soft);
  border-radius: var(--kind-radius);
  padding: var(--kind-space-4);
  margin-bottom: var(--kind-space-4);
  position: static;
}
/* (RETIRED with V6: the old html:has(.kind-fastplats) scroll-padding-top
 * reserve for the sticky header + PINNED tray. The tray is not sticky any more,
 * and the zoned chat page cannot document-scroll, the .kind-body--chat
 * app-shell is height-locked + overflow:hidden, so a root scroll-padding is
 * inert here. A focused element in the LOG scrollport is kept clear of the
 * fixed rails by the log's own scroll-margin rules on .kind-chat__log-list
 * :focus-visible below. The tray renders on no other surface, so nothing else
 * relied on this reserve.) */
.kind-fastplats__heading {
  margin: 0 0 var(--kind-space-3) 0;
  font-size: 1rem;
  font-weight: 700;
  color: var(--kind-color-text);
}
.kind-fastplats__heading:focus-visible {
  outline: var(--kind-focus-ring);
  outline-offset: 3px;
}
.kind-fastplats__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-2);
}
/* Each card is a full-row tappable link: icon, body (eyebrow + rubrik + meta),
 * verb. min-height 56px clears the 48px patient tap-target floor comfortably.
 * P2-2 (deploy-verify 2220d2f, 2026-07-12, DIAGNOS reproducerad exakt i
 * headless stub-render): vid 320px kollapsade body/rubriken till 2.7px och
 * rubriken radbröts tecken för tecken. Breddberäkningen: kortets innermått är
 * 222px (254 - 32px padding), ikonen är fast 36px, verbet är white-space:
 * nowrap + flex:0 0 auto (kan varken krympa eller radbryta; "Öppna vårdresa"
 * plus ::after-pilen mäter 157.3px i 700-vikt), och 2x12px gap tar resten:
 * 222 - 36 - 24 - 157.3 = 4.7px kvar till body, vars flex: 1 (= 1 1 0%, basis
 * NOLL) + min-width: 0 lydigt krymper till ~2.7px i stället för att tvinga en
 * radbrytning. Kort verb ("Visa") drabbas inte, det var därför buggen bara
 * syntes på vårdresa/formulär-kort. Fix: flex-wrap på kortet + en RIKTIG
 * flex-basis på body (12rem) så att raden ÖVERSKRIDS när ikon + verb + body-
 * basen inte får plats och verbet radbryts till en egen rad under, i stället
 * för att krossa rubriken (uppmätt efter fix: body 220px, rubriken en rad,
 * ingen horisontell overflow vid 320px). På breda ytor ryms allt på en rad
 * som förut (wrap utlöses aldrig när basarna får plats). */
.kind-fastplats__card {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--kind-space-3);
  min-height: 56px;
  padding: var(--kind-space-3) var(--kind-space-4);
  background: var(--kind-color-surface);       /* white card so body text is max contrast */
  /* CP-02-resten (#87): hela kortet ar en lank, alltsa den klickbara enheten,
     sa kanten ar funktionell (kind.css §6). Regeln ritar ingen yta i dag (se
     RETIRED-noten ovan), men den ar kvar i arket och ska darfor inte bara en
     avvikelse som en aterupplivning tyst arver. */
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius);
  text-decoration: none;
  color: var(--kind-color-text);
}
.kind-fastplats__card:hover {
  border-color: var(--kind-color-accent);
}
.kind-fastplats__card:focus-visible {
  outline: var(--kind-focus-ring);
  outline-offset: 2px;
}
.kind-fastplats__icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--kind-radius-pill);
  background: var(--kind-color-accent-soft);   /* pale blush; accent icon 4.63:1 */
  color: var(--kind-color-accent);
}
.kind-fastplats__body {
  /* P2-2: a REAL flex basis (12rem), not `flex: 1` (whose basis is 0%): with
     basis 0 the card row could never overflow, so flex-wrap never triggered
     and the nowrap verb crushed this column to ~2.7px at 320px. With a 12rem
     base the row overflows when icon + verb + base do not fit, the verb wraps
     to its own line, and this column keeps a readable width. */
  flex: 1 1 12rem;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;                                /* allow the rubrik to truncate */
}
.kind-fastplats__eyebrow {
  font-size: 0.8125rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--kind-color-text-muted);          /* 5.87:1, AA */
}
.kind-fastplats__rubrik {
  font-weight: 600;
  color: var(--kind-color-text);
  overflow: hidden;
  text-overflow: ellipsis;
}
.kind-fastplats__meta {
  font-size: 0.9375rem;
  color: var(--kind-color-text-muted);
}
.kind-fastplats__verb {
  flex: 0 0 auto;
  font-weight: 700;
  color: var(--kind-color-accent);              /* 5.34:1 on white card, AA */
  white-space: nowrap;
}
.kind-fastplats__verb::after {
  content: " \2192";                            /* right arrow affordance */
}
/* The overflow ("+N till") slot reads as a quieter link-row, not a card action. */
.kind-fastplats__item--overflow .kind-fastplats__card {
  justify-content: center;
  min-height: 48px;
  background: transparent;
  border-style: dashed;
}
.kind-fastplats__item--overflow .kind-fastplats__icon { display: none; }
.kind-fastplats__item--overflow .kind-fastplats__verb { display: none; }
.kind-fastplats__item--overflow .kind-fastplats__rubrik {
  color: var(--kind-color-accent);
  font-weight: 700;
}

/* HÄR LÅG .kind-todo-chip och dess sju underregler (V6 2026-07-14, den slimmade
 * "Att göra"-chippen i ZON 1). Reglerna är BORTTAGNA 2026-07-26: sedan
 * pixelbudgeten emitterar ingen mall längre klassen, chippet ersattes av
 * notifieringsbadgen på fliken Aktiviteter (.kind-tabbar__badge i base.html,
 * antalet från context-processorn _inject_patient_tabbar_todo). Kvarlämnad
 * CSS för ett retirerat element är inte gratis: den läser som levande design
 * för nästa som öppnar filen, och det är exakt den sortens dubbeltydighet som
 * gör att man mäter fel yta. Historiken finns i git, chippets
 * retireringsmotiv i templates/patient/chatt.html. */

/* ----------------------------------------------------------------------------
 * Aktiviteter tab (2.1, KIND kundfeedback 2.2a). The full chronological listing
 * of the patient's visits + care-journey, the calendar-lens complement to the
 * #50 "Att göra nu" tray. It REUSES the Fästplats card shape (icon + eyebrow +
 * rubrik + meta + verb) so no new visual language is introduced (2.1-ribban);
 * the .kind-aktivitet__card mirrors .kind-fastplats__card on the SAME patient
 * tokens. Unlike the pinned tray this page is a plain scrolling list of sections
 * (Kommande / Din vårdresa / Tidigare), not sticky.
 *
 * A11y (WCAG 2.2 AA): each card is a full-row <a> at min 56px (2.5.8, patient
 * floor); the icon is aria-hidden (eyebrow text carries the type); status badge
 * carries text (never colour-alone, 1.4.1); visible focus ring (2.4.7); the
 * cards get scroll-margin so a tab-focused card is not obscured by the sticky
 * header or the fixed bottom bar (2.4.11 Focus Not Obscured, NEW in 2.2).
 * -------------------------------------------------------------------------- */
/* `.kind-aktiviteter__heading` BORTTAGEN 2026-08-11 (#170). Sidans H1 bar
   `kind-visually-hidden` nu, eftersom bottennavets flik redan heter
   "Aktiviteter". En typskaleregel pa ett element med 1x1px klippyta ar dod kod
   som ser levande ut, sa regeln foljer med rubriken ut i stallet for att
   staplas under gomningen. Historiken CP-04-1 (#99) bor kvar i
   tests/test_cp04_h1_typskala.py, som fortfarande sveper de kvarvarande tio
   sidspecifika h1-klasserna. */
/* `.kind-aktiviteter__lede` BORTTAGEN 2026-08-11 (#171). Ingressen den formade
   upprepade ordagrant tomtillstandets hjalptext, och de tva grenarna ar
   omsesidigt uteslutande, sa forklaringen visades bara nar den INTE behovdes. */
.kind-aktiviteter__section {
  margin: 0 0 var(--kind-space-6) 0;
}
.kind-aktiviteter__section:last-child { margin-bottom: 0; }
.kind-aktiviteter__section-heading {
  margin: 0 0 var(--kind-space-3) 0;
  font-size: 1.125rem;
  font-weight: 600;
  color: var(--kind-color-text);
}
.kind-aktiviteter__section-intro {
  margin: calc(-1 * var(--kind-space-2)) 0 var(--kind-space-3) 0;
  color: var(--kind-color-text-muted);
  font-size: var(--kind-font-small);
}
/* A calm one-line "no upcoming" row (only in the Kommande section when there is
   past history). NOT a per-section empty shell for the whole-tab-empty case. */
.kind-aktiviteter__tom-rad {
  margin: 0;
  padding: var(--kind-space-4);
  background: var(--kind-color-surface);
  border: 1px dashed var(--kind-color-border-soft);
  border-radius: var(--kind-radius);
  color: var(--kind-color-text-muted);
}
.kind-aktiviteter__tom { margin-top: var(--kind-space-5); }

.kind-aktivitet__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-2);
}
/* F-1 (a11y-granskning docs/reviews/aktiviteter-a11y-2026-07-17.md, P1): samma
 * buggklass som P2-2 på .kind-fastplats__card (rad ~380). Kortet byggdes som en
 * spegel av Fästplats-kortet men fick aldrig med sig P2-2-fixen: utan flex-wrap
 * kan raden aldrig överskridas, så nowrap-verbet (flex: 0 0 auto, "Öppna
 * vårdresa" 157.3px) krossade __body (flex: 1 = basis NOLL) till uppmätta
 * 36.7px vid 320px default och 0px vid xxlarge, med horisontell scroll
 * (WCAG 1.4.10-brott). Fix = exakt P2-2-receptet: flex-wrap här + riktig
 * flex-basis (12rem) på __body nedan, så verbet radbryts till egen rad i
 * stället för att klämma rubriken. Invariant-guard:
 * tests/test_patient_card_flex_invariant_css.py (sveper alla kortfamiljer);
 * CSS-math mot rapportens mätvärden: tests/test_patient_aktivitet_card_flex_css.py. */
.kind-aktivitet__card {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--kind-space-3);
  min-height: 56px;
  padding: var(--kind-space-3) var(--kind-space-4);
  background: var(--kind-color-surface);       /* white card, body text max contrast */
  /* CP-02-resten (#87): kortet ar en <a>, hela raden oppnar aktiviteten, sa
     kanten ar funktionell och inte dekoration (kind.css §6). */
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius);
  text-decoration: none;
  color: var(--kind-color-text);
  /* 2.4.11 Focus Not Obscured: keep a tab-focused card clear of the sticky
     header (top) and the fixed bottom bar (56px + safe-area). */
  scroll-margin-top: var(--kind-header-height);
  scroll-margin-bottom: calc(56px + env(safe-area-inset-bottom, 0px) + var(--kind-space-3));
}
.kind-aktivitet__card:hover { border-color: var(--kind-color-accent); }
.kind-aktivitet__card:focus-visible {
  outline: var(--kind-focus-ring);
  outline-offset: 2px;
}
.kind-aktivitet__icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--kind-radius-pill);
  background: var(--kind-color-accent-soft);   /* pale blush; accent icon 4.63:1 */
  color: var(--kind-color-accent);
}
.kind-aktivitet__body {
  /* F-1: en RIKTIG flex-basis (12rem), inte `flex: 1` (basis 0%): med basis 0
     "får raden alltid plats", wrap utlöses aldrig och kolumnen krymper i
     stället för att radbryta (se .kind-fastplats__body, samma P2-2-recept). */
  flex: 1 1 12rem;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;                                /* allow the rubrik to truncate */
}
.kind-aktivitet__eyebrow {
  font-size: 0.8125rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--kind-color-text-muted);          /* 5.87:1, AA */
}
.kind-aktivitet__rubrik {
  font-weight: 600;
  color: var(--kind-color-text);
  overflow-wrap: anywhere;                       /* long titles wrap, no side-scroll */
}
.kind-aktivitet__meta {
  font-size: 0.9375rem;
  color: var(--kind-color-text-muted);
}
.kind-aktivitet__verb {
  flex: 0 0 auto;
  font-weight: 700;
  color: var(--kind-color-accent);              /* 5.34:1 on white card, AA */
  white-space: nowrap;
}
.kind-aktivitet__verb::after {
  content: " \2192";                            /* right arrow affordance */
}
/* A LIVE video-möte lifted to the top of Kommande: a subtle accent left rule +
   soft accent wash so "Pågår nu" reads as the salient row without alarm (calm,
   D7/D8). The meaning is still carried by the "Pågår nu" text + eyebrow, not by
   colour alone (1.4.1). */
.kind-aktivitet__item--live .kind-aktivitet__card {
  border-color: var(--kind-color-accent);
  border-left-width: 4px;
  background: var(--kind-color-accent-bg);      /* blush wash; dark text 15.70:1 */
}

/* Snabbknapp: the persistent chip revealed once the tray scrolls off the top.
 * Fixed to the lower-right of the viewport, large tap target (>=48px), accent
 * fill (white text 5.34:1). `hidden` by default (no-JS users never see it); the
 * JS un-hides it only while the tray is out of view.
 *
 * Issue #45: the fixed patient tabbar (kind-tabbar, 56px + safe-area, z-index
 * 200) sits at bottom:0 and is the "fasta footern" in the report. Offsetting the
 * chip only 16px from the viewport bottom parked its lower ~41px BEHIND the
 * tabbar (chip z-index 30 < tabbar 200), so the chip was clipped/hidden behind
 * the footer. Clear the tabbar: bottom = tabbar height + safe-area inset + the
 * 16px gap, so the chip floats fully above the tabbar on every viewport incl.
 * 320px. This mirrors the .kind-main--patient content reserve (56px + inset). */
.kind-snabbknapp {
  position: fixed;
  right: var(--kind-space-4);
  bottom: calc(56px + env(safe-area-inset-bottom, 0px) + var(--kind-space-4));
  z-index: 30;
  display: inline-flex;
  align-items: center;
  gap: var(--kind-space-2);
  min-height: 48px;
  padding: 0 var(--kind-space-4);
  border: none;
  border-radius: var(--kind-radius-pill);
  background: var(--kind-color-accent);
  color: var(--kind-color-text-on-accent);
  font-size: 1rem;
  font-weight: 700;
  cursor: pointer;
  box-shadow: var(--kind-shadow-md);
}
.kind-snabbknapp[hidden] { display: none; }     /* belt-and-braces vs UA quirks */
.kind-snabbknapp:hover { background: var(--kind-color-accent-hover); }
.kind-snabbknapp:focus-visible {
  outline: 3px solid var(--kind-color-text);
  outline-offset: 2px;
}
.kind-snabbknapp__icon {
  display: inline-flex;
  align-items: center;
}
@media (prefers-reduced-motion: reduce) {
  .kind-snabbknapp { transition: none; }
}
/* The Snabbknapp is fixed bottom-right; reserve clearance at the foot of the
 * chat thread so it never overlaps the "Skicka" button / compose field on small
 * screens (a11y target-overlap, WCAG 2.5.8 spacing intent). ~88px = chip height
 * + the bottom inset. Applied to the chat article so the reserve appears only on
 * the thread surface where the chip can exist. */
.kind-chat { padding-bottom: 88px; }

/* Snabbknapp RETIRED from render in V6 (chatt-fönster-restfix 2026-07-14, spec
   §G1 + consultant decision Alternativ 1, reviewer CHANGE-REQUIRED, rule 36):
   patient/chatt.html no longer emits the Snabbknapp chip (nor the in-thread tray
   it re-summoned), and kind_fastplats.js is no longer loaded. The care-journey
   "Att göra" surface is the Aktiviteter tab's notification badge now
   (.kind-tabbar__badge in base.html, pixelbudget 2026-07-26).
   This hide rule + the .kind-snabbknapp styles above therefore match NO rendered
   element; they are retained as a dead-safe guard (if a Snabbknapp were ever
   reintroduced on the zoned surface it stays hidden here, since its fixed
   position re-created the 320x568 send-button trap: qa measured 14.7px free
   height vs the composer's 48px icon row) pending a follow-up dead-CSS cleanup
   this fix-round defers to bound the blast radius. Guard-pinned (rule presence,
   not render) by tests/test_chat_zoned_layout_css.py; the render-side ABSENCE of
   the chip is pinned by tests/test_patient_fastplats.py. */
.kind-body--chat .kind-snabbknapp { display: none; }

/* With the chip gone from the zoned surface (and never present on the admin
   surfaces), the 88px chip-clearance reserve above is dead weight INSIDE the
   height-bound column: it re-created a smaller version of the very "dead gap
   under the composer" the zoned layout removed. Zero it where the layout is
   zoned. */
.kind-chat--zoned { padding-bottom: 0; }

/* Chat */
.kind-chat {
  display: flex;
  flex-direction: column;
  min-height: 60vh;
}

/* ----------------------------------------------------------------------------
 * V1 (#55, chatt-yta 2.1 feedback-plan 2026-07-08): 3-zone viewport layout.
 *
 * Today .kind-chat is only min-height:60vh, so the whole PAGE window-scrolls
 * (the thread does not scroll internally) and .kind-chat__compose is sticky
 * against the DOCUMENT (with a patient-tabbar-shaped bottom offset that admin
 * pages inherit even though they have no tabbar, the "phantom gap" bug). This
 * block binds the chat column to a BOUNDED, viewport-relative height so ONLY
 * .kind-chat__log scrolls internally; the header + composer + share-popover +
 * schemalagda panel become ordinary (non-sticky) flex children that are simply
 * always in view, the same idea the arbetsvy kö-rail already uses
 * (position:sticky + max-height + its OWN overflow-y:auto,
 * .kind-arbetsvy__ko in kind_admin.css; högerpanelen .kind-arbetsvy__patient
 * bar samma konvention men är borttagen 2026-07-27, issue #80).
 *
 * Opt-in via .kind-chat--zoned on the <article class="kind-chat"> root.
 * ÄNDRAD PREMISS 2026-07-26 (pixelbudget, issue #82): the opt-in now covers ALL
 * FOUR chat surfaces, admin/chatt.html, the arbetsvy center pane,
 * patient/chatt.html AND admin/team_chat_visa.html. Kollegie-chatten was
 * deliberately out of scope while nobody had measured it; when someone did, it
 * turned out to be the WORST of the three (19 percent of the column to the
 * conversation, against the patient surface's 32 and the clinician's 27), for
 * exactly the reason this block exists: an unzoned column makes the log
 * content-sized, so freed chrome becomes empty space at the bottom instead of
 * conversation. The BASE (unzoned) sticky rules further down are consequently
 * retained as a fallback that no shipped surface uses any more, not as a
 * description of team_chat_visa.
 *
 * The exact viewport BUDGET (how much of 100dvh the surrounding chrome eats)
 * differs per surface: kind_admin.css binds the whole COLUMN (sticky +
 * max-height, nothing variable-height above its chat pane, no fixed bottom
 * nav), while the PATIENT surface (P0 rework, deploy-verify df69af8) caps
 * only the LOG (.kind-body--chat .kind-chat__log max-height below) and lets
 * the page flow normally with the pre-V1 sticky composer riding above the
 * fixed tabbar. The original V1 patient technique (a height:100dvh
 * flex:1/min-height:0 chain through <main>) is RETIRED: it silently stopped
 * binding whenever the aggregate min-content exceeded the viewport (every
 * active conversation), spilling the then-static composer under the fixed
 * tabbar (the P0 Skicka occlusion).
 *
 * Deliberately NOT set here: overflow:hidden on .kind-chat--zoned itself. The
 * ONLY flexible child is .kind-chat__log (flex:1;min-height:0), so in the
 * ordinary case the box never exceeds its bound; the rare case where the
 * OTHER (auto-height) siblings alone need more room than the bound allows
 * (e.g. the schemalagda panel showing many items while the share popover is
 * also open, on a very short viewport) is left to overflow VISIBLY rather than
 * be clipped, so a floated child (the emoji popover, position:absolute) is
 * never hidden. Graceful degradation over a hard, potentially content-eating
 * cap. */
.kind-chat--zoned {
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.kind-chat--zoned .kind-chat__log {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  /* P1-A (deploy-verify 2220d2f, 2026-07-12; ROTORSAK empiriskt bevisad i
     headless stub-render av de RIKTIGA templaterna, Pattern 9): dokumentet
     bakom den zonade kolumnen var 10-16x viewporten (uppmätt 14841px admin /
     9535px patient) trots att loggen klippte sitt synliga innehåll korrekt.
     Boven är skärmläsar-styckena <p class="kind-visually-hidden">X skrev,</p>
     i varje bubbla: sr-only-mönstret är position:absolute, och eftersom
     skrollaren (detta element) var OPOSITIONERAD hoppade deras containing
     block ÖVER skrollaren (till närmsta positionerade förfader, eller
     viewporten). En overflow-klippare klipper BARA avkomlingar vars
     containing-block-kedja passerar genom den, så varje sr-stycke la sin
     1x1px-ruta på sin statiska flödesposition (y upp till ~14800) RAKT UT i
     dokumentets skrollbara yta; en mushjuls-scroll vid trådens gräns kedjade
     då vidare ut i ~10000px fantomtomrum och drog bort header + composer.
     position:relative gör skrollaren till containing block för sina absoluta
     avkomlingar, så sr-styckena hamnar i LOGGENS scrollable overflow (klipps
     och skrollar med) i stället för dokumentets: uppmätt föll dokumenthöjden
     14841 -> 1201 (admin) och 9535 -> 1178 (patient), fantomytan borta.
     overscroll-behavior: contain är bältet ovanpå rotorsaksfixen: en
     wheel/touch-scroll som når trådens topp/botten stannar i skrollaren i
     stället för att kedja vidare till sidan (qa-rapportens båda åtgärder).
     Guard-pinnad av tests/test_chat_zoned_layout_css.py. */
  position: relative;
  overscroll-behavior: contain;
}
/* The header, the reply form, the share-popover wrapper, and the schemalagda
   panel are all DIRECT siblings inside .kind-chat--zoned (the chat_composer
   macro emits the popover + schemalagda as siblings of the <form>, not nested
   inside it); none of them should compete with the log for the bounded
   leftover space. .kind-compose-popover carries an existing (patient-authored)
   `flex: 1 1 100%` meant for the WRAPPING row context on the patient surface
   (.kind-chat__compose-row); on admin it is a direct .kind-chat--zoned child
   with no such row, so left alone it would flex-grow into the newly-bounded
   column and silently eat half the log's viewing area. Reset all four to
   their natural (content) height inside the zoned column. */
/* (.kind-todo-chip stod med i den här listan tills 2026-07-26; chippet är
   retirerat och dess regler borttagna, så selektorn matchade ingenting.) */
.kind-chat--zoned .kind-chat__header,
.kind-chat--zoned .kind-chat__compose,
.kind-chat--zoned .kind-compose-popover,
.kind-chat--zoned .kind-schemalagda {
  flex: 0 0 auto;
}
/* The macro header: inside a bounded ADMIN zoned column its old top-sticky
   has nothing to stick against (the column does not document-scroll), it is
   an ordinary flex child that is always in view; static everywhere zoned
   (the patient surface never renders the .kind-chat-header macro root, so
   this is de facto admin-only). */
.kind-chat--zoned .kind-chat-header {
  position: static;
}
/* P0 (deploy-verify df69af8 punkt 3b, 2026-07-12): the composer
   de-stickying is now scoped to ADMIN ONLY. The V1 assumption ("the bounded
   flex chain keeps the composer in view, sticky is dead weight") held on the
   admin surfaces (sticky + max-height, no fixed bottom nav) but was FALSE on
   the patient surface: the .kind-body--chat chain is overflow-visible by
   design, and as soon as the page's aggregate min-content (header + tray +
   log floor + composer + schemalagda + status) exceeded 100dvh, which it
   does for EVERY patient with an active conversation (qa measured
   main.scrollHeight 1099px vs 481.6px allotted at 320x568), the content
   spilled past main's tabbar padding reserve and the now-static composer
   landed exactly under the fixed .kind-tabbar (z 200): the Skicka button was
   pointer-occluded at EVERY tested width, 320 to 1280 (0/25 elementFromPoint
   hits, Playwright "subtree intercepts pointer events"). On the patient
   surface the base .kind-chat__compose sticky rule (further down: bottom
   56px + safe-area + gap, z 20, opaque bg) is REACTIVATED by this scoping;
   it is the pre-V1 shipped-and-verified behaviour, and its containing block
   is sound again because the patient column is content-sized (see the
   .kind-body--chat block below). */
.kind-body--admin .kind-chat--zoned .kind-chat__compose {
  position: static;
  bottom: auto;
}
/* G1 (V6, chatt-fönster-restfix 2026-07-14, spec docs/design/patient-chatt-3zon-
   2026-07-14.md): the patient composer is ALSO de-stickied now, becoming a
   fixed-height flex sibling at the foot of a VIEWPORT-BOUND column (the
   .kind-body--chat app-shell block below), NOT sticky.

   This REVERSES the P0-era decision (deploy-verify df69af8, the rule right
   above) that kept the patient composer sticky. That decision was correct FOR
   ITS MODEL: the page flowed freely (overflow-visible), so a STATIC composer
   in an over-tall page landed under the fixed tabbar (the Skicka occlusion,
   0/25 elementFromPoint). The V6 model removes the PREMISE of that failure
   instead of the composer's stickiness: the app-shell binds the body to
   100dvh + overflow:hidden (the page can no longer scroll AT ALL), and the
   zoned column is a definite-height flex column whose ONLY flexible child is
   the log, so the composer's own box is sized by flex to sit ABOVE the tabbar
   by construction (since UAT-01B the shell HEIGHT excludes the bar, see the
   .kind-body--chat block) and the page can never scroll it anywhere. A static
   composer that a scroll can never move under the tabbar is exactly the 2.4.11
   Focus-Not-Obscured win the spec wants "by design" (a focused thread element
   can never hide behind a composer that does not overlay the log), which
   retires #74's --kind-composer-reserve + focus-scroll assist on this surface
   (they existed only for the STICKY composer that DID overlay).
   (Sedan 2026-07-26 är även team_chat_visa zonad, issue #82, så den base-sticky
   composer-regeln längre ned tjänar inte längre någon levererad yta; den är kvar
   som fallback, inte som beskrivning av en yta.)
   Guard-pinned by tests/test_chat_zoned_layout_css.py (co-evolved for V6). */
.kind-body--chat .kind-chat--zoned .kind-chat__compose {
  position: static;
  bottom: auto;
}
/* (The --kind-composer-reserve:0px pin for this surface lives on the
   .kind-body--chat .kind-chat--zoned app-shell rule below, folded in with the
   flex bind so there is one zoned-article block per surface.) */
/* (P0 follow-through: the V1 zero-out of the 2.4.11 scroll-margin reserve on
   the zoned .kind-chat__log-list focusables is REMOVED. That selector only
   ever matched the PATIENT surface (the admin zoned threads have no inner
   __log-list), and with the patient composer sticky again the base reserve
   further down this file, scroll-margin-bottom 96px + safe-area and
   scroll-margin-top var(--kind-header-height), is exactly right again: a
   focused element must scroll clear of the sticky composer below and the
   sticky patient header above. The admin-side top-reserve zero-out lives in
   kind_admin.css and is unaffected.) */

/* .kind-body--chat: the PATIENT zoned chat surface (patient/chatt.html ALONE,
   never admin, via {% block body_class %}).

   G1 (V6, chatt-fönster-restfix 2026-07-14, spec docs/design/patient-chatt-3zon-
   2026-07-14.md): a real 3-zone app-shell. The body is locked to the dynamic
   viewport and CANNOT page-scroll; the zoned chat article is a definite-height
   flex column whose ONLY flexible child is the log, so header + composer are
   fixed rails and the THREAD is the single scroller (spec §G1: samma zonmodell
   som arbetsvyn, composer fast flex-syskon i botten, INTE sticky).

   Why this SUPERSEDES the P0 REWORK (deploy-verify df69af8) that shipped a log
   max-height cap + a sticky composer + a free-scrolling page: that model's
   Skicka occlusion (a de-stickied composer under the fixed tabbar) came from
   the page being ALLOWED to scroll while overflow-visible. The even-earlier
   retired V1 flex chain broke for a DIFFERENT reason (a height:100% chain
   through <main> with a 16rem log FLOOR that refused to shrink, so min-content
   exceeded 100dvh and, with NO overflow:hidden belt, the page grew + scrolled).
   V6 removes BOTH root causes at once:
     * overflow:hidden on the height-locked body => the page can NEVER scroll,
       so a STATIC composer can NEVER be pushed under the tabbar (the P0 belt);
     * NO min-height floor on the log (min-height:0 only) => the log always
       absorbs the shrink first, so the fixed rails never push min-content past
       the bound (the retired-V1 fix);
     * the column height comes from FLEX sizing (main fills the shell minus the
       header via flex:1), NOT a hand-counted calc chain, so it tracks header /
       safety-row / font-scale changes without a magic number.

   UAT-01B (P0, qa deployed-browser sweep 2026-07-16 on 6c226d8): the V6 shell
   above STILL occluded Skicka on short viewports, because its tabbar reserve
   lived in main's PADDING-BOTTOM and padding does not stop visible OVERFLOW.
   With the composer ACTIVE and grown, the article's non-shrinkable rails
   (header + composer, the log already at 0) exceeded main's content box and
   spilled straight THROUGH the 72px padding reserve to the viewport bottom
   edge: the compose form's bottom measured 568.2 in a 568-tall viewport, the
   Skicka button sat ~33px under nav.kind-tabbar (position:fixed, z 200), real
   unforced clicks timed out at 320x568, 390x544, 412x595, and 375x667 cleared
   by only 0.9px. (body's own overflow:hidden never clips this: a body overflow
   value PROPAGATES to the viewport per css-overflow-3 and body's used value
   becomes visible, so it only disables page scroll, which is also why qa saw a
   51px programmatic scrollY that changed nothing.)
   The fix moves the tabbar reserve OUT of ignorable padding INTO the shell
   HEIGHT itself: the body ends ABOVE the tabbar, not at the viewport edge, so
   the flex budget the rails are sized within already excludes the bar and the
   zoned column's foot (composer + Skicka) lands above it by construction.
   main keeps only a small clearance gap as padding (see below), and an
   overflow clip on main is the belt for any future over-budget state.

   The log's viewport-relative max-height cap is therefore RETIRED: the flex
   bind sizes it now (shared .kind-chat--zoned .kind-chat__log flex:1;
   min-height:0; overflow-y:auto). The footer stays hidden (established since
   V1). Residual (honest, same class the admin column documents): on a very
   short viewport (landscape phone) the non-shrinkable header + status + safety
   + composer alone can exceed the bound and the log goes to 0; the main clip
   then clips at the tabbar top rather than page-scrolls, an accepted
   portrait-first degradation.
   NOTE (P0 safety): this reworks a browser-verified P0 surface, so the send
   button reachability MUST be re-verified in a real browser with real unforced
   clicks at 320x568, 375x667, 390x544, 412x595, 430x932 (rules 22/26) before
   deploy; CSS math is necessary but not sufficient.
   Guard-pinned by tests/test_chat_zoned_layout_css.py (co-evolved for V6 and
   again for UAT-01B). */
.kind-body--chat {
  /* Lock the shell to the dynamic viewport MINUS the fixed tabbar and forbid
     page scroll: the only scroller is the log. 100dvh tracks the browser UI
     chrome (the address bar / toolbars collapsing + expanding), NOT the
     on-screen keyboard, so the shell stays exactly the currently-visible
     viewport height as that chrome changes; on Android the base.html viewport
     interactive-widget=resizes-content makes 100dvh shrink under the soft
     keyboard too. Body is already display:flex;flex-direction:column
     (kind.css), so the fixed header rail takes its natural flow height and
     <main> (flex:1) fills the rest.
     --kind-tabbar-reserve (UAT-01B) = the tabbar's REAL footprint: 57px
     (56px .kind-tabbar__link min-height + 1px .kind-tabbar border-top, qa
     measured 57.3 rendered) + the safe-area inset the bar itself grows by
     (its padding-bottom). The 56px-only reserves elsewhere in this file
     under-counted by the border, which is how 375x667 ended up 0.9px from
     failing. The CSS-math invariant in tests/test_chat_zoned_layout_css.py
     recomputes this from the tabbar's own declarations, so a taller tabbar
     fails the test instead of silently re-occluding Skicka. */
  --kind-tabbar-reserve: calc(57px + env(safe-area-inset-bottom, 0px));
  height: calc(100dvh - var(--kind-tabbar-reserve));
  overflow: hidden;
}
/* P1-1 (V6 fix-round, chatt-fönster-restfix 2026-07-14, reviewer
   CHANGE-REQUIRED): override the base min-height floor on the chat shell. The
   base `body.kind-body { min-height: 100vh }` (kind.css) is specificity (0,1,1)
   and OTHERWISE beats a bare `.kind-body--chat` (0,1,0), so the used height
   resolves to max(height 100dvh, min-height 100vh) = 100vh = the LARGE viewport
   on mobile (100vh == lvh > dvh whenever the browser toolbars are expanded).
   That pushes the static composer below the dynamic-viewport fold while
   overflow:hidden removes the page-scroll rescue = the Skicka occlusion df69af8
   fixed, reintroduced. Pin the floor to the DYNAMIC viewport with a selector
   that actually WINS the cascade: body.kind-body.kind-body--chat is (0,2,1) >
   the base (0,1,1), so it does not rely on source order.
   NOTE: a fixed-viewport browser (in-app preview + device emulation) cannot
   exhibit the vh/dvh delta (vh == dvh there), so this fix is code-correct by
   construction + statically pinned (tests/test_chat_zoned_layout_css.py); the
   real-device pass is the consultant's / UAT's final check.
   UAT-01B: the floor MUST stay the EXACT same expression as the height above.
   Used height resolves to max(height, min-height), so a min-height left at
   100dvh would silently cancel the tabbar subtraction and reintroduce the
   occlusion; the invariant test asserts expression equality. */
body.kind-body.kind-body--chat {
  min-height: calc(100dvh - var(--kind-tabbar-reserve));
}
.kind-body--chat .kind-main {
  /* Fill the shell as a flex column so the zoned article (its last flex child)
     can grow into the leftover space. min-height:0 lets that article shrink so
     its inner log scroller engages. The top padding is trimmed so the thread
     owns more of the screen. */
  display: flex;
  flex-direction: column;
  min-height: 0;
  padding-top: var(--kind-space-3);
  /* UAT-01B: the shell HEIGHT owns the tabbar reserve now (see .kind-body--chat
     above), so the inherited .kind-main--patient padding-bottom (56px +
     safe-area + space-4, ~72px) would double-count it and starve the composer
     of exactly the budget it was missing on short viewports. Replace it with
     the small visible clearance gap between the composer's foot and the tabbar
     top: space-3 = 12px, comfortably over the 8px minimum clearance the P0
     re-verify demands (the old model measured 0.9px at 375x667). This wins the
     cascade over .kind-main--patient by specificity ((0,2,0) > (0,1,0)),
     independent of source order. */
  padding-bottom: var(--kind-space-3);
  /* UAT-01B belt: if the rails ever exceed the budget again (extreme font
     scale, the no-JS open share panel), clip the spill at main's box (= the
     tabbar top) instead of letting it paint on under the fixed tabbar as a
     dead, deceptive hit target. body's own overflow:hidden CANNOT do this
     (its overflow propagates to the viewport, see the shell comment).
     overflow:clip does not create a scroll container, so no focus-scroll or
     programmatic scroll can displace the shell content (the #73/#74/#75
     sticky-era class); the plain hidden line is the fallback for engines
     without clip support (it clips the same, it is merely scrollable by
     script). Native <dialog> overlays (slot-grid, crash forms) render in the
     top layer and are NOT clipped; position:fixed descendants are likewise
     unaffected (main has no transform/filter, so it is not their containing
     block). The emoji/share popovers are absolute WITHIN the shell area and
     stay inside the clip box. */
  overflow: hidden;
  overflow: clip;
}
.kind-body--chat .kind-chat--zoned {
  /* Grow to fill <main>'s content box (a definite height via the flex chain
     above) and shrink to it (min-height:0), so the inner log flex child gets a
     definite height to scroll within (the shared .kind-chat--zoned rules make
     the log flex:1;min-height:0;overflow-y:auto and the header/composer
     flex:0 0 auto rails). */
  flex: 1 1 auto;
  min-height: 0;
  /* Composer static below the log = it can never overlay a focused thread
     element, so the 2.4.11 bottom reserve is pure phantom offset here; pin
     --kind-composer-reserve to 0px (mirrors the admin zoned column).
     kind_composer_mode.js already skips publishing a measured value when the
     composer is not sticky (its getComputedStyle(form).position gate), so this
     pin is never overridden by an inline value. */
  --kind-composer-reserve: 0px;
}
.kind-body--chat .kind-footer {
  display: none;
}
/* UAT-01B / RETEST-03 (qa retest 2026-07-16, MEDIUM) short-viewport
   compaction: at <= 600px of height (covers the three failing qa viewports
   568/544/595 and the OS-keyboard sims) the shell budget is so tight that
   even with the textarea at its 48px floor the fixed rails sat within ~20px
   of the bound at 320x568. Trim the pure BREATHING space in the rails
   (never a tap target, never a text size): the article header's
   padding/margin and the composer's top padding + internal gaps step down
   one spacing token (~24px recovered). Scoped to .kind-body--chat so the
   clinician surfaces keep the roomier defaults.

   RETEST-03 widened the gate: 375x667 (a plain phone viewport, no OS
   keyboard) has height 667px, which the old max-height:600px-only query
   never covered, so the message log there got only ~68-90px of the
   375x667 stack (sticky header 98.4 + chat__header 104.2 + todo-chip 56 +
   composer 225.2 + tabbar 57.3, measured). The gate is now a QUERY LIST:
   the original max-height:600px branch (unconditional, any width) OR
   (max-width:900px) AND (max-height:700px) together (narrow-AND-short,
   which is what actually starves the log, never a plain short desktop
   window: a >900px-wide window at 600-700px height keeps its roomy
   defaults). 375x667 satisfies the SECOND branch only (667 > 600 but
   <= 700, and 375 <= 900). */
@media (max-height: 600px), (max-width: 900px) and (max-height: 700px) {
  .kind-body--chat .kind-chat__header {
    padding-bottom: var(--kind-space-2);
    margin-bottom: var(--kind-space-2);
  }
  .kind-body--chat .kind-chat__compose {
    padding-top: var(--kind-space-2);
    gap: var(--kind-space-2);
  }
  /* UAT-01B P2:s HJÄLPTEXTREGEL ÄR PENSIONERAD 2026-09-24 (web#564).
     Här låg `.kind-body--chat .kind-chat__compose > .kind-chat__compose-row >
     .kind-field > .kind-field__help`, som gjorde meddelandefältets hjälptext
     sr-only på viewporthöjder <= 600px (UAT-01B P2, qa-ommätning 2026-07-16:
     ~49-84px hjälptext plus 8px fältgap var den sista avskalbara kromen när
     rälsen kapade Skicka 5,8px vid 390x544).

     ELEMENTET FINNS INTE LÄNGRE: `<p id="kind-compose-help">` är borttaget ur
     templates/patient/chatt.html på kundens uttryckliga begäran (Maria/Alex,
     web#564, "tas bort helt, också för skärmläsare"), se den långa noten där.
     Regeln är därför borttagen i SAMMA ändring och inte lämnad kvar: den direkta
     barnkedjan hade matchat NOLL element, vilket är exakt GAP-2 (2026-08-08) --
     en stale kedja vars vakt var ärligt grön medan verkligheten var en annan.
     Pixelåtervinningen som regeln bar finns kvar med råge: hela stycket är borta
     i alla lägen och på alla höjder, inte bara sr-only vid <= 600px.

     ETIKETTENS motsvarande regel står KVAR nedan och är oförändrad -- <label>
     ligger kvar i DOM:en och bär fältets programmatiska namn (WCAG 3.3.2).
     `.kind-compose--collapsed .kind-field__help` längre ned i filen står också
     kvar, och det är inte en glömd rest: den är en DESCENDANT-selektor och
     matchar fortfarande komposerns kvarvarande hjälptexter (chunked-uploadens
     statusstycke och bilagepanelens hjälp), som ska fortsätta kosta 0px i
     viloläget. */

  /* GAP-2, andra ledet: etiketten "Skriv ett meddelande" går sr-only även i
     AKTIVT läge inom det här bandet. Viloläget gör redan exakt detta
     (.kind-compose--collapsed .kind-field__label längre ned i filen), så
     mönstret är etablerat på ytan och inte uppfunnet här. Etiketten ligger
     KVAR i DOM:en med sitt `for`, alltså behåller fältet sitt programmatiska
     namn (WCAG 1.3.1 / 3.3.2 / 4.1.2), och platshållaren bär den synliga
     ledtexten (kontrastpinnad längre ned i filen). Uppmätt kostnad vid
     320x568 xxlarge: 33,59px etikett plus 12px gap. Vi byter aldrig ett
     utrymmesproblem mot en WCAG-regression: display:none hade tagit bort
     namnet och är därför förbjudet här, samma resonemang som hjälptexten. */
  .kind-body--chat .kind-chat__compose > .kind-chat__compose-row > .kind-field > .kind-field__label {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
  }

  /* GAP-2, tredje ledet: ikonradens knappar hålls vid sitt 48px-golv i stället
     för att växa med textskalan.

     VARFÖR HÖJD OCH INTE BREDD. Den befintliga 360px-regeln längre ned i filen
     komprimerar knapparnas INLINE-padding, alltså bredden, och löser radbrytning
     vid 320px. Vid textskala xxlarge (rotFont 24px) är det i stället
     BLOCK-paddingen som växer: varje knapp blev 70,39px hög i stället för 48, och
     hela ikonraden 140,39px, alltså två rader. Uppmätt återvinning: raden går till
     ~48px och konversationen får tillbaka den höjden.

     TRÄFFYTAN RÖRS INTE. min-height/min-width 48px står kvar på varje kontroll
     (patientgolvet, strängare än WCAG 2.5.8:s 24px och 2.5.5:s 44px), och
     ikonstorleken är oförändrad. Det som tas bort är enbart luft som skalas med
     rotfonten, inte något som gör knappen svårare att träffa. */
  .kind-body--chat .kind-compose__actions .kind-btn {
    padding-block: 0;
  }
  /* RETEST-03/KIND-UAT-02 (qa retest 2026-07-16): the conversation title's
     already-fluid clamp (.kind-chat__header h1, clamp(1.5rem, 4.5vw + 0.4rem,
     var(--kind-font-h1)) further up this file) can still land ABOVE its own
     1.5rem persona-approved floor at some width/height combinations inside
     this widened gate (e.g. a ~500-900px-wide short window), keeping the
     heading at 2 wrapped lines. Pin it to the SAME 1.5rem floor unconditionally
     inside this band, so every viewport this gate covers (narrow-and-short,
     including 375x667) gets the heading's smallest persona-approved size, not
     just whatever the vw-term happens to compute. Expected recovery at
     375x667: hint ~45-65px + header/compose pads ~16px + h1 (2 rows -> 1 row)
     ~19px => the message log gains roughly ~155-175px total, enough for the
     newest message's opening line (~138-155px currently) to clear. */
  .kind-body--chat .kind-chat__header h1 {
    font-size: 1.5rem;
  }
}
/* ------------------------------------------------------------------------ */

.kind-chat__header {
  padding-bottom: var(--kind-space-3);
  border-bottom: 1px solid var(--kind-color-border);
  margin-bottom: var(--kind-space-3);
}
/* PROBLEM 2 (V6 polish, chatt-fönster-restfix 2026-07-14): the conversation title
   is the base 2.5rem hero H1 (--kind-font-h1). On mobile ("Konversation med Eva
   Lundström" at 375px) that wraps to ~3 lines / ~270px and eats the fixed header
   rail, squeezing the thread; on desktop it is 1 line / ~44px (fine). Compress it
   FLUIDLY at narrow widths while leaving the desktop size EXACTLY as shipped: the
   clamp MAX term IS var(--kind-font-h1), so at wide/desktop widths the used size
   clamps to 2.5rem (the vw term only drops it below ~desktop widths), and the min
   floor keeps it a readable 1.5rem (24px, still a large heading for the older /
   lower-vision patient audience) at 320-375px, landing the header at ~1-2 lines.
   It stays a stable <h1> (the heading-identity invariant, no data-dependent tag
   switch); text-wrap:balance evens a 2-line wrap and degrades to normal wrapping
   on older engines. Pinned by tests/test_patient_chatt_zone_dom.py. */
.kind-chat__header h1 {
  font-size: clamp(1.5rem, 4.5vw + 0.4rem, var(--kind-font-h1));
  text-wrap: balance;
}
/* A11Y-1 (2026-06-20): the message log is split into a live-region wrapper
   (.kind-chat__log, role="log") and an inner semantic list (.kind-chat__log-list,
   <ol role="list">) so the <li> message bubbles stay inside a list role. The flex
   column layout (right-aligned self-bubbles + gap) lives on the inner list, which
   is now the direct parent of the bubbles; the wrapper is a neutral block. Both
   carry flex: 1 so the log still grows to fill the chat column. */
.kind-chat__log {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: var(--kind-space-3) 0;
  /* #44 note, RETIRED PREMISE (P3-1, reviewer 2026-07-12): this rule used to
     carry the message gap too, because chatt.html + arbetsvy.html once
     rendered the <li> bubbles as DIRECT children of an
     <ol class="kind-chat__log">. Since the axe/K5 unification (2026-07-12)
     ALL four chat surfaces render the wrapper split
     (<div class="kind-chat__log"> live region around
     <ol class="kind-chat__log-list">), so .kind-chat__log is everywhere a
     single-child wrapper and a flex gap here was inert (a gap needs 2+
     children to paint); it was removed rather than left as cargo. The gap
     lives ONLY on the -list rule below, the uniform flex parent of the
     bubbles. */
}
.kind-chat__log-list {
  flex: 1;
  display: flex;
  flex-direction: column;
  /* ---- TÄTHET, konsultbeslut 2026-08-10 --------------------------------
     Kontrakt: `docs/contracts/konversationstathet-2026-08-10.md`.

     HISTORIK, så riktningsbytet syns i stället för att se ut som en slarvfel:
     #44 höjde luckan space-3 -> space-4 (12 -> 16px) och V1 P2-1
     (deploy-verify 2220d2f) vidare space-4 -> space-5 (16 -> 24px), båda på
     KIND:s begäran den 30 juni ("Utöka marginal mellan meddelanden"). Kunden
     bad sedan den 23 juli om MOTSATSEN ("chattråden får fortfarande minimalt
     utrymme ... konversationsdelen större"). De två går inte att uppfylla
     samtidigt. Konsulten vägde av 2026-08-10 och valde TÄTT, alltså att matcha
     nuvarande Kind, med den senaste feedbacken som tyngst vägande.

     TALET ÄR HÄRLETT, INTE VALT. Uppmätt i riktig webbläsare på
     vard-arbetsvy 1440x900 (`e2e/konversationstathet.mjs`, etikett "fore"):
       skrollportens höjd H  = 571px
       enradig bubbla   B1  = 83px
       lucka            gap = 24px  (--kind-space-5)
       steglängd        S1  = 107px
       kapacitet    floor(571/107) = 5 meddelanden
     Målet 7 kräver S1 <= 571/7 = 81,57px, alltså 25,43px mindre.

     LUCKAN ENSAM RÄCKER INTE, och det är hela poängen med att mäta i stället
     för att kopiera underlagets modell: största lucka som ger 7 med en 83px
     bubbla är 571/7 - 83 = -1,43px, alltså NEGATIV. Även gap: 0 ger bara 6.
     Underlagets tabell (38px lucka -> 5,4, 8px -> 7,5) modellerade bubblan
     som 68px; den är 83. Därför sänks luckan HÄR och två termer inuti bubblan
     sänks där de bor (se `.kind-chat__message` och dess `> p`), tillsammans
     32px, vilket ger S1 = 75 och kapacitet 7.

     ---- #205 RUNDA 2 VARIANT B (konsultbeslut 2026-08-15) -----------------
     Luckan tillbaka till space-5 (24px vid normal skala), FINANSIERAD av att
     enradsbubblan sjönk 67 -> 57,5px via `line-height: normal` på
     `.kind-chat__message` (produktionens eget värde; godkänd mock
     docs/design-proposals/205/runda-2/variant-b.html i agents-repot, som
     också bär rödbeviset). Golvet Ukap >= 7 vid 1440x900 HÅLLER: S1 = 57,5 +
     24 = 81,5 mot kravet <= 571/7 = 81,57. En lucka på 25px FÄLLER golvet
     (mätt i mockrundan och vaktat i e2e/tathet-rodbevis.sh M1), så 24 är ett
     exakt tal och inte en smak. 2026-08-10-beslutets två bubbeltermer
     (blockvaddering 8px, styckemarginal 0) står oförändrat kvar.

     space-5 och inte ett px-tal: luckan ska följa textskalan som förut
     (1,5rem ger 24 / 27 / 30 / 36px vid normal / large / xlarge / xxlarge).
     Delad av ALLA FYRA chattytorna (patient-chatt, vård-arbetsvy, vård-chatt,
     kollegie-chatt), vilket är avsiktligt: ändringen landar på den gemensamma
     noden och inte per rapporterad yta. Vänster/höger-placeringen (patient
     vänster, self/klinik höger via --self) är oförändrad. */
  gap: var(--kind-space-5);
  list-style: none;
  margin: 0;
  padding: 0;
}
/* G1 (V6 polish, chatt-fönster-restfix 2026-07-14, PROBLEM 1): the log HEAD holds
   the svarstid strip, the "Be om en tid" launcher and the composer-side 112/1177
   safety note. It lives INSIDE .kind-chat__log (the scroller) BEFORE the message
   list, so those blocks scroll with the thread instead of being fixed-height flex
   SIBLINGS of the log in the zoned column (as siblings they ate the column height
   and shrank the log to a ~24px sliver, the reverted V6 deploy regression
   7b86880). It sits at the HEAD (not the foot) so the land-at-newest auto-scroll
   (kind_patient_chatt_scroll.js: log.scrollTop = log.scrollHeight on load) lands
   the user on the NEWEST message (thread bottom) while the meta rests at the top
   (scroll up to see), the ordinary chat pattern. flex:0 0 auto so the head keeps
   its natural height and the message list (flex:1) still grows to fill; when the
   thread overflows, the whole log scrolls and the head scrolls up out of view. A
   flex column (not a plain block) so the children's own vertical margins do NOT
   collapse, preserving the spacing they had before the move; a margin-bottom
   separates the pinned intro from the first message. Guard:
   tests/test_patient_chatt_zone_dom.py (the DIRECT children of .kind-chat--zoned
   are only header/chip/log/compose; the head is a descendant of
   .kind-chat__log and comes BEFORE the message list; no .kind-safety card is a
   flex sibling between the log and the composer).
   WEB#564 (2026-09-24): huvudet är TOMT sedan svarstidsremsan och
   "Be om en tid" togs bort. Behållaren och ordningen står kvar; det som föll
   bort var .kind-chat__statusrad, som därför inte längre nämns här. */
.kind-chat__log-head {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  /* P3-a (V6 a11y fix-round 2026-07-15, ux ux-a11y-v6-chatt-2026-07-14 §P3-a):
     the zoned log scroller computes overflow-x:auto (from its overflow-y:auto,
     line 1017-1021), so a focusable head control flush at the log's x=0 (the
     "Be om en tid" launcher <a>, safety-card links) had its LEFT focus ring
     clipped at the scrollport edge. A space-4 (16px) inline padding moves the
     head's focusable children clear of x=0 so the ring (~6px = 3px width +
     3px offset) is never clipped (WCAG 2.4.7). RETIRED PREMISE (#205 runda 2
     B, 2026-08-15): this used to be "the SAME inset the bubbles carry", but
     the bubbles now carry space-2 inline (production's bubble character), so
     the head keeps space-4 for the FOCUS-RING reason alone. Guard:
     tests/test_chat_zoned_layout_css.py::test_log_head_has_focus_ring_inset_v6. */
  padding-inline: var(--kind-space-4);
  margin-bottom: var(--kind-space-4);
}

/* G-5 (2026-08-08): logghuvudet klistras mot scrollportens överkant, så
   svarstidsstatusen (D7) och "Be om en tid" syns för en patient med historik.

   WEB#564 (2026-09-24): BÅDA de innehållen är borta, så klistringen är i dag
   utan verkan (ett tomt huvud har ingen höjd att klistra). Regeln står ändå
   kvar, och det är ett val: den bär INGEN borttagen markup (den matchar
   `.kind-chat__log-head`, som finns kvar), och den är den mätta lösningen på
   G-5 för det ögonblick huvudet får innehåll igen. Regler som matchade noll
   element (GAP-2) togs däremot bort i samma ändring.
   Se den långa noten i templates/patient/chatt.html för varför en FAST räls
   föll på sina egna tal (49,6px normal, 105,6px xxlarge, mot en pixelmarginal
   på 28,2px) och varför klistring kostar noll fast höjd.

   Reglen ligger på HUVUDET och inte på raden inuti: en stickys
   fasthållningsrektangel är förälderns box, så en sticky rad inne i ett huvud
   som självt skrollar bort följer med bort (uppmätt y = -9803,6).

   `.kind-chat__log` är `position: relative` sedan P1-A-fixen 2026-07-12, alltså
   är scrollporten rätt referens. Ogenomskinlig bakgrund: utan den skiner
   meddelanden igenom när de skrollar under, och båda blir oläsliga.

   Scopad till `.kind-body--chat` så vårdgivarytorna, som laddar samma fil, är
   oberörda. */
.kind-body--chat .kind-chat__log-head {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--kind-color-bg);
  margin-bottom: var(--kind-space-2);
}

/* PRIORITETSORDNING NÄR PATIENTEN SKRIVER, och den kommer ur en mätning som
   fällde den första versionen av den här fixen.
 *
 * Med raden klistrad i ALLA lägen mätte 320x568 xxlarge med skrivmodulen
 * utfälld NOLL procent av det senaste meddelandet synligt: loggfönstret är då
 * 123px och den klistrade raden 135,56px vid den textskalan, alltså tog raden
 * hela fönstret. Samma sak vid 375 och 390 xxlarge. G-5 hade då lösts genom att
 * bryta GAP-2:s andra dimension, exakt den endimensionella fällan (minne
 * feedback-one-dimension-budget-moves-the-error). Det syntes bara därför att
 * mätningen bär båda måtten.
 *
 * Ordningen är därför: när patienten LÄSER (skrivmodulen i viloläge) är
 * svarstiden fastnålad, för det är då den betyder något och det är då D7 gäller
 * mot läskvittenserna. När patienten SKRIVER väger konversationen tyngre än
 * statusraden, så raden släpper och skrollar med tråden som allt annat.
 *
 * `:has()` är Baseline sedan Firefox 121 (2023-12-19), och Chrome 105 samt
 * Safari 15.4 dessförinnan. Utan stöd faller regeln bort och raden förblir
 * klistrad, alltså det läge som är rätt i de flesta tillstånd och fel bara i
 * det trängsta; ingen krasch, ingen borttappad information. */
.kind-body--chat .kind-chat:has(.kind-chat__compose.kind-compose--active) .kind-chat__log-head {
  position: static;
}
/* RADLÄNGDSTAK för läskolumnen (WCAG 2.2 SC 1.4.8, ux-underlag
   docs/ux/triage-kolumn-beslutsunderlag-2026-07-27.md avsnitt 3, kontrakt
   docs/contracts/chat-pixel-budget.md).

   VARFÖR: uppmätt i riktig webbläsare mot driftsatt 2.1.12 vid viewport 1280 är
   chattkolumnen i arbetsvyn 992px, och eftersom bubblan är 80 procent av tråden
   blir den bredaste TEXTraden 760px, alltså cirka 96 tecken (101 räknat på
   bubblans yttermått). SC 1.4.8 sätter gränsen vid 80. Det är alltså ett brott i
   DRIFT på den vanligaste klinikskärmen, inte en framtida risk, och det är värre
   på de ytor ingen klagat på: kollegie-chatten kör tråden i hela mainbredden
   (1248px, cirka 122 tecken) och patientens chatt i desktopbredd landar på
   1088px, cirka 95 tecken.

   MEKANISM: taket sitter på BEHÅLLAREN, aldrig på bubblan. Överskjutande bredd
   ska bli symmetrisk MARGINAL, inte längre rader, och bubblornas inbördes
   vänster-/högerplacering (motpart vänster, egen höger) måste bevaras. Ett tak
   på bubblan hade i stället drivit isär två bubbelkanter med ett dött fält
   emellan.

   VÄRDET: 44rem = 704px ger 0,8 x 704 - 34 = 529px textrad. Med den uppmätta
   medelteckenbredden 7,87px vid 16px blir det cirka 67 tecken, mitt i
   acceptansbandet 60 till 75 och i övre halvan av Bringhursts 50 till 75, vilket
   är rätt halva för svenska: vi bildar långa sammansättningar och avstavar inte,
   så en för smal spalt blir raggig. De 34px är bubblans egen inramning (2 x 16px
   padding plus 2 x 1px kant) och MÅSTE räknas bort, annars mäter man lådan i
   stället för texten. `ch` duger inte som enhet här: `ch` är bredden på glyfen
   `0`, inte medelbokstaven, så 70ch hade gett cirka 78 verkliga tecken, alltså
   nästan vid gränsen i stället för under den. `rem` framför `em` eftersom rem
   följer användarens rotstorlek, så teckenantalet håller sig när någon höjer
   webbläsarens grundstorlek.

   INERT DÄR LAYOUTEN REDAN ÄR BRA: vid 1366 och 1440 är chattkolumnen 636px
   (patientpanelen ligger kvar bredvid), alltså 68px UNDER taket, och patientens
   tråd är 288px vid 320 och 358px vid 390. Regeln biter bara där raderna
   faktiskt är för långa.

   `width: 100%` ÄR LOAD-BEARING, inte kosmetik. Listan är flexobjekt i en
   flexKOLUMN, så inline-axeln är KORSaxeln, och flexbox stretchar bara ett
   objekt vars korsaxelmarginaler INTE är auto (CSS Flexbox 1, 9.4 steg 11). Med
   enbart `margin-inline: auto` hade listan därför fallit tillbaka på fit-content
   och krympt till den längsta bubblans innehållsbredd: en tråd med korta
   meddelanden hade blivit en smal centrerad remsa och hela vänster-/höger-
   geometrin gått förlorad, alltså en tyst breddregression ur en breddfix.
   `width: 100%` gör bredden bestämd igen, taket klämmer den, auto-marginalerna
   centrerar resten.

   VARFÖR ÄVEN `__log-head`: huvudet är patientytans egen strip (svarstid,
   tidsbokningslänk, 112/1177-noten) och dess egen regel ovan säger uttryckligen
   att dess innehåll ska ligga i linje med bubblornas läskolumn. Kapas bara
   listan bryts den invarianten så fort taket biter, alltså på patientens
   desktopbredd. Inert på mobil, där ingetdera når 704px.

   Vakt: tests/test_chat_pixel_budget.py, avsnittet RADLÄNGD. */
.kind-chat__log-head,
.kind-chat__log-list {
  width: 100%;
  max-width: 44rem;
  margin-inline: auto;
}

/* ---- G-5: statusraden ovanför loggen. PENSIONERAD 2026-09-24 (web#564) ----
 *
 * Här låg `.kind-chat__statusrad`, `.kind-chat__statusrad-text` och
 * `.kind-chat__statusrad-cta`: den klistrade raden med D7-svarstiden och
 * avtryckaren "Be om en tid". BÅDA ELEMENTEN ÄR BORTA ur
 * templates/patient/chatt.html (KIND:s begäran om paritet med den gamla
 * patientklienten, beslutad av Alex 2026-09-24, prövad av `domain-compliance`
 * mot 942f6f5, se docs/compliance/web-564-chattytan-2026-09-24.md).
 *
 * REGLERNA TOGS BORT I SAMMA ÄNDRING OCH INTE SENARE, och skälet är husets
 * eget: GAP-2 (2026-08-08) var en selektorkedja som stod kvar i filen medan
 * den matchade NOLL element, och dess vakt var ärligt grön hela tiden. Kvar-
 * lämnade regler för borttagen markup är alltså inte harmlös dödvikt här, de
 * är exakt den felmod som redan kostat en tyst defekt.
 *
 * KLISTRINGEN LIGGER KVAR på `.kind-body--chat .kind-chat__log-head` längre
 * upp i filen, tillsammans med `:has()`-regeln som släpper den när patienten
 * skriver. Huvudet finns kvar som behållare (tomt), ordningen huvud-före-lista
 * är oförändrad, och pixelbudgeten är oberörd: raden kostade noll FAST höjd
 * redan innan, så borttagningen ger inga pixlar tillbaka och tar inga.
 *
 * Talen bakom den ursprungliga konstruktionen (fast räls 49,6px normal /
 * 105,6px xxlarge mot en marginal på 28,2px vid 390x664 och 6,8px vid 320x568,
 * kontraktets 60-procentsgolv i docs/contracts/chat-pixel-budget.md) står kvar
 * i git-historiken och i noten i templates/patient/chatt.html; de återupprepas
 * inte här, eftersom ingen regel längre vilar på dem. */
.kind-chat__message {
  max-width: 80%;
  /* #205 RUNDA 2 VARIANT B (konsultbeslut 2026-08-15): produktionens
     bubbelkaraktär pa den DELADE noden. Tre grepp i den godkända mocken
     (docs/design-proposals/205/runda-2/variant-b.html, agents-repot):
     1) Vadderingen 8px RUNTOM (space-2; inline gick 16 -> 8px, produktionens
        uppmätta värde). Blockvadderingen är oförändrad sedan 2026-08-10.
     2) `line-height: normal` i stället för husets 1,55: sänker enradsbubblan
        67 -> 57,5px och FINANSIERAR 24px-luckan pa `.kind-chat__log-list`
        (se härledningen där). Detta är ett KONSULTACCEPTERAT AVSTEG fran
        husets typskala, bokfört i kind.css-avvikelseloggen; WCAG 1.4.12
        bryts inte (användarens egen övermarkering vinner över en regel utan
        !important, verifierat i mockrundan med axe plus egen mätning).
     3) Svanshörnsradien nedan.
     Bubblans 1px kantlinje star kvar oförändrad: kanten är en icke-textuell
     gränsyta under WCAG 1.4.11 som skiljer tva meddelanden at. */
  padding: var(--kind-space-2);
  line-height: normal;
  /* Svanshörn: inkommande bär spetsen uppe till vänster, utgaende speglas
     uppe till höger (--self nedan). Literala px och inte --kind-radius:
     20/3 är produktionens uppmätta karaktärsvärden, inte husets kortform. */
  border-radius: 3px 20px 20px 20px;
  background: var(--kind-color-surface);
  border: 1px solid var(--kind-color-border);
  /* UAT round 2 P1 (2026-07-03, empirically proven on pod 2.1.4): an
     unbreakable user-authored token (a long URL / pasted no-space string) in
     the bare message <p> ran out of the bubble as text ink (computed
     overflow-wrap: normal + overflow: visible) and stretched the document to
     ~353px scrollWidth at a 320px viewport; counterfactual: anywhere on the
     message text alone restored scrollWidth 320. overflow-wrap is INHERITED,
     so setting it on the bubble covers the bare <p>, shared-card titles and
     attachment names on EVERY bubble surface (patient chatt.html + admin
     chatt/arbetsvy/team_chat_visa all render li.kind-chat__message and load
     this file). Scoped to user-generated bubble content, deliberately NOT
     global. `anywhere` only breaks inside a token when the line would
     otherwise overflow, and the bubble already carries max-width, so normal
     text and desktop rendering are unchanged. min-width: 0 releases the
     flex-item automatic minimum so a (current or future) row-flex ancestor
     can shrink the bubble below an unbreakable token's intrinsic width;
     inert in today's column-flex log (cross-axis stretch governs width), so
     no desktop layout shift. */
  overflow-wrap: anywhere;
  min-width: 0;
}
/* Tredje termen i täthetsbeslutet 2026-08-10, och den enda som är REN DÖD YTA.
 *
 * Husets `p { margin-bottom: var(--kind-space-3) }` (kind.css) gav kroppstexten
 * 12px undermarginal inuti bubblan. Metaraden under bär redan sin EGEN
 * `margin-top: var(--kind-space-1)`, och de två marginalerna KOLLAPSAR till
 * max(12, 4) = 12px. Att nolla textens undermarginal lämnar alltså kvar 4px
 * mellan text och metarad, inte noll: avståndet minskar 12 -> 4, alltså 8px.
 *
 * Uppmätt kvitto på att kollapsen är verklig och inte antagen: bubblan mätte
 * 83px = text 24 + kollaps 12 + metarad 21 + vaddering 24 + kant 2. Räknat med
 * BÅDA marginalerna adderade hade den varit 87.
 *
 * Räckvidd: `> p` träffar kroppstexten OCH metaraden, båda direkta
 * `<p>`-barn. Metaradens undermarginal är redan 0 via husets `p:last-child`
 * när den är sist, och när ett läskvittens följer bär kvittensen sin egen
 * `margin: 2px 0 0`, så regeln ändrar ingenting där. Meddelandekroppen kan
 * inte innehålla flera stycken: `_MESSAGE_ALLOWED_TAGS` är exakt
 * `["strong", "a"]`, alltså finns inget styckeavstånd inuti en bubbla att
 * råka ta bort.
 *
 * WCAG 1.4.12 Text Spacing: kriteriet kräver att innehållet TÅL användarens
 * egen övermarkering (styckeavstånd 2x teckenstorleken), inte att vi själva
 * levererar den. En författarregel utan `!important` viker för användarens
 * `!important`, så tåligheten är oförändrad. Verifierad, inte antagen, med
 * övermarkeringen påslagen på alla fyra ytorna. */
.kind-chat__message > p {
  margin-block-end: 0;
}
.kind-chat__message--self {
  align-self: flex-end;
  background: var(--kind-color-accent);
  color: var(--kind-color-text-on-accent);
  border-color: var(--kind-color-accent);
  /* Utgaende svanshörn uppe till höger, spegeln av basregelns 3px-hörn
     (#205 runda 2 B, produktionens uppmätta "20px 3px 20px 20px"). */
  border-radius: 20px 3px 20px 20px;
}
.kind-chat__message--self a { color: var(--kind-color-text-on-accent); text-decoration: underline; }
.kind-chat__message-meta {
  font-size: var(--kind-font-small);
  margin-top: var(--kind-space-1);
  display: flex;
  gap: var(--kind-space-2);
  align-items: center;
}
/* P-03 fix (2026-05-30, re-themed 2026-06-02, coral-CORRECTED 2026-06-02): the
   self-bubble meta uses the --kind-color-text-on-accent token (solid white) on the
   accent bubble, never a tint. After the kind.app coral re-theme the accent is
   --kind-color-accent and white-on-it is 5.26:1, comfortably past WCAG 2.2 AA
   1.4.3 4.5:1. NOTE: do NOT add opacity here, a translucent white over the accent
   would composite below AA. The meta stays visually subordinate via the smaller
   --kind-font-small size, not via reduced contrast. Token-driven, so it tracks any
   future accent change. */
/* ---- F-30: DAGSSEPARATOR (chattråden, konsultbeslut 2026-08-14) -----------
 *
 * Produktionens chattråd (`e2e/paritet-utdata/prod-2026-08-14/chatt-full.png`)
 * bryter tråden med en liten grå CENTRERAD rad per svenskt kalenderdygn,
 * `Idag` respektive `Igår`. Uttrycket är medvetet TYST: raden ska kunna hoppas
 * över av ögat och bara finnas där när man letar.
 *
 * VARFÖR ETT EGET REGELBLOCK OCH INTE EN `--variant` PÅ `.kind-chat__message`:
 * separatorn ÄR inget meddelande. Den ska varken ha bubblans bakgrund, dess
 * 1px-kant, dess `max-width: 80%` eller dess vaddering, och den ska inte
 * räknas som en bubbla av täthetsinstrumentet (`e2e/konversationstathet.mjs`
 * räknar `li.kind-chat__message`). Att ge den bubbelklassen och sedan nolla
 * fyra egenskaper hade varit fyra tysta beroenden i stället för noll.
 *
 * `align-self: center` och inte `text-align`: listan är en flexkolumn med
 * vänsterställda bubblor och högerställda `--self`-bubblor, alltså styr
 * TVÄRAXELN placeringen. `text-align` hade centrerat texten INUTI en
 * vänsterställd, innehållsbred låda, vilket ser centrerat ut bara när texten
 * råkar vara lika bred som lådan.
 *
 * INGEN EGEN MARGINAL. Listans `gap: var(--kind-space-2)` ger redan 8px på
 * BÅDA sidor om raden, alltså kostar separatorn sin egen linjebox och
 * ingenting mer. En extra marginal hade lagt 4 till 8px per dygnsbyte i en
 * skrollport som är kundens uttalade klagomål (`chat-pixel-budget.md`).
 *
 * KONTRAST: `--kind-color-text-muted` (#626C77) mäter 5,34:1 mot chattens
 * `--kind-color-surface` (#FFFFFF), alltså över WCAG 2.2 AA 1.4.3:s 4,5:1 för
 * normaltext. Tokendriven, så den följer en framtida temaändring, och i
 * mörkt läge är samma token 7,62:1. `--kind-font-small` är 14px, alltså över
 * husets absoluta golv 13px. Färgen bär INTE information ensam (1.4.1):
 * raden är text, och dess betydelse är dess ord. */
.kind-chat__dagsseparator {
  align-self: center;
  color: var(--kind-color-text-muted);
  font-size: var(--kind-font-small);
  line-height: 1.5;
}
.kind-chat__message--self .kind-chat__message-meta { color: var(--kind-color-text-on-accent); }
.kind-chat__message:not(.kind-chat__message--self) .kind-chat__message-meta { color: var(--kind-color-text-muted); }

/* #48 + 2.1b DISCREET per-message read-receipt marker (persona-patient spec
   docs/design/readindicator-discreet-2.1b-2026-07-02.md). Rendered under a PATIENT
   message's meta line. It carries the ADR-011 honest state as a ONE-vs-TWO check
   glyph (form) + a single visible WORD (never colour-alone, WCAG 1.4.1):
     - "mottaget" -> a single ✓, visible word "Mottaget".
     - "oppnad"   -> a double ✓✓, visible word "Sett".
   2.1b: the old two-line label + always-visible micro-sentence read like a
   banner-in-miniature; now it is ONE discreet inline line (glyph + word), and the
   full honesty sentence moves to title= + a .kind-visually-hidden span (template),
   never to visible body text. It reads as meta-text, not a heading: small,
   normal-weight, inline, muted-subordinate (matches the .kind-chat__message-meta
   line above it). It is static text, NOT a control (no tap target / expander,
   2.1b: do not re-introduce chrome).
   Contrast: on the coral self-bubble the icon + word stay on-accent WHITE (5.34:1,
   AA); the aria-hidden decorative glyph carries no standalone meaning so 1.4.11 is
   exempt; the meaning is in the ONE-vs-TWO check FORM + the visible word. */
.kind-chat__receipt {
  display: inline-flex;
  align-items: baseline;
  gap: var(--kind-space-1);
  margin: 2px 0 0;
  font-size: var(--kind-font-small);
  font-weight: 400;
  line-height: 1.3;
}
.kind-chat__receipt-icon {
  display: inline-flex;
  flex: 0 0 auto;
  align-self: center;
}
.kind-chat__receipt-word { white-space: nowrap; }
/* The receipt sits inside the coral self-bubble. The MEANING is carried by the
   ONE-vs-TWO check FORM + the visible word ("Mottaget" / "Sett"), so on the
   self-bubble the icon + word stay on-accent WHITE (5.34:1, AA) rather than a
   low-contrast green-on-coral. This keeps 1.4.1 (never colour-alone: form + word)
   and 1.4.3 AA satisfied. On the rare non-self surface (should not occur, patient
   receipts only render on the patient's own messages) the ✓✓ falls back to
   success-green and ✓ to muted, still form + word carried. */
.kind-chat__receipt { color: var(--kind-color-text); }
.kind-chat__receipt--oppnad .kind-chat__receipt-icon { color: var(--kind-color-success); }
.kind-chat__receipt--mottaget .kind-chat__receipt-icon { color: var(--kind-color-text-muted); }
.kind-chat__message--self .kind-chat__receipt,
.kind-chat__message--self .kind-chat__receipt .kind-chat__receipt-icon {
  color: var(--kind-color-text-on-accent);
}

/* web#466: patientens bekräftelse av en BEGÄRD läskvittens. Renderas bara på
   vårdgivarens meddelanden (aldrig i .kind-chat__message--self), och bara när
   vårdgivaren uttryckligen bett om en kvittens, så den kostar noll pixlar i en
   vanlig tråd. Knappen har 44px touchmål (WCAG 2.1 AA 2.5.5) via .kind-btn.
   MEDVETET INTE stilad som .kind-chat__receipt: den diskreta ✓/✓✓-statusen är en
   härledd observation, det här är en handling patienten ska se att hon kan
   göra. Att göra dem visuellt lika hade bjudit in exakt den sammanblandning
   web#466 finns för att ta bort. */
.kind-chat__bekraftelse {
  margin: var(--kind-space-2) 0 0;
  padding: var(--kind-space-2);
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius);
  background: var(--kind-color-surface);
}
.kind-chat__bekraftelse-fraga {
  margin: 0 0 var(--kind-space-2);
  font-size: var(--kind-font-small);
  line-height: 1.4;
}
.kind-chat__bekraftelse--klar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--kind-space-1);
  font-size: var(--kind-font-small);
  color: var(--kind-color-text-muted);
}

/* B2 (snabbtest, 2026-06-04): the attachment is a real download <a> (was static
   text). Loaded by BOTH chat templates (admin links this file explicitly), so the
   link reads identically on the patient + clinician surface. A11y notes:
   - own muted surface + dark text, so it RE-ASSERTS dark text inside a
     .kind-chat__message--self bubble (line 146 would otherwise force white link
     text on its own muted background, dropping below AA);
   - min-height 44px (WCAG 2.1 AA 2.5.5 touch target);
   - the two-tone focus ring (white box-shadow ring + offset coral outline) is the
     same pattern as the article card so it stays visible inside the coral
     self-bubble where a bare coral outline would be invisible. */
.kind-chat__attachment,
.kind-chat__attachment-open {
  display: flex;
  align-items: center;
  gap: var(--kind-space-2);
  min-height: 44px;
  max-width: 100%;
  margin-top: var(--kind-space-2);
  padding: var(--kind-space-2) var(--kind-space-3);
  background: var(--kind-color-surface-muted);
  border-radius: var(--kind-radius);
  font-size: var(--kind-font-small);
  color: var(--kind-color-text);
  text-decoration: underline;
}
.kind-chat__attachment[hidden],
.kind-chat__attachment-open[hidden] {
  display: none;
}
.kind-chat__attachment-group {
  display: grid;
  gap: var(--kind-space-2);
  max-width: 100%;
}
.kind-chat__attachment-trigger {
  width: 100%;
  border: 0;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.kind-chat__attachment-trigger:disabled {
  cursor: wait;
  opacity: 0.75;
}
.kind-chat__attachment-preview {
  max-width: min(100%, 32rem);
  padding: var(--kind-space-2);
  overflow: hidden;
  background: var(--kind-color-surface-muted);
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius);
}
.kind-chat__attachment-image {
  display: block;
  width: auto;
  max-width: 100%;
  max-height: 32rem;
  margin-inline: auto;
  object-fit: contain;
  border-radius: calc(var(--kind-radius) / 2);
}
.kind-chat__attachment-image[hidden] {
  display: none;
}
/* web#900: the image is a thumbnail in the bubble; a tap opens it fullscreen. */
.kind-chat__attachment-thumb {
  display: block;
  cursor: zoom-in;
}
.kind-chat__attachment-thumb .kind-chat__attachment-image {
  max-height: 16rem;
}
/* web#1228: the static notice that replaces a thumbnail whose bytes did not
 * load (kind_attachment_reveal.js). Plain text in the preview box; the download
 * link below stays as it was. */
.kind-chat__attachment-failed {
  margin: 0;
  color: var(--kind-color-text-muted, inherit);
  font-size: 0.875rem;
}
.kind-chat__attachment-image:fullscreen {
  max-height: none;
  background: #000;
}
/* web#469: the revealed video. Same box discipline as the image above -- it must
 * never widen the chat bubble or force horizontal scroll at 320px / 200% zoom
 * (WCAG 1.4.10 reflow), so it shrinks with the column and is capped in height.
 * `background: #000` is the letterbox, not decoration: a video element with no
 * poster (deliberately -- a poster would fetch bytes before the reveal click)
 * paints transparent until a frame exists, and a transparent media box over the
 * muted surface reads as a broken element. */
.kind-chat__attachment-video {
  display: block;
  width: 100%;
  max-width: 100%;
  max-height: 32rem;
  margin-inline: auto;
  background: #000;
  border-radius: calc(var(--kind-radius) / 2);
}
.kind-chat__attachment-video[hidden] {
  display: none;
}
/* A long unbreakable filename token (Provsvar_2026_xyz...pdf) must wrap inside
 * the chat bubble and never force horizontal scroll at 320px / high zoom
 * (WCAG 1.4.10 reflow). Mirrors the .kind-tidslinje__titel pattern; min-width:0
 * lets the flex item shrink below its content size so the break can happen. */
.kind-chat__attachment-name {
  overflow-wrap: anywhere;
  word-break: break-word;
  min-width: 0;
}
.kind-chat__message--self .kind-chat__attachment,
.kind-chat__message--self .kind-chat__attachment-open {
  color: var(--kind-color-text);
  text-decoration: underline;
}
.kind-chat__attachment:hover,
.kind-chat__attachment-open:hover {
  background: var(--kind-color-surface);
}
.kind-chat__attachment:focus-visible,
.kind-chat__attachment-open:focus-visible {
  outline: var(--kind-focus-ring);
  outline-offset: 3px;
  box-shadow: 0 0 0 3px var(--kind-color-surface);
}
.kind-chat__attachment-icon {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  color: var(--kind-color-accent);
}
.kind-chat__message--self .kind-chat__attachment-icon { color: var(--kind-color-accent); }

/* AT-17 shared-article card (kind.app coral, 2026-06-02).
   A shared article renders as <a class="kind-card kind-chat__artikel-card"> inside
   a .kind-chat__message bubble. This file is loaded by BOTH chat templates (the
   admin template links it explicitly), so the card is styled once here and reads
   identically on the patient + the clinician surface.
   A11y notes:
   - The card is a self-contained coral panel with its OWN warm surface + dark text,
     so it RE-ASSERTS dark text even when it lands inside a .kind-chat__message--self
     bubble (which otherwise forces white link text via line 85). Token-driven dark
     text on the blush card is 15.37:1 (accent-soft surface), the coral eyebrow +
     "Las artikel" affordance are --kind-color-accent (4.63:1 on accent-soft, past
     WCAG 2.1 AA 1.4.3 4.5:1).
   - The whole card is one <a>, so the entire 16px-radius panel is the click/tap
     target (well past the 44x44 CSS-px floor, WCAG 2.5.5); the focus ring is the
     shared accent ring inherited from kind.css. */
.kind-chat__artikel-card {
  display: flex;
  align-items: flex-start;
  gap: var(--kind-space-3);
  max-width: 22rem;
  padding: var(--kind-space-4);
  /* CP-02-resten (#87): hela kortet ar en <a> (se a11y-noten ovan), alltsa den
     klickbara enheten. Accentstapeln till vanster markerade bara EN av fyra
     kanter; de tre ovriga lag pa hairlinen. Mattet tas mot bararytan bakom
     bubblan (3.34:1 vit, 3.11:1 arbetsyta), inte mot kortets egen accent-soft-
     fyllning, som ar kanten inat. */
  border: 1px solid var(--kind-color-border);
  border-left: 4px solid var(--kind-color-accent);
  border-radius: var(--kind-radius);
  background: var(--kind-color-accent-soft);
  color: var(--kind-color-text);
  text-decoration: none;
  box-shadow: var(--kind-shadow-sm);
  transition: box-shadow 120ms ease, transform 120ms ease;
}
.kind-chat__artikel-card:hover {
  box-shadow: var(--kind-shadow-md);
  transform: translateY(-1px);
}
/* Focus ring (WCAG 2.1 AA 2.4.7). The card can sit inside a coral
   .kind-chat__message--self bubble, and the shared focus ring (--kind-focus-ring) is
   the SAME coral as that bubble, so a bare coral outline is invisible against it
   (verified 2026-06-02 keyboard-focus screenshot). A two-tone ring fixes it on
   every background, from the card edge outward: a 3px surface-white box-shadow
   ring, then the coral outline offset to 3px so it sits just OUTSIDE the white
   ring (not touching the coral bubble). White-on-coral is 5.34:1 (the white ring
   is the visible cue inside the self-bubble) and the coral outline is the cue on
   the page / white patient bubble. The outline is retained (not box-shadow-only)
   so Windows High-Contrast / forced-colors users, where box-shadow is stripped,
   still get the system focus outline; kind.css already repoints the HC ring to
   black/white. */
.kind-chat__artikel-card:focus-visible {
  outline: var(--kind-focus-ring);
  outline-offset: 3px;
  box-shadow: 0 0 0 3px var(--kind-color-surface), var(--kind-shadow-md);
}
/* When the article card sits in a self-bubble, the bubble rule (line 85) would
   paint the card link white; re-assert the card's own dark text + coral accent so
   it stays legible on the blush card surface in either bubble. */
.kind-chat__message--self .kind-chat__artikel-card,
.kind-chat__message--self .kind-chat__artikel-card .kind-chat__artikel-titel {
  color: var(--kind-color-text);
  text-decoration: none;
}
.kind-chat__artikel-icon {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--kind-radius-pill);
  background: var(--kind-color-surface);
  color: var(--kind-color-accent);
  box-shadow: var(--kind-shadow-sm);
}
/* web#618 punkt 5: artikelkortets OMSLAGSBILD, som ersätter bokikonen när
 * inlägget har ett omslag (gamla KIND `MessageTypeArticlePreview`, mod/2363).
 *
 * EXAKT SAMMA BOX SOM IKONEN DEN ERSÄTTER: 2.75rem i kvadrat, `flex: 0 0 auto`,
 * samma skugga. Det är ett höjdbeslut och inte en slump — chattraden mäts
 * (`tests/test_chat_pixel_budget.py`, `scripts/chattraden_stubrender.py`), och
 * ett kort som växer när artikeln råkar ha ett omslag hade flyttat budgeten på
 * en datamängd i stället för på en ändring. Enda skillnaden mot ikonen är
 * hörnradien: en bild i en pill-form beskärs till oigenkännlighet, så den får
 * kortets egen radie.
 *
 * `object-fit: cover` så ett omslag i valfritt bildförhållande fyller rutan
 * utan att förvrängas. Bakgrunden är kvar under bilden och bär både
 * laddningstillståndet och CP-17:s platshållare, som ÄRVER bildens klasser när
 * den byter ut en trasig <img>. */
.kind-chat__artikel-omslag {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--kind-radius);
  background: var(--kind-color-surface);
  overflow: hidden;
  box-shadow: var(--kind-shadow-sm);
}
.kind-chat__artikel-omslag-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.kind-chat__artikel-body {
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-1);
  min-width: 0;
}
.kind-chat__artikel-eyebrow {
  font-size: var(--kind-font-small);
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--kind-color-accent);
}
.kind-chat__message--self .kind-chat__artikel-card .kind-chat__artikel-eyebrow,
.kind-chat__message--self .kind-chat__artikel-card .kind-chat__artikel-link {
  color: var(--kind-color-accent);
}
.kind-chat__artikel-titel {
  font-family: var(--kind-font-serif);
  font-size: 1.0625rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--kind-color-text);
}
/* Wave B videomöte card meta line (date/time + clinician). Muted, sits between
   the titel and the "Starta videomötet" link on the inline kalenderinbjudan
   card; uses the same artikel-card scaffolding as the share cards. */
.kind-chat__artikel-meta {
  font-size: var(--kind-font-small);
  color: var(--kind-color-text-muted);   /* 5.87:1 on bg, past AA */
  line-height: 1.4;
}
.kind-chat__message--self .kind-chat__artikel-card .kind-chat__artikel-meta {
  color: var(--kind-color-text-muted);
}

/* #532: harledd formularstatus pa det delade formularkortet ("Ej besvarat" /
   "Besvarat"). Samma dampade behandling som artikel-meta ovan: statusen ar en
   biupplysning pa kortet, inte dess rubrik. En regel racker for ALLA TRE
   ytorna, eftersom vardgivarportalen laddar kind_patient.css efter kind.css
   (se admin/_chat_composer.html).

   INGEN FARGKODNING. Statusens barare ar ordet, per acceptanskriterium 3 i
   #532 (lasbar for skarmlasare) och WCAG 1.4.1: en gron eller gra prick hade
   gjort farg till enda signal. `data-kind-formular-status` finns for e2e och
   for en framtida visuell forstarkning, aldrig som statusens barare. */
.kind-chat__formular-status {
  font-size: var(--kind-font-small);
  font-weight: 600;
  color: var(--kind-color-text-muted);   /* 5.87:1 pa bg, past AA */
}
.kind-chat__message--self .kind-chat__artikel-card .kind-chat__formular-status {
  color: var(--kind-color-text-muted);
}
.kind-chat__artikel-link {
  display: inline-flex;
  align-items: center;
  gap: var(--kind-space-1);
  margin-top: var(--kind-space-1);
  font-size: var(--kind-font-small);
  font-weight: 600;
  color: var(--kind-color-accent);
}
.kind-chat__artikel-link::after {
  content: "\2192";                        /* rightwards arrow, decorative affordance */
  font-size: 1.1em;
  line-height: 1;
}
.kind-chat__artikel-card:hover .kind-chat__artikel-link,
.kind-chat__artikel-card:focus-visible .kind-chat__artikel-link {
  color: var(--kind-color-accent-hover);
  text-decoration: underline;
}

/* #576 punkt 4: beskedet under en artikeldelning vars kort inte gick att
   rendera (hårdraderad artikel -> `artikel_id` nollad av FK:ns ON DELETE SET
   NULL). Renderas av `templates/admin/chatt.html` och `arbetsvy.html` som en
   egen rad EFTER den lagrade textbubblans innehåll, aldrig i stället för den.

   INGEN EGEN FÄRGKODNING, med avsikt: beskedet är TEXT, och dess betydelse är
   dess ord (WCAG 2.2 AA 1.4.1 — färg får inte bära information ensam). Det
   enda uttrycket är att raden är visuellt underordnad, via --kind-font-small
   (14px, över husets golv 13px) och en dämpad textfärg.

   KONTRAST, båda bubbeltyperna, och de kräver olika token: delningen är i
   praktiken alltid en UTGÅENDE bubbla hos vårdgivaren
   (.kind-chat__message--self, accentfylld), där --kind-color-text-muted hade
   legat under AA. Där används --kind-color-text-on-accent (solid vit, 5,26:1
   mot accenten), samma val och samma skäl som .kind-chat__message-meta gör en
   bit upp i filen — och av exakt samma skäl INGEN opacity, en genomskinlig vit
   över accenten komponerar under 4,5:1. I en inkommande bubbla (vit yta)
   används --kind-color-text-muted (#626C77, 5,34:1 mot --kind-color-surface,
   7,62:1 i mörkt läge). Tokendrivet, så det följer en framtida temaändring. */
.kind-chat__artikel-saknas {
  font-size: var(--kind-font-small);
  margin-top: var(--kind-space-1);
  margin-bottom: 0;
  color: var(--kind-color-text-muted);
}
.kind-chat__message--self .kind-chat__artikel-saknas {
  color: var(--kind-color-text-on-accent);
}

/* Article-picker compose row (admin "Dela en artikel" form): the select + the
   submit button sit on one baseline-aligned row, wrapping on narrow widths. */
.kind-chat__compose--artikel .kind-chat__artikel-row {
  display: flex;
  gap: var(--kind-space-3);
  align-items: flex-end;
  flex-wrap: wrap;
}
.kind-chat__compose--artikel .kind-chat__artikel-field {
  flex: 1;
  min-width: 240px;
}

.kind-chat__compose {
  border-top: 1px solid var(--kind-color-border);
  padding-top: var(--kind-space-4);
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-3);
  /* #47 (chatt-yta 2.1): sticky skrivfält. The composer sticks to the bottom of
     the SCROLLING thread column (not the viewport), so it stays reachable as the
     patient scrolls a long thread. The fixed .kind-tabbar (56px + safe-area, z
     200) sits at the viewport bottom, so the composer's sticky `bottom` is offset
     by that height + a small gap: `bottom: 0` alone would park the composer's
     action row UNDER the tabbar (verified: the Skicka button clipped behind the
     tabbar at 320px). Now it floats just ABOVE the tabbar. z 20 keeps it UNDER
     popovers + the tabbar but OVER the thread (spec DEL A "Sticky skrivfält"). An
     opaque page bg so the thread does not show through. */
  position: sticky;
  bottom: calc(56px + env(safe-area-inset-bottom, 0px) + var(--kind-space-2));
  z-index: 20;
  background: var(--kind-color-bg);
}
.kind-chat__compose-row {
  display: flex;
  gap: var(--kind-space-3);
  flex-wrap: wrap;
  align-items: flex-start;
  /* #178: "+"-KNAPPENS TRÄFFYTEGOLV PÅ FÄLTETS RAD.
   * 48px är patientens träffytegolv (WCAG 2.5.8) och ligger över vårdgivarytans
   * 44px, alltså är den gemensamma siffran den HÖGRE, aldrig den lägre.
   * Deklarerad här och inte i kind_admin.css eftersom alla fyra chattytorna
   * laddar den här filen, medan bara klinikerytorna laddar den andra.
   *
   * NOTERA att det här är ett GOLV och inte knappens faktiska bredd: vid
   * textskala xxlarge mäter knappen 58px, eftersom `padding-inline` är
   * rem-baserad och skalar med rotens teckenstorlek. Fältets golv nedan får
   * därför INTE subtrahera den här siffran, se noten där. */
  --kind-komposer-plus: 48px;
}
.kind-chat__compose-row .kind-field { flex: 1; min-width: 240px; }
/* #178: FÄLTETS GOLV MÅSTE LÄMNA PLATS ÅT "+" PÅ SAMMA RAD.
 *
 * Uppmätt efter att knappen flyttat in i raden, före den här regeln: i AKTIVT
 * läge vid 320px och 390px bröt fältet till en EGEN rad UNDER knappen, alltså
 * mått P "ovanfor" i stället för "vanster". Räkningen: innehållsbredden är
 * 288px vid 320px viewport, och `48 + 12 + 240 = 300`. Knappen låg stilla
 * (radDx/radDy 0,0 i båda lägena), så CP-20:s klicktjuv var aldrig tillbaka,
 * men fältet flyttade sig, och kravet "samma plats i båda lägena" handlar just
 * om relationen till fältet.
 *
 * VARFÖR EN PROCENT OCH INTE `calc(100% - knappbredd - gap)`. Första försöket
 * subtraherade knappens 48px-golv och var grönt vid normal textskala men RÖTT
 * vid xxlarge på 320px: knappen mäter då 58px, eftersom `padding-inline` är
 * rem-baserad och skalar med rotens teckenstorlek, alltså var reservationen
 * 10px för liten och raden bröt igen. En pixelformel måste känna till knappens
 * ikonstorlek, vaddering och ram, och driver isär så fort någon av dem ändras.
 * Golvet uttrycks därför som en ANDEL av raden: meddelandefältet behåller
 * alltid minst 55 procent av sin egen rad. Vid det tyngsta uppmätta
 * tillståndet (xxlarge, 320px) får fältet 218px av 288px, alltså 76 procent,
 * så golvet har 21 procentenheters marginal och binder bara när raden ändå är
 * för smal för 240px.
 *
 * `min()` behåller alltså 240px-golvet överallt där det får plats. Procenten
 * löses mot flexbehållarens innehållsbredd, så regeln följer arbetsvyns smala
 * mittkolumn utan en egen brytpunkt. VILOLÄGET är opåverkat: dess egen regel
 * `min-width: 0` har högre specificitet (0,4,0) och står kvar.
 *
 * Selektorn kräver att knappen FAKTISKT ligger före fältet i raden. Ligger den
 * inte där (en framtida yta som inte flyttat med) matchar regeln inte och det
 * gamla 240px-golvet gäller oförändrat, alltså ingen tyst sänkning på en yta
 * som inte behöver den. */
.kind-chat__compose-row > .kind-compose__share-trigger ~ .kind-field {
  min-width: min(240px, 55%);
}

/* K27: RADEN BÄR TVÅ KONTROLLER NU, ALLTSÅ MÅSTE FÄLTETS GOLV SÄNKAS.
 *
 * Golvet ovan (55 procent) räknades för EN knapp på raden. Bifoga-knappen är
 * den andra, och 55-procentsgolvet är då inte längre uppfyllbart i det tyngsta
 * rimliga tillståndet, alltså bryter raden och fältet hamnar på egen rad.
 *
 * TALEN ÄR UPPMÄTTA, INTE RÄKNADE. Första versionen av den här regeln satte 45
 * procent ur en handräkning på 288px rad och 12px gap. Den var FEL: både radens
 * innehållsbredd och gapet är rem-baserade och krymper respektive växer med
 * textskalan, så vid xxlarge är raden 272px och gapet 18px, inte 288 och 12.
 * Det är exakt den drift noten ovan varnar för, och den upprepades här innan
 * mätningen fångade den. Uppmätt utrymme kvar åt fältet, patientchatten,
 * AKTIVT läge, med båda knapparna på raden:
 *
 *   skala     320px viewport        390px viewport
 *   normal    168px av 288 = 58,3%  238px av 358 = 66,5%
 *   large     159px av 284 = 56,0%  229px av 354 = 64,7%
 *   xlarge    146px av 280 = 52,1%  216px av 350 = 61,7%
 *   xxlarge   120px av 272 = 44,1%  190px av 342 = 55,6%
 *
 * Bindande fall är alltså xxlarge vid 320px, 44,1 procent. Golvet sätts till
 * 40 procent, vilket ger 4,1 procentenheters marginal.
 *
 * VARFÖR EN RAD OCH INTE EN BRYTNING, avgjort med mätning och inte med tycke.
 * Att låta raden bryta vid xxlarge/320 lät först som det tillgängliga valet
 * (reflow framför hoptryckning). Mätningen säger motsatsen: med brytning växer
 * skrivmodulen från 172px till 248px och `.kind-chat__log` kollapsar från 112px
 * till 36px, alltså från 19,7 till 6,3 procent av viewporten. Konversationen
 * försvinner nästan helt medan patienten skriver, på den minsta skärmen med den
 * största texten. Med golvet nedan är loggen 112px, IDENTISKT med före bygget,
 * i samtliga tolv mätta kombinationer av skala, bredd och läge. Fältet blir
 * smalare (120px vid xxlarge/320) men textarean växer på HÖJDEN, så ingen text
 * går förlorad, medan de 76 pixlarna konversationsyta gör det.
 *
 * VARFÖR DET INTE ÄR EN UPPMJUKNING AV EN VAKT (regel 49b). 55 var ett MEDEL
 * för att hålla fältet på raden med EN knapp. Utfallsmåttet är konversationens
 * yta, och det är OFÖRÄNDRAT av den här raden, medan alternativet sänker det
 * med 76px. Ändras premissen igen, alltså en tredje kontroll på raden, ska
 * tabellen mätas om och skrivas om, aldrig gissas.
 *
 * Selektorn kräver att bifoga-knappen FAKTISKT ligger i raden. Saknas den
 * matchar regeln inte och 55-procentsgolvet gäller oförändrat, alltså ingen
 * tyst sänkning på en yta som bara har "+". Samma specificitet (0,3,0) som
 * regeln ovan, så källordningen avgör och den här måste stå EFTER. */
/* #395 variant B: gemet bor numera i kvittensgruppen .kind-attachvald, som är
 * radens direkta barn i stället för knappen själv. Selektorlistan täcker BÅDA
 * formerna, så en yta som ännu bär knappen bar (vårdgivarens framtida flytt)
 * får samma golv utan egen regel. Samma specificitet, samma källposition. */
.kind-chat__compose-row > .kind-compose__attach-trigger ~ .kind-field,
.kind-chat__compose-row > .kind-attachvald ~ .kind-field {
  min-width: min(240px, 40%);
}

/* K27: bifoga-knappen delar "+"-knappens form (ikonstorlek, träffytegolv,
 * kompakt vaddering) genom att bära `.kind-compose__share-trigger`, så den här
 * regeln behöver bara golvet för egen del. Den ligger som ANDRA barn i raden,
 * före fältet, alltså gäller `.kind-chat__compose-row > ...`-reglerna ovan den
 * också. `.kind-btn[hidden] { display: none }` på basklassen (kind.css) är det
 * som håller den dold tills skriptet avslöjar den. */
.kind-chat__compose-row > .kind-compose__attach-trigger,
.kind-chat__compose-row > .kind-attachvald > .kind-compose__attach-trigger {
  flex: 0 0 auto;
  min-width: var(--kind-komposer-plus);
}

/* ==========================================================================
 * #395 VARIANT B (godkänd mock docs/design-proposals/395/variant-b.html,
 * BESLUT.md 2026-08-24): filnamnskvittens PÅ GEMRADEN. Gemet + filnamn + x
 * som EN grupp; gemknappen får --vald (fylld) när en fil är vald. Enda
 * varianten som håller pixelbudgetens 60px-vilotak (55px uppmätt) och
 * loggolvet 60 procent (65,0) med vald fil i vila.
 *
 * MOCKAVVIKELSE, avsiktlig: mocken renderade bara gruppen i valt läge och
 * behövde ingen modifierare; i drift finns gruppen alltid (den ÄGER gemet),
 * så chipdekoren och radbeteendet nycklas på .kind-attachvald--vald. I
 * neutralt läge är gruppen en odekorerad inline-flex-låda runt enbart gemet,
 * samma fotavtryck som den bara knappen.
 * ====================================================================== */
.kind-attachvald {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  min-width: 0;
}
/* [hidden]-guard (regel 27 korollarium 2 / P1-1-mekanismen): display ovan är
 * en författardeklaration och slår annars UA-arkets [hidden]-regel. Gruppen
 * renderas hidden och avslöjas av kind_composer_attach.js ihop med gemet. */
.kind-attachvald[hidden] { display: none; }
.kind-attachvald--vald {
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius-pill);
  background: var(--kind-color-accent-soft);
  padding: 0 2px 0 0;
  min-height: 48px;
  font-size: 0.94rem;
  color: var(--kind-color-text);
}
/* Aktivt läge: kvittensgruppen tar EGEN rad över fältet, så det långa namnet
 * får radbredden och fältet behåller sin fulla bredd (mockmätning: utan detta
 * kläms fältet till 270px vid 1440 och textytan växer 107px på höjden). */
.kind-compose--active .kind-attachvald--vald {
  flex: 1 1 100%;
  max-width: max-content;
}
/* Viloläge: EN rad, gruppen trunkerar och fältet står kvar bredvid. Det är
 * variantens poäng: viloläget kostar +2px mot baslinjens 53 (55 mot tak 60). */
.kind-compose--collapsed .kind-attachvald--vald {
  flex: 0 1 auto;
  max-width: min(60%, 320px);
}
.kind-compose__attach-trigger--vald {
  background: var(--kind-color-accent);
  color: #fff;
  border-color: var(--kind-color-accent);
}
.kind-compose__attach-trigger--vald:hover { background: var(--kind-color-accent-hover); }
/* Feltillstånd: gemet markeras vid sin källa (mockens "markerat gem"). */
.kind-compose__attach-trigger--fel {
  outline: 2px solid var(--kind-color-error);
  outline-offset: 2px;
}
.kind-attachvald__namn {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kind-attachvald__suffix { flex: 0 0 auto; padding-inline-end: 2px; }
.kind-attachvald__tabort {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  border: 0;
  border-radius: var(--kind-radius-pill);
  background: transparent;
  color: var(--kind-color-text-muted);
  cursor: pointer;
}
.kind-attachvald__tabort:hover,
.kind-attachvald__tabort:focus-visible {
  background: var(--kind-color-surface);
  color: var(--kind-color-text);
}
.kind-attachvald__tabort:focus-visible {
  outline: var(--kind-focus-ring);
  outline-offset: 2px;
}
/* [hidden]-guard för x-knappen (display:inline-flex ovan); namn- och
 * suffix-spannen författar ingen display och behöver ingen. */
.kind-attachvald__tabort[hidden] { display: none; }

/* #395 punkt 3: klientfelremsan vid otillåten filtyp (role=alert i mallen).
 * Ligger ovanför komposerraden; hidden i vila, alltså 0px mot pixelbudgeten. */
.kind-filfel {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 0 0 var(--kind-space-2);
  padding: var(--kind-space-2) var(--kind-space-3);
  border: 1px solid var(--kind-color-error);
  border-radius: var(--kind-radius);
  background: var(--kind-color-error-bg);
  color: var(--kind-color-text);
  font-size: 0.94rem;
  line-height: 1.45;
}
/* [hidden]-guard: display:flex ovan slår annars UA-regeln (P1-1). */
.kind-filfel[hidden] { display: none; }
.kind-filfel__ikon {
  flex: 0 0 auto;
  color: var(--kind-color-error);
  margin-top: 2px;
  display: inline-flex;
}
.kind-filfel__text { margin: 0; min-width: 0; overflow-wrap: anywhere; }

/* ---- web#489: vårdgivarrutans upplysning och delningsutfall ---------------
 *
 * Bor här och inte i kind_admin.css av samma skäl som .kind-filfel ovan: den
 * DELADE skrivmodulen (templates/admin/_chat_composer.html) renderar bagaget,
 * och båda vårdgivarytorna (admin/chatt.html, admin/arbetsvy.html) laddar den
 * här filen. Två kopior hade kunnat drifta isär; en kan det inte.
 *
 * PIXELBUDGETEN ÄR ORÖRD (docs/contracts/chat-pixel-budget.md): allt här bor
 * inuti popoverns delningsruta, som är [hidden] i skrivmodulens viläge.
 *
 * `:empty { display: none }` är det som låter kvittens- och felregionen ligga
 * KVAR i DOM:en från första render utan att synas. En live-region som skapas
 * först när texten ska in hinner ofta inte bli observerad av hjälpmedlet
 * (WCAG 2.2 SC 4.1.3), medan en tom och döld nod annonserar sin första text
 * pålitligt. */
.kind-fildelning__upplysning {
  margin: 0 0 var(--kind-space-2);
  color: var(--kind-color-text-muted);
  font-size: 0.94rem;
  line-height: 1.45;
}
.kind-fildelning__kvitto,
.kind-fildelning__fel {
  margin: 0 0 var(--kind-space-2);
  padding: var(--kind-space-2) var(--kind-space-3);
  border-radius: var(--kind-radius);
  font-size: 0.94rem;
  line-height: 1.45;
  overflow-wrap: anywhere;
}
.kind-fildelning__kvitto {
  border: 1px solid var(--kind-color-border);
  background: var(--kind-color-surface-muted);
  color: var(--kind-color-text);
}
.kind-fildelning__fel {
  border: 1px solid var(--kind-color-error);
  background: var(--kind-color-error-bg);
  color: var(--kind-color-text);
}
.kind-fildelning__kvitto:empty,
.kind-fildelning__fel:empty { display: none; }

/* #47 (chatt-yta 2.1) auto-expand textarea. The composer field starts short (one
   comfortable row) and grows with the content via kind_patient_composer_popover.js
   (which sets height inline). The min-height keeps the empty field a 48px tap
   target (patient floor, WCAG 2.5.8) rather than the tall 8rem the base
   .kind-field__textarea uses; resize:none because the JS owns the height (a manual
   drag would fight the auto-grow). With NO JS the server rows="3" gives a usable
   default height, so nothing is lost. */
.kind-compose__textarea {
  /* ---- #146: EN RAD, uttryckt i fältets EGEN text ------------------------
   *
   * DELAD av alla fyra chattytor. Deklarationen ligger på själva textarean, så
   * `kind_admin.css` kan läsa den ur samma element utan att de två filerna
   * behöver enas om en ordning eller om en gemensam förälder. Varje användning
   * bär ett fallback-värde, så en admin-yta som (mot dagens ordning) laddar
   * kind_admin.css UTAN kind_patient.css degraderar till gamla tal i stället
   * för att tappa hela deklarationen vid substitutionen.
   *
   * VARFÖR EN TOKEN OCH INTE ETT TAL. Höjden på ett fält vars innehåll skalar
   * får inte uttryckas i en enhet som är blind för textskalan. `1em` är
   * textareans egen `font-size` (= --kind-font-base) och `--kind-line-height`
   * är samma tal som `font: inherit` ger radhöjden, så produkten ÄR den
   * renderade radhöjden. Verifierat mot webbläsaren och inte härlett på papper:
   * patient 1,6 x 18 = 28,8px och vårdgivare 1,5 x 16 = 24px vid normal skala,
   * 1,6 x 27 = 43,2 respektive 1,5 x 24 = 36 vid xxlarge.
   *
   * DRIFTRISKEN ÄR UTTALAD: sätter någon `line-height` direkt på fältet utan
   * att röra token blir härledningen fel. Det är precis vad
   * `e2e/komposer-lasbarhet.mjs` mäter i riktig webbläsare, och den grinden är
   * driftdetektorn (en modell får inte vara auktoritet över sin egen
   * approximation, se docs/contracts/chat-pixel-budget.md). */
  --kind-komposer-enrad: calc(
    (var(--kind-line-height, 1.5) * 1em) + (2 * var(--kind-space-3, 0.75rem)) + 2px
  );
  /* Vilolägets EGNA vaddering. En tom enradsyta behöver inte det aktiva lägets
   * luft, och skillnaden är precis det som håller vilofältet kvar på
   * a11y-golvet 48px vid NORMAL skala i stället för att spränga pixelbudgeten:
   * 28,8 + 2x8 + 2 = 46,8, alltså under golvet, medan aktiv vaddering hade gett
   * 54,8 och tryckt modulen till ~60px, exakt på kontraktets tak. Se
   * ändringsloggen i docs/contracts/chat-pixel-budget.md. */
  --kind-komposer-vilo-vaddering: var(--kind-space-2, 0.5rem);
  --kind-komposer-enrad-vilo: calc(
    (var(--kind-line-height, 1.5) * 1em)
    + (2 * var(--kind-komposer-vilo-vaddering)) + 2px
  );
  min-height: 48px;
  resize: none;
  /* UAT-01 (release-blocker, short-mobile Skicka occlusion): bound the grown
     textarea to a VIEWPORT-RELATIVE height so the composer, and the Skicka
     action row below it, always fit inside the height-locked chat shell
     (.kind-body--chat 100dvh + overflow:hidden). Priority order under pressure:
     (1) the action row with Skicka is ALWAYS visible, (2) the textarea shrinks
     and scrolls internally.
     The BASE cap is calc(100dvh - 28rem), the fixed chrome that must stay on
     screen around the field. UAT-01B (qa deployed-browser sweep 2026-07-16):
     28rem provably does NOT cover the PATIENT chat shell (it never included
     the tabbar, and the article chrome outgrew it; Skicka landed ~33px under
     the bar at 320x568, 390x544, 412x595 with real clicks timing out), so the
     patient shell carries its own stricter budget in the .kind-body--chat
     override right below; this base value now serves team_chat_visa + the
     clinician composer only. Never below the
     48px patient tap floor (2.5.8, the clamp min). overflow-y:auto scrolls the
     field INTERNALLY past the cap. The autoexpand JS honours this cap (rowCap =
     min(6 rows, this max-height)) and a safety belt there forces internal
     scroll if the box is ever clamped.
     NB (Android): base.html's viewport interactive-widget=resizes-content is
     what makes 100dvh actually shrink when the soft keyboard opens, so this
     budget applies under a real keyboard; iOS ignores the hint harmlessly.

     #146, GOLVET ÄR NU EN LÄSBAR RAD OCH INTE ETT TRÄFFYTETAL. Det gamla
     golvet 48px motiverades med träffytan (2.5.8), och en träffyta är ett
     MINSTA MÅTT för att kunna peka på fältet, aldrig ett påstående om att en
     textrad ryms i det. Mellantermen blandar dessutom två enheter som rör sig
     åt olika håll: `100dvh` är blind för textskalan medan `28rem` skalar med
     den (480px vid normal, 720px vid xxlarge). Subtraktionen gör alltså taket
     MINDRE precis när innehållet blir STÖRRE, och på en 664px-viewport gick
     mellantermen negativ vid xlarge/xxlarge så clampen föll till sitt eget
     golv: uppmätt max-height 48px där en rad kräver 43,2 + 36 + 2 = 81,2px.
     Prioritetsordningen (1) Skicka alltid synlig, (2) fältet krymper och
     skrollar internt står kvar, men (2) får inte gå UNDER en läsbar rad: ett
     fält som visar 10px av en 43,2px rad har slutat fungera, och kontraktets
     egen slutklausul säger att a11y vinner vid konflikt och att man eskalerar
     i stället för att offra den. */
  max-height: clamp(
    max(48px, var(--kind-komposer-enrad, 48px)),
    calc(100dvh - 28rem),
    9rem
  );
  overflow-y: auto;
}
/* Platshållartext i chattens skrivfält, DELAD av patientytan, vårdgivarytan och
   kollegie-chatten (alla tre laddar den här filen, klinikerytorna laddar den
   SIST, så regeln vinner där oavsett filordning).

   Varför den finns (pixelbudget-granskning 2026-07-26, P2-1b): i det inaktiva
   läget är fältets <label> sr-only, så platshållaren är den enda synliga texten
   i rutan. Webbläsarnas default-platshållarfärg varierar och ligger nära
   4.5:1-gränsen, och Firefox lägger dessutom på en egen opacitet ovanpå färgen.
   Färgen pinnas därför till --kind-color-text-muted (5.87:1 mot bakgrunden, och
   den har egna varianter för mörkt läge och högkontrastläge), med `opacity: 1`
   så Firefox inte tunnar ut den igen.

   Platshållaren är ett komplement, aldrig en ersättning för etiketten
   (WCAG 3.3.2 / 1.3.1): <label for=...> ligger kvar i DOM:en och blir synlig
   igen så fort modulen aktiveras. */
.kind-compose__textarea::placeholder {
  color: var(--kind-color-text-muted);
  opacity: 1;
  /* #146: PLATSHÅLLAREN HÅLLS PÅ EN RAD OCH KAPAS MED ELLIPS.
   *
   * Fältet i viloläge är EN rad, det är hela pixelbudgetens poäng. En
   * platshållare som bryter till två eller tre rader får då sin andra rad
   * klippt mitt i nedstaplarna, vilket är precis det granskaren rapporterade
   * ("Skriv ett" med avskurna nedstaplar). Uppmätt före: `scrollHeight`
   * 154 mot `clientHeight` 67 vid 320x664 xxlarge, 110 mot 67 vid 390.
   *
   * Alternativet, att låta fältet växa till platshållarens brutna höjd, hade
   * kostat 87px av viewporten vid 320 xxlarge FÖR EN LEDTEXT, alltså sänkt
   * konversationens andel under utfallskravet. En ledtext får inte äta
   * utfallsmåttet.
   *
   * REGELN LIGGER PÅ ::placeholder OCH INTE PÅ FÄLTET, och det är avsiktligt:
   * `white-space: nowrap` på textarean själv hade även styrt VÄRDETS brytning,
   * och uppmätt lämnade den dessutom en horisontell överskjutning
   * (scrollWidth 289 mot clientWidth 194) i stället för en ellips. På
   * pseudoelementet blir scrollWidth == clientWidth, alltså kapas ledtexten
   * inuti sin egen ruta och värdet är helt orört. Villkorslös, eftersom en
   * platshållare per definition bara syns när fältet är tomt.
   *
   * A11Y: ledtexten är ETT KOMPLEMENT, aldrig fältets namn. <label for=...>
   * ligger kvar i DOM:en (sr-only i viloläge, synlig i aktivt läge) och
   * aria-describedby-hjälptexten är oförändrad, så hela texten finns kvar för
   * skärmläsare även när den visuella ledtexten kapas. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* UAT-01B (P0, qa deployed-browser sweep 2026-07-16 on 6c226d8): on the
   PATIENT chat shell the 28rem budget above is provably ~50-90px too small.
   With the composer active and grown it left the compose form's bottom at the
   viewport edge (568.2 at 320x568) and the Skicka row ~33px under the fixed
   tabbar; real clicks timed out at 320x568, 390x544, 412x595 and 375x667
   cleared by only 0.9px. Two corrections, scoped to .kind-body--chat so
   team_chat_visa + the clinician composer (which also load this file) keep
   the 28rem base budget:
     * subtract the TABBAR (via the shell's --kind-tabbar-reserve token, which
       the 28rem constant never actually covered, despite its comment) so the
       cap tracks the same budget the shell height is bound to;
     * grow the chrome constant to 30rem: the non-textarea chrome at 320px
       width is ~485-515px worst case (header rail ~69 + main paddings 20 +
       article header up to ~110 with a 2-line clamped h1 + todo-chip ~56 +
       composer chrome ~230-260 incl. a 4-line wrapped help text and the 48px
       action row), and 30rem (480px) + the <=600px compaction below covers it
       where 28rem did not.
   The clamp floor stays the 48px patient tap target (2.5.8); on the shortest
   viewports (568/544 tall) the mid term drops BELOW the floor, so the floor
   wins and the textarea holds one internally-scrolling row, exactly the
   spec's priority order (Skicka row first, field second). The autoexpand JS
   follows automatically (it reads getComputedStyle().maxHeight).
   Budget-pinned by tests/test_chat_zoned_layout_css.py. */
.kind-body--chat .kind-compose__textarea {
  /* #146: samma golvbyte som basregeln ovan, av samma skäl. Här är
     mellantermen ännu hårdare pressad (30rem = 720px vid xxlarge mot en
     viewport på 664), så den går negativ redan vid xlarge och clampen föll
     till 48px på SAMTLIGA fem mobilbredder. Uppmätt på deployen 2026-08-09,
     patient-chatt 390x664: computed max-height 48px vid både xlarge och
     xxlarge, mot ett radbehov på 74 respektive 81,2px. */
  max-height: clamp(
    max(48px, var(--kind-komposer-enrad, 48px)),
    calc(100dvh - var(--kind-tabbar-reserve) - 30rem),
    9rem
  );
}

/* #47 (chatt-yta 2.1) restyled primary send, always the last control in
   .kind-compose__actions. Keeps the shared .kind-btn--primary look; the
   min-height matches the 48px patient floor so the send target never shrinks
   below the share/emoji triggers beside it (2.5.8).
   V1 B1 (chatt-yta feedback-plan 2026-07-08, decision 2026-07-12): this button
   was "icon + text, never icon-only" (WCAG 4.1.2); the kundkrav-parity
   decision replaces that with icon-only + aria-label + title tooltip (see the
   consolidated rule + rationale below, and the amended DEL A contract note in
   docs/design/chatt-yta-2-1-refresh.md). The naming/text SPAN stays in markup
   (a no-JS-independent, template-owned accessible fallback) and is hidden
   here via CSS, never deleted, so nothing regresses if B1 is ever reverted. */
.kind-compose__send {
  display: inline-flex;
  align-items: center;
  gap: var(--kind-space-2);
  min-height: 48px;
  min-width: 48px;
  justify-content: center;
  /* push the send to the end of the actions row when there is room; on a narrow
     wrap it drops to its own line (still the last child). */
  margin-left: auto;
}
.kind-compose__send-icon { display: inline-flex; flex: 0 0 auto; }
.kind-compose__send-text { white-space: nowrap; }

/* UAT-03 follow-up (review P2, WCAG 3.3.1): the composer's gate-block note, a
   polite live region DOM-injected by kind_composer_mode.js on BOTH surfaces
   (patient + clinician composers; every chat template links this file). Empty
   at rest (zero height, margin 0 so it costs the height budget nothing until
   it speaks); error token when populated (--kind-color-error, past AA on white);
   14px (--kind-font-small) is above the 13px patient floor. Never display:none,
   a live region must stay in the accessibility tree to announce. */
.kind-compose__gate-note {
  margin: 0;
  font-size: var(--kind-font-small);
  color: var(--kind-color-error);
}

/* ----------------------------------------------------------------------------
 * V1 B1 (#56, chatt-yta 2.1 feedback-plan 2026-07-08): ren ikonrad.
 *
 * Consultant-approved decision, 2026-07-12 (see the plan's beslutslogg): the
 * clinician + patient composer action row (share/"+"-trigger, emoji, send)
 * drops its visible text label in favour of a pure icon row, matching Kind's
 * own product. This SUPERSEDES the "icon + text, never icon-only" contract
 * note that was written into _chat_composer.html on 2026-07-01; the amended
 * contract lives there now, with a pointer back to this decision.
 *
 * The 3 buttons keep (added where missing): a real Swedish aria-label (WCAG
 * 4.1.2 Name, Role, Value), a matching `title` (desktop hover tooltip, never
 * the ONLY carrier per testing-patterns.md, aria-label is), a visible focus
 * ring (inherited from the shared :focus-visible rule in kind.css), and a
 * >=44px (admin) / >=48px (patient) tap target explicitly (not just incidental
 * padding math, now that the text no longer pads the button out). The
 * "-text" spans (share-trigger/emoji-trigger/send, above + below) stay IN THE
 * DOM (a template-owned, no-JS-independent fallback carrier), hidden purely
 * via `display:none` here: since every button ALSO carries an explicit
 * aria-label, the nested text is redundant for the accessible name
 * computation (aria-label always wins per the HTML-AAM spec) and safe to
 * remove from the render tree. The POPOVER MENU items ("Dela mall", "Dela
 * formulär", ...) are NOT touched by this decision (out of scope; a disclosure
 * menu list keeps its visible labels), only the outer action row's 3 buttons. */
.kind-compose__share-trigger-text,
.kind-compose__emoji-trigger-text,
.kind-compose__format-trigger-text {
  display: none;
}

/* ---- CP-06 (issue #91, briefens §4.4): SKICKA ÅTERFÅR SIN SYNLIGA ETIKETT ---
 *
 * `.kind-compose__send-text` låg i gruppen ovan sedan B1 (2026-07-12). Den är
 * utbruten hit, inte uppmjukad: B1 tog ett generellt beslut om HELA ikonraden,
 * och §4.4 skiljer på kritiska och sekundära åtgärder. Emoji, Fetstil och
 * Infoga länk är kvar ikon-only, de är sekundära enligt BÅDA personorna
 * (patient 2026-08-04, vårdpersonal 2026-08-04).
 *
 * VARFÖR SKICKA ÄR ANNORLUNDA, och det är inte en smakfråga. Båda personorna
 * klassar den KRITISK oberoende av varandra: meddelandet journalförs, går till
 * en annan människa och kan inte tas tillbaka. Produkten hade dessutom REDAN
 * tagit ställning åt båda håll samtidigt, vilket är själva fyndet: kollegie-
 * chatten (`team_chat_visa.html`) skickar med en TEXTKNAPP medan patientchatten
 * skickar med en naken pappersflygplansikon. Ytan med störst konsekvens var den
 * som tappade sitt ord. Ingen beslutade den asymmetrin, bredden gjorde det.
 *
 * KOSTAR DEN PIXELBUDGETEN? Nej, och det är MÄTT och inte antaget.
 * `docs/contracts/chat-pixel-budget.md` sätter tak 60px på `.kind-chat__compose`
 * i `--collapsed`, och i det läget ligger Skicka på `display:none` (regeln längre
 * ned i den här filen, verifierad i webbläsare 2026-08-04: vila = 58px vid 320px
 * normal, en enda synlig kontroll, `+`). Etiketten syns alltså BARA i det aktiva
 * läget, som budgeten inte mäter. Budgeten gäller dessutom HÖJD medan en etikett
 * bredvid en glyf kostar BREDD.
 *
 * `white-space: nowrap` (regeln ovan) är load-bearing: utan den bryter "Skicka"
 * inne i knappen vid xxlarge och gör knappen tvåradig i stället för bredare. */
.kind-compose__send-text {
  display: inline;
}
.kind-compose__share-trigger,
.kind-compose__emoji-trigger {
  min-width: 48px;
  justify-content: center;
}

/* G2 (V6, chatt-fönster-restfix 2026-07-14, spec docs/design/patient-chatt-3zon-
 * 2026-07-14.md): the V4 (#63) Fetstil + Infoga länk format triggers join the
 * SAME ren-ikonrad as +/emoji/skicka (decision B1 extended per the DEL B
 * forward-compat note). Their "-text" span is CSS-hidden above (icon-only), the
 * accessible name is the template's aria-label + matching title (WCAG 4.1.2),
 * and they get the SAME square patient tap floor (48px, 2.5.8) so the row reads
 * as one icon strip and no longer wrap-forces at 320px (persona-patient O1/c).
 * Footprint mirrors the emoji trigger; the [hidden] guard restores the UA
 * [hidden]{display:none} that this rule's display:inline-flex would otherwise
 * beat (author-origin precedence), so the no-JS `hidden` posture (JS-only
 * insertion helper, dead without kind_composer_format.js, same as emoji) still
 * holds and no dead button shows without JS. */
.kind-compose__format-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--kind-space-2);
  min-height: 48px;
  min-width: 48px;
  /* persona-vardpersonal V2 (2026-07-14): keep the "B" (Fetstil) glyph FLAT, not
     a circle/chip, because a circled "B" reads as a circular patient-avatar
     initial in a clinical UI. --kind-radius (10px after CP-05, < 24 = half of
     48, so never a circle) keeps it a distinct, flat format tool.
     CP-05 (#90) note: .kind-btn is no longer a pill, so this override is no
     longer CORRECTING a circle, it PINS the flat shape against a future change
     to the shared button. Keep it; the persona finding is about the glyph. */
  border-radius: var(--kind-radius);
}
.kind-compose__format-trigger[hidden] { display: none; }
.kind-compose__format-trigger-icon { display: inline-flex; flex: 0 0 auto; }
.kind-compose__format-trigger-text { white-space: nowrap; }

/* ----------------------------------------------------------------------------
 * V1 (#56, chatt-yta 2.1 feedback-plan 2026-07-08): composer modes.
 *
 * JS-progressive-enhancement ONLY (kind_composer_mode.js). The two classes
 * below are NEVER present without JS (the script is the sole place that adds
 * them), so with no JS the composer stays in its plain default markup state,
 * fully open (every control visible), exactly as it renders today. Only a
 * <form> the template opts in via [data-composer-mode] (the main reply form,
 * not the schemalägg / share panes) is ever touched.
 *
 * INACTIVE (kind-compose--collapsed, textarea empty + unfocused): a low input
 * row + the plus/share icon only; the emoji trigger and Send are hidden.
 * ACTIVE (kind-compose--active, textarea focused OR has content): the full
 * icon row (plus, emoji, send) is visible. Both states are icon-only per B1
 * above; nothing here re-introduces visible text. */
.kind-chat__compose.kind-compose--collapsed .kind-compose__emoji-trigger,
.kind-chat__compose.kind-compose--collapsed .kind-compose__format-trigger,
.kind-chat__compose.kind-compose--collapsed .kind-compose__send {
  display: none;
}

/* G3 (V6, chatt-fönster-restfix 2026-07-14): the inactive/collapsed patient
   textarea is COMPACT (48px, the patient tap floor) at EVERY breakpoint, not
   199px on desktop / 53px on mobile (the pre-V6 finding: the base 8rem
   .kind-field__textarea height leaked through on desktop while the mobile
   composer compacted). Scoped to .kind-body--chat so the clinician composer
   (which loads kind_patient.css too) keeps its own 44px floor. height:48px +
   the min-height floor collapse the field to one row whenever the composer is
   inactive; the moment focus/content re-activates it, kind_patient_composer_
   popover.js's autoexpand takes over the inline height and grows it to the
   ~6-row cap. Falls out of G1: with the composer static in a bounded column a
   tall collapsed field would eat the thread's space directly.

   #146: TALET 48 ÄR KVAR SOM GOLV, MEN ÄR INTE LÄNGRE TAKET. `height: 48px`
   var en absolut pixelhöjd på ett fält vars innehåll skalar, alltså samma
   klass av fel som taket ovan. Vid xxlarge äter vadderingen 36 av 46px och
   lämnar 10px åt en radhöjd på 43,2 (uppmätt, deployen 2026-08-09).

   Två delar, båda härledda:
     * vilolägets EGNA vaddering (--kind-komposer-vilo-vaddering, 8px vid
       normal mot det aktiva lägets 12) gör att en hel rad ryms INOM golvet
       48px vid normal skala: 48 - 2 kant - 16 vaddering = 30px åt en 28,8px
       rad. Vilofältets höjd är alltså OFÖRÄNDRAD 48px vid normal skala och
       pixelbudgeten rörs inte där.
     * höjden är max(48px, en vilorad), så fältet växer FÖRST när textskalan
       kräver det: 48 / 52,4 / 58 / 69,2px vid normal / large / xlarge /
       xxlarge.
   Träffytan (2.5.8) rörs inte: 48px är golv i båda leden. */
.kind-body--chat .kind-chat__compose.kind-compose--collapsed .kind-compose__textarea {
  padding-block: var(--kind-komposer-vilo-vaddering, 0.5rem);
  min-height: max(48px, var(--kind-komposer-enrad-vilo, 48px));
  height: max(48px, var(--kind-komposer-enrad-vilo, 48px));
}

/* ---- PIXELBUDGET 2026-07-26: det inaktiva läget är EN rad (tak 60px) --------
 * docs/contracts/chat-pixel-budget.md (taket är 60px, härlett ur 44px a11y-golv
 * plus krom; 56 var en påhittad siffra, se ändringsloggen).
 * Patientens spegling av samma block i
 * kind_admin.css; G3 ovan hade redan gjort FÄLTET enradigt, men modulen mätte
 * ändå 225px av 844px, eftersom etiketten, hjälptexten och ikonraden låg kvar i
 * flödet ovanför och under det. Det är exakt kontraktets poäng: en delåtgärd
 * mätt på sin egen selektor säger ingenting om utfallet.
 *
 * Höjdbudget inaktivt läge, deklaration för deklaration:
 *   border-top                       1px
 *   padding-top (space-1)            4px
 *   raden: max(fält 48, "+" 48)     48px
 *   -------------------------------------
 *   summa                           53px  (tak 60px)
 *
 * Etikett och hjälptext går till sr-only-mönstret, ALDRIG display:none:
 * textareans aria-describedby måste fortsätta lösa ut (WCAG 3.3.2). Samma
 * mönster som kompakteringsblocket redan använder för hjälptexten på korta
 * viewportar, nu bundet till LÄGET i stället för till skärmhöjden. */
.kind-chat__compose.kind-compose--collapsed {
  padding-top: var(--kind-space-1);
  gap: 0;
}
.kind-chat__compose.kind-compose--collapsed .kind-field__label,
.kind-chat__compose.kind-compose--collapsed .kind-field__help {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
/* #178: DELNINGSKNAPPEN ÄR RADENS FÖRSTA BARN, I BÅDA LÄGENA.
 *
 * Annica (KIND) 2026-08-11: "+ på vänster sida istället för höger sida."
 * Knappen flyttade ut ur `.kind-compose__actions` och in i rad-wrappern, i BÅDA
 * skrivmodulerna, se den långa noten i templates/admin/_chat_composer.html för
 * mekanismen och för varför en `order` på åtgärdsraden inte dög.
 * `flex: 0 0 auto` så knappen varken växer eller krymper med fältet;
 * `align-items: flex-start` på raden håller den på radens överkant. Följden är
 * att knappens position i radens koordinatsystem är IDENTISK i de två lägena,
 * en starkare gard mot CP-20:s tvåklicksdefekt än lägesneutraliteten ensam
 * (som står kvar). Uppmätt i e2e/cp181920-komposer-utfall.mjs mått P.
 *
 * Den här filen laddas av ALLA FYRA chattytorna (patientchatten, arbetsvyn,
 * vårdgivarchatten och kollegie-chatten), så regeln är den delade noden. Samma
 * deklaration finns i kind_admin.css av samma skäl som `.kind-compose__send-text`:
 * en regel som bara finns i det ena sheetet vilar på en laddningsordning ingen
 * assertion vaktar. */
.kind-chat__compose-row > .kind-compose__share-trigger,
.kind-chat__compose-row > .kind-attachvald > .kind-compose__share-trigger {
  flex: 0 0 auto;
  /* Samma token som fältets golv subtraherar, se `--kind-komposer-plus` på
   * raden. Att knappen fyller reservationen EXAKT är det som gör räkningen
   * `100% - plus - gap` sann; en bredare knapp hade brutit raden igen.
   * #395: andra selektorn är gemet inuti kvittensgruppen .kind-attachvald. */
  min-width: var(--kind-komposer-plus);
}
/* LOAD-BEARING: `.kind-compose__actions { flex: 1 1 100% }` ovan ger ikonraden
 * HELA radbredden som flex-basis, så den bryter till en egen rad.
 *
 * #178 ÄNDRADE PREMISSEN, läs inte raden ovan som nuläge: sedan "+" flyttade ut
 * ur åtgärdsraden är den TOM i viloläge (emoji, format och Skicka är
 * `display:none` där, och emoji-panelens skal är `hidden`). En tom flexruta är
 * 0px bred men äter ändå ett radgap, alltså 12px av fältets bredd på en 320px
 * viewport där utrymmet redan tar slut. Därför tas den UR FLÖDET i viloläge i
 * stället för att krympas till sitt innehåll. Inget syns mindre: varje barn var
 * redan dolt. */
.kind-chat__compose.kind-compose--collapsed .kind-compose__actions {
  display: none;
}
/* Popover-wrappern är tom i viloläge (panelen är hopfälld av skriptet), men dess
 * flex-basis skulle ändå reservera en rad i rad-wrappern. */
.kind-chat__compose.kind-compose--collapsed .kind-compose-popover {
  flex: 0 0 auto;
}
/* Fältets 240px min-width är rätt för det AKTIVA läget (ett skrivfält ska inte
 * bli en frimärksruta), men i viloläge äter den enradigheten på smala
 * viewportar: vid 320px är mainens innerbredd 288px, och 240 + 12 gap + 48 för
 * "+" är 300, alltså en radbrytning och 113px i stället för 53px. I viloläge är
 * fältet en tom en-rads yta som får krympa; taket blir då oberoende av bredden.
 * Aktivt läge återfår 240px-golvet omedelbart. */
.kind-chat__compose.kind-compose--collapsed .kind-chat__compose-row .kind-field {
  min-width: 0;
}

/* #47 (chatt-yta 2.1) Focus Not Obscured (WCAG 2.2 AA 2.4.11, NEW in 2.2). When a
   control inside the thread column receives focus, the sticky composer at the
   bottom must not hide it. scroll-margin-bottom = composer footprint keeps a
   focused element scrolled clear of the sticky composer; scroll-margin-top clears
   the sticky page header. Applied to the focusable elements in the thread.
   (P0 rework, deploy-verify df69af8: the V1 zoned zero-out of this reserve is
   REMOVED again, because the patient composer is sticky again and CAN overlay
   the log; this base rule is live on the patient zoned surface AND on
   team_chat_visa.html.)
   #74 (qa browserverifiering 2026-07-12, WCAG 2.4.11 AA-miss bekräftad): the
   static 96px reserve was ~3x smaller than the composer's REAL footprint at
   320px (~304px active, ~303px collapsed; band [200..504] at 320x568), so
   every focused thread element scrolled to a resting spot FULLY BEHIND the
   opaque sticky composer (65/65 probe points hit composer/tabbar, 0 hit the
   element). The reserve is now the --kind-composer-reserve custom property,
   published on the chat article by kind_composer_mode.js from the composer's
   MEASURED height + tabbar + gap + buffer (ResizeObserver-tracked, so
   autoexpand/mode/viewport changes follow along). The old static value stays
   as the var() fallback for the no-JS degradation, and kind_admin.css pins
   the variable to 0px on the admin zoned surfaces (static composer, nothing
   to clear; mirrors the scroll-margin-top zero-out there). team_chat_visa
   (no zoned class, no [data-composer-mode]) keeps the 96px fallback. */
.kind-chat__log-list a:focus-visible,
.kind-chat__log-list button:focus-visible {
  scroll-margin-bottom: var(
    --kind-composer-reserve,
    calc(96px + env(safe-area-inset-bottom, 0px))
  );
  scroll-margin-top: var(--kind-header-height);
}

/* ----------------------------------------------------------------------------
 * Composer "+" share popover (Wave B, patient chat-native)
 *
 * Mirrors the clinician composer popover (static/css/kind_admin.css) so the two
 * surfaces read the same. The "+" trigger sits left of the input; the panel is a
 * bordered card with a 2-item menu (Dela foto/video, Dela PDF). Unlike the
 * clinician popover (which reveals separate form panes), the patient items act on
 * ONE shared file input (the bilaga field rendered inside the panel) by setting
 * its `accept` and opening the picker (see kind_patient_composer_popover.js).
 *
 * Progressive enhancement: the markup renders the panel + the plain file input
 * OPEN (aria-expanded="true"); the JS collapses it. With NO JS the panel stays
 * open and the patient still attaches a file via the plain input. The
 * .kind-compose-popover__panel[hidden] rule below only bites once the JS adds
 * [hidden], so a no-JS user is never left with a dead/empty composer.
 *
 * A11y (WCAG 2.2 AA): trigger + every item are min 48px tall (patient floor),
 * visible focus ring, accent icons inherit accent. The MENU ITEMS inside the
 * panel keep a visible text label (unaffected by decision B1 above); the
 * trigger button itself went icon-only + aria-label + title under B1.
 * -------------------------------------------------------------------------- */
.kind-compose__actions {
  display: flex;
  flex: 1 1 100%;
  align-items: center;
  /* #47 (chatt-yta 2.1): the actions row (share + emoji + send) must WRAP at
     narrow widths so it never forces horizontal scroll at 320px (WCAG 1.4.10
     reflow, verified: without wrap the row was 389px wide in a 320px viewport).
     A gap keeps the buttons apart once wrapped. The send button keeps its own
     margin-left so it sits at the end of the row when there is room. */
  flex-wrap: wrap;
  gap: var(--kind-space-2);
}
.kind-compose__share-trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--kind-space-2);
  min-height: 48px;
}
/* GARD, ursprungsprecedens och INTE specificitet (regel 27 korollarium 2).
   UA-arkets `[hidden]:not([hidden=until-found i]):not(embed) { display: none }`
   saknar `!important`, och en NORMAL forfattardeklaration slar en NORMAL
   user-agent-deklaration i kaskadens sorteringsordning oavsett specificitet.
   `display: inline-flex` ovan gor darfor `hidden` INERT pa den har klassen.

   Elementen bar idag ocksa `.kind-btn`, vars egen gard (kind.css) ar 0-2-0 och
   raddar dem, alltsa var defekten LATENT och inte synlig: kaskadsonden mater
   `display:none` pa alla tre barare i dag, men samma knapp UTAN `.kind-btn`
   mattes till 48x48 malad. Att lana en syskonklass gard ar precis den smala
   tillampning regel 27 korollarium 2 varnar for, sa klassen bar nu sin egen.

   PER KLASS och UTAN `!important`, medvetet: den generella
   `[hidden] { display: none !important }` (Bootstrap Reboot) bryter
   `hidden="until-found"` och ar en oppen defekt dar (twbs/bootstrap#40688).
   Den har formen vinner pa specificitet 0-2-0 mot regeln ovans 0-1-0.
   Samma gard som `.kind-compose__emoji-trigger` och `.kind-compose__format-trigger`
   redan bar. Vakt: tests/test_hidden_display_gard.py. */
.kind-compose__share-trigger[hidden] { display: none; }
.kind-compose__share-trigger-icon { display: inline-flex; flex: 0 0 auto; }
.kind-compose__share-trigger-text { white-space: nowrap; }

/* #47 (chatt-yta 2.1, Del A) compact icon-forward action row, the patient mirror
   of the clinician --compact rule (kind_admin.css, not loaded here). The three
   controls (share + emoji + Skicka) read as a tight icon row: since V1 B1 the
   label text is CSS-hidden (display:none, see above) and the accessible name
   comes from aria-label + a matching title tooltip instead. The >=48px patient
   tap floor (2.5.8) is preserved via an explicit min-width on the icon-only
   buttons (above), not incidental label-padding math any more. At 320px the
   row still wraps (.kind-compose__actions flex-wrap:wrap) so it never
   side-scrolls (WCAG 1.4.10). */
.kind-compose__actions--compact {
  gap: var(--kind-space-2);
}
/* #178: "+" sitter inte längre i `.kind-compose__actions--compact` utan först i
   rad-wrappern, så den nya selektorn måste stå MED här. Utan den tappade knappen
   sin kompakta vaddering och sitt teckensnitt och blev bredare än de övriga
   ikonknapparna, alltså mindre plats åt fältet på 320px. Samma specificitet
   (0,2,0) som de andra i listan. */
.kind-chat__compose-row > .kind-compose__share-trigger,
.kind-chat__compose-row > .kind-attachvald > .kind-compose__share-trigger,
.kind-compose__actions--compact .kind-compose__share-trigger,
.kind-compose__actions--compact .kind-compose__emoji-trigger,
.kind-compose__actions--compact .kind-compose__format-trigger {
  flex: 0 0 auto;
  padding-inline: var(--kind-space-3);
  gap: var(--kind-space-1);
  font-size: var(--kind-font-small);
  font-weight: 600;
}

/* P3-b (V6 a11y fix-round 2026-07-15, orchestrator live-mät 2026-07-14): the
   send button is NOT in the --compact list above, so it keeps the full .kind-btn
   24px inline padding (var(--kind-space-5)); at its 20px icon that is a ~70px
   border-box, ~22px past the 48px square floor the other four icon controls hold.
   At 320px that pushed the five-icon row (4x48 + 70 + 4x8gap = 294px) past the
   288px content width (320 - 2x space-4 gutter) and wrapped Skicka onto a second
   line (measured: 4 controls row 1, Skicka row 2). Compacting the send's inline
   padding to space-3 (the same value the share/emoji/format triggers use above)
   makes it a 48px square like them: border-box = 20 icon + 2x12 padding + 2x1px
   border = 46px, floored to the 48px min-width, so 5x48 + 4x8 = 272px now fits
   288px on ONE line at 320px, with the 48px patient tap floor KEPT (never dropped
   to the 24px 2.5.8 minimum). Scoped to .kind-body--chat + <=360px so the >=375px
   pill send (marknads-look) and the clinician surface (44px floor, already
   one-line at 320px) are untouched. Guard: test_composer_iconrow_g2_css.py::
   test_patient_send_compacted_to_icon_floor_at_narrow_width. */
@media (max-width: 360px) {
  .kind-body--chat .kind-compose__send {
    padding-inline: var(--kind-space-3);
  }
}

/* Emoji smiley trigger (2.0 #4). Same affordance footprint as the share trigger
   (>=48px patient floor, icon-only + aria-label + title since V1 B1, accent
   icon). The wrapping .kind-compose__actions becomes the positioning context
   for the floating emoji panel below. */
.kind-compose__actions { position: relative; }
.kind-compose__emoji-trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--kind-space-2);
  min-height: 48px;
  /* the actions-row gap owns inter-button spacing now (#47 wrap fix); no
     per-button margin so it does not double up when the row wraps. */
}
.kind-compose__emoji-trigger[hidden] { display: none; }
.kind-compose__emoji-trigger-icon { display: inline-flex; flex: 0 0 auto; }
.kind-compose__emoji-trigger-text { white-space: nowrap; }

/* The emoji popover panel is created by kind_emoji_picker.js and inserted right
   after the trigger. It floats above the composer; the <emoji-picker> web
   component carries its own internal styling (shadow DOM). */
.kind-emoji-popover__panel {
  position: absolute;
  z-index: 30;
  bottom: calc(100% + var(--kind-space-2));
  left: 0;
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius);
  background: var(--kind-color-surface);
  box-shadow: var(--kind-shadow-md);
}
.kind-emoji-popover__panel[hidden] { display: none; }
.kind-emoji-popover__panel emoji-picker {
  /* Track the app theme tokens; keep the picker sized for an older/low-vision
     user (a touch larger than the library default). */
  --background: var(--kind-color-surface);
  --border-color: var(--kind-color-border);
  --num-columns: 8;
  --emoji-size: 1.5rem;
  width: 22rem;
  max-width: min(22rem, 92vw);
  height: 24rem;
  max-height: 60vh;
}

.kind-compose-popover {
  position: relative;
  flex: 1 1 100%;
  /* UAT-01B P1 (qa 2026-07-16): the wrapper is a flex item, and the flex
     default min-width:auto resolves to its CONTENT min-content size, which the
     panel's file-input field drives to a viewport-INDEPENDENT ~565px. The item
     then refuses to shrink below that on every mobile width (qa: a fixed
     565.5px panel overflowing 375px by 206.5px). min-width:0 lets flex size
     the wrapper to its line. GLOBAL on purpose (this file is loaded by the
     clinician chat surfaces too): it only changes the case where the line is
     NARROWER than the content's intrinsic minimum, which today renders as
     horizontal overflow, strictly worse; where space is ample the resolved
     size is unchanged. */
  min-width: 0;
  margin: 0;
}
.kind-compose-popover__panel {
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius);
  background: var(--kind-color-surface);
  box-shadow: var(--kind-shadow-md);
  padding: var(--kind-space-4);
  /* UAT-01B P1 belt: never wider than the box that positions it. */
  max-width: 100%;
}
.kind-compose-popover__panel[hidden] { display: none; }
/* F-22: the top-level Avbryt <li> renders [hidden] until the popover script
   reveals it. No author rule targets the menu's <li> today, so the UA [hidden]
   rule suffices; this guard pins that against a future li display rule (the
   regel 27-korollarium-2 hidden-vs-author-display mechanism). */
.kind-compose-popover__menu li[hidden] { display: none; }
/* UAT-01B P1 (NEW regression from the overflow clip belt, qa 2026-07-16): the
   share panel used to open DOWNWARD as an IN-FLOW block below the actions row,
   growing the composer. Inside the tabbar-subtracted shell that growth blows
   the rail budget, and the clip belt on main (correctly) clips the spill: at
   320x568 the open panel spanned y 515.2-877.6 vs the 511 clip line, 100%
   invisible, its items dead to elementFromPoint. The emoji picker beside it was
   untouched because it opens UPWARD (absolute, bottom-anchored above the
   actions row). Adopt the SAME proven pattern for the share panel on the
   patient chat shell: float the whole wrapper above the actions row so it
   overlays the LOG (out of flow = zero rail-budget cost, and removing the
   wrapper's in-flow wrapped line also removes a phantom 12px row-gap from the
   compose-row at every height).
   Scoped TWICE, deliberately:
     * .kind-body--chat: patient chat shell only, the admin arbetsvy popover
       keeps its in-flow open-down layout (its column is not clipped this way);
     * .kind-compose-popover--js: added by kind_patient_composer_popover.js at
       init, so the float only applies when the toggle script actually runs.
       With NO JS the panel renders OPEN in flow (the server-side fallback,
       unchanged posture): a no-JS float could clip at the shell top and CSS
       must never assume a script ran (progressive enhancement).
   The row is the positioning context (relative below); bottom: 100% + gap =
   just above the actions row, the emoji panel's exact anchor line. left/right
   pin the width to the row (no intrinsic-width escape). The max-height keeps
   the panel inside the shell between the actions row and main's top clip edge
   (worst measured headroom ~354px at 390x544; 12rem covers header + article
   header + gap chrome above the anchor) with internal scroll past it; menu
   items keep their 48px tap floor and scroll into view. z 30 = the emoji
   panel's layer. Guard-pinned by tests/test_chat_zoned_layout_css.py. */
.kind-body--chat .kind-chat__compose-row {
  position: relative;
}
.kind-body--chat .kind-compose-popover--js {
  position: absolute;
  bottom: calc(100% + var(--kind-space-2));
  left: 0;
  right: 0;
  z-index: 30;
}
.kind-body--chat .kind-compose-popover--js .kind-compose-popover__panel {
  max-height: min(24rem, calc(100dvh - var(--kind-tabbar-reserve) - 12rem));
  overflow-y: auto;
}
.kind-compose-popover__title {
  margin: 0 0 var(--kind-space-2);
  font-weight: 600;
  color: var(--kind-color-text);
}
/* K12 (#196): den nakna filväljaren i patientens plus-panel är inte längre en
   SYNLIG tredje väg in till samma dialog som de två menyraderna redan öppnar.
   Kontrollen är kvar i DOM:en (menyraderna klickar den, se mallens kommentar);
   det som göms är dess visuella närvaro.

   SCOPAD TVÅ GÅNGER, av exakt samma skäl som floaten ovan:
     * .kind-compose-popover--js sätts av kind_patient_composer_popover.js vid
       init, så UTAN JavaScript renderas panelen ÖPPEN med fältet SYNLIGT och
       den no-JS-patienten har kvar sin enda väg att bifoga en fil. CSS får
       aldrig anta att ett skript kört.
     * en egen klass, inte .kind-field, eftersom vårdgivarens composer delar
       klassrymd med patientens och en bredare selektor hade gömt fält där.

   display:none och inte visually-hidden, med avsikt: display:none tar bort
   fältet ur BÅDE tabbordningen och tillgänglighetsträdet, alltså blir det inget
   fokuserbart-men-osynligt element, och .click() på ett display:none-filfält
   öppnar ändå den inbyggda väljaren (MDN, "Using files from web applications"). */
.kind-compose-popover--js .kind-compose-popover__file {
  display: none;
}
.kind-compose-popover__menu {
  list-style: none;
  margin: 0 0 var(--kind-space-3);
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-1);
}
/* P4 (UAT 2026-07-02, 320px): with the en pilot live the longer labels ("Share
   PDF or document") wrap at 320px, and the old space-2 padding + inherited ~1.5
   line-height grew a wrapped item to ~75px. Compact wrap math (html 100% = 16px):
   line-height 1.3 => 20.8px per line; block padding 2 x --kind-space-1 = 8px.
   1 line = 28.8px -> the min-height 48px floor rules (the patient tap floor,
   WCAG 2.5.8, >=44px); 2 lines = 49.6px (~50px, materially under the ~60px
   target); a further +30% text expansion (ADR-042 layout rule) still wraps to
   2 lines and stays ~50px. font: inherit must precede line-height so the
   shorthand does not reset it. */
/* Menyn blandar elementtyper: syskonen är <button> medan "Boka tid" är ett
   <a> till /patient/tider (fungerar utan JavaScript). Utan den här
   deklarationen ärver enbart <a>-posten user-agentens understrykning och
   läser som en avvikelse bland knapparna. Posten är i dag gatad bakom
   kan_boka_tid (tom PATIENT_SJALVBOKNINGSBARA_TYPER), så regeln håller
   ytan korrekt den dag gaten öppnas. */
.kind-compose-popover__item {
  display: flex;
  align-items: center;
  gap: var(--kind-space-3);
  width: 100%;
  min-height: 48px;
  padding: var(--kind-space-1) var(--kind-space-3);
  border: 1px solid transparent;
  border-radius: var(--kind-radius);
  background: transparent;
  color: var(--kind-color-text);
  text-decoration: none;
  font: inherit;
  line-height: 1.3;
  text-align: left;
  cursor: pointer;
}
.kind-compose-popover__item:hover { background: var(--kind-color-surface-muted); }
.kind-compose-popover__item:focus-visible {
  outline: var(--kind-focus-ring);
  outline-offset: 2px;
}
.kind-compose-popover__item-icon {
  display: inline-flex;
  flex: 0 0 auto;
  color: var(--kind-color-accent);
}

@media (prefers-reduced-motion: reduce) {
  .kind-compose-popover__panel { transition: none; }
}

/* Ärlig status (2.1 UX pivot D7 + D8). A slim, low-chrome strip at the foot of
   the message log, sitting just above the composer. Deliberately calm: a muted
   inset card, no chat-toy "delivered/read" theatre. Loaded only by the patient
   chat template.
   A11y / contrast (light theme tokens; floor WCAG 2.2 AA 1.4.3 = 4.5:1 text,
   1.4.11 = 3:1 non-text):
   - status + svarstid + 112 TEXT use --kind-color-text on the muted
     inset surface (--kind-color-surface-muted), far past AA,
     chosen full-strength (not muted) for the older / lower-vision patient floor.
   - the seen check icon is --kind-color-success, used as a
     non-text status colour (>3:1 on the inset); the MEANING is in the text, the
     icon is aria-hidden decoration, so colour is never the sole carrier (1.4.1).
   - the 112 line is a plain high-contrast paragraph (never visually-hidden,
     never buried), with the phone glyph as decoration only.
   Token-driven, so it tracks the dark-theme + high-contrast overrides in
   kind.css for free. */
.kind-status {
  margin-top: var(--kind-space-3);
  padding: var(--kind-space-3) var(--kind-space-4);
  background: var(--kind-color-surface-muted);
  border: 1px solid var(--kind-color-border-soft);
  border-radius: var(--kind-radius);
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-2);
}
.kind-status__live {
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-1);
}
.kind-status__line {
  display: flex;
  align-items: center;
  gap: var(--kind-space-2);
  margin: 0;
  font-weight: 600;
  color: var(--kind-color-text);
}
.kind-status__icon {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  color: var(--kind-color-text-muted);
}
.kind-status__line--sett .kind-status__icon { color: var(--kind-color-success); }
.kind-status__text { color: var(--kind-color-text); }
.kind-status__svarstid {
  margin: 0;
  /* paired with the status per D7; padded to align under the status text, past
     the icon column (icon 18px + 0.5rem gap). */
  padding-left: calc(18px + var(--kind-space-2));
  font-size: var(--kind-font-small);
  color: var(--kind-color-text);
}
/* #48: after the aggregate seen-line was replaced by the per-message ✓/✓✓
   markers, the svarstid line stands on its own in the status strip (D7: it must
   stay visible so a read marker never stands alone), so it no longer needs the
   icon-column indent. */
.kind-status__svarstid--standalone { padding-left: 0; }
.kind-status__nodlinje {
  display: flex;
  align-items: center;
  gap: var(--kind-space-2);
  margin: 0;
  padding-top: var(--kind-space-2);
  border-top: 1px solid var(--kind-color-border-soft);
  font-size: var(--kind-font-small);
  color: var(--kind-color-text);
}
.kind-status__nodlinje-icon {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  color: var(--kind-color-text-muted);
}

/* (The FINDING-2 / AT-09 "Ny konversation" disclosure rules were removed
   2026-06-24: the chat-native pivot (Wave A) dropped the patient-initiated
   "Ny konversation" affordance, so .kind-chatt-ny / __toggle / __form are
   orphaned and gone.) */

/* Articles (artiklar list) */
.kind-articles {
  display: grid;
  gap: var(--kind-space-4);
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
.kind-article-card {
  background: var(--kind-color-surface);
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius);
  padding: var(--kind-space-5);
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-3);
}
.kind-article-card__title { font-family: var(--kind-font-serif); margin: 0; }
.kind-article-card__title a { color: var(--kind-color-text); text-decoration: none; }
.kind-article-card__title a:hover { color: var(--kind-color-accent); text-decoration: underline; }
.kind-article-card__meta { font-size: var(--kind-font-small); color: var(--kind-color-text-muted); }

/* Login surface */
.kind-login-page {
  min-height: calc(100vh - 12rem);
  display: flex;
  justify-content: center;
  align-items: center;
  padding: var(--kind-space-5) var(--kind-space-4);
}
.kind-login-box {
  width: 100%;
  max-width: 26rem;
  background: var(--kind-color-surface);
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius);
  padding: var(--kind-space-6);
  box-shadow: var(--kind-shadow-md);
}
.kind-login-box__title { text-align: center; font-family: var(--kind-font-serif); }
.kind-login-box__sub { text-align: center; color: var(--kind-color-text-muted); margin-bottom: var(--kind-space-5); }

/* "eller logga in på annat sätt" divider with hairline rules either side. The
   text carries the meaning; the rules are decorative (aria-hidden via ::before/
   ::after, so a screen reader hears only the centred phrase). */
.kind-login-box__divider {
  display: flex;
  align-items: center;
  gap: var(--kind-space-3);
  text-align: center;
  color: var(--kind-color-text-muted);
  font-size: var(--kind-font-small);
  margin-bottom: var(--kind-space-4);
}
.kind-login-box__divider::before,
.kind-login-box__divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--kind-color-border-soft);
}

/* ============ ADR-027 DEMO login (mock BankID + per-device PIN) ============
 *
 * DEMO-only surface, flag-gated behind DEMO_LOGIN_ENABLED. Reuses the existing
 * login-box / field / button design tokens so it reads as the same app. Every
 * colour here is a token already proven AA against its surface; tap targets ride
 * the base .kind-btn min-height 44px (WCAG 2.2 AA 2.5.5). The honest "Demoläge"
 * badge keeps the mock screen from impersonating real BankID branding.
 */

/* Full-width primary action so each demo screen has ONE obvious thing to tap
   (inclusion priority: clear single primary action, large target). */
.kind-btn--block { display: flex; width: 100%; }

/* Honest demo badge sitting above the box title. Pale blush pill, deep-coral
   ink (accent-on-accent-soft is 4.63:1, clears AA). NOT the BankID logo. */
.kind-demo-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--kind-space-1);
  margin: 0 auto var(--kind-space-3);
  padding: var(--kind-space-1) var(--kind-space-3);
  border-radius: var(--kind-radius-pill);
  background: var(--kind-color-accent-soft);
  color: var(--kind-color-accent);
  font-size: var(--kind-font-small);
  font-weight: 600;
  width: fit-content;
}
.kind-demo-badge svg { flex: none; }

/* Simulated "Startar BankID ..." block: a brand-coral spinner ring + a polite
   aria-live status line. Decorative spinner (aria-hidden in markup); the status
   text is what assistive tech announces. */
.kind-demo-start {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--kind-space-3);
  margin-bottom: var(--kind-space-5);
  text-align: center;
}
.kind-demo-start__spinner {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 3px solid var(--kind-color-accent-soft);
  border-top-color: var(--kind-color-accent);
  animation: kind-demo-spin 1s linear infinite;
}
.kind-demo-start__status {
  margin: 0;
  color: var(--kind-color-text-muted);
  font-size: var(--kind-font-base);
}
@keyframes kind-demo-spin {
  to { transform: rotate(360deg); }
}
/* Motion-safe fallback: a steady brand dot instead of a spin (the global
   reduced-motion rule also neutralises the animation; this keeps the shape
   meaningful rather than a frozen partial ring). */
@media (prefers-reduced-motion: reduce) {
  .kind-demo-start__spinner {
    animation: none;
    border-color: var(--kind-color-accent-soft);
    background: var(--kind-color-accent);
  }
}

/* Large, evenly-spaced PIN entry: bigger glyphs + letter-spacing so a six-digit
   code is easy to read on a phone for a 12-year-old and a 90-year-old alike. */
.kind-field__input--pin {
  font-size: var(--kind-font-h3);
  letter-spacing: 0.4em;
  text-align: center;
  /* compensate trailing letter-spacing so the text stays visually centred */
  text-indent: 0.4em;
}

/* The always-present "log in another way" fallback link, centred + spaced. */
.kind-demo-alt { text-align: center; }

/* ============ W2-13 single article reader ============ */

.kind-article {
  max-width: 44rem;
  margin: 0 auto;
}
.kind-article__back { margin-bottom: var(--kind-space-3); }
/* CP-10 (#95): tillbaka-länkens TRÄFFYTA. Uppmätt 2026-08-06 var den 21px hög
   vid normal textskala och 32px vid xxlarge, alltså under BÅDE WCAG 2.2 AA
   2.5.8 (24px) och vårt strängare 44px-golv. Defekten fanns före CP-10 och satt
   på båda länkarna, huvudets och fotens. `inline-flex` med `min-height` växer
   träffytan utan att flytta textens baslinje, och den vertikala marginalen är
   sänkt lika mycket som länken växer, så nettohöjden på blocket är oförändrad
   och utfallsmåttet inte betalt med tillgänglighet. */
.kind-article__back a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}
/* CP-10 (#95). Huvudet är en RAD: omslag till vänster, rubrik och byline till
   höger. Uppmätt 2026-08-06 var det staplade huvudet 135px vid 320 normal och
   278px vid xxlarge, och brödtexten började på y=607 vid 320 xxlarge, alltså
   utanför viewporten. Marginalerna under huvudet är halverade (space-5 -> 4,
   space-4 -> 3) och det är ren komprimering: avdelaren står kvar, ingen text
   krymper. */
.kind-article__header {
  display: flex;
  align-items: flex-start;
  gap: var(--kind-space-3);
  margin-bottom: var(--kind-space-4);
  padding-bottom: var(--kind-space-3);
  border-bottom: 1px solid var(--kind-color-border-soft);
}
.kind-article__rubrikband {
  flex: 1 1 auto;
  min-width: 0;
}
.kind-article__rubrikband h1 {
  margin: 0 0 var(--kind-space-1);
  /* Långa sammansatta svenska titlar bryter i stället för att spränga en
     320px-viewport, samma regel och skäl som artikelraden i biblioteket. */
  overflow-wrap: break-word;
  hyphens: auto;
}
/* web#618 PUNKT 3: OMSLAGET ÄR EN STOR BILD ÖVERST I LÄSLÄGET.
 *
 * HÄR STOD `width: 56px; height: 56px` med noten "SAMMA fasta 56x56 som
 * bibliotekets miniatyr ... kostar noll extra höjd eftersom rubriken bredvid
 * alltid är högre". Det var CP-10:s (#95) svar på en MÄTT defekt: det staplade
 * huvudet var 278px vid 320 xxlarge och brödtexten började på y=607, alltså
 * utanför viewporten.
 *
 * ALEX 2026-09-25 UPPHÄVER DEN FORMEN, inte mätningen bakom den: gamla KIND
 * visar omslaget som en stor bild överst (fångst `gammal-patient/live-03-
 * artikel`, `gammal-vardgivare/45-49`), och paritet med gamla KIND är kravet.
 *
 * TAKET ÄR DET SOM GÖR ÅTERGÅNGEN ANSVARIG. `aspect-ratio` ensamt hade gett en
 * bild som växer med viewportbredden — vid 900px hade en 2:1-hero blivit 450px
 * hög och återskapat exakt den defekt CP-10 mätte upp. `max-height` kapar den
 * kurvan: kostnaden är känd och konstant i stället för proportionell, och vid
 * 320px (180px hög) ligger rubriken fortfarande inom första skärmen.
 *
 * MINIATYREN FINNS KVAR DÄR DEN HÖR HEMMA: bibliotekets rad
 * (`.kind-artikelrad__omslag`, `.kind-library-item__thumb`) är alltjämt 56px
 * och rörs inte av den här ändringen. Det är LISTAN som skannas; det är
 * LÄSLÄGET som öppnas för att läsas.
 *
 * Dekorativt (aria-hidden i mallen): rubriken är sidans tillgängliga namn. */
.kind-article__omslag {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  max-height: 220px;
  margin-bottom: var(--kind-space-3);
  border-radius: var(--kind-radius);
  background: var(--kind-color-surface-muted);
  overflow: hidden;
}
.kind-article__omslag-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* web#1208 punkt 6: inläggets huvudvideo i läsläget, samma plats som omslaget
   (ett inlägg har en bild ELLER en video). */
.kind-article__huvudvideo { margin-bottom: var(--kind-space-3); }
.kind-article__huvudvideo-spelare {
  display: block;
  width: 100%;
  max-height: 60vh;
  border-radius: var(--kind-radius);
  background: #000;
}
.kind-article__byline { color: var(--kind-color-text-muted); font-size: var(--kind-font-small); margin: 0; }
/* Proveniens (uppdaterad, författare) i foten. Metadata, alltså 14px muted med
   13px som absolut golv per ADR-065 §D4. */
.kind-article__proveniens {
  margin: 0 0 var(--kind-space-3);
  color: var(--kind-color-text-muted);
  font-size: var(--kind-font-small);
}

/* Article body uses serif headings + comfortable measure; safe HTML comes from
 * the sanitised Markdown renderer in the backend. */
.kind-article__body h2,
.kind-article__body h3 { font-family: var(--kind-font-serif); margin-top: var(--kind-space-5); }
.kind-article__body p { margin-bottom: var(--kind-space-4); }
.kind-article__body ul,
.kind-article__body ol { margin-bottom: var(--kind-space-4); padding-left: var(--kind-space-5); list-style: revert; }
.kind-article__body li { margin-bottom: var(--kind-space-2); }
.kind-article__body blockquote {
  margin: var(--kind-space-4) 0;
  padding: var(--kind-space-3) var(--kind-space-4);
  border-left: 4px solid var(--kind-color-accent);
  background: var(--kind-color-accent-bg);
  border-radius: 0 var(--kind-radius) var(--kind-radius) 0;
}
.kind-article__body img { border-radius: var(--kind-radius); margin: var(--kind-space-4) 0; }
.kind-article__body a { text-decoration: underline; }
.kind-article__footer { margin-top: var(--kind-space-6); padding-top: var(--kind-space-4); border-top: 1px solid var(--kind-color-border-soft); }

@media print {
  .kind-header, .kind-footer, .kind-nav, .kind-tabbar, .kind-skip-link,
  .kind-article__back, .kind-article__footer { display: none !important; }
  .kind-main--patient { padding-bottom: 0 !important; }
  body.kind-body--patient { background: #fff; color: #000; font-size: 11pt; }
  .kind-article { max-width: none; }
  .kind-article__body a { color: #000; text-decoration: underline; }
  .kind-article__body a[href]::after { content: " (" attr(href) ")"; font-size: 9pt; color: #444; }
}

/* ============ W2-13 vårdresor list + detail ============ */

.kind-vardresor-list { gap: var(--kind-space-4); }
.kind-vardresa-card { display: flex; flex-direction: column; gap: var(--kind-space-3); padding: var(--kind-space-5); }
.kind-vardresa-card__title { margin: 0; font-family: var(--kind-font-serif); font-size: var(--kind-font-h3); }
.kind-vardresa-card__title a { color: var(--kind-color-text); text-decoration: none; }
.kind-vardresa-card__title a:hover { color: var(--kind-color-accent); text-decoration: underline; }
.kind-vardresa-card__desc { margin: 0; color: var(--kind-color-text-muted); }

.kind-vardresa { max-width: 50rem; margin: 0 auto; }
.kind-vardresa__header { margin-bottom: var(--kind-space-5); padding-bottom: var(--kind-space-4); border-bottom: 1px solid var(--kind-color-border-soft); }
.kind-vardresa__progress { margin-top: var(--kind-space-3); display: flex; flex-direction: column; gap: var(--kind-space-2); }

/* Native <meter> styling: native fallback is the baseline, we just give it a
 * predictable size + cross-browser fill colour. The accent fill is decorative;
 * the percentage is also exposed as visible text + aria-label so colour is
 * never the only signal (WCAG 1.4.1). */
meter.kind-progress {
  width: 100%;
  height: 14px;
  appearance: none;
  -webkit-appearance: none;
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius-pill);
  background: var(--kind-color-surface-muted);
  overflow: hidden;
}
meter.kind-progress::-webkit-meter-bar {
  background: var(--kind-color-surface-muted);
  border-radius: var(--kind-radius-pill);
  border: none;
}
meter.kind-progress::-webkit-meter-optimum-value,
meter.kind-progress::-webkit-meter-suboptimum-value,
meter.kind-progress::-webkit-meter-even-less-good-value {
  background: var(--kind-color-accent);
  border-radius: var(--kind-radius-pill);
}
meter.kind-progress::-moz-meter-bar {
  background: var(--kind-color-accent);
  border-radius: var(--kind-radius-pill);
}

/* Step list */
.kind-steps { display: flex; flex-direction: column; gap: var(--kind-space-3); padding: 0; }
.kind-step {
  display: grid;
  grid-template-columns: 3rem 1fr;
  gap: var(--kind-space-4);
  padding: var(--kind-space-4);
  background: var(--kind-color-surface);
  border: 1px solid var(--kind-color-border-soft);
  border-radius: var(--kind-radius);
}
.kind-step--current {
  border: 2px solid var(--kind-color-accent);
  background: var(--kind-color-accent-bg);
}
.kind-step--before { opacity: 0.85; }
.kind-step__marker {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--kind-color-surface-muted);
  color: var(--kind-color-text);
  font-weight: 700;
  border: 1px solid var(--kind-color-border);
}
.kind-step--before .kind-step__marker {
  background: var(--kind-color-surface-muted);
  color: var(--kind-color-text);
  border-color: var(--kind-color-border);
}
.kind-step--current .kind-step__marker {
  background: var(--kind-color-accent);
  color: var(--kind-color-text-on-accent);
  border-color: var(--kind-color-accent);
}
.kind-step__status {
  font-size: var(--kind-font-small);
  margin: 0 0 var(--kind-space-1) 0;
  color: var(--kind-color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 600;
}
.kind-step--current .kind-step__status { color: var(--kind-color-accent); }
.kind-step__title { margin: 0 0 var(--kind-space-2) 0; font-family: var(--kind-font-serif); font-size: var(--kind-font-h3); }
.kind-step__instruktion { margin-bottom: var(--kind-space-2); }

/* B1: visual timeline spine.
 *
 * The base .kind-steps is a card list; .kind-timeline upgrades it to a
 * connected vertical timeline by drawing a spine through the marker column
 * so the ordered steps read as one continuous resa. The spine + the
 * upcoming/current/before marker treatments are PURELY decorative: every
 * state is also announced as text (.kind-step__status) and the current step
 * carries aria-current="step", so the timeline never relies on colour or
 * shape alone (WCAG 1.4.1). No completion is implied; this is the patient's
 * POSITION in the sequence (honest AT-20 framing, unchanged).
 *
 * Layout note: .kind-step is a 3rem|1fr grid with --kind-space-4 column gap
 * and --kind-space-3 row gap from .kind-steps. The spine sits centred on the
 * 2.5rem marker (so 1.25rem from the left edge of the 3rem column) and the
 * gap between cards is bridged with a pseudo-element on each non-last step. */
.kind-timeline { position: relative; }
.kind-timeline .kind-step { position: relative; }
/* Connector segment: bridges the row gap from this step's marker down to the
 * next step's marker. Drawn on every step except the last (which has no
 * successor to connect to). 1.25rem = half the 2.5rem marker, so the line is
 * centred on the marker circle. The segment starts just below the marker and
 * extends past the card edge into the inter-card gap. */
.kind-timeline .kind-step:not(:last-child)::before {
  content: "";
  position: absolute;
  left: calc(var(--kind-space-4) + 1.25rem - 1px);
  top: calc(var(--kind-space-4) + 2.5rem);
  bottom: calc(-1 * var(--kind-space-3) - var(--kind-space-4));
  width: 2px;
  background: var(--kind-color-border);
  /* The spine sits behind the marker circle, never over text. */
  z-index: 0;
}
/* Keep the marker + body above the spine. */
.kind-timeline .kind-step__marker,
.kind-timeline .kind-step__body { position: relative; z-index: 1; }

/* Upcoming (after current) steps: the base .kind-step has no dedicated style,
 * so an explicit pending treatment makes the not-yet steps visually distinct
 * from the current one. A hollow marker (outline, surface fill) reads as
 * "not reached yet" without implying anything about completion. The muted
 * text colour still clears WCAG AA (--kind-color-text-muted is 7.5:1 on bg). */
.kind-step--pending .kind-step__marker {
  background: var(--kind-color-surface);
  color: var(--kind-color-text-muted);
  border: 2px dashed var(--kind-color-border);
}
.kind-step--pending { opacity: 1; }
/* The connector segment LEADING INTO the current step is accented so the eye
 * is drawn down the resa to "where you are now". Segments after the current
 * step stay neutral (the patient has not reached them). */
.kind-timeline .kind-step--before:not(:last-child)::before {
  background: var(--kind-color-accent);
}

/* Empty state utility shared by patient surfaces */
.kind-empty-state {
  text-align: center;
  padding: var(--kind-space-6) var(--kind-space-4);
  max-width: 28rem;
  margin: var(--kind-space-6) auto;
}

/* Empty-state copy block (NIGHT-PASS 2026-06-04). Transparent so it reads on a
 * tinted section; ink heading-ish line + muted help + optional CTA. Replaces the
 * bare .kind-empty one-liner on the patient dashboard with a what-this-is +
 * why-it-is-empty + how-to-start pattern. */
.kind-empty-state__title {
  font-family: var(--kind-font-serif);
  font-size: var(--kind-font-h3);
  margin: 0 0 var(--kind-space-2) 0;
}
.kind-empty-state__help {
  color: var(--kind-color-text-muted);
  margin: 0 0 var(--kind-space-3) 0;
  max-width: 40ch;
  margin-inline: auto;
}
/* #410 / K11 villkor 6 (konsultbeslut 2026-08-25): tomlägets illustration.
   Dekorativ (`aria-hidden` i markup), centrerad, med samma bokmotiv och samma
   accent-tokens som radens standardomslag, så det tomma och det fyllda
   biblioteket läser som samma yta. Egen klass i stället för en utility, så
   storleken kan ändras utan att röra `.kind-empty-state`s övriga användare. */
.kind-empty-state__bild {
  display: block;
  margin: 0 auto var(--kind-space-4);
}
/* Centred wrap-friendly CTA row for an empty-state's how-to-start buttons (and
 * any patient-surface action pair). The shared .kind-cta-row primitive lives in
 * kind_patterns.css, which the patient surfaces do NOT load (they load kind.css
 * + kind_patient.css), so the same rule is defined here for patient pages. The
 * buttons keep their .kind-btn 44px touch target + AA contrast; the row only
 * lays them out. */
.kind-cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--kind-space-3);
  justify-content: center;
  align-items: center;
  margin-top: var(--kind-space-4);
}

/* --------------------------------------------------------------------------
 * W6-01 / PMV-11: patient profile + GDPR-radering modal + success page.
 *
 * Surfaces:
 *  - .kind-profile               page wrapper for /patient/profil + success.
 *  - .kind-profile-section       grouped subsection (uppgifter, radera).
 *  - .kind-profile-section--danger    red-accented "danger zone" subsection.
 *  - .kind-kv                    key-value list for read-only patient info.
 *  - .kind-dialog                native <dialog> styling for the modal.
 *  - .kind-btn--danger           destructive-action CTA, accent color.
 *  - .kind-actions-row           horizontal CTA row on the success page.
 *
 * a11y: dialog uses native <dialog>.showModal(); focus-trap + Escape are
 * browser-built-in. Color contrast on .kind-btn--danger verified WCAG AA
 * against white: #fff on --kind-color-accent = 5.26:1 (Classic+, ADR-065; was
 * 2026-06-02 to the kind.app-hued coral; the prior blue pass measured 6.5:1,
 * and Adde's original #bc424a measured 5.23:1, both also AA-safe).
 * -------------------------------------------------------------------------- */

.kind-profile {
  max-width: var(--kind-container-narrow);
  margin: 0 auto;
  padding: var(--kind-space-4) 0;
}
.kind-profile__lede {
  color: var(--kind-color-text-muted);
  font-size: 1.0625rem;
  margin: var(--kind-space-2) 0 var(--kind-space-5) 0;
}
.kind-profile-section {
  background: var(--kind-color-surface);
  border: 1px solid var(--kind-color-border-soft);
  border-radius: var(--kind-radius);
  padding: var(--kind-space-4);
  margin-bottom: var(--kind-space-4);
}
.kind-profile-section--danger {
  border-color: var(--kind-color-accent);
  background: var(--kind-color-accent-bg);
}
.kind-profile-section__title {
  margin-top: 0;
  margin-bottom: var(--kind-space-3);
  font-family: var(--kind-font-serif);
  font-size: var(--kind-font-h3);
}
.kind-profile-section__body {
  margin: 0 0 var(--kind-space-3) 0;
  line-height: 1.5;
}

/* Read-only key-value list for "Uppgifter" subsection. */
.kind-kv {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--kind-space-2) var(--kind-space-3);
  margin: 0;
}
.kind-kv > div { display: contents; }
.kind-kv__label {
  color: var(--kind-color-text-muted);
  font-weight: 600;
}
.kind-kv__value {
  margin: 0;
  color: var(--kind-color-text);
}

/* Destructive-action button: same shape as .kind-btn but the ERROR token, NOT
 * the coral accent, so "radera" is visually distinct from a primary CTA (which
 * is the accent). White on --kind-color-error clears AA; dark-theme
 * near-black on #ff7373 = 7.11:1, both WCAG AA. text-on-accent token carries
 * the correct white/near-black per theme. */
.kind-btn--danger {
  background: var(--kind-color-error);
  color: var(--kind-color-text-on-accent);
  border-color: var(--kind-color-error);
}
.kind-btn--danger:hover {
  filter: brightness(0.9);
}

/* Native <dialog> modal for the deletion confirmation.
 * Browser owns the backdrop + focus-trap via showModal(); we only style
 * the panel + actions row. */
.kind-dialog {
  border: none;
  padding: 0;
  border-radius: var(--kind-radius);
  background: transparent;
  max-width: 32rem;
  width: calc(100% - 2rem);
}
.kind-dialog::backdrop {
  background: rgba(0, 0, 0, 0.45);
}
.kind-dialog__panel {
  background: var(--kind-color-surface);
  border-radius: var(--kind-radius);
  padding: var(--kind-space-5);
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-3);
}
.kind-dialog__title {
  margin: 0;
  font-family: var(--kind-font-serif);
  font-size: var(--kind-font-h2);
}
.kind-dialog__body {
  margin: 0;
  line-height: 1.5;
}
.kind-dialog__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--kind-space-3);
  justify-content: flex-end;
  margin-top: var(--kind-space-2);
}

/* Horizontal CTA row on the success page (mirrors kind_admin.css pattern). */
.kind-actions-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--kind-space-3);
  margin-top: var(--kind-space-4);
  align-items: center;
}

/* Success-state variant of the profile page. */
.kind-profile--success .kind-flash {
  margin-bottom: var(--kind-space-4);
}

/* ==========================================================================
 * Kind 3.0 vardresa-tidslinje (PM-007). Patient care-journey timeline.
 *
 * One reverse-chronological, month-grouped stream of the patient's own care
 * events. Built ON the shipped .kind-timeline spine (the vardresa step view) +
 * the .kind-card surface tokens + the a11y-panel aria-pressed button pattern, so
 * it introduces NO new design-system primitives, only this view's composition.
 *
 * a11y (WCAG 2.1 AA, ux §5):
 *   - Type carried by icon-shape + text label, NEVER colour (1.4.1). The bright
 *     brand coral #FF676E is NOT used as a type-carrier; icons inherit the AA-safe
 *     --kind-color-accent via currentColor.
 *   - Cards are NON-interactive (only the action link focuses), so a long stream
 *     is not a multi-stop tab tunnel (2.1.2 / AC-T-10).
 *   - Filter toggles + links are >=44x44 CSS px (2.5.5 uplift for the older /
 *     motor-impaired patient cohort).
 *   - Body/meta/label text >=4.5:1 on the warm surface + the high-contrast theme
 *     (1.4.3); the muted date uses --kind-color-text-muted (5.87:1 on bg).
 *   - Single-column reflow at 320px / 400% (1.4.10); the filter strip wraps.
 *   - Entrance/stagger gated behind prefers-reduced-motion: no-preference (2.3.3).
 * ========================================================================== */

.kind-tidslinje { max-width: 50rem; margin: 0 auto; }

.kind-tidslinje__head {
  margin-bottom: var(--kind-space-5);
  padding-bottom: var(--kind-space-4);
  border-bottom: 1px solid var(--kind-color-border-soft);
}
/* `.kind-tidslinje__intro` BORTTAGEN 2026-08-11 (#171), orienteringsmeningen
   den formade beskrev vad en omvand kronologisk lista redan visar. */
/* The persistent history-vs-journal boundary line (persona must-address 4). */
.kind-tidslinje__boundary {
  color: var(--kind-color-text-muted);
  font-size: var(--kind-font-small);
  margin: 0;
}

/* ---- Filter strip ---- */
/* Calm control strip, reusing the a11y-panel fontscale segmented-button look
 * (aria-pressed carries state). Revealed by JS (hidden until enhanced). */
.kind-tidslinje__filter {
  display: flex;
  flex-wrap: wrap;
  gap: var(--kind-space-2);
  margin-bottom: var(--kind-space-5);
}
/* [hidden]-gard, samma monster som .kind-mine__filter pa rad 4617. Kommentaren
   ovan sager "hidden until enhanced", men `display: flex` slog UA-lagrets
   `[hidden]{display:none}`, sa remsan var malad aven fore JS hunnit koppla den,
   alltsa exakt den doda kontroll `hidden` skulle forhindra. */
.kind-tidslinje__filter[hidden] { display: none; }
.kind-tidslinje__filter-btn {
  min-height: 44px;
  padding: var(--kind-space-2) var(--kind-space-4);
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius-pill);
  background: var(--kind-color-surface);
  color: var(--kind-color-text);
  font-weight: 600;
  line-height: 1.2;
  font-size: var(--kind-font-small);
  cursor: pointer;
}
.kind-tidslinje__filter-btn:hover { background: var(--kind-color-surface-muted); }
.kind-tidslinje__filter-btn[aria-pressed="true"] {
  background: var(--kind-color-accent-bg);
  border-color: var(--kind-color-accent);
  color: var(--kind-color-accent);
}

/* ---- Month waypoints ---- */
.kind-tidslinje__manad {
  font-family: var(--kind-font-serif);
  font-size: var(--kind-font-h2);
  margin: var(--kind-space-5) 0 var(--kind-space-3) 0;
}
/* First month heading sits flush under the filter strip / head. */
.kind-tidslinje__manad:first-of-type { margin-top: 0; }

/* ---- The stream: reuse the .kind-timeline spine on each month's <ol> ---- */
/* .kind-timeline (kind_patient.css "B1 visual timeline spine") draws a connecting
 * vertical spine through the marker column. The base spine rule keys off
 * .kind-step; here the rows are .kind-tidslinje__kort, so this block re-states the
 * marker-column grid + the connector for the timeline cards. The spine + markers
 * are PURELY decorative (aria-hidden); every type is ALSO text. */
.kind-tidslinje__lista {
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-3);
  padding: 0;
  margin: 0;
  list-style: none;
  position: relative;
}
.kind-tidslinje__kort {
  position: relative;
  display: grid;
  grid-template-columns: 2.5rem 1fr;
  gap: var(--kind-space-4);
  padding: var(--kind-space-4);
  background: var(--kind-color-surface);
  border: 1px solid var(--kind-color-border-soft);
  border-radius: var(--kind-radius);
  box-shadow: var(--kind-shadow-sm);
}
/* Connector segment: bridges the row gap from this card's marker to the next.
 * Drawn on every card except the last. 1.125rem = half the 2.25rem marker, so
 * the line is centred on the marker circle. Sits behind the marker (z-index 0). */
.kind-tidslinje__lista .kind-tidslinje__kort:not(:last-child)::before {
  content: "";
  position: absolute;
  left: calc(var(--kind-space-4) + 1.125rem - 1px);
  top: calc(var(--kind-space-4) + 2.25rem);
  bottom: calc(-1 * var(--kind-space-3) - var(--kind-space-4));
  width: 2px;
  background: var(--kind-color-border);
  z-index: 0;
}
.kind-tidslinje__marker,
.kind-tidslinje__kropp { position: relative; z-index: 1; }
/* min-width: 0 lets the 1fr body column shrink below its content's min-content
 * width (CSS grid tracks default to min-width: auto, which otherwise forces
 * horizontal overflow when a long token like a filename can't shrink). Paired
 * with overflow-wrap on the text below, this keeps the card single-column at
 * 320px / 400% zoom / max font-scale with no horizontal scroll (1.4.10 reflow). */
.kind-tidslinje__kropp { min-width: 0; }

/* Marker: a round chip carrying the type icon (decorative; the type is also the
 * text label in the body). Accent-tinted icon via currentColor. */
.kind-tidslinje__marker {
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--kind-color-surface-muted);
  color: var(--kind-color-accent);
  border: 1px solid var(--kind-color-border-soft);
}

/* ---- Card body ---- */
/* Type eyebrow: small inline icon + the text type-label (the scan target +
 * colour-independent type cue, 1.4.1). Uppercase eyebrow like .kind-step__status. */
.kind-tidslinje__typ {
  display: flex;
  align-items: center;
  /* Wrap at extreme font-scales so the "Kommande" badge drops to a new line
   * rather than forcing horizontal overflow at 320px / max font-scale (1.4.10). */
  flex-wrap: wrap;
  gap: var(--kind-space-2);
  margin: 0 0 var(--kind-space-1) 0;
  font-size: var(--kind-font-small);
  color: var(--kind-color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 600;
}
.kind-tidslinje__typ-ikon { display: inline-flex; color: var(--kind-color-accent); }
.kind-tidslinje__typ-text { white-space: nowrap; }
.kind-tidslinje__titel {
  margin: 0 0 var(--kind-space-2) 0;
  font-family: var(--kind-font-serif);
  font-size: var(--kind-font-h3);
  /* Long unbreakable tokens (a filename like Provsvar_2026.pdf) must wrap inside
   * the constrained body column at narrow widths / high zoom (1.4.10 reflow). */
  overflow-wrap: anywhere;
}
.kind-tidslinje__sammanfattning {
  margin: 0 0 var(--kind-space-2) 0;
  overflow-wrap: anywhere;
}
/* R-1 (persona-patient): a remiss row's plain-language reassurance line. Muted,
 * smaller, calm, distinct from the who/where summary above it. Not colour-coded
 * (it is a reassurance, never a status), so it carries no AA-contrast risk
 * beyond the muted body token already used across the timeline. */
.kind-tidslinje__remiss-info {
  margin: 0 0 var(--kind-space-2) 0;
  font-size: var(--kind-font-small);
  color: var(--kind-color-text-muted);
  overflow-wrap: anywhere;
}
.kind-tidslinje__status {
  margin: 0 0 var(--kind-space-2) 0;
  font-size: var(--kind-font-small);
  font-weight: 600;
  color: var(--kind-color-text-muted);
}
.kind-tidslinje__tid {
  margin: 0;
  color: var(--kind-color-text-muted);
  font-size: var(--kind-font-small);
}
.kind-tidslinje__lank-rad { margin: var(--kind-space-3) 0 0 0; }
.kind-tidslinje__lank {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: var(--kind-space-2) 0;
  font-weight: 600;
}

/* ---- Past vs upcoming (persona must-address 6) ---- */
/* A future booking ("Kommande") reads visually distinct from history: an accent
 * left-edge + an accent marker + a worded "Kommande" badge (the word carries the
 * meaning; colour is a redundant cue only, 1.4.1 / AC-T-19). */
.kind-tidslinje__kort--kommande {
  border-left: 4px solid var(--kind-color-accent);
  background: var(--kind-color-accent-bg);
}
.kind-tidslinje__kort--kommande .kind-tidslinje__marker {
  background: var(--kind-color-accent);
  color: var(--kind-color-text-on-accent);
  border-color: var(--kind-color-accent);
}
.kind-tidslinje__badge {
  display: inline-block;
  margin-left: var(--kind-space-1);
  padding: 0.1rem var(--kind-space-2);
  border-radius: var(--kind-radius-pill);
  background: var(--kind-color-accent);
  color: var(--kind-color-text-on-accent);
  font-size: var(--kind-font-small);
  letter-spacing: 0;
  text-transform: none;
}

/* ---- Empty-after-filter (distinct from empty-overall) ---- */
.kind-tidslinje__filter-tomt {
  padding: var(--kind-space-5);
  background: var(--kind-color-surface-muted);
  border-radius: var(--kind-radius);
  color: var(--kind-color-text-muted);
  text-align: center;
}
.kind-tidslinje__filter-tomt-titel {
  font-weight: 600;
  color: var(--kind-color-text);
  margin: 0 0 var(--kind-space-2) 0;
}

/* ---- Pagination ---- */
.kind-tidslinje__pagination {
  display: flex;
  justify-content: center;
  margin-top: var(--kind-space-5);
}

/* ---- Reduced motion: gate the only entrance animation behind no-preference.
 * A gentle fade-up on the cards when motion is welcome; nothing (static) when the
 * patient prefers reduced motion (vestibular-safe, 2.3.3 / AC-T-22). The global
 * kind.css reduced-motion rule also neutralises durations as a backstop. */
@media (prefers-reduced-motion: no-preference) {
  .kind-tidslinje__kort {
    animation: kind-tidslinje-in 280ms ease both;
  }
  @keyframes kind-tidslinje-in {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: none; }
  }
}

/* ---- Reflow: single column with no horizontal scroll at narrow widths /
 * high zoom (1.4.10 / AC-T-23). The grid marker column shrinks slightly so the
 * card body keeps room; the filter strip already wraps via flex-wrap. */
@media (max-width: 30rem) {
  .kind-tidslinje__kort {
    grid-template-columns: 2rem 1fr;
    gap: var(--kind-space-3);
  }
  .kind-tidslinje__lista .kind-tidslinje__kort:not(:last-child)::before {
    left: calc(var(--kind-space-4) + 1rem - 1px);
  }
}

/* ---- Print: drop the decorative spine + marker fills, keep the text. ---- */
@media print {
  .kind-tidslinje__filter,
  .kind-tidslinje__pagination { display: none; }
  .kind-tidslinje__kort { box-shadow: none; break-inside: avoid; }
  .kind-tidslinje__lista .kind-tidslinje__kort:not(:last-child)::before { display: none; }
}

/* ==========================================================================
 * Crash-safe forms + overlays (2.1 UX pivot, D5/D6). Owner: frontend-web.
 *
 * Surfaces:
 *  - .kind-crash-overlay        the short/atomic in-chat form as a native
 *                               <dialog> overlay (D5). Reuses the .kind-dialog
 *                               backdrop + panel shape; explicit Stang only.
 *  - .kind-restore-banner       the "Vi sparade dina svar" banner shown on
 *                               reopen when a localStorage draft was restored.
 *  - .kind-steg                 the step indicator for the multi-field own-page
 *                               form (D5: long forms get their own page + steg).
 *
 * a11y: the overlay is a native <dialog> (browser focus-trap + Escape, kept by
 * the JS as an explicit-close path, D6). The restore banner is a polite live
 * region, not a focus-stealer. Colours reuse audited tokens (info / success).
 * ========================================================================== */

/* ---- Short/atomic overlay (D5). Reuses .kind-dialog backdrop/panel. ---- */
.kind-crash-overlay {
  border: none;
  padding: 0;
  border-radius: var(--kind-radius);
  background: transparent;
  max-width: 34rem;
  width: calc(100% - 2rem);
}
/* xxlarge-kompaktering av akutkanalens ICKE-TEXTKROM i overlay-kontexten
   (X2:s uttryckliga trimordning: den dekorativa aria-hidden-ikonen forst,
   sedan padding). Textstorlek och lydelser rors ALDRIG (X1); numren goms
   ALDRIG (X6, ikonen ar dekoration, inte innehall). Scopat till xxlarge dar
   panelbudgeten faktiskt brister, sa normal skala renderar som fore. */
html[data-kind-font-scale="xxlarge"] .kind-crash-overlay .kind-safety__icon {
  display: none;
}
html[data-kind-font-scale="xxlarge"] .kind-crash-overlay .kind-safety {
  gap: 0;
  padding-inline: var(--kind-space-3);
  /* Panelens flex-gap ager redan vertikalavstandet; asidens egen margin-block
     ovanpa gapet var 18px dubbelbetald dodyta rakt ovanfor akutkanalen. */
  margin-block: 0;
}
.kind-crash-overlay::backdrop {
  background: rgba(0, 0, 0, 0.45);
}
.kind-crash-overlay__panel {
  background: var(--kind-color-surface);
  border-radius: var(--kind-radius);
  padding: var(--kind-space-5);
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-3);
  max-height: calc(100vh - 4rem);
  overflow-y: auto;
}
.kind-crash-overlay__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--kind-space-3);
}
.kind-crash-overlay__title {
  margin: 0;
  font-family: var(--kind-font-serif);
  font-size: var(--kind-font-h2);
}
.kind-crash-overlay__lede {
  margin: 0;
  line-height: 1.5;
  color: var(--kind-color-text-muted);
}
/* Explicit close button (D6: the ONLY dismiss path). A real labelled control,
 * not a bare glyph; the visible glyph is decorative, the text carries meaning. */
.kind-crash-overlay__close {
  flex: 0 0 auto;
}

/* Smala viewports: overlay-KROMET bantas sa panelens innehallsbredd och
   synliga band vaxer (Y2/X2, akutnummer-fixram-2026-08-07). Vid 320px och
   xxlarge var innehallsbredden ~200px (~12 tecken/rad): akutkanalens
   nummer-mening radbrots da sa langt att tel:1177 hamnade under PANELENS
   synliga botten i panelens initiala skrollage (uppmatt 2026-08-07,
   tel:1177 pa y 689-851 beroende pa sprak, mot panelbotten ~616). Bredare
   innehall + hogre panel ar de enda spakar som lyfter malet UTAN att rora
   text eller lydelse (X1/X5-forbuden); marginal, padding och 4rem-slacken
   (96px dodyta pa en 664px-telefon) ar icke-textkrom av exakt X2-sorten.
   rem i media-frageuttryck laser INITIALT fontvarde, opaverkat av
   data-kind-font-scale, sa brytpunkten ar stabil over textskalorna.
   OBS KALLORDNING: blocket MASTE sta EFTER basreglerna ovan, samma
   specificitet avgor pa ordning, och en tidigare placering forlorade tyst
   (uppmatt 2026-08-07: clientHeight 568 trots max-height-regeln). */
@media (max-width: 480px) {
  .kind-crash-overlay {
    width: calc(100% - 0.5rem);
  }
  .kind-crash-overlay__panel {
    padding: var(--kind-space-3) var(--kind-space-2);
    gap: var(--kind-space-2);
    max-height: calc(100vh - 1rem);
  }
}

/* ---- Restore banner: "Vi sparade dina svar". -------------------------- */
.kind-restore-banner {
  display: flex;
  align-items: flex-start;
  gap: var(--kind-space-3);
  background: var(--kind-color-success-bg);
  border: 1px solid var(--kind-color-success);
  border-radius: var(--kind-radius);
  padding: var(--kind-space-3) var(--kind-space-4);
  margin: 0 0 var(--kind-space-4) 0;
}
.kind-restore-banner[hidden] { display: none; }
.kind-restore-banner__icon {
  flex: 0 0 auto;
  color: var(--kind-color-success);
  display: inline-flex;
  margin-top: 0.1rem;
}
.kind-restore-banner__body {
  flex: 1 1 auto;
  min-width: 0;
}
.kind-restore-banner__text {
  margin: 0;
  font-weight: 600;
  color: var(--kind-color-text);
}
.kind-restore-banner__sub {
  margin: var(--kind-space-1) 0 0 0;
  color: var(--kind-color-text-muted);
  font-size: 0.9375rem;
  line-height: 1.4;
}
.kind-restore-banner__clear {
  margin-top: var(--kind-space-2);
}

/* ---- Step indicator for the multi-field own-page form (D5). ----------- */
.kind-steg {
  margin: 0 0 var(--kind-space-5) 0;
}
.kind-steg__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--kind-space-2) var(--kind-space-4);
}
.kind-steg__item {
  display: flex;
  align-items: center;
  gap: var(--kind-space-2);
  color: var(--kind-color-text-muted);
  font-size: 0.9375rem;
}
.kind-steg__num {
  flex: 0 0 auto;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: var(--kind-radius-pill);
  border: 2px solid var(--kind-color-border);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 0.875rem;
  color: var(--kind-color-text);
}
/* The currently-active step (the one the form is on) is accent-ringed + bold. */
.kind-steg__item--current { color: var(--kind-color-text); font-weight: 600; }
.kind-steg__item--current .kind-steg__num {
  border-color: var(--kind-color-accent);
  background: var(--kind-color-accent);
  color: var(--kind-color-text-on-accent);
}
/* A completed step gets a filled success mark. CP-03 (issue #88): the glyph was
 * a hardcoded #fff on a TOKEN fill, which is 4.94:1 on the light success green
 * and 1.57:1 on the dark one, i.e. an unreadable step number in the dark theme.
 * --kind-color-text-on-accent is the token whose whole job is "readable label ON
 * a filled accent/status surface"; it is #FFFFFF in light (byte-identical
 * rendering) and #0D1218 in dark, measured 9.38:1 there. */
.kind-steg__item--done .kind-steg__num {
  border-color: var(--kind-color-success);
  background: var(--kind-color-success);
  color: var(--kind-color-text-on-accent);
}
.kind-steg__progress {
  margin: var(--kind-space-3) 0 0 0;
  font-size: 0.9375rem;
  color: var(--kind-color-text-muted);
}

@media (prefers-reduced-motion: reduce) {
  .kind-crash-overlay { animation: none; }
}

/* ==========================================================================
 * WS-A (inclusion 1A): patient formulär-fill radios, error state, badges
 *
 * The patient surface loads kind.css + kind_patient.css ONLY (NOT kind_admin.css),
 * so the .kind-radio / .kind-badge families that exist for the clinician inbox
 * were absent here. The form-fill page (templates/patient/formular_fill.html)
 * referenced these classes with no rule, so radio options rendered inline +
 * overlapping (WCAG 2.5.8 target-size fail) and the missing-answer error state
 * was visually invisible (WCAG 3.3.1). These rules add them, sized a touch
 * larger than the clinician versions for the older / lower-vision patient
 * surface (48px rows, 1.5rem controls). Tokens are the same WCAG-clean palette
 * the audit measured (--kind-color-error on white, past AA; on
 * --kind-color-error-bg #fbe7e7 well above 4.5:1 in both themes).
 * ========================================================================== */

/* Radio group: stacked, never inline (the missing rule caused the overlap). */
.kind-radio-group {
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-2);
}
/* The whole row is a 48px+ tappable target (WCAG 2.5.8), not just the dot.
   CP-02-resten (#87): raden ÄR alltså kontrollen, och en kontrollkant är per
   kind.css §1 WATCH-ITEM 1 aldrig den dekorativa hairlinen. */
.kind-radio {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-height: 48px;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius);
  cursor: pointer;
}
.kind-radio:hover { background: var(--kind-color-surface-muted); }
/* Enlarged native control (default ~13px is below a comfortable target). */
.kind-radio input {
  width: 1.5rem;
  height: 1.5rem;
  margin: 0;
  flex: 0 0 auto;
  accent-color: var(--kind-color-accent);
}
/* Selected row reads as chosen by more than colour alone (border + tint). */
.kind-radio:has(input:checked) {
  border-color: var(--kind-color-accent);
  background: var(--kind-color-accent-bg);
}
.kind-radio__label { color: var(--kind-color-text); }

/* WS-A leftover (WCAG 1.4.10 reflow): a long Swedish compound form title
 * (e.g. "Hälsodeklaration inför specialistmottagningsbesök") must wrap inside
 * the 320px viewport instead of forcing horizontal scroll. overflow-wrap keeps
 * normal words intact but breaks an over-long token at the box edge; hyphens
 * lets the UA insert a soft hyphen where the lang allows (the page is sv-SE). */
.kind-formular-fill__heading {
  overflow-wrap: break-word;
  hyphens: auto;
}

/* Missing-answer error state on a re-rendered fieldset: a visible red frame +
 * tinted fill so the question that needs an answer is obvious at a scan, not
 * conveyed by the helper text alone (WCAG 3.3.1 / 1.4.1). */
.kind-formular-fill__fraga--missing {
  border: 2px solid var(--kind-color-error);
  background: var(--kind-color-error-bg);
  border-radius: var(--kind-radius);
  padding: var(--kind-space-3);
}
.kind-field__help--error {
  color: var(--kind-color-error);
  font-weight: 600;
}
.kind-field__required { color: var(--kind-color-error); }
.kind-field__optional {
  color: var(--kind-color-text-muted);
  font-weight: 400;
  font-size: var(--kind-font-small);
}

/* Status chips on Bokningar / Formulär (rendered as plain text before this).
 * Mirrors the clinician kind_admin.css .kind-badge family on the same semantic
 * tokens so the two surfaces read consistently; patient surface only needs the
 * success / warning / info / base variants.
 *
 * ===== #439: BASREGELN ÄR `:where()`-LINDAD, OCH DET ÄR LOAD-BEARING =====
 * Sex vårdgivarmallar (admin/arbetsvy.html, admin/chatt.html,
 * admin/team_chat_visa.html, admin/artikel_lasvy.html,
 * admin/artikel_radera_bekrafta.html, admin/vardresa_steg_bekrafta.html) laddar
 * DET HÄR arket EFTER kind_admin.css. Den ordningen är i sin tur load-bearing
 * och får inte bara kastas om: tests/test_420_stilarksordning.py håller fast
 * att omvänd ordning ger `.kind-btn--danger` kontrasten 1:1, alltså en osynlig
 * Radera-knapp på artikelytorna.
 *
 * Som BAR `.kind-badge` (specificitet 0,1,0) låg regeln därmed senare i
 * kaskaden än HELA kind_admin.css:s badge-familj på EXAKT samma specificitet,
 * och vann alltså background/color/border-color över varje modifierare som den
 * filen äger och den här filen inte råkar återdeklarera: `--akut`, `--error`,
 * `--draft`, `--tillstand`, `--unread`, `--unread-egna`, `--unread-andras`.
 * Uppmätt på /admin/arbetsvy 2026-09-19 (#439): brickan "Brådskande" renderade
 * background rgb(235, 239, 244), alltså samma neutrala pilla som varje annan
 * bricka, så kö-rälens enda patientsäkerhetsmarkör hade ingen brådskefärg.
 * `--unread-egna` / `--unread-andras` dog av samma mekanism (#250).
 * `--success` / `--warning` / `--info` överlevde BARA för att de råkar
 * återdeklareras här nedanför; det var tur och inte design, och att bygga på
 * den turen (återdeklarera även vårdgivarens modifierare här) hade lagt en
 * andra sanningskälla för samma modifierare i ett ark som inte äger dem.
 *
 * `:where(.kind-badge)` matchar exakt samma element men bär specificitet
 * (0,0,0). Varje modifierare (0,1,0) i BÅDA arken vinner därför över basen
 * oavsett filordning, och basen är återigen det den är avsedd att vara: en
 * reserv, inte en konkurrent. Deklarationerna nedan är ORÖRDA och är
 * byte-identiska med kind_admin.css:s basregel, så en bricka UTAN modifierare
 * renderar oförändrat på båda ytorna. Patientytan laddar aldrig kind_admin.css,
 * och ingen annan regel i kind.css eller i den här filen matchar brickelementet
 * på egen hand, så nedskrivningen till (0,0,0) tappar ingen patientstyling.
 *
 * Vakt: tests/test_439_badge_kaskad_css.py löser den FAKTISKA kaskaden över
 * mallens länkade ark och faller när en modifierare plattas ut av en bar regel
 * igen, alltså mätt på utfallet och inte på att regeln finns i källan. */
:where(.kind-badge) {
  display: inline-block;
  padding: 2px 10px;
  border-radius: var(--kind-radius-pill);
  font-size: var(--kind-font-small);
  font-weight: 600;
  background: var(--kind-color-surface-muted);
  color: var(--kind-color-text);
  border: 1px solid var(--kind-color-border-soft);
}
.kind-badge--success { background: var(--kind-color-success-bg); color: var(--kind-color-success); border-color: var(--kind-color-success); }
.kind-badge--warning { background: var(--kind-color-warning-bg); color: var(--kind-color-warning); border-color: var(--kind-color-warning); }
.kind-badge--info    { background: var(--kind-color-info-bg);    color: var(--kind-color-info);    border-color: var(--kind-color-info); }

/* --------------------------------------------------------------------------
 * FRMSVAR-ROUTING-PT: persistent post-submit form receipt (formular_kvittens).
 *
 * Replaces the old transient-flash-on-the-list confirmation with a dedicated,
 * revisitable page (rule 38 spot-ability). The .kind-kvittens block is a calm
 * success surface: a success-tinted icon, a focusable heading the JS lands on
 * after the PRG redirect, the named next step, and a repeated 112/1177 safety
 * line in a warning tint. All colours use shipped tokens (verified AA in the
 * kind.css contrast table). ----------------------------------------------- */
.kind-kvittens {
  max-width: 38rem;
  margin: 0 auto;
}
.kind-kvittens__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3.5rem;
  height: 3.5rem;
  border-radius: var(--kind-radius-pill);
  background: var(--kind-color-success-bg);
  color: var(--kind-color-success);
  margin: 0 0 var(--kind-space-3) 0;
}
.kind-kvittens__heading {
  margin: 0 0 var(--kind-space-3) 0;
}
/* The heading is programmatically focused on load (WCAG 3.2.2); keep the focus
 * ring visible so a keyboard/SR user sees where focus landed, but do not show it
 * to mouse users (it is not interactive). */
.kind-kvittens__heading:focus-visible {
  outline: var(--kind-focus-ring);
  outline-offset: var(--kind-focus-ring-offset);
}
.kind-kvittens__lede {
  font-size: 1.0625rem;
  line-height: 1.5;
  color: var(--kind-color-text);
  margin: 0 0 var(--kind-space-5) 0;
}
.kind-kvittens__akut {
  background: var(--kind-color-warning-bg);
  border: 1px solid var(--kind-color-warning);
  border-radius: var(--kind-radius);
  padding: var(--kind-space-4);
  margin: 0 0 var(--kind-space-5) 0;
}
.kind-kvittens__akut p {
  margin: 0;
  color: var(--kind-color-text);
  line-height: 1.5;
}

/* W6F-07 unread "Nytt svar" chip (persona-patient spec, 2026-06-21).
 *
 * Binary chip on the chat-list clinic-name line: present when the conversation
 * has clinician-authored messages the patient has not read (k.olast_antal > 0),
 * absent otherwise. NEVER a number, NEVER a "0"/greyed marker; absence IS the
 * read state. The chip is decorative (aria-hidden); the new-reply fact is in the
 * row link's accessible name, so the chip carries no separate role/action.
 *
 * Colour: solid --kind-color-accent (#1769D2) fill with --kind-color-text-on-accent
 * (white) text = 5.26:1, clears WCAG 1.4.3 for the small chip text (NOT the
 * marketplace coral --kind-color-brand-coral #ff676e, which fails AA). The chip carries the WORD
 * "Nytt svar", so meaning never relies on colour alone (WCAG 1.4.1). The solid
 * fill against the white row gives the pill a >=3:1 non-text edge (1.4.11) without
 * a separate border, and forced-colors mode keeps the pill shape + a system border
 * so the token still reads as distinct.
 */
.kind-chatt-rad__namn {
  display: flex;
  flex-wrap: wrap;          /* name + chip reflow at 320px / 150-200% zoom, no side-scroll */
  align-items: center;
  gap: var(--kind-space-2);
  margin-bottom: var(--kind-space-1);
}
.kind-chip {
  display: inline-flex;
  align-items: center;
  padding: var(--kind-space-1) var(--kind-space-3);
  border-radius: var(--kind-radius-pill);
  font-size: var(--kind-font-small);
  font-weight: 700;
  line-height: 1.2;
  white-space: nowrap;      /* keep "Nytt svar" intact; the line wraps, the chip does not split */
}
.kind-chip--nytt {
  background: var(--kind-color-accent);
  color: var(--kind-color-text-on-accent);       /* white on accent = 5.34:1 */
}
@media (forced-colors: active) {
  .kind-chip--nytt {
    border: 1px solid CanvasText;                /* keep a visible token edge in HC mode */
  }
}

/* ==========================================================================
   Broadcast OPT-OUT pages (FEATURE_BROADCAST, dark), BROADCAST-OPTOUT-FRAMING-FE
   ..........................................................................
   The patient-facing /utskick/avregistrera/<token> confirm + done pages. The
   patient followed an opt-out link from a broadcast body. These pages are
   UNAUTHENTICATED + reached cold, often by an older / lower-vision patient, so
   the layout stays calm + single-column + generously spaced, body text at the
   patient-surface 1.0625rem floor (>=16px) for readability.

   a11y: the h1 carries tabindex="-1" so the page lands focus on the heading for
   a keyboard / SR user; the focus ring is shown ONLY to keyboard users
   (:focus-visible) since the heading is not interactive. The "keep getting" note
   uses a calm reassurance surface (success-bg, dark ink 15.37:1 in light mode
   per the token comments), NOT an alarm colour, because the message is
   reassuring ("you keep your kallelser"), and carries role="note" in the markup
   so it reads as an aside, never colour-alone (WCAG 1.4.1). The primary button
   inherits .kind-btn--primary (>=44px target, AA contrast, focus ring).
   ========================================================================== */
.kind-optout {
  max-width: 34rem;
  margin: 0 auto;
  padding: var(--kind-space-5) 0;
}
.kind-optout h1 {
  margin: 0 0 var(--kind-space-4) 0;
}
/* Heading is programmatically focusable (tabindex=-1) for the focus-landing
   pattern; show the ring to keyboard users only (WCAG 2.4.7), hide for mouse. */
.kind-optout h1:focus-visible {
  outline: var(--kind-focus-ring);
  outline-offset: var(--kind-focus-ring-offset);
}
.kind-optout p {
  font-size: 1.0625rem;          /* >=16px patient-surface readability floor */
  line-height: 1.5;
  color: var(--kind-color-text);
  margin: 0 0 var(--kind-space-4) 0;
}
.kind-optout__lede {
  color: var(--kind-color-text-muted);
}
/* The care-critical reassurance ("you still get personal messages"): a calm
   success-tinted inset, NOT an alarm colour. The patient's biggest worry is
   answered here, so it is visually distinct + easy to spot, but soothing. */
.kind-optout__keep {
  background: var(--kind-color-success-bg);
  border: 1px solid var(--kind-color-success);
  border-radius: var(--kind-radius);
  padding: var(--kind-space-4);
}
.kind-optout__form {
  margin-top: var(--kind-space-5);
}

/* ============================================================================
 * Bibliotek / Library tab (Wave C, patient chat-native, 2026-06-24)
 *
 * Matches the real KIND iOS "Library" tab: a search field at the top, a
 * "N artiklar" count, then a list of rows (title + meta on the left, a square
 * thumbnail on the right). The whole row is one keyboard-reachable link.
 * A11y (WCAG 2.2 AA): the search input + submit are min 48px tall (patient
 * floor); the row link is min 56px tall; visible focus ring; the thumb is a
 * decorative placeholder (aria-hidden in markup), so no alt needed.
 * ========================================================================== */
.kind-library {
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-4);
}
/* CP-09 (#94). Mellanrummen mellan bandets block är fem stycken, och vid
   xxlarge kostar de tillsammans cirka 120px av en 664px hög viewport. Att
   halvera dem är ren komprimering: inget block försvinner, ingen text krymper,
   och rytmen i listan under är oförändrad (`.kind-library-list` har sin egen
   gap). Gäller bara stor textskala, där utrymmet faktiskt är kritiskt. */
html[data-kind-font-scale="xlarge"] .kind-library,
html[data-kind-font-scale="xxlarge"] .kind-library {
  /* 2026-08-07 (#94, delmoment 1): space-2 -> space-1. Baslinjekörningen
     2026-08-07 visade M9b fortsatt röd på fem mobilpunkter i
     med-välkomst-tillståndet (y=664-762 mot tak ~556), så även det sista
     tomrumslagret halveras. Blocken har egen inramning (välkomstrutan bär
     bakgrund och kantlinje), så 4px mellanrum läser fortfarande som paus. */
  gap: var(--kind-space-1);
}
/* `.kind-library__band`, `.kind-library__band h1` och `.kind-library__lead`
   BORTTAGNA 2026-08-11 (#170). Bandet fanns för att hålla ihop rubriken och
   introduktionen; introduktionen "Utvalt för dig." är struken och rubriken är
   `kind-visually-hidden`, alltså finns inget block kvar att forma. Wrappern är
   borttagen ur mallen i samma ändring, så ingen av de tre reglerna hade någon
   matchande nod kvar. Blockets uppmätta höjd var 129px vid 390 xxlarge
   (docs/design/bibliotek-cp09-cp10.md §4); den är nu 0px. */
.kind-library__section-title {
  margin: var(--kind-space-4) 0 0;
}
html[data-kind-font-scale="xlarge"] .kind-library__section-title,
html[data-kind-font-scale="xxlarge"] .kind-library__section-title {
  /* 2026-08-07 (#94): space-2 -> space-1, samma skäl som .kind-library-gapet. */
  margin-top: var(--kind-space-1);
}
/* Sökfältets vertikala luft vid stor textskala: fältet är 70px högt vid
   xxlarge (27px text plus 8px padding uppe och nere plus kant). Halverad
   padding-block ger ~62px, fortfarande långt över 44px-golvet som dessutom
   hålls explicit. Ingen text krymper, bara luften runt den. */
html[data-kind-font-scale="xlarge"] .kind-library-search__input,
html[data-kind-font-scale="xxlarge"] .kind-library-search__input {
  padding-block: var(--kind-space-1);
  min-height: 44px;
}
/* Radens höjd drivs av KNAPPEN, inte fältet (uppmätt 2026-08-07: raden låg
   kvar på 70px efter fälttrimningen; `.kind-btn` bär space-3-padding och
   `align-items: stretch` drar fältet med sig). Samma halvering för knappen,
   skopad till biblioteksformuläret så produktens övriga knappar är orörda.
   44px-golvet hålls explicit. */
html[data-kind-font-scale="xlarge"] .kind-library-search__submit,
html[data-kind-font-scale="xxlarge"] .kind-library-search__submit {
  padding-block: var(--kind-space-1);
  min-height: 44px;
}
/* CP-09, komprimering vid stor textskala. Varje regel här tar bort TOMRUM, inte
   innehåll: ingen text krymper, inget block försvinner, ingen rad avkortas.
   Uppmätt vinst 320 xxlarge: 662px -> se docs/design/bibliotek-cp09-cp10.md.

   Att `<h1>` och `<h2>` behåller sina egna storlekar är avsiktligt. ADR-065 §D4
   sätter typskalan och den rörs inte av en yta som behöver plats; det vore att
   lösa sitt eget mått på designsystemets bekostnad. */
/* Skalvarianten för `.kind-library__band` följde med bandet ut 2026-08-11
   (#170); den nollade ett mellanrum i ett block som inte längre finns. */
html[data-kind-font-scale="xlarge"] .kind-library-search,
html[data-kind-font-scale="xxlarge"] .kind-library-search {
  /* 2026-08-07 (#94): 4px -> 0. Etikettraden (min-height 44) och fältet bär
     egen inre luft, mellanrummet dubblerade den. */
  gap: 0;
}
/* Sidramens övre luft är ren padding och skalar med rotfonten: space-5 är
   20px vid normal men 30px vid xxlarge, alltså VÄXER tomrummet exakt när
   utrymmet är som dyrast. Skopat med :has(.kind-library) till biblioteksytan
   så ingen annan patientyta (chattens kontrakterade zoner!) ändrar ram. */
html[data-kind-font-scale="xlarge"] .kind-main--patient:has(.kind-library),
html[data-kind-font-scale="xxlarge"] .kind-main--patient:has(.kind-library) {
  padding-block-start: var(--kind-space-2);
}
html[data-kind-font-scale="xlarge"] .kind-library-search__head,
html[data-kind-font-scale="xxlarge"] .kind-library-search__head {
  /* Etiketten och "Rensa" bryter till var sin rad vid stor textskala, vilket är
     rätt (ingen avkortning), men mellanrummet mellan dem behöver inte vara
     sektionsmellanrummet. */
  gap: 0 var(--kind-space-2);
}
.kind-library__count {
  margin: 0;
  color: var(--kind-color-text-muted);   /* 5.87:1 on bg, past AA */
  font-size: var(--kind-font-small);
  font-weight: 600;
}
/* #410 / K11 (konsultbeslut 2026-08-25): `.kind-library-list ~ .kind-library__count`
   ÄR BORTTAGEN, inte kvarlämnad.

   Regeln bar gränsen mellan patientens TVÅ artikellistor med 2rem luft, och
   den var syskonskopad (`~`) just för att gränsen bara skulle finnas när den
   FÖRSTA listan faktiskt renderades. K11 slår ihop listorna till EN och flyttar
   räknarraden ÖVANFÖR den, så selektorn har efter den ändringen ingen
   matchning kvar: det finns aldrig en `.kind-library-list` FÖRE räknaren.

   BORTTAGEN och inte kvarlämnad, samma disciplin och samma skäl som K6
   tillämpade på `.kind-tilldelade__note` några rader ned: en regel utan bärare
   läses av nästa läsare som en aktiv del av arket och inbjuder till att någon
   återanvänder den på ett element den aldrig designades för.

   SÖKMÄNGD bakom påståendet att bäraren är borta (regel 49g): `grep -rn
   "kind-library__count"` över `templates/`, `static/`, `tests/` och `e2e/`
   gav 2026-08-26 träffar enbart på den enda kvarvarande `<p>`:n i
   patient/artiklar.html, som nu står FÖRE listan, plus basregeln
   `.kind-library__count` ovan, som står kvar och fortfarande används.

   Uppmätningen som motiverade 2rem (kvoten listgap mot radgap, 10,8x vid 390
   och 320 normal, 7,8x vid 320 xxlarge) bevaras i git-historiken; den mätte
   en gräns som inte längre finns. */
/* K6 (konsultbeslut 2026-08-18): `.kind-tilldelade__note` är BORTTAGEN.
 *
 * Klassen stylade `<span>`:en som bar "(visas alltid)" intill rubriken
 * "Tilldelat till dig" i patientens bibliotek. K6 tog bort den rubriken ur
 * markup och vek in noten i listans `aria-label`, alltså finns ingen bärare
 * kvar för klassen och ingen framtida rendering kan träffa den.
 *
 * BORTTAGEN, inte kvarlämnad: en regel utan bärare läses av nästa läsare som
 * en aktiv del av arket och inbjuder till att någon "återanvänder" den på ett
 * element den aldrig designades för. Sökmängden bakom påståendet att bäraren
 * är borta: `grep -rn kind-tilldelade__note` över hela trädet utom .git,
 * node_modules och .venv gav 2026-08-18 exakt en träff, den här regeln själv.
 *
 * Sättet noten ser ut på är därmed inte längre en CSS-fråga: den läses upp av
 * skärmläsaren som en del av listans namn och har ingen visuell form. */

/* Search. A labelled <form role="search"> with an icon-prefixed input + a
   submit button on one row; the optional "Rensa sökning" clear link sits below. */
.kind-library-search {
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-2);
}
/* CP-09 (#94): etiketten och "Rensa" på SAMMA rad. Före låg de på var sin, och
   formuläret blev 137px vid normal och 182px vid xxlarge. Raden är
   `flex-wrap: wrap` så en lång etikett vid stor textskala bryter till två rader
   i stället för att trycka ut "Rensa" ur viewporten (mått 6). */
.kind-library-search__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--kind-space-2);
}
.kind-library-search__label {
  font-weight: 600;
  color: var(--kind-color-text);
}
.kind-library-search__row {
  display: flex;
  align-items: stretch;
  /* INGEN `flex-wrap` här, och det är ett MÄTT beslut. Ett första försök satte
     wrap i tron att raden orsakade den horisontella skrollen; knappen lade sig
     då under fältet och formuläret växte från 182px till 263px vid 320 xxlarge,
     alltså blev utfallet SÄMRE av en fix mot fel orsak. Boven var artikeltiteln
     (se `.kind-library-item__title`). Fältet har `min-width: 0` och krymper, så
     raden håller sig innanför viewporten utan wrap. */
  gap: var(--kind-space-2);
  position: relative;
}
.kind-library-search__icon {
  position: absolute;
  left: var(--kind-space-3);
  top: 50%;
  transform: translateY(-50%);
  pointer-events: none;
  color: var(--kind-color-text-muted);
  font-size: 1.1rem;
  line-height: 1;
}
.kind-library-search__input {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 48px;
  padding: var(--kind-space-2) var(--kind-space-3) var(--kind-space-2) calc(var(--kind-space-6) + var(--kind-space-2));
  border: 1px solid var(--kind-color-border);   /* 3.94:1, WCAG 1.4.11 */
  /* CP-05 (#90), brief §4.3: a FÄLT takes the 6-10px band, never the pill. This
     was the only capsule-shaped input left in the product (measured 2026-08-05
     on the rendered patient library, radius 999px on a 48px search field). */
  border-radius: var(--kind-radius);
  background: var(--kind-color-surface);
  color: var(--kind-color-text);
  font: inherit;
}
.kind-library-search__input:focus-visible {
  outline: var(--kind-focus-ring);
  outline-offset: 1px;
}
.kind-library-search__submit {
  flex: 0 0 auto;
  min-height: 48px;
}
.kind-library-search__clear {
  /* 44px träffyta står kvar (WCAG 2.5.8 plus vårt strängare golv). Den ligger
     nu bredvid etiketten i stället för under formuläret, alltså kostar den noll
     extra höjd så länge etikettraden ändå är minst 44px hög. */
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  color: var(--kind-color-accent);
  font-weight: 600;
}

/* #637: rensa-krysset i sökfältet (gamla KIND-paritet). Visas bara av
   static/js/kind_bibliotekssok.js, och bara medan fältet inte är tomt. Ligger
   inne i fältets högerkant; 44px träffyta (WCAG 2.5.8 plus vårt golv). */
.kind-library-search__kryss {
  position: absolute;
  right: var(--kind-space-1);
  top: 50%;
  transform: translateY(-50%);
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: transparent;
  color: var(--kind-color-text-muted);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
}
.kind-library-search__kryss:focus-visible {
  outline: var(--kind-focus-ring);
  outline-offset: 1px;
}
.kind-library-search--js .kind-library-search__input {
  padding-right: calc(44px + var(--kind-space-2));
}
/* [hidden]-gard: `display: flex/inline-flex` på de här slår UA-lagrets
   `[hidden]{display:none}`, och skriptet döljer dem med attributet. */
.kind-library-search__kryss[hidden],
.kind-library-search__submit[hidden],
.kind-library-search__clear[hidden],
.kind-library-list[hidden],
.kind-library-item[hidden],
.kind-library .kind-empty[hidden] { display: none; }

/* List + rows. */
.kind-library-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-2);
}
.kind-library-item { margin: 0; }
/* CP-02-resten (#87). Artikelraden är det tredje exemplet designregeln i
   kind.css §6 namnger ("an article"): hela raden är en <a>, alltså den
   klickbara enheten, så kanten är funktionell. */
.kind-library-item__link {
  display: flex;
  align-items: center;
  gap: var(--kind-space-4);
  min-height: 56px;
  padding: var(--kind-space-3) var(--kind-space-4);
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius);
  background: var(--kind-color-surface);
  text-decoration: none;
  color: var(--kind-color-text);
  box-shadow: var(--kind-shadow-sm);
}
.kind-library-item__link:hover { background: var(--kind-color-surface-muted); }
.kind-library-item__link:focus-visible {
  outline: var(--kind-focus-ring);
  outline-offset: 2px;
}
.kind-library-item__body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
/* CP-09 (#94), mått 6: DIAGNOSTISERAD, inte gissad. Sidan sköt ut 71px
   horisontellt vid 320 xxlarge, 16px vid 375 och 1px vid 390, och boven var
   INTE sökfältet utan artikeltiteln: `span.kind-library-item__body` mättes till
   scrollWidth 342 mot clientWidth 142 på "Egenvårdsrekommendationer". Svenskan
   bygger ihop ord utan mellanslag, så det är den längsta ORDLÄNGDEN och inte
   teckenantalet som spränger en 320px-rad, och vid xxlarge räcker ett enda
   sammansatt ord. Samma regel och samma motivering som #109 redan etablerat för
   formulärrubriken (`.kind-formular-fill__heading`), och `<html lang="sv">` gör
   `hyphens: auto` verksam. */
.kind-library-item__title {
  font-family: var(--kind-font-serif);
  font-size: 1.0625rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--kind-color-text);
  overflow-wrap: break-word;
  hyphens: auto;
  /* #158, samma golv och samma skäl som `.kind-artikelrad__titel` i kind.css,
     där hela motiveringen står. Här delades "fungerar" och "efter" i titlar med
     gott om plats. Boxen storleksätts av behållaren (`min-width: 0` på
     rubrikbandet), så avstavningen krymper den inte, alltså är golvet allt som
     behövs. */
  hyphenate-limit-chars: 12 3 3;
}
.kind-library-item__meta {
  font-size: var(--kind-font-small);
  color: var(--kind-color-text-muted);   /* 5.87:1, past AA */
  overflow-wrap: break-word;
  /* #410 / K11: metaraden bär numera BARA märkningen "Tilldelad dig", och den
     är en pill med egen bakgrund. `flex` plus `wrap` gör att pillen kan brytas
     ned på egen rad vid 320px och stor textskala i stället för att tvinga
     titelkolumnen smalare. `align-items: baseline` håller pillens text i linje
     med titelns baslinje när de delar rad. */
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 4px;
  margin-block-start: 2px;
}
/* #410 / K11 bindande villkor 2 (konsultbeslut 2026-08-25): märkningen
   `Tilldelad dig` på RADEN.

   VARFÖR DEN FINNS. K11 slår ihop patientens två artikellistor till en. Innan
   dess bars skillnaden mellan "en vårdpersonal valde den här åt dig" och "den
   ligger i mottagningens allmänna utbud" av LISTTILLHÖRIGHET. Med en lista är
   den bäraren borta, och informationen måste flytta till raden (WCAG 1.3.1,
   information och relationer ska framgå av strukturen, inte av presentationen).

   FÄRGEN ÄR ALDRIG ENSAM BÄRARE (1.4.1): ordet står utskrivet i markup, och
   raden är fullt begriplig utan stilarket. Kanten är med av samma skäl som på
   husets övriga pill-liknande element, en yta som bara skiljs med bakgrundsfärg
   försvinner i högkontrastläge.

   TOKENBASERAD, ingen hårdkodad hex: accent-soft som platta, accent-hover som
   text (accent-hover är den mörkare av de två accenterna och är den som klarar
   AA mot accent-soft), accent som kant. Samma trio och samma roller som mockens
   `.mock-marke` i docs/design-proposals/410-patientens-bibliotek/variant-a.html.

   `white-space: nowrap` på SJÄLVA pillen så etiketten inte bryts mitt itu;
   metaradens `flex-wrap` ovan är det som ger den en egen rad när den inte får
   plats. */
.kind-library-item__marke {
  display: inline-block;
  background: var(--kind-color-accent-soft);
  color: var(--kind-color-accent-hover);
  border: 1px solid var(--kind-color-accent);
  border-radius: 999px;
  padding: 1px 8px;
  font-size: var(--kind-font-small);
  font-weight: 600;
  line-height: 1.5;
  white-space: nowrap;
}
/* HUSMÖNSTER, läs kommentaren innan du tar bort raden (CLAUDE.md regel 27
   korollarium 2): en författarregel med `display` slår UA-arkets
   `[hidden] { display: none }` på URSPRUNG och inte på specificitet, så ett
   framtida `hidden` på den här noden hade varit verkningslöst utan garden.
   Skopad per klass och utan `!important`, exakt som `.kind-btn[hidden]`. */
.kind-library-item__marke[hidden] { display: none; }
.kind-library-item__thumb {
  flex: 0 0 auto;
  width: 56px;
  height: 56px;
  border-radius: var(--kind-radius);
  background: var(--kind-color-surface-muted);
  overflow: hidden;
}
/* UAT-05: no cover set. An INTENTIONAL default cover, a soft blush square with a
   centered open-book line illustration (the inline SVG in artiklar.html), NOT
   the old empty pink box that read as a missing thumbnail. Decorative
   (aria-hidden in markup). The blush background makes the white book pages pop;
   the SVG fills the fixed 56x56 wrapper. */
/* K10 (#201): plattan läses ur `--kind-omslag-platta`, som variantregeln i
   kind.css sätter (EN palett, delad med vårdgivarens biblioteksrad och
   delningsväljaren). Fallbacken är den gamla accentfärgen, så en rad UTAN
   variantklass renderar byte för byte som före ändringen.

   INDIREKTIONEN ÄR INTE KOSMETIK. kind.css laddas FÖRE den här stilmallen, så
   en variantregel som skrev `background` direkt hade förlorat mot raden nedan
   på KÄLLORDNING (samma specificitet 0-1-0), och patientens platta hade
   förblivit identisk på varje rad medan bara bokstrecket varierade. Hela
   motiveringen står vid paletten i kind.css. */
.kind-library-item__thumb--default {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--kind-omslag-platta, var(--kind-color-accent-soft));
}
.kind-library-item__thumb-cover {
  display: block;
  width: 100%;
  height: 100%;
}
/* V3b (agents#62, B7): the real cover thumbnail. Fills the SAME fixed
   56x56 wrapper as the placeholder (flex: 0 0 auto + overflow: hidden
   above), so the row geometry, and therefore the 320px layout, is
   byte-for-byte the placeholder's: no new width is introduced. */
.kind-library-item__thumb-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* #12 (2.2): per-org welcome message slot on the patient library surface. A calm
   informational note in the org accent tint, never alarmist, never overshadowing
   the 112/safety disclaimer (which lives in the chat composer, not here). */
/* CP-09 (#94): rutan är nu en NATIV `<details>`, hopfälld som förval.
   Uppmätt 2026-08-06 var den 226px vid 320 normal och 511px vid 320 xxlarge,
   alltså det enskilt största blocket före första artikelraden. Hopfälld är den
   en 44px hög rad. Texten är hopfälld, INTE avkortad: ingen information går
   förlorad, den ligger ett tryck bort. */
.kind-org-welcome {
  margin: 0;
  border-left: 4px solid var(--kind-color-accent);
  border-radius: var(--kind-radius);
  background: var(--kind-color-accent-soft);
  color: var(--kind-color-text);   /* 15.37:1 on accent-soft, past AA */
}
.kind-org-welcome__summary {
  /* Träffyta 44px och en synlig fokusring: `<summary>` är en riktig
     tangentbordskontroll och ska se ut som en.

     `display: list-item` är BÄRANDE (persona-villkor 3, 2026-08-07): en
     tidigare version satte `display: flex`, vilket tar bort webbläsarens egen
     disclosure-trekant (markören renderas bara för list-item-lådor), samtidigt
     som kommentaren PÅSTOD att trekanten behölls. Utan pil är raden bara en
     textrad, och då öppnar ingen den (NN/g om accordions på mobil). Den nativa
     markören ärver textfärgen, alltså rätt i ljust läge, mörkt läge och
     forced-colors, och 4.1.2 sköts av det nativa elementet.
     `align-content: center` vertikalcentrerar blockinnehållet (Chromium 123+,
     Safari 17.4+, Firefox 125+). */
  display: list-item;
  list-style-position: inside;
  align-content: center;
  min-height: 44px;
  padding: var(--kind-space-2) var(--kind-space-4);
  font-weight: 600;
  cursor: pointer;
}
/* Vid stor textskala är varje pixel före första artikelraden dyr (M9b):
   summaryraden behåller 44px-golvet via min-height, så det vertikala
   luftlagret ovanpå kan halveras utan att träffytan krymper. */
html[data-kind-font-scale="xlarge"] .kind-org-welcome__summary,
html[data-kind-font-scale="xxlarge"] .kind-org-welcome__summary {
  padding-block: var(--kind-space-1);
}
/* Markören är en ikon, inte text: vid xxlarge tog en textstor (27px) trekant
   så mycket inline-plats att etiketten bröt till en TREDJE rad vid 320
   (uppmätt 2026-08-07: summaryn 110 -> 142px). 0.75em ger en fortsatt tydligt
   synlig pil (~20px vid xxlarge, större än normallägets text) utan att stjäla
   en hel rad. Ingen etikett-text krymps, bara glyfen. */
html[data-kind-font-scale="xlarge"] .kind-org-welcome__summary::marker,
html[data-kind-font-scale="xxlarge"] .kind-org-welcome__summary::marker {
  font-size: 0.75em;
}
.kind-org-welcome__summary:focus-visible {
  outline: var(--kind-focus-ring);
  outline-offset: 2px;
  border-radius: var(--kind-radius);
}
.kind-org-welcome__text {
  margin: 0;
  padding: 0 var(--kind-space-4) var(--kind-space-3);
}

/* ============================================================================
 * Mer / More tab (Wave C, patient chat-native, 2026-06-24)
 *
 * Matches the real KIND iOS "More" tab: a centered avatar (initials) + name at
 * the top, an "Inställningar" list of rows (label + value, or label + chevron
 * for links/actions), a Logga ut button, and a version/copyright footer.
 * A11y (WCAG 2.2 AA): link/action rows are min 56px tall; the destructive
 * "Radera"-row trigger is a real <button> spanning the full row; visible focus
 * ring; the chevron + avatar are decorative (aria-hidden in markup).
 * ========================================================================== */
.kind-more {
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-5);
  max-width: 40rem;
}
/* CP-13 (#98): identiteten är en RAD, inte en centrerad kolumn.
 *
 * UPPMÄTT mot deployen 2026-08-04: den stående varianten (72px avatar ÖVER
 * namnet, centrerad, `padding: space-5 0 space-2`) var 151px hög vid normal
 * textskala och 191px vid xxlarge. Det är 29 procent av en 664px hög viewport
 * för en avatar och ett namn, och det var den enskilt största posten bakom att
 * andelen aktuell information på ytan föll från 63.6 till 24 procent enbart
 * genom textskalan (mått 4, docs/contracts/classic-plus-utfall.md).
 *
 * Radvarianten lägger avataren bredvid namnet i stället för över det, och
 * avataren krymper till 48px. `flex-wrap: wrap` så ett långt namn får bryta ned
 * på egen rad vid 320px och xxlarge i stället för att bredda sidan (mått 6).
 */
/* 2026-08-08: blocket LIGGER NU INUTI `.kind-nu`, briefens §6.4 bokstavligt.
 *
 * Vadderingen är därför NOLL och inte `space-3 0 space-2`: kortet bär redan sin
 * egen `space-4` runt om, och den gamla vadderingen hade adderats ovanpå den.
 * Separationen nedåt bärs av MARGINALEN, som ligger utanför blockets border-box
 * och därmed klassas som kortets yta (aktuell) i stället för som identitet.
 * Uppmätt bidrag av just det bytet vid 320 xxlarge: 30px, se ändringsloggen
 * 2026-08-08 i docs/contracts/classic-plus-utfall.md.
 */
.kind-more__identity {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--kind-space-3);
  padding: 0;
  margin: 0 0 var(--kind-space-3);
}
/* 8rem och inte 12rem: 12rem kunde inte rymmas bredvid en 48px avatar inne i
 * kortet vid 320px, så textblocket bröt ned på egen rad och avataren kostade
 * en HEL rad i stället för noll. Basen är nu smalare än det smalaste kortet. */
.kind-more__identity-text {
  min-width: 0;
  flex: 1 1 8rem;
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-1);
}

/* Kontaktraden, briefens §6.4 (konsultbeslut 2026-08-08).
 *
 * `flex-wrap` med kolumngap i stället för ett skiljetecken: vid bredare
 * viewporter står e-post och telefon på samma rad, vid 320px och stor textskala
 * bryter de till var sin rad UTAN att en dinglande mittpunkt blir kvar sist på
 * en rad. `overflow-wrap: anywhere` på posten eftersom en e-postadress är ett
 * osplittbart token som annars breddar sidan (mått 6, horisontell skroll).
 *
 * Radavståndet är 1.35 och inte brödtextens 1.55. Det är en METADATARAD på
 * högst två rader, inte löpande text, och tätare radavstånd på korta
 * metadatarader är typografisk standard. WCAG 2.2 1.4.12 gäller ANVÄNDARENS
 * override till 1.5 och hindrar inte ett tätare utgångsläge; texten bryter
 * fortfarande fritt och inget klipps. Uppmätt bidrag vid 320 xxlarge: 12px.
 */
.kind-more__kontakt {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  column-gap: var(--kind-space-3);
  font-size: var(--kind-font-small);
  line-height: 1.35;
  color: var(--kind-color-text-muted);   /* 5.87:1 mot surface, förbi AA */
}
.kind-more__kontakt-post { min-width: 0; overflow-wrap: anywhere; }

/* Vid xxlarge textskala göms den DEKORATIVA avataren.
 *
 * UPPMÄTT 2026-08-05 vid 320x664 xxlarge: radlayouten degenererar till en
 * kolumn där ändå (textblockets min-content ryms inte bredvid en 48px avatar,
 * så `flex-wrap` bryter ned det), och avataren kostar då 48px plus 18px
 * mellanrum, alltså 66px av en 408px hög innehållsyta. Den bär noll
 * information: initialerna är `aria-hidden`, namnet står bredvid, och det finns
 * ingen bild bakom. Utan den här regeln blev identitetsblocket 216px, alltså
 * STÖRRE än de 191px det var före ändringen, och andelen aktuell information
 * FÖLL trots att sammanfattningen lagts till.
 *
 * Att låta dekoration vika vid stor textskala är den avsedda innebörden i
 * WCAG 2.2 1.4.4 (Resize Text) och 1.4.10 (Reflow): innehållet får omorganiseras
 * så länge ingen information eller funktion går förlorad. Här går ingendera
 * förlorad, eftersom avataren varken bär information eller funktion.
 * Vid normal textskala står avataren kvar.
 */
html[data-kind-font-scale="xxlarge"] .kind-more__avatar { display: none; }
.kind-more__kontakt {
  margin: 0;
  font-size: var(--kind-font-small);
  color: var(--kind-color-text-muted);
  /* En e-postadress är ett osplittbart token och skulle annars bredda sidan. */
  overflow-wrap: anywhere;
}
.kind-more__avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 48px och inte 72px: avataren bär ingen information (initialerna är
   * `aria-hidden`, namnet står bredvid), så dess enda kostnad är höjd. */
  width: 48px;
  height: 48px;
  flex: 0 0 auto;
  border-radius: var(--kind-radius-pill);
  background: var(--kind-color-accent-soft);
  color: var(--kind-color-accent);       /* 4.63:1 on accent-soft, AA */
  font-family: var(--kind-font-serif);
  font-size: 1.75rem;
  font-weight: 700;
  line-height: 1;
}
.kind-more__name {
  margin: 0;
  font-family: var(--kind-font-serif);
  font-size: 1.375rem;
  font-weight: 600;  /* ADR-065 §D4 (CP-04): display-sized heading role, cap 600 */
  /* 1.2, husets egen rubrikleding (`h1, h2, h3` i kind.css) i stället för
   * brödtextens ärvda 1.55. Namnet spelar rubrikroll och är en till två rader,
   * inte löpande text. Uppmätt bidrag vid 320 xxlarge: 12px. */
  line-height: 1.2;
  color: var(--kind-color-text);
}

/* SPAK-KONTAKT typskalesteg, smal viewport OCH stor textskala (2026-08-08).
 *
 * Samma spak och samma skopning som SPAK-XXL §S-1 på arbetsvyn (kontraktets
 * ändringslogg 2026-08-07), och av samma skäl. Uppmätt vid 320 xxlarge med ett
 * långt dubbelnamn (`Marie-Charlotte Gustafsson-Lindqvist af Ugglebo`, husets
 * egen tyngsta-fixtur): namnet kräver 741,54px på en rad, kolumnen ger 243,00px,
 * alltså FEM rader om 39,59px, vilket ensamt är 197,97px av en innehållsyta på
 * 383px. Vid 1.125rem faller det till tre rader om 32,40px.
 *
 * Rubriken blir ALDRIG mindre än brödtexten vid samma skala, som är husets
 * gräns för det här steget: 1.125rem är 27,00px vid xxlarge mot brödtextens
 * 1.0625rem, alltså 25,50px. Namnet fortsätter dessutom skala med
 * textskalinställningen (22,00px vid normal, 27,00px vid xxlarge), så WCAG 2.2
 * 1.4.4 håller; det är storleksSKILLNADEN mot brödtexten som minskar, inte
 * skalbarheten.
 */
@media (max-width: 430px) {
  html[data-kind-font-scale="xlarge"] .kind-more__name,
  html[data-kind-font-scale="xxlarge"] .kind-more__name { font-size: 1.125rem; }
}

/* ---- CP-13 (#98): Aktuellt, patientens kompakta sammanfattning ----
 *
 * Egen deklaration i patientarket och inte delad med kind_admin.css:
 * patientsidan laddar bara `kind_patient.css`, och att lyfta ut ett gemensamt
 * ark är en större städning som inte hör hemma i den här ändringen.
 *
 * Mobilförst med etikett över värde, tvåkolumnigt först när det finns bredd.
 * En fast etikettkolumn kan inte krympa under sin min-content vid xxlarge och
 * trycker då ut sidan i horisontell skroll vid 320px (mått 6).
 */
.kind-nu {
  background: var(--kind-color-surface);
  border: 1px solid var(--kind-color-border);
  border-left: 4px solid var(--kind-color-accent);
  border-radius: var(--kind-radius);
  padding: var(--kind-space-4);
  margin-bottom: var(--kind-space-4);
}
.kind-nu__title {
  margin: 0 0 var(--kind-space-3);
  font-size: var(--kind-font-small);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--kind-color-text-muted);
}
.kind-nu__list { margin: 0; display: grid; gap: var(--kind-space-3); }
.kind-nu__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--kind-space-1);
  min-width: 0;
}
.kind-nu__label { font-size: var(--kind-font-small); color: var(--kind-color-text-muted); }
.kind-nu__value { margin: 0; min-width: 0; overflow-wrap: anywhere; }
/* Hela raden är en träffyta, inte bara textens bredd. `inline-flex` med
 * `min-height` så länken växer med texten vid xxlarge i stället för att klippa. */
.kind-nu__link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--kind-color-accent);
}
.kind-nu__meta { display: block; font-size: var(--kind-font-small); color: var(--kind-color-text-muted); }
.kind-nu__tom {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--kind-color-text-muted);
}
@media (min-width: 30rem) {
  .kind-nu__row {
    grid-template-columns: minmax(0, 10rem) minmax(0, 1fr);
    gap: var(--kind-space-3);
    align-items: baseline;
  }
}

/* ---- SPAK-KONTAKT: textkolumnens bredd vid smal viewport (2026-08-08) ----
 *
 * Kontaktraden bär en e-postadress, som är ett OSPLITTBART token på 27 tecken.
 * Varje pixel gutter är därför en pixel som kan tvinga fram en HEL extra rad,
 * och en rad kostar 28,34px vid xxlarge. Uppmätt behov vid 320 xxlarge:
 * e-postadressen kräver 355,80px och kortet gav 219,00px.
 *
 * Sidvadderingen är rent krom och bär noll information, alltså precis det
 * SPAK-XXL komprimerade på arbetsvyn (kontraktets ändringslogg 2026-08-07 §S-4,
 * `space-4 -> space-2 ... plus 24px radbredd`). Samma trappa här: space-3 på all
 * mobil, space-2 när textskalan dessutom är stor. Måtten i mediefrågan är i px
 * och inte rem, eftersom rem i en mediefråga löses mot rotens INITIALA
 * teckenstorlek och inte mot vår skalade rot, alltså hade ett rem-tak flyttat
 * sig 50 procent när användaren valde xxlarge.
 *
 * Uppmätt utfall, se kontraktets ändringslogg 2026-08-08 för spak-för-spak.
 */
@media (max-width: 430px) {
  .kind-nu { padding-inline: var(--kind-space-3); }
}
@media (max-width: 430px) {
  html[data-kind-font-scale="xlarge"] .kind-nu,
  html[data-kind-font-scale="xxlarge"] .kind-nu { padding-inline: var(--kind-space-2); }
}

.kind-more-section {
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-2);
}
.kind-more-section__title {
  margin: 0;
  font-size: var(--kind-font-small);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--kind-color-text-muted);   /* 5.87:1, past AA */
}
.kind-more-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border: 1px solid var(--kind-color-border-soft);
  border-radius: var(--kind-radius);
  background: var(--kind-color-surface);
  overflow: hidden;
  box-shadow: var(--kind-shadow-sm);
}
/* A row is a flex line: label on the left, value/chevron on the right. Plain
   display rows are not interactive; link/danger rows carry an affordance. */
.kind-more-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--kind-space-3);
  min-height: 56px;
  padding: var(--kind-space-3) var(--kind-space-4);
  margin: 0;
}
.kind-more-row + .kind-more-row {
  border-top: 1px solid var(--kind-color-border-soft);
}
.kind-more-row__label {
  color: var(--kind-color-text);
  font-weight: 600;
}
.kind-more-row__value {
  color: var(--kind-color-text-muted);   /* 5.87:1, past AA */
  text-align: right;
  min-width: 0;
  overflow-wrap: anywhere;
}
.kind-more-row__chevron {
  flex: 0 0 auto;
  color: var(--kind-color-text-muted);
  font-size: 1.4rem;
  line-height: 1;
}
/* Link rows (Support, Användarvillkor): the whole row is a real <a> (ADR-045
   D-45.3 wired them to /patient/support + /patient/villkor). The anchor fills
   the row so the entire 56px line is the tappable target (2.5.5), takes the
   focus ring, and the label/chevron lay out like a plain row. */
.kind-more-row--link { padding: 0; cursor: pointer; }
.kind-more-row__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--kind-space-3);
  width: 100%;
  min-height: 56px;
  padding: var(--kind-space-3) var(--kind-space-4);
  text-decoration: none;
  color: inherit;
}
.kind-more-row__link:hover { background: var(--kind-color-surface-muted); }
.kind-more-row__link:focus-visible {
  outline: var(--kind-focus-ring);
  outline-offset: -3px;
}

/* Danger row (Radera ditt Kind-konto): a full-row <button> trigger. The button is the
   interactive element so it takes the focus ring; the row label goes accent-red
   so the destructive nature reads without relying on the chevron alone. */
.kind-more-row--danger { padding: 0; }
.kind-more-row__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--kind-space-3);
  width: 100%;
  min-height: 56px;
  padding: var(--kind-space-3) var(--kind-space-4);
  border: 0;
  background: transparent;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.kind-more-row__trigger:hover { background: var(--kind-color-surface-muted); }
.kind-more-row__trigger:focus-visible {
  outline: var(--kind-focus-ring);
  outline-offset: -3px;
}
.kind-more-row--danger .kind-more-row__label {
  color: var(--kind-color-error);
}
/* pa-052 (P-lanen 2026-08-16): vägen-tillbaka-raden under Radera ditt Kind-konto.
   Postens EGEN hjälptext (ingen tredje rad i avslutszonen): diskret metatext,
   indragen till triggerns vaddering så den läses ihop med etiketten ovanför. */
.kind-more-row__help {
  margin: 0;
  padding: 0 var(--kind-space-4) var(--kind-space-3);
  color: var(--kind-color-text-muted);
  font-size: 0.9375rem;
  line-height: 1.4;
}

.kind-more__logout {
  margin: 0;
}
.kind-more__logout-btn {
  width: 100%;
  min-height: 48px;
}

/* #206 ångerkortet (variant A, BESLUT.md 2026-08-16): raderingsärendets status
   i avslutszonen Konto, visas ENDAST vid utestående begäran och ersätter
   Radera-raden. Tokenbaserad (warning-familjen) så tema, mörkt läge och hög
   kontrast följer med via kaskaden. Markup: templates/patient/profil.html. */
.kind-angerkort {
  background: var(--kind-color-warning-bg);
  border: 1px solid var(--kind-color-border);
  border-left: 6px solid var(--kind-color-warning);
  border-radius: var(--kind-radius);
  padding: var(--kind-space-4);
  display: grid;
  gap: var(--kind-space-3);
  color: var(--kind-color-text);
}
.kind-angerkort__rubrik {
  margin: 0;
  font-size: var(--kind-font-h3);
  display: flex;
  align-items: center;
  gap: var(--kind-space-2);
}
.kind-angerkort__rubrik .kind-icon { color: var(--kind-color-warning); flex: none; }
.kind-angerkort p { margin: 0; }
.kind-angerkort__form { margin: 0; }
/* 44px-mål (WCAG 2.2 AA, 2.5.8+): knappen får aldrig krympa under målgolvet. */
.kind-angerkort__knapp { min-height: 44px; }
.kind-angerkort__hjalp {
  color: var(--kind-color-text-muted);
  font-size: var(--kind-font-small);
}

.kind-more__footer {
  text-align: center;
  color: var(--kind-color-text-muted);
  font-size: var(--kind-font-small);
}
.kind-more__version { margin: 0; }
.kind-more__copyright { margin: var(--kind-space-1) 0 0; }

/* ----------------------------------------------------------------------------
   "Om mig" overview (ADR-045). A calm, filterable INDEX of the patient's OWN
   items, the upper section of the Om mig (profil) page. Reuses the kind-more
   tokens. The grouped list is the no-JS baseline; the filter chips are revealed
   by kind_om_mig.js (rendered with [hidden] until then). WCAG 2.2 AA: chips are
   44px+ targets with a visible focus ring + a non-color active state.
   ------------------------------------------------------------------------- */
.kind-mine {
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-3);
}

/* Filter toolbar. [hidden] keeps it invisible for no-JS users (no dead control);
   kind_om_mig.js removes the attribute. Chips wrap on narrow viewports. */
.kind-mine__filter {
  display: flex;
  flex-wrap: wrap;
  gap: var(--kind-space-2);
}
.kind-mine__filter[hidden] { display: none; }   /* belt-and-braces vs UA quirks */

.kind-mine__chip {
  display: inline-flex;
  align-items: center;
  gap: var(--kind-space-1);
  min-height: 44px;                       /* 2.5.5 touch target */
  padding: var(--kind-space-2) var(--kind-space-3);
  /* CP-02-resten (#87): chipet är en <button>, alltså en kontroll, och en
     kontrollkant är aldrig hairlinen (kind.css §1 WATCH-ITEM 1). */
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius-pill);
  background: var(--kind-color-surface);
  color: var(--kind-color-text);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.kind-mine__chip:hover:not([disabled]) { background: var(--kind-color-surface-muted); }
.kind-mine__chip:focus-visible {
  outline: var(--kind-focus-ring);
  outline-offset: 2px;
}
/* Active filter: NOT color alone (1.4.1). A filled accent surface + a heavier
   bottom border + a bold weight carry the state alongside aria-pressed. */
.kind-mine__chip[aria-pressed="true"] {
  background: var(--kind-color-accent-soft);
  border-color: var(--kind-color-accent);
  box-shadow: inset 0 -3px 0 0 var(--kind-color-accent);
  color: var(--kind-color-accent);        /* 4.63:1 on accent-soft, AA */
}
.kind-mine__chip[disabled] {
  opacity: 0.5;
  cursor: default;
}
.kind-mine__chip-count {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--kind-color-text-muted);
}
.kind-mine__chip[aria-pressed="true"] .kind-mine__chip-count { color: var(--kind-color-accent); }

.kind-mine__count {
  margin: 0;
  font-size: var(--kind-font-small);
  color: var(--kind-color-text-muted);    /* 5.87:1, past AA */
}

.kind-mine-group { display: flex; flex-direction: column; gap: var(--kind-space-2); }
.kind-mine-group[hidden] { display: none; }
.kind-mine-group__title {
  margin: 0;
  font-size: var(--kind-font-small);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--kind-color-text-muted);
}
.kind-mine-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border: 1px solid var(--kind-color-border-soft);
  border-radius: var(--kind-radius);
  background: var(--kind-color-surface);
  overflow: hidden;
  box-shadow: var(--kind-shadow-sm);
}
.kind-mine-item + .kind-mine-item { border-top: 1px solid var(--kind-color-border-soft); }
.kind-mine-item__link {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  column-gap: var(--kind-space-3);
  min-height: 56px;                       /* >= 44px target (2.5.5) */
  padding: var(--kind-space-3) var(--kind-space-4);
  text-decoration: none;
  color: var(--kind-color-text);
}
.kind-mine-item__link:hover { background: var(--kind-color-surface-muted); }
.kind-mine-item__link:focus-visible {
  outline: var(--kind-focus-ring);
  outline-offset: -3px;
}
.kind-mine-item__rubrik {
  grid-column: 1;
  font-weight: 600;
  overflow-wrap: anywhere;
}
.kind-mine-item__meta {
  grid-column: 1;
  font-size: var(--kind-font-small);
  color: var(--kind-color-text-muted);    /* 5.87:1, past AA */
  overflow-wrap: anywhere;
}
.kind-mine-item__chevron {
  grid-column: 2;
  grid-row: 1 / span 2;
  color: var(--kind-color-text-muted);
  font-size: 1.4rem;
  line-height: 1;
}

.kind-mine__empty,
.kind-mine__empty-all {
  margin: 0;
  padding: var(--kind-space-3) 0;
  color: var(--kind-color-text-muted);    /* 5.87:1, past AA */
}
.kind-mine__empty[hidden] { display: none; }

/* ----------------------------------------------------------------------------
   Static content pages (Support och hjälp / Användarvillkor, ADR-045 D-45.3).
   Simple prose surfaces reached from the Om mig account section. Calm, readable,
   max line length for comfortable reading on the patient surface.
   ------------------------------------------------------------------------- */
.kind-static {
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-4);
  max-width: 40rem;
}
.kind-static__title {
  margin: 0;
  font-family: var(--kind-font-serif);
  /* CP-04-1 (#99), samma defekt som .kind-aktiviteter__heading: 24px vid alla
     bredder, alltså 6px under briefens desktopgolv (30 till 34). Hittad av
     svepet över SAMTLIGA h1-klasser i templates/, inte av rapporten, som bara
     namngav /patient/aktiviteter (regel 48 följdkrav b: svep varje yta som
     delar defekten, kunden rapporterar det den ser). Ytor: /patient/support
     (mätt yta `patient-support` i utfallskontraktet) och /patient/villkor. */
  font-size: var(--kind-font-h1);
  font-weight: 600;  /* ADR-065 §D4 (CP-04): display-sized heading role, cap 600 */
  color: var(--kind-color-text);
}
.kind-static__body {
  margin: 0;
  color: var(--kind-color-text);
  line-height: 1.6;
}
.kind-static__actions { margin: 0; }
.kind-static__safety {
  margin: 0;
  padding: var(--kind-space-3) var(--kind-space-4);
  border-radius: var(--kind-radius);
  background: var(--kind-color-surface-muted);
  color: var(--kind-color-text);          /* high contrast on muted */
  line-height: 1.6;
}
.kind-static__back { margin: 0; }

/* ----------------------------------------------------------------------------
   F-26 (nattpasset 2026-08-14): FAQ-avdelningen på Support & Hjälp. Produktionens
   form: en plan lista där frågeraden fälls ut till sitt svar, utfälld rad på
   inset-yta. Nativ <details>/<summary>, samma beslut som .kind-org-welcome__summary:
   `display: list-item` är BÄRANDE (Chromium ritar ::marker bara för
   list-item-lådor; utan pil är raden bara en textrad och ingen öppnar den),
   44px-golvet tas med min-height plus padding, och markören krymps till ikon
   vid stor textskala så etiketten inte bryter en extra rad vid 320.
   Skiljelinjerna är dekorativa (--kind-color-border-soft, aldrig fältkant).
   ------------------------------------------------------------------------- */
.kind-faq {
  margin: 0;
}
.kind-faq__heading {
  margin: 0 0 var(--kind-space-2);
  font-size: var(--kind-font-h2);
  font-weight: 600;
  color: var(--kind-color-text);
}
.kind-faq__list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.kind-faq__item {
  border-top: 1px solid var(--kind-color-border-soft);
}
.kind-faq__item:last-child {
  border-bottom: 1px solid var(--kind-color-border-soft);
}
.kind-faq__summary {
  display: list-item;
  list-style-position: inside;
  align-content: center;
  min-height: 44px;
  padding: var(--kind-space-2) var(--kind-space-2);
  font-weight: 600;
  color: var(--kind-color-text);
  cursor: pointer;
}
.kind-faq__summary:focus-visible {
  outline: var(--kind-focus-ring);
  outline-offset: 2px;
  border-radius: var(--kind-radius);
}
.kind-faq__fraga[open] {
  background: var(--kind-color-surface-muted); /* text 13.36:1, past AA */
  border-radius: var(--kind-radius);
}
.kind-faq__svar {
  margin: 0;
  padding: 0 var(--kind-space-4) var(--kind-space-3);
  line-height: 1.6;
  color: var(--kind-color-text);
}
/* Vid stor textskala är markören en ikon, inte text: en textstor trekant tog
   inline-plats nog att bryta etiketten en extra rad vid 320 (uppmätt på
   .kind-org-welcome 2026-08-07, samma mekanism). */
html[data-kind-font-scale="xlarge"] .kind-faq__summary::marker,
html[data-kind-font-scale="xxlarge"] .kind-faq__summary::marker {
  font-size: 0.75em;
}

/* ----------------------------------------------------------------------------
 * ADR-046: the in-chat "Boka tid" slot-grid overlay (Wave 5)
 *
 * Reuses .kind-crash-overlay / __panel / __header / __title / __lede / __close
 * (the native <dialog> chrome the "Be om en tid" overlay uses). These rules add
 * the type-filter, the live-region, and the slot grid inside that panel.
 *
 * A11y (WCAG 2.2 AA, design:accessibility-review 2026-06-26):
 *  - each slot is a min 48px-tall button (patient floor, well over 2.5.8 24px);
 *  - the slot label carries when/type/clinician as visible text (never icon
 *    only, 1.4.1 not colour-only);
 *  - visible 3px accent focus ring (2.4.7) on the slots;
 *  - the live region is visually a calm status strip; its meaning is the text.
 *
 * #175 (2026-08-11): the type-filter fieldset was removed from the markup (a
 * patient may self-book exactly one type), so .kind-slot-grid__filter* went
 * with it rather than rotting as unreachable rules. The paragraph that replaced
 * it is .kind-slot-grid__note below.
 * -------------------------------------------------------------------------- */
.kind-slot-grid .kind-crash-overlay__panel {
  /* a touch more room for the grid than a one-field form overlay */
  max-width: 36rem;
}

/* The "here you book a video meeting, a physical visit is booked by your clinic"
 * line. Same calm secondary voice as the lede above it, not a warning. */
.kind-slot-grid__note {
  margin: 0;
  line-height: 1.5;
  color: var(--kind-color-text-muted);
}

/* The polite live region: the loser/success/load-error announcement. Shown as a
 * calm strip when it has content; collapses to nothing when empty so it never
 * leaves a blank gap. */
.kind-slot-grid__live:empty {
  display: none;
}
.kind-slot-grid__live {
  background: var(--kind-color-accent-bg);   /* blush wash, dark text 15.70:1 */
  color: var(--kind-color-text);
  border-radius: var(--kind-radius);
  padding: var(--kind-space-3) var(--kind-space-4);
  line-height: 1.5;
}

.kind-slot-grid__body {
  display: block;
}
.kind-slot-grid__loading,
.kind-slot-grid__empty {
  margin: 0;
  color: var(--kind-color-text-muted);
}

.kind-slot-grid__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--kind-space-3);
}
@media (min-width: 30rem) {
  .kind-slot-grid__list {
    grid-template-columns: 1fr 1fr;
  }
}
.kind-slot-grid__item {
  margin: 0;
}

/* One free slot = one full-width button. min 48px high (patient floor). */
.kind-slot-grid__slot {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.15rem;
  min-height: 48px;
  text-align: left;
  padding: var(--kind-space-3) var(--kind-space-4);
}
.kind-slot-grid__slot:focus-visible {
  outline: var(--kind-focus-ring);
  outline-offset: var(--kind-focus-ring-offset);
}
.kind-slot-grid__slot[disabled],
.kind-slot-grid__slot.is-booking {
  opacity: 0.6;
  cursor: progress;
}
.kind-slot-grid__slot-when {
  font-weight: 600;
}
.kind-slot-grid__slot-meta {
  font-size: 0.9em;
  color: var(--kind-color-text-muted);
}

/* The booked confirmation panel (after a winning 200). */
.kind-slot-grid__booked {
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-3);
  align-items: flex-start;
  background: var(--kind-color-success-bg);
  border: 1px solid var(--kind-color-success);
  border-radius: var(--kind-radius);
  padding: var(--kind-space-4);
}
.kind-slot-grid__booked-text {
  margin: 0;
  color: var(--kind-color-text);
}

/* ----------------------------------------------------------------------------
 * 2.2 proxy / delegation PATIENT surfaces (#9/#22), dark behind the proxy flags.
 * The shared primitives (.kind-section-title, .kind-divider, .kind-checkbox*,
 * .kind-assurance-line) live in kind.css since both portals consume them (the
 * clinician guardian panel uses .kind-checkbox too). Tokens only; targets >=44px.
 * -------------------------------------------------------------------------- */

/* agera-som picker cards: name + capacity line, then the switch button. */
.kind-agera-som-list { list-style: none; padding: 0; margin: 0; }
.kind-agera-som-card {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--kind-space-3);
  padding: var(--kind-space-4);
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius);
  margin-bottom: var(--kind-space-3);
}
.kind-agera-som-card__body { flex: 1 1 14rem; min-width: 0; }
.kind-agera-som-card__action { flex: 0 0 auto; margin: 0; }
@media (max-width: 32rem) {
  .kind-agera-som-card__action { flex: 1 1 100%; }
  .kind-agera-som-card__action .kind-btn { width: 100%; }
}

/* Delegation list rows + the coercion-aware revoke (calm, not alarmist). */
.kind-delegation-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--kind-space-3);
  padding: var(--kind-space-4);
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius);
  margin-bottom: var(--kind-space-3);
}
.kind-delegation-row__body { flex: 1 1 16rem; min-width: 0; }
.kind-delegation-row__scope { display: flex; flex-wrap: wrap; gap: var(--kind-space-2); margin: var(--kind-space-2) 0; }
.kind-delegation-row__actions { flex: 0 0 auto; display: flex; gap: var(--kind-space-2); margin: 0; }
/* The inline confirm expansion (a calm single extra tap, never a big red modal). */
.kind-inline-confirm { margin: var(--kind-space-2) 0 0 0; }
.kind-inline-confirm summary {
  cursor: pointer;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}
.kind-inline-confirm__panel {
  margin-top: var(--kind-space-2);
  padding: var(--kind-space-3);
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius);
}
.kind-inline-confirm__panel p { margin: 0 0 var(--kind-space-3) 0; }

/* Expiry quick-set chips (3/6/12 mån). PE convenience; the date field stays the
 * required source of truth. Chips wrap on a narrow screen. */
.kind-quickset { display: flex; flex-wrap: wrap; gap: var(--kind-space-2); margin-top: var(--kind-space-2); }
.kind-quickset__btn { flex: 0 0 auto; }

/* #22 delegation 2-step confirm panel (FLOW 2e). PE-revealed (hidden until the
 * confirm step); tokens only so it reads in both colour-schemes + high-contrast.
 * Anti-enumeration is a copy/JS property, not styling; this is just a calm
 * bordered panel that sets the confirm step apart from the form. */
.kind-delegation-confirm {
  margin-top: var(--kind-space-4);
  padding: var(--kind-space-5);
  background: var(--kind-color-surface-muted);
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius);
}
.kind-delegation-confirm__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--kind-space-3);
  margin-top: var(--kind-space-4);
}

/* ============ Fas 2 D (#52) telefon SMS-OTP two-step login ============
 *
 * Patient telefon two-step page (templates/patient/telefon_login.html). Reuses
 * the login-box / field / .kind-btn--block tokens so it reads as the same app;
 * only the inline "skicka en ny kod" restart control needs a link-styled button.
 */

/* CRITICAL: the step forms are .kind-form, which sets display:flex. That flex
   declaration BEATS the [hidden] attribute's UA display:none, so without this
   rule step 2 renders VISIBLE on initial load (both steps at once). Restore the
   hide, matching the .component[hidden] pattern used across the video/admin CSS.
   The JS toggles the `hidden` attribute to reveal step 2. */
.kind-form[data-kind-telotp-step2][hidden],
.kind-form[data-kind-telotp-step1][hidden] {
  display: none;
}

/* Link-styled button: looks like a link, is a real <button> (correct semantics
   for an in-page action, not navigation). Accent is 5.34:1 on white (AA). The
   generous vertical padding keeps the tap/click target near the 44px guideline
   (WCAG 2.2 AA 2.5.5) without looking like a filled button. */
.kind-linkbtn {
  display: inline-block;
  background: none;
  border: 0;
  padding: var(--kind-space-2) 0;
  min-height: 44px;
  color: var(--kind-color-accent);
  font: inherit;
  text-decoration: underline;
  cursor: pointer;
}
.kind-linkbtn:hover { color: var(--kind-color-accent-hover); }
.kind-linkbtn:focus-visible {
  outline: var(--kind-focus-ring);
  outline-offset: 2px;
  border-radius: var(--kind-radius);
}

/* #53 patient self-edit rows (Fas 2 cluster E, FEATURE_IDENTITY_LAYER, DARK).
   Absent from the deployed page while the flag is OFF (the whole block gates on
   feature_identity_layer), so this CSS is inert until the flag flips.

   Each editable row is a stacked card: a label + current-value line, then the
   inline edit control. The rows reuse the shared .kind-field / .kind-btn
   vocabulary (44px targets, error tokens, focus ring) so no new interactive
   sizing is invented here; these rules only handle the row layout, the calm
   status message, the locked-row treatment, and the two-step reveal. */
.kind-selfedit {
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-2);
  padding: var(--kind-space-4) var(--kind-space-4);
  margin: 0;
}
.kind-selfedit + .kind-selfedit {
  border-top: 1px solid var(--kind-color-border-soft);
}
.kind-selfedit__label {
  color: var(--kind-color-text);
  font-weight: 600;
}
.kind-selfedit__value {
  color: var(--kind-color-text-muted);   /* 5.87:1, past AA */
  overflow-wrap: anywhere;
}
.kind-selfedit__form {
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-3);
  margin-top: var(--kind-space-2);
}

/* Locked rows (namn / pnr, and a verified-bankid telefon): read-only, never a
   form. A plain padlock note reads them as clinic-managed; the row is NOT a
   disabled input dressed as an editable field (2.5.3 / no affordance trap). */
.kind-selfedit--locked .kind-selfedit__value {
  color: var(--kind-color-text);   /* full ink; a locked value is not "muted-away" */
}
.kind-selfedit__lock-note {
  display: inline-flex;
  align-items: center;
  gap: var(--kind-space-2);
  font-size: var(--kind-font-small);
  color: var(--kind-color-text-muted);
}
.kind-selfedit__lock-icon {
  flex: 0 0 auto;
  color: var(--kind-color-text-muted);
}
/* F-28 (beslut 12, 2026-08-16): hänvisningsraden under det låsta namnfältet.
   Samma dämpade metaton som låsnoten, egen rad under radhuvudet. */
.kind-selfedit__referral {
  margin: var(--kind-space-1) 0 0;
  font-size: var(--kind-font-small);
  color: var(--kind-color-text-muted);
  line-height: 1.4;
}

/* Calm status region for the two-step flows (telefon "we sent a code to your
   OLD number", e-post "we sent a confirm link to your CURRENT address"). A pale
   surface, dark ink; announced via aria-live in the markup. */
.kind-selfedit__status {
  background: var(--kind-color-surface-muted);
  border-radius: var(--kind-radius);
  padding: var(--kind-space-3) var(--kind-space-4);
  color: var(--kind-color-text);
  font-size: var(--kind-font-small);
}

/* The broadcast_opt_out toggle row. A real checkbox + label; the checkbox keeps
   a 44px target via padding on its label wrapper. */
.kind-selfedit__toggle {
  display: flex;
  align-items: flex-start;
  gap: var(--kind-space-3);
  min-height: 44px;
  cursor: pointer;
}
.kind-selfedit__toggle input[type="checkbox"] {
  flex: 0 0 auto;
  width: 1.4rem;
  height: 1.4rem;
  margin-top: 0.15rem;
  accent-color: var(--kind-color-accent);
}
.kind-selfedit__toggle:focus-within {
  outline: var(--kind-focus-ring);
  outline-offset: 2px;
  border-radius: var(--kind-radius);
}

/* The telefon code-entry step, hidden until the JSON reply arms it. Same
   [hidden] hide as the telefon-login two-step (a specificity guard so the
   flex/display here does not beat the UA [hidden] display:none). */
.kind-selfedit__step[hidden] { display: none; }
.kind-selfedit__step {
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-3);
  margin-top: var(--kind-space-3);
  padding-top: var(--kind-space-3);
  border-top: 1px dashed var(--kind-color-border-soft);
}

/* Change 2b: the "börja om" affordance row under a verification status. Muted,
   left-aligned, revealed together with the status/step by kind_self_edit.js. The
   [hidden] guard mirrors .kind-selfedit__step so the flex layout does not beat
   the UA [hidden] display:none. */
.kind-selfedit__restart[hidden] { display: none; }
.kind-selfedit__restart {
  margin: 0;
}

/* A small ghost button (patient surface twin of kind_admin.css .kind-btn--sm)
   for the low-emphasis "börja om" controls, so they read as secondary to the
   primary confirm action above them. */
.kind-btn--sm {
  font-size: var(--kind-font-small);
  padding-top: var(--kind-space-2);
  padding-bottom: var(--kind-space-2);
  padding-left: var(--kind-space-4);
  padding-right: var(--kind-space-4);
}

/* Change 4a: the opt-out "Sparat" confirmation. A calm success line, announced
   via aria-live in the markup; auto-cleared by the JS. The [hidden] guard keeps
   the flex parent from overriding the hide. */
.kind-selfedit__saved[hidden] { display: none; }
.kind-selfedit__saved {
  margin: 0;
  font-size: var(--kind-font-small);
  color: var(--kind-color-success);
  font-weight: 600;
}

/* N1 (qa 2026-07-02): the PERSISTENT visible "Sparat" chip next to the opt-out
   toggle. Unlike .kind-selfedit__saved (the transient aria-live line), this chip
   stays until the next change, so a sighted user keeps a lasting confirmation the
   save persisted. It sits inline at the end of the toggle label; the [hidden]
   guard keeps the toggle's flex layout from overriding the hide. Colours reuse the
   success tokens (dark green on the light success background, well past 4.5:1, with
   a dark-mode variant defined on the tokens themselves). */
.kind-selfedit__chip[hidden] { display: none; }
.kind-selfedit__chip {
  display: inline-flex;
  align-items: center;
  gap: var(--kind-space-1);
  margin-left: auto;
  padding: 0.15rem var(--kind-space-3);
  border-radius: 999px;
  background: var(--kind-color-success-bg);
  color: var(--kind-color-success);
  font-size: var(--kind-font-small);
  font-weight: 600;
  white-space: nowrap;
}
.kind-selfedit__chip-icon {
  font-weight: 700;
}

/* ----------------------------------------------------------------------------
 * Change 3: the self-edit REVOKE surface ("Var det inte du?"), the highest-
 * anxiety page in the product. Calm-but-serious: reassurance line under the
 * restore button + a bordered escalation note (role="note", warning border +
 * icon, NOT colour-only, 1.4.1). Reuses the shared .kind-flash--warning tokens.
 * -------------------------------------------------------------------------- */
.kind-selfedit-revoke,
.kind-selfedit-done {
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-4);
  max-width: 34rem;
  margin: 0 auto;
  padding: var(--kind-space-6) var(--kind-space-4);
}
.kind-selfedit-revoke__reassure {
  margin: 0;
  color: var(--kind-color-text-muted);   /* past AA on the page background */
  font-size: var(--kind-font-small);
}
/* The escalation note is a flex row: warning icon + body. Reuses .kind-flash's
   surface/border; only the internal layout is added here. */
.kind-selfedit-revoke__escalate {
  display: flex;
  align-items: flex-start;
  gap: var(--kind-space-3);
}
.kind-selfedit-revoke__escalate .kind-flash__body {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-2);
}
.kind-selfedit-revoke__escalate-icon {
  flex: 0 0 auto;
  font-size: 1.25rem;
  line-height: 1.4;
  color: var(--kind-color-warning);
}
.kind-selfedit-revoke__escalate .kind-flash__link { margin: 0; }
.kind-selfedit-revoke__escalate .kind-flash__link a {
  color: var(--kind-color-text);
  font-weight: 600;
}

/* ============ SAMMANHÅLLEN CHATTSPALT (issue #80, 2026-07-27) ==============
 *
 * Radlängdstaket (44rem, se `.kind-chat__log-head, .kind-chat__log-list` ovan)
 * kapade LÄSKOLUMNEN men lämnade resten av chattkolumnen i full bredd. Uppmätt
 * av konsulten i riktig webbläsare 2026-07-27 vid 1280: läskolumn 704px mot
 * skrivmodul 992px, alltså 288px obalans, och tråden flöt centrerad medan
 * headern började längst till vänster. I kundens målbild ligger de i linje.
 *
 * Efter borttagningen av arbetsvyns högerpanel (delsteg 1) är chattkolumnen
 * 972px på ALLA bredder, så obalansen hade blivit universell i stället för att
 * bara drabba 1280. Därför kapas headern, skrivmodulen, dela-popovern och
 * schemalagda-raden till SAMMA 44rem och centreras på samma sätt, så hela
 * kolumnen läser som en spalt.
 *
 * VILKA TRE OCH VARFÖR PRECIS DE: det är chattkolumnens övriga flödesbarn med
 * egen synlig kant eller bakgrund. Två uttryckliga undantag:
 *
 *   `.kind-chat__log` (skrollporten) kapas INTE. Den har ingen synlig bakgrund
 *   och dess innehåll ligger redan i spalten via listan; att kapa den hade
 *   flyttat in skrollisten mitt i kolumnen.
 *
 *   `.kind-compose-popover` ("+"-panelen) kapas INTE, och det är ett MÄTT
 *   beslut, inte ett förbiseende. Den låg med i första versionen av den här
 *   regeln och gjorde patientens INAKTIVA skrivmodul 12px högre (modellen: 53px
 *   -> 65px, alltså över kontraktets 60px-tak). Orsaken är inte bredden utan
 *   flexbox: popovern är ett flexobjekt i skrivmodulens rad med `flex: 0 0 auto`
 *   i hopfällt läge, och en `flex-basis: auto` läser sin storlek ur `width`, så
 *   `width: 100%` gjorde att den krävde hela raden och bröt till en EGEN rad,
 *   plus radgapet, trots att den är tom och 0px hög. Ett breddbeslut som blev
 *   ett höjdbrott, fångat av pixelbudgettestet och inte av ögat.
 *
 * `width: 100%` är load-bearing av exakt samma skäl som på listan: barnen är
 * flexobjekt i en flexKOLUMN, alltså är inline-axeln KORSaxeln, och flexbox
 * stretchar bara ett objekt vars korsaxelmarginaler inte är auto (CSS Flexbox 1,
 * 9.4 steg 11). Utan den blir skrivmodulen fit-content, alltså en smal remsa.
 *
 * INERT VID SMALA BREDDER, precis som taket: patientens chattyta är 358px vid
 * 390 och 288px vid 320, och arbetsvyn i staplat läge (<=900px) ger som mest
 * 868px minus krom. Regeln biter bara där kolumnen faktiskt är bredare än
 * 704px, alltså på de vårdgivarbredder kunden tittar på.
 *
 * PLACERINGEN SIST I FILEN ÄR AVSIKTLIG, inte slarv. En `margin`-KORTFORM
 * någonstans senare i kaskaden nollar `margin-inline`, och med samma
 * specificitet avgör källordningen. Vakt: tests/test_chat_pixel_budget.py
 * kontrollerar rank(margin-inline) > rank(margin) för varje element här, så en
 * framtida flytt uppåt i filen blir röd i stället för tyst felcentrerad. */
.kind-chat__header,
.kind-chat__compose,
.kind-schemalagda {
  width: 100%;
  max-width: 44rem;
  margin-inline: auto;
}
/* UNDANTAG: sr-only behåller SIN egen geometri (konsultens mätning 2026-07-27).
 *
 * På patientens chattyta bär `.kind-chat__header` klassen
 * `kind-visually-hidden` (kontraktet: konversationstiteln ska ha 0px VISUELL
 * höjd men stanna kvar i DOM:en och i tillgänglighetsträdet). Regeln ovan gav
 * den `width: 100%`, så sr-only-boxen växte från 1x1 till 390x13.
 *
 * Det var INTE en synlig defekt: föräldern behåller `clip: rect(0 0 0 0)` och
 * `overflow: hidden`, titeln var mätt osynlig och skymde ingenting
 * (`elementFromPoint` i boxens mittpunkt returnerade meddelandet under). Men
 * sr-only-tekniken vilar på TRE samverkande egenskaper, 1x1-storleken,
 * clip-rektangeln och overflow, och efter regeln ovan hängde hela osynligheten
 * på EN av dem. Den som städar bort `clip` i framtiden, i tron att en
 * 1px-box ändå inte syns, får då konversationstiteln tillbaka på precis den yta
 * kunden bad oss ta bort den från. Djupförsvar är billigt här: tre rader CSS.
 *
 * `margin-inline: -1px` återställer utility-klassens `margin: -1px`, som
 * `margin-inline: auto` ovan hade skrivit över på inline-axeln.
 *
 * Vakt: tests/test_chat_pixel_budget.py itererar över linjeringsregelns EGNA
 * selektorer och kräver att var och en har en sr-only-motsvarighet här, så en
 * fjärde klass i regeln ovan kan inte läggas till utan sitt undantag. */
.kind-chat__log-head.kind-visually-hidden,
.kind-chat__log-list.kind-visually-hidden,
.kind-chat__header.kind-visually-hidden,
.kind-chat__compose.kind-visually-hidden,
.kind-schemalagda.kind-visually-hidden {
  width: 1px;
  max-width: 1px;
  margin-inline: -1px;
}

/* ============================================================================
 * #212 (kundsvar 2026-09-11, konsultbeslut 2026-09-14): PATIENTNAVET ÄR ETT
 * BOTTENBAND PÅ ALLA BREDDER. Kundens ord: "den skall alltid ligga på botten."
 *
 * Här låg #164:s desktopform, en @media (min-width: 1024px) som restylade
 * <nav class="kind-tabbar"> till en vänsterspalt. Hela blocket är borttaget,
 * inte avstängt, eftersom varje regel i det fanns för spaltformen: spaltens
 * bredd, lucka och topp (#225:s härledning av sidhuvudets höjd), <main>s och
 * sidfotens sidoreserv, nollningen av --kind-tabbar-reserve och av rotens
 * scroll-padding-block-end (#183), snabbknappens bottenluft och lyftet av
 * Mer-sidans 40rem-tak. Utan spalten gäller basreglerna högre upp i filen på
 * varje bredd, alltså samma bottenband som vårdpersonal och klinik-admin redan
 * har vid 1440px.
 *
 * TVÅ FÖLJDER SOM ÄR AVSIKTLIGA OCH MÄTTA, inte bieffekter:
 *  - Chattskalet reserverar åter 57px för bandet även på desktop, eftersom
 *    bandet nu finns där (docs/contracts/chat-pixel-budget.md räknar mot det).
 *  - Mer-sidan har åter sitt 40rem-tak på desktop. Lyftet var motiverat av att
 *    spalten åt bredden; utan spalt vore en radlängd på hela 70rem-containern
 *    för lång för läsning.
 *
 * Vakter: tests/test_patient_desktopnav_css.py (ingen spaltform på någon bredd)
 * och tests/test_tabbar_fokusreserv_css.py (reserverna nollas inte på desktop).
 * Utfallet mäts i webbläsare av e2e/212-bottenband-matning.mjs.
 * ========================================================================== */

/* ============================================================================
 * #207 VARIANT C: dragspel pa patientens Mer-yta (godkand mock
 * docs/design-proposals/207/variant-c.html, BESLUT.md 2026-08-15, agents-repot).
 *
 * Skopat under .kind-body--patient (produktionens motsvarighet till mockens
 * body.kind-mock-delta): (0,2,0) vinner over basreglerna (0,1,0) oavsett
 * kallordning, och kind_patient.css laddas anda bara pa patientytor.
 *
 * Pixelvardena ar PORTADE UR GODKAND MOCK, inte harledda pa nytt. Tva medvetna
 * avvikelser, bada listade i byggrapporten: sidfotstexterna ar 13px och inte
 * mockens 12px (husets 13px-golv, se --kind-font-small-kommentaren i kind.css,
 * tillganglighet vinner mot mock), och installningspartialernas enrads-layout
 * (rubrik + kontroll pa samma rad) ar INTE portad eftersom den kraver
 * markupandring i tva DELADE partialer (admin-ytan renderar samma filer,
 * regel 27 korollarium 2); kompaktionen har ar CSS-enbart pa befintlig DOM.
 * ========================================================================== */

/* C0: tatare flode pa ytan (mock: gap 12px mot basens space-5). */
.kind-body--patient .kind-more { gap: 12px; }
.kind-body--patient .kind-more-section { padding: 12px 16px 14px; }
.kind-body--patient .kind-more-section__title { margin: 0 0 4px; }

/* Variant A-taggbytets neutraliserande rad: h3-etiketten behaller radens
 * typografi (rubrikrollen ar for skarmlasaren och M2-matningen, inte for
 * typskalan). */
.kind-body--patient h3.kind-selfedit__label { font-size: inherit; margin: 0; }

/* Radlayouten i Mina uppgifter: etikett + varde vanster, Andra/lasnot hoger. */
.kind-body--patient .m207-rad { padding: 8px 0; margin: 0; }
.kind-body--patient .m207-radhuvud { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; }
.kind-body--patient .m207-radtext { flex: 1 1 200px; min-width: 0; }
.kind-body--patient .m207-radtext .kind-selfedit__value { display: block; margin: 0;
  color: var(--kind-color-text-muted); font-size: 14px; overflow-wrap: anywhere; }
/* Laasta rader behaller full farg pa vardet (basens regel), bara layouten ny. */
.kind-body--patient .kind-selfedit--locked .m207-radtext .kind-selfedit__value {
  color: var(--kind-color-text); }
.kind-body--patient .m207-andra { margin-left: auto; }
.kind-body--patient .m207-andra[open] { flex: 1 1 100%; margin-left: 0; }
.kind-body--patient .m207-las { margin: 0; flex: 0 0 auto; font-size: 13px;
  color: var(--kind-color-text-muted); }

/* Installningspartialerna som undersektioner: avdelare i stallet for kort.
 * Skopat under .kind-more sa admin-profilens likadana partialer inte rors. */
.kind-body--patient .kind-more .kind-profile-section { padding: 8px 0 0; margin: 8px 0 0;
  border: 0; background: transparent; box-shadow: none;
  border-top: 1px solid var(--kind-color-border-soft); border-radius: 0; }
.kind-body--patient .kind-more .kind-profile-section__title { margin: 0; font-size: 1rem; }
.kind-body--patient .kind-more .kind-profile-section__body { font-size: 13px;
  color: var(--kind-color-text-muted); margin: 4px 0 0; }
.kind-body--patient .kind-more .kind-push__status { font-size: 13px; margin: 4px 0 0; }
.kind-body--patient .kind-more .kind-field__help { font-size: 13px; }
.kind-body--patient .kind-more .kind-selfedit--optout { padding: 4px 0 0; margin: 0; }
.kind-body--patient .kind-more .kind-selfedit--optout .kind-field__help { margin: 4px 0 0; }

/* Lankrader: 44px traffyta (WCAG 2.2 AA 2.5.5) i stallet for basens 56px. */
.kind-body--patient .kind-more .kind-more-row__link,
.kind-body--patient .kind-more .kind-more-row__trigger {
  padding-top: 10px; padding-bottom: 10px; min-height: 44px; }

/* Identitetsblocket: nagot mindre avatar + tat kontaktrad (mock). */
.kind-body--patient .kind-more__avatar { width: 40px; height: 40px; font-size: 15px; }
.kind-body--patient .kind-more__kontakt { margin: 2px 0 0; font-size: 13px; }

/* Barnformularets infallning. */
.kind-body--patient .m207-barnform > .kind-form { margin-top: 8px; }

/* C1: sjalva dragspelet (APG accordion, h2 > button behaller rubrikrollen).
 * Knappen byggs av kind_mer_dragspel.js; utan JS finns den inte. font: inherit
 * arver rubrikens versala smatext, muted 5.87:1 mot ytan, forbi AA. */
.kind-body--patient .m207-dragspel { display: flex; width: 100%; align-items: center;
  justify-content: space-between; gap: 8px; background: none; border: 0; padding: 2px 0;
  margin: 0; font: inherit; font-weight: inherit; color: inherit; cursor: pointer;
  min-height: 44px; text-align: left; }
/* Ringen via tokenet, inte accenten: byte-identisk med mockens
 * `3px solid accent` i de tva normaltemana, men i high contrast gar
 * --kind-focus-ring till ren motfarg (ADR-065 §D6.2 regel 6). Mockens
 * accent-stavning ar exakt den doda stavning
 * tests/test_classic_plus_dark_tokens.py vaktar mot. */
.kind-body--patient .m207-dragspel:focus-visible {
  outline: var(--kind-focus-ring); outline-offset: var(--kind-focus-ring-offset); }
.kind-body--patient .m207-pil { transition: transform .15s ease; }
@media (prefers-reduced-motion: reduce) {
  .kind-body--patient .m207-pil { transition: none; }
}
.kind-body--patient .m207-dragspel[aria-expanded="true"] .m207-pil { transform: rotate(90deg); }
/* Garden PER KLASS, utan !important, aldrig generell [hidden] (regel 27
 * korollarium 2: forfattarregler pa forfader kan annars sla ut UA-arkets
 * [hidden] i kaskadens ursprungsordning). */
.kind-body--patient .m207-grupp[hidden] { display: none; }

/* C2: kompakt sidfot. DELAD PATIENTKROM: kind_patient.css laddas pa varje
 * patientyta, sa detta sveper alla patientytor med synlig sidfot (chatten
 * gommer sin). Tabbar-reserven .kind-tabbar ~ .kind-footer .kind-footer__inner
 * (0,3,0, issue #45) vinner padding-bottom precis som i mocken; det som
 * kompakteras ar topp/sidor + radtypografin. 13px och inte mockens 12px:
 * husets typgolv, tillganglighet vinner mot mock (listad avvikelse). */
.kind-body--patient .kind-footer__inner { padding: 14px 16px 18px; }
.kind-body--patient .kind-footer__legal,
.kind-body--patient .kind-footer__version,
.kind-body--patient .kind-footer__copy { font-size: 13px; margin: 2px 0; }

/* ==========================================================================
 * #397 variant A: detaljvy per bokning (templates/patient/bokning_detalj.html)
 * Portad ORORD ur godkand mock docs/design-proposals/397/variant-a.html
 * (agents-repot, BESLUT.md f6140f6), sektionen "FORSLAGS-CSS variant A".
 * Bara befintliga tokens, inga nya.
 * ========================================================================== */
.kind-bokning-detalj { max-width: 40rem; }
.kind-bokning-detalj__eyebrow {
  display: inline-flex; align-items: center; gap: var(--kind-space-2);
  margin: 0 0 var(--kind-space-2);
  font-size: var(--kind-font-small); font-weight: 700;
  letter-spacing: .02em; text-transform: uppercase;
  color: var(--kind-color-text-muted);
}
.kind-bokning-detalj__eyebrow .kind-icon { color: var(--kind-color-accent); }
.kind-bokning-detalj__huvud {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--kind-space-3);
  margin-bottom: var(--kind-space-4);
}
.kind-bokning-detalj__huvud h1 { margin: 0; }
.kind-bokning-detalj__fakta {
  margin: 0 0 var(--kind-space-5); padding: var(--kind-space-4);
  border: 1px solid var(--kind-color-border-soft);
  border-radius: var(--kind-radius);
  background: var(--kind-color-surface);
  display: grid; gap: var(--kind-space-3);
}
.kind-bokning-detalj__fakta > div { display: grid; gap: 2px; }
.kind-bokning-detalj__fakta dt { font-size: var(--kind-font-small); color: var(--kind-color-text-muted); }
.kind-bokning-detalj__fakta dd { margin: 0; font-weight: 600; overflow-wrap: anywhere; }
.kind-bokning-detalj__videoinfo {
  display: flex; gap: var(--kind-space-2); align-items: flex-start;
  padding: var(--kind-space-3) var(--kind-space-4);
  border-radius: var(--kind-radius);
  background: var(--kind-color-accent-soft);
  margin: 0 0 var(--kind-space-5);
}
.kind-bokning-detalj__videoinfo .kind-icon { flex: none; margin-top: 2px; color: var(--kind-color-accent); }
.kind-bokning-detalj__videoinfo p { margin: 0; }
.kind-bokning-detalj__hjalp {
  border-top: 1px solid var(--kind-color-border-soft);
  padding-top: var(--kind-space-4);
}
.kind-bokning-detalj__hjalp p { margin: 0 0 var(--kind-space-3); color: var(--kind-color-text-muted); }

/* ---------------------------------------------------------------------------
   web#512: "Dela mall" — kallelsens ark, kort och detaljvy.

   LIGGER I `kind_patient.css` OCH INTE I BÅDA ARKEN, med flit. Kallelsen
   renderas av EN delad partial (`templates/_kallelse_detalj.html`, villkor V1)
   på både patientens och vårdgivarens yta, och vårdgivarens sidor laddar
   `kind_admin.css` FÖLJT AV `kind_patient.css` (se
   `tests/test_420_stilarksordning.py` och noten i
   `tests/test_composer_popover_item_decoration_css.py`). Ett andra exemplar i
   admin-arket hade alltså inte gett något som inte redan gäller, men det hade
   gett två bärare att hålla i fas — precis den skörhet #281 dokumenterar.

   Ingen ny token, ingen ny färg: allt nedan återanvänder husets variabler, så
   kontrasterna är de redan mätta (ADR-065 Classic+).
   --------------------------------------------------------------------------- */

/* Arket: Välj mall / fälten / förhandsvisningen / detaljvyn. Toppraden är
   gamla KIND:s: stäng eller tillbaka till vänster, rubrik i mitten, den
   framåtdrivande knappen (Nästa / Dela) till höger. */
.kind-kallelse-ark { max-width: 40rem; margin: 0 auto; }
.kind-kallelse-ark__topp {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--kind-space-3); margin-bottom: var(--kind-space-4);
}
.kind-kallelse-ark__rubrik { margin: 0; flex: 1 1 auto; }
.kind-kallelse-ark__nasta, .kind-kallelse-ark__dela-form { margin-left: auto; }
.kind-kallelse-ark__delas-med {
  margin: 0 0 var(--kind-space-4); color: var(--kind-color-text-muted);
}
.kind-kallelse-ark__lista { list-style: none; margin: 0; padding: 0; }
.kind-kallelse-ark__rad { padding: 0; }
.kind-kallelse-ark__lank {
  display: flex; align-items: center; gap: var(--kind-space-3);
  /* 48px: husets träffytegolv (WCAG 2.5.5 / 2.5.8), samma som menyposterna. */
  min-height: 48px; padding: var(--kind-space-3) var(--kind-space-4);
  text-decoration: none; color: inherit;
}
.kind-kallelse-ark__radikon, .kind-kallelse-ark__radpil { flex: none; color: var(--kind-color-accent); }
.kind-kallelse-ark__radtitel { flex: 1 1 auto; font-weight: 600; }
.kind-kallelse-ark__radmeta { color: var(--kind-color-text-muted); font-size: var(--kind-font-small); }

/* Kallelsens innehåll (förhandsvisning och detaljvy, samma partial). */
.kind-kallelse { padding: var(--kind-space-4); }
.kind-kallelse__banderoll {
  margin: 0 0 var(--kind-space-4); padding: var(--kind-space-3) var(--kind-space-4);
  border-radius: var(--kind-radius);
  background: var(--kind-color-accent-soft);
}
.kind-kallelse__titel { margin: 0 0 2px; }
.kind-kallelse__arbetsyta {
  margin: 0 0 var(--kind-space-4); color: var(--kind-color-text-muted);
}
/* Den grå identitetsrutan. Renderas ENBART för vårdpersonal/admin; villkoret
   ligger i partialen och skälet i dess huvud. */
.kind-kallelse__identitet {
  margin: 0 0 var(--kind-space-4); padding: var(--kind-space-4);
  border: 1px solid var(--kind-color-border-soft);
  border-radius: var(--kind-radius);
  background: var(--kind-color-surface-muted);
  display: grid; gap: var(--kind-space-2);
}
.kind-kallelse__identitet-rad { display: grid; gap: 2px; }
.kind-kallelse__identitet dt { font-size: var(--kind-font-small); color: var(--kind-color-text-muted); }
.kind-kallelse__identitet dd { margin: 0; font-weight: 600; overflow-wrap: anywhere; }
.kind-kallelse__varden { list-style: none; margin: 0 0 var(--kind-space-4); padding: 0; display: grid; gap: var(--kind-space-2); }
.kind-kallelse__varde { display: flex; align-items: center; gap: var(--kind-space-2); }
.kind-kallelse__varde-ikon { flex: none; color: var(--kind-color-accent); }
.kind-kallelse__varde-namn { color: var(--kind-color-text-muted); }
.kind-kallelse__varde-text { overflow-wrap: anywhere; }
.kind-kallelse__skiljelinje {
  border: 0; border-top: 1px solid var(--kind-color-border-soft);
  margin: 0 0 var(--kind-space-4);
}
.kind-kallelse__text > :first-child { margin-top: 0; }
.kind-kallelse__text > :last-child { margin-bottom: 0; }
.kind-kallelse__skickad { margin: var(--kind-space-4) 0 0; color: var(--kind-color-text-muted); font-size: var(--kind-font-small); }

/* ---------------------------------------------------------------------------
   web#154 slice 1 -- patientens arbetsytelåda ("Workspaces").
   Knappen sitter till vänster i patientens sidhuvud; lådan glider in från
   vänster över ytan. Enbart presentation. Avgränsningen och
   compliance-underlaget står i templates/patient/_arbetsytelada.html;
   GRINDNINGEN (`nav_role|trim == 'patient'`) och placeringen står i
   templates/base.html -- knappen inne i patientens sidhuvud, dialogen
   (overlay + panel) efter `</header>` men innanför samma patientgren
   (web#1073). Dialogen måste ligga utanför det sticky sidhuvudet: det skapar
   en egen staplingskontext, och inget tal nedan kan då lyfta den över
   `.kind-tabbar` (position: fixed; z-index: 200). Talen 220/221 ligger över
   tabbaren, som vårdgivarlådans (kind.css, web#627).
   --------------------------------------------------------------------------- */
.kind-arbetsyteknapp {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--kind-color-surface-alt, #eef1f5);
  color: var(--kind-color-text, #16202b);
  cursor: pointer;
}

.kind-arbetsyteknapp:focus-visible {
  outline: 2px solid var(--kind-color-accent, #208aef);
  outline-offset: 2px;
}

.kind-arbetsyteknapp__logga {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  object-fit: contain;
}

.kind-arbetsyteknapp__initial {
  font-weight: 600;
  font-size: 1rem;
  line-height: 1;
}

.kind-arbetsytelada__overlay {
  position: fixed;
  inset: 0;
  z-index: 220;
  background: rgba(16, 32, 43, 0.45);
}

.kind-arbetsytelada {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  z-index: 221;
  width: min(85vw, 320px);
  display: flex;
  flex-direction: column;
  background: var(--kind-color-surface, #fff);
  box-shadow: 0 0 24px rgba(16, 32, 43, 0.25);
  overflow-y: auto;
}

.kind-arbetsytelada[hidden],
.kind-arbetsytelada__overlay[hidden] {
  display: none;
}

.kind-arbetsytelada__huvud {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 16px;
  border-bottom: 1px solid var(--kind-color-border, #dfe4ea);
}

.kind-arbetsytelada__rubrik {
  margin: 0;
  font-size: 1.0625rem;
  font-weight: 600;
}

.kind-arbetsytelada__stang {
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--kind-color-text, #16202b);
  cursor: pointer;
}

.kind-arbetsytelada__stang:focus-visible {
  outline: 2px solid var(--kind-color-accent, #208aef);
  outline-offset: 2px;
}

.kind-arbetsytelada__lista {
  list-style: none;
  margin: 0;
  padding: 8px 0;
}

.kind-arbetsytelada__rad {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
}

/* Den aktiva raden är markerad (gamla KIND mod/2332.js). Färg är aldrig enda
   signalen: raden bär aria-current och en visuellt dold "Aktiv arbetsyta". */
.kind-arbetsytelada__rad--aktiv {
  background: var(--kind-color-surface-alt, #eef1f5);
  border-left: 3px solid var(--kind-color-accent, #208aef);
  font-weight: 600;
}

.kind-arbetsytelada__logga {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  object-fit: contain;
}

.kind-arbetsytelada__initial {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--kind-color-accent, #208aef);
  color: #fff;
  font-weight: 600;
}

.kind-arbetsytelada__namn {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* web#1308: inbjudningssidans välkomstmeddelande behåller radbrytningarna. */
.kind-bokning-detalj__valkomst {
  white-space: pre-line;
}

/* web#706 kriterium 4 (villkor K): olästbricka för en ANNAN arbetsyta i lådan.
   Sätts bara av kind_patient_arbetsytesession.js, aldrig serverrenderad (D4/L). */
.kind-arbetsytelada__bricka {
  margin-inline-start: auto;
  min-width: 18px;
  height: 18px;
  padding-inline: 5px;
  border-radius: 999px;
  background: var(--kind-color-accent, #208aef);
  color: #fff;
  font-size: 0.8125rem;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}
