/* KIND 2.0 base stylesheet
 *
 * Owner: frontend-web (per docs/contracts/file-ownership.md).
 * Scope: shared chrome only. Per-domain palette + density lives in
 *        kind_patient.css and kind_admin.css.
 * A11y target: WCAG 2.1 AA. Focus ring is min 3:1 contrast (3px outline +
 *              2px offset, accent-coloured ring against any background).
 * No frameworks. No inline styles in templates. No inline scripts.
 *
 * Layers (top to bottom):
 *   1. Tokens (custom properties, light + dark scheme)
 *   2. Reset
 *   3. Typography
 *   4. Layout primitives + landmarks
 *   5. Forms + buttons
 *   6. Cards + lists + tables
 *   7. Flash / messages / error pages
 *   8. Utilities (sr-only, visually-hidden, skip-link)
 */

/* ============ 1. Tokens ============ */

:root {
  /* ---- Classic+ palette (ADR-065, CP-02, 2026-08-04) ----------------------
     LIGHT NORMAL token set. Light, clinical, system-near: cool neutral greys,
     ONE chromatic accent in blue, white content surface, sans throughout.

     READ THIS BEFORE YOU "CORRECT" IT BACK TO CORAL. The block that used to sit
     here described a live capture of https://www.kind.app/ and concluded the
     brand is coral-red on warm blush with serif display headings. That capture
     was REAL and the observation was TRUE. It was the wrong SURFACE.
     www.kind.app is the MARKETPLACE: the public sales page, coral, serif,
     illustration-led, built for recognition and conversion. The PRODUCT that
     patients and clinicians log in to is blue and sans, which the customer's own
     "Nuvarande KIND" screenshots show on every page. We hue-matched the
     marketplace and shipped it into the product. ADR-065 §Context is the full
     diagnosis; do not re-derive the palette from another kind.app capture.

     NORMATIVE SOURCE FOR EVERY VALUE HERE: docs/design/classic-plus-kontrastmatris.md
     (generated by scripts/classic_plus_kontrast.py). Where the ADR's start value
     and the matrix disagree, the MATRIX wins, and the matrix's measured value is
     what is written below. A requirement is NEVER lowered to fit a value; the
     value moves.

     WATCH-ITEM 1 (SURVIVES from the old block, unchanged in force): functional
     input/control borders use --kind-color-border, NEVER --kind-color-border-soft.
     The two roles are different WCAG questions: a list divider is decoration with
     no requirement, a field edge is a UI component boundary and needs 3:1 (SC
     1.4.11). Collapsing them back into one token is what made the brief's single
     #DCE2E8 fail. Keep the split.
     WATCH-ITEM 2: a functional delineation is NEVER drawn with fill difference
     alone. #FFFFFF content surface on #F5F7FA page is 1.07:1, effectively
     invisible. See §6 Cards for the design rule this produces.
     WATCH-ITEM 3: --kind-color-brand-coral is the MARKETPLACE colour. It stays
     DECLARED (removing it would silently break kind_patterns.css) but has no
     place in a logged-in surface. Non-text decoration only, wherever it survives.
     WATCH-ITEM 4: --kind-color-info now ALIASES the accent. Consequence, and it
     is load-bearing: information status must NEVER be carried by colour alone,
     it always needs icon plus text (WCAG 1.4.1). An info box that looks like a
     primary action is a real confusion risk in a clinical view.

     Ratios below are measured with WCAG 2.x relative luminance and rounded DOWN
     to two decimals (rounding up toward a floor would pass 4.4951 as 4.50). */
  --kind-color-accent: #1769D2;          /* Classic+ primary blue. 5.26:1 white, 4.90:1 page bg, 4.56:1 muted */
  --kind-color-accent-hover: #0F4FA3;    /* 7.87:1 white, 7.33:1 page bg */
  --kind-color-accent-soft: #E9F1FC;     /* accent-on-it 4.62:1, dark text 13.55:1. ADJUSTED, see below */
  --kind-color-accent-bg: #EFF4FC;       /* section wash / active tab. accent-on-it 4.76:1, dark text 13.97:1 */

  /* Decorative section-tint set. BACKGROUNDS ONLY, never a text colour, never a
   * UI boundary, never a button fill. Ink (--kind-color-text) on each is >=12.9:1.
   * mint + blush alias the semantic status tints so the product speaks one tint
   * vocabulary; lavender + butter are their own values. */
  --kind-tint-lavender: #EDE9F5;   /* ink 12.91:1 */
  --kind-tint-butter:   #FAF2DA;   /* ink 13.79:1 */
  --kind-tint-mint:     #F1F9F5;   /* ink 14.40:1 ; == --kind-color-success-bg (alias) */
  --kind-tint-blush:    #FCF1F2;   /* ink 13.96:1 ; == --kind-color-error-bg (alias) */

  /* Marketplace coral. NON-TEXT decoration only (2.5-2.8:1, fails AA text and the
     3:1 graphic bar). Kept declared for kind_patterns.css + the public landing
     illustration; it must not appear in a patient or clinician surface. */
  --kind-color-brand-coral: #ff676e;

  /* Bearing surfaces (cool neutral, ADR-065 §D3) */
  --kind-color-bg: #F5F7FA;              /* page / outer work surface, text 14.37:1 */
  --kind-color-surface: #FFFFFF;         /* content surface: cards, lists, chat */
  --kind-color-surface-muted: #EBEFF4;   /* inset surface, table striping, text 13.36:1 */
  --kind-color-border: #788FA6;          /* FUNCTIONAL field / control edge. 3.34:1 white, 3.11:1 page bg (SC 1.4.11) */
  --kind-color-border-strong: #59626D;   /* emphasised edge, active field. 6.18:1 white, 5.76:1 page bg */
  --kind-color-border-soft: #DCE2E8;     /* DECORATIVE hairline / list divider. NO contrast requirement, NEVER a field edge */

  /* Text */
  --kind-color-text: #20252B;            /* 15.43:1 on white, 14.37:1 on page bg */
  --kind-color-text-muted: #626C77;      /* 5.34:1 white, 4.97:1 page bg, 4.62:1 muted. ADJUSTED, see below */
  --kind-color-text-on-accent: #FFFFFF;  /* white on the blue accent, 5.26:1 */

  /* Status. Every status colour is measured BOTH as text on the two bearing
     surfaces AND as text on its own tint, because that is where badges live. */
  --kind-color-success: #227F59;         /* 4.94:1 white, 4.60:1 page bg */
  --kind-color-success-bg: #F1F9F5;      /* success-on-it 4.61:1. ADJUSTED, see below */
  --kind-color-error: #C43D4B;           /* 5.10:1 white, 4.75:1 page bg */
  --kind-color-error-bg: #FCF1F2;        /* error-on-it 4.61:1. ADJUSTED, see below */
  --kind-color-warning: #A26100;         /* 4.94:1 white, 4.60:1 page bg */
  --kind-color-warning-bg: #FDF6EB;      /* warning-on-it 4.60:1. ADJUSTED, see below */
  --kind-color-info: #1769D2;            /* ALIAS of the accent, see WATCH-ITEM 4 */
  --kind-color-info-bg: #EFF4FC;         /* ALIAS of --kind-color-accent-bg */

  /* Focus ring. The ring colour and the primary-button FILL are the same token,
     so a ring drawn ON the button would be 1.00:1, invisible. The offset is what
     makes it work: the ring lands on the PAGE surface, not on the component fill.
     The offset is therefore load-bearing geometry, not cosmetic spacing. See the
     focus-geometry rule below §3. */
  --kind-focus-ring: 3px solid #1769D2;  /* 5.26:1 white, 4.90:1 page bg, 4.56:1 muted, 4.76:1 accent-bg */
  --kind-focus-ring-offset: 2px;         /* LOAD-BEARING, do not set to 0 on an accent-filled control */

  /* Inline checkmark used as a CSS mask on the success flash (UAT P6). Same glyph
     as the _kind_icons.html 'check' path; tinted via background-color on the
     masked element, so it inherits whatever token that element sets. */
  --kind-icon-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7'/%3E%3C/svg%3E");

  /* Uppslagen bok, samma glyf som standardomslaget i templates/patient/artiklar.html
     och templates/admin/artiklar.html (identiska path-data, viewBox 0 0 56 56).
     Används som CSS-mask av .kind-omslag-fallback nedan, alltså tintad via
     background-color, så platshållaren följer temat i både ljust och mörkt läge.
     Ett data-URI kan inte läsa våra var()-tokens, vilket är precis varför den
     här glyfen är maskad och inte en färdigfärgad bakgrundsbild. */
  --kind-icon-bok: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 56 56' fill='none' stroke='%23000' stroke-width='2' stroke-linejoin='round' stroke-linecap='round'%3E%3Cpath d='M28 17c-3.5-1.8-10-2-15-0.8v22c5-1.2 11.5-1 15 0.8z'/%3E%3Cpath d='M28 17c3.5-1.8 10-2 15-0.8v22c-5-1.2-11.5-1-15 0.8z'/%3E%3Cpath d='M17 23h7M17 27h7M32 23h7M32 27h7'/%3E%3C/svg%3E");

  /* Typography. BODY + UI controls stay in the Inter/system sans (clean, renders
     Swedish diacritics well, no FOUT, no render-blocking webfont fetch). */
  --kind-font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
                    "Helvetica Neue", Arial, "Noto Sans", sans-serif;
  /* DISPLAY headings (h1/h2/h3 + .kind-*__title). ADR-065 §D4 + §D7: the NAME is
     historical, the VALUE is sans. Classic+ runs ONE sans family across the whole
     product, zero serif headings in the application UI, because the serif belongs
     to the MARKETPLACE (www.kind.app) and not to the PRODUCT people log in to.
     38 component rules across the five CSS files reference this token, so
     repointing it flips every heading through the cascade with zero component or
     template edits, and back-out is one hunk. Do NOT point this back at a serif
     stack; read ADR-065 §D2 first if you are about to.
     The rename to --kind-font-display is a separate mechanical follow-up (ADR-065
     §Öppna frågor 3), deliberately NOT bundled here so a visual regression stays
     attributable to one change. */
  --kind-font-serif: var(--kind-font-sans);
  --kind-font-mono: ui-monospace, SFMono-Regular, "Cascadia Mono",
                    Consolas, monospace;

  /* Type scale. ADR-065 §D4 (CP-04, issue #89) after the implementation brief
     §4.2: "Desktop H1 30 till 34 px, inte marknadsföringsstorlek. Mobil H1 24
     till 28. Brödtext 16 px som grund. Metadata minst 13 till 14."

     The heading tokens are declared MOBILE-FIRST and raised to the desktop band
     in the @media block right below this one. Two reasons, both load-bearing:

       * A missing media query then fails toward the SMALL end. A heading that is
         too large is what breaks WCAG 2.2 AA SC 1.4.10 Reflow at 320px, and it
         is exactly the failure `docs/contracts/inloggning-320px-budget.md` was
         written about (/admin/login clipping its own h1). Failing toward small
         costs legibility, which the data-kind-font-scale control below gives the
         user a lever for; failing toward large costs INFORMATION, which no user
         control can recover.
       * Declaring the responsive step ON THE TOKEN means every one of the ~38
         component rules that reference --kind-font-h1/h2/h3 gets the band for
         free, with zero per-component media queries to keep in sync.

     Measured BEFORE this change (static read of the shipped rules, root 16px):
     h1 40px / h2 28px / h3 21px at EVERY width, with no mobile band at all, so
     the 40px h1 was also the 320px h1. Brief cap for desktop H1 is 34.

     --kind-font-base stays 17px on purpose. ADR-065 §D4 reads the brief's "16 px
     som grund" as a FLOOR, not a ceiling, and this codebase deliberately sits
     above it (patient 18px, shared chrome 17px, admin 16px) because the patient
     surface skews older and lower-vision. Lowering 17 -> 16 would be a
     regression on the surface where it would do the most harm, dressed up as
     compliance with a floor we already clear. */
  --kind-font-base: 1.0625rem;           /* 17px, comfortable for older readers (KEEP, older-reader floor) */
  --kind-line-height: 1.55;
  --kind-font-h1: 1.625rem;              /* 26px, mobil-bandet (briefen 24 till 28) */
  --kind-font-h2: 1.25rem;               /* 20px, mobil-bandet */
  --kind-font-h3: 1.125rem;              /* 18px, mobil-bandet */
  --kind-font-small: 0.875rem;           /* 14px metadata; 13px är det absoluta golvet */

  /* Spacing scale (4px base) */
  --kind-space-1: 0.25rem;
  --kind-space-2: 0.5rem;
  --kind-space-3: 0.75rem;
  --kind-space-4: 1rem;
  --kind-space-5: 1.5rem;
  --kind-space-6: 2rem;
  --kind-space-7: 3rem;

  /* Other */
  /* Form and density. CP-05 (issue #90) after the implementation brief §4.3:
     "Radie 6 till 10 px på fält och kort. Undvik stora kapslar som standardform."

     10px is the TOP of the brief's band, chosen so cards keep a soft edge while
     fields stop reading as marketing pills. Measured BEFORE this change against
     13 rendered surfaces at 10 measurement points each (320/375/390/412 at
     height 664 plus 1280, normal AND xxlarge text scale, instrument
     e2e/cp0405-typografi-form-utfall.mjs): 1831 card/panel readings above 10px
     and 100 field readings outside the band, all of them this one 16px token.
     Repointing the VALUE fixes every one of them through the cascade with zero
     component edits, the same mechanism ADR-065 §D7 used for the font token.

     The retired comment said "softer; kind.app cards read generous". That is the
     MARKETPLACE reading that ADR-065 supersedes for every logged-in surface: the
     product people log into is clinical and system-near, not generous.

     WHY NOT THE BOTTOM OF THE BAND: 6px on a 48px chat bubble reads as a plain
     box and loses the message-bubble affordance the chat surface depends on.
     The band is 6 to 10; nothing in it is more correct than the rest, so the
     value is picked for the heaviest consumer (chat) and applied to all. */
  --kind-radius: 10px;
  /* PILL. Reserved for CHIPS, BADGES, AVATARS and segmented filters, which are
     small accents. It is NOT the default form of a field, a card or a button:
     .kind-btn moved off it in CP-05, see the rule below. A pill on a full-width
     control is exactly the "stor kapsel som standardform" the brief rejects. */
  --kind-radius-pill: 999px;
  --kind-shadow-sm: 0 1px 2px rgba(16, 20, 26, 0.06);          /* cool-tinted */
  --kind-shadow-md: 0 8px 28px rgba(16, 20, 26, 0.10);         /* softer + larger spread, kind.app feel */
  --kind-container-max: 70rem;
  --kind-container-narrow: 38rem;

  /* ==========================================================================
     KROMETS HÖJD, EN DEFINITION (#217, konsultbeslut 2026-08-16, regel 51).

     Sju sticky-höjdbudgetar i kind_admin.css bar tidigare HANDSKRIVNA kopior av
     samma fysiska storhet: fyra `top: calc(var(--kind-space-6) + 4rem)` och tre
     `max-height: calc(100dvh - 8rem)`. Talet 8rem är 128px och är summan av
     sidhuvudet (81), mainens övre vaddering (12) och slacken under kolumnen
     (35). Ingenting tvingade någon av de sju att följa med när kromet ändrades.

     Det är inte teoretiskt. Variant D tar bort sidhuvudet från chattytorna, och
     UTAN den här variabeln hade konversationen fått exakt NOLL pixlar tillbaka,
     eftersom `max-height` är ett tak och inte en höjd: luften hade bara flyttat
     nedåt. Defekten syns inte som ett fel, den syns som att ändringen inte
     gjorde någon skillnad.

     `--kind-krom-topp`   sticky-elementets avstånd till viewportens överkant.
     `--kind-krom-budget` total höjd som INTE är tillgänglig för innehållet.

     Värdena är oförändrade mot literalerna de ersätter, alltså är den här
     raden en ren omflyttning för varje yta utom chattytorna, som sätter om dem
     till 0 i kind_admin.css.
     ========================================================================== */
  --kind-krom-topp: calc(var(--kind-space-6) + 4rem);
  --kind-krom-budget: 8rem;
}

/* Desktop band of the type scale (ADR-065 §D4, CP-04). 45rem == 720px, the same
   boundary the surrounding stylesheet already uses as its phone/desktop split
   (the (min-width: 720px) / (max-width: 719.98px) pair further down), restated
   in rem per §D4 implementation binding 2.
   NO vw, NO clamp() with a vw term: a vw-driven size does not answer the
   data-kind-font-scale control below and silently breaks WCAG 2.2 AA SC 1.4.4
   for a patient who enlarged the text (§D4 binding 1).

   EMPIRICAL RESULT for §D4 binding 2, which asked for this to be verified
   rather than assumed (Chromium via Playwright, 2026-08-04, four widths x two
   font scales):

     bredd  700px  normal: rot=16px token=mobil   | xxlarge: rot=24px token=mobil
     bredd  719px  normal: rot=16px token=mobil   | xxlarge: rot=24px token=mobil
     bredd  721px  normal: rot=16px token=desktop | xxlarge: rot=24px token=desktop
     bredd  760px  normal: rot=16px token=desktop | xxlarge: rot=24px token=desktop

   Setting data-kind-font-scale="xxlarge" raised the root font-size from 16px to
   24px and did NOT move the breakpoint (it stayed at 720px, it did not become
   45 x 24 = 1080px). So rem in a media query resolves against the browser's
   INITIAL font-size, not against html's computed one, exactly as the ADR
   hypothesised. Consequence, and it is why rem is still the right unit here: the
   breakpoint is immune to our own font-scale control (good, an enlarged text
   must not flip the layout band) while still answering a user who raised their
   BROWSER's default font size (good, that is a real accessibility signal a px
   breakpoint would ignore). */
@media (min-width: 45rem) {
  :root {
    --kind-font-h1: 2rem;                /* 32px, mitt i briefens 30 till 34 */
    --kind-font-h2: 1.5rem;              /* 24px */
    --kind-font-h3: 1.25rem;             /* 20px */
  }
}

/* ---- ADR-065 avvikelselogg: fem HÄRLEDDA tokens justerade i CP-02 ----------
 *
 * The contrast matrix measured the NINE tokens of the implementation brief. It
 * did NOT measure the DERIVED tokens (tints, muted surface), even though ADR-065
 * §Normerande rule 2 requires every pair that ACTUALLY OCCURS to be measured and
 * §Riskpar 4 names accent-on-tint as the system's historically tightest pair.
 * CP-02 measured them with the matrix's own method. SIX pairs failed, and every
 * one of them occurs in the real stylesheet (badges are literally
 * `color: var(--kind-color-X); background: var(--kind-color-X-bg)`).
 *
 * Today's coral production set PASSES all six. Shipping the start values
 * unadjusted would therefore have been a REGRESSION against production on six
 * real pairs, not merely an unverified value.
 *
 * The nine matrix-approved values are UNTOUCHED. Only derived values moved, and
 * only upward. No requirement was lowered. Search target is the matrix's own
 * "requirement + 0.10" margin, so a later hex nudge does not crack the floor.
 *
 *   token                      start     measured   ->  adjusted   new ratio
 *   --kind-color-accent-soft   #E3EDFB   4.45 FAIL      #E9F1FC    4.62  (accent on it)
 *   --kind-color-error-bg      #FBE9EB   4.36 FAIL      #FCF1F2    4.61  (error on it)
 *   --kind-color-warning-bg    #FBF1DE   4.41 FAIL      #FDF6EB    4.60  (warning on it)
 *   --kind-color-success-bg    #E4F3EC   4.31 FAIL      #F1F9F5    4.61  (success on it)
 *   --kind-color-text-muted    #66717D   4.30 FAIL      #626C77    4.62  (on --surface-muted)
 *
 * text-muted is the one adjustment that touches a token the matrix DID measure,
 * so it needs its own justification. It is DARKENED, which strictly STRENGTHENS
 * both measured pairs (white 4.97 -> 5.34, page bg 4.63 -> 4.97, both still
 * GODKÄND with more margin) while fixing the pair the matrix never measured
 * (on --surface-muted 4.30 FAIL -> 4.62). This is exactly the remedy ADR-065
 * §Riskpar 1 prescribes ("mörkna sekundärtexten inom samma hue"). The rejected
 * alternative was lightening --surface-muted instead: it would have needed
 * ~#F3F5F9, which is 1.01:1 against the page background, i.e. the inset surface
 * would have stopped existing. Fixing a contrast pair by deleting one of the two
 * surfaces is not a fix.
 *
 * Sixth failing pair, deliberately NOT "fixed": --kind-color-border #788FA6 on
 * --kind-color-surface-muted #EBEFF4 is 2.89:1. It occurs on eight chip/container
 * rules whose fill is the muted surface and which sit ON white or the page bg.
 * SC 1.4.11 asks for 3:1 against the ADJACENT BACKGROUND, and the boundary that
 * identifies these components is the OUTER edge, which is 3.34:1 against white
 * and 3.11:1 against the page. The inner neighbour is the component's own fill,
 * not a background. No input field in the product uses a muted fill, so the
 * strict case does not occur. Moving either value would have cost a measured
 * token, so this one is documented rather than papered over.
 *
 * ACTION FOR qa: regenerate the matrix with the derived pairs included, so these
 * numbers live in the normative document and not only in this comment. */

/* ---- Avvikelselogg 2026-08-15: radavstand `normal` pa meddelandebubblor ----
 *
 * #205 runda 2 variant B (konsultbeslut 2026-08-15, godkänd mock
 * docs/design-proposals/205/runda-2/ i agents-repot): `.kind-chat__message`
 * i kind_patient.css sätter `line-height: normal` (~1,18 vid 17px) i stället
 * för husets `--kind-line-height: 1.55`. Det är ett REDOVISAT AVSTEG fran
 * typskalan, inte en tyst drift (regel 48-mönstret):
 *
 *   - VARFÖR: produktionens egen bubbelkaraktär. Sänkningen 67 -> 57,5px per
 *     enradsbubbla finansierar 24px meddelandelucka under täthetsgolvet
 *     Ukap >= 7 (docs/contracts/konversationstathet-2026-08-10.md §3).
 *   - BESLUTSPUNKT: uttryckligen accepterad i valalternativets text
 *     (runda-2/BESLUT.md), med ux läsbarhetsflagga for langa meddelanden.
 *   - WCAG 1.4.12 bryts INTE: regeln saknar !important, sa användarens egen
 *     övermarkering (radhöjd 1,5x) vinner. Verifierat i mockrundan (axe plus
 *     egen mätning) och i tathet-a11y-svepet.
 *   - RÄCKVIDD: enbart chattens bubbelinnehall (alla fyra chattytorna delar
 *     noden). Övriga ytor behaller husets 1,55. */

/* ============ 1a. DARK NORMAL token set ============
 *
 * CP-03 (issue #88, ADR-065 §D6.1). The selector is an ATTRIBUTE, never
 * `@media (prefers-color-scheme: dark)`. Read the next paragraph before you
 * "modernise" it back to a media query.
 *
 * The media query meant the OS decided which product KIND looked like. Nobody
 * chose that: a clinician on a dark-OS laptop and a clinician on a light-OS
 * laptop saw two different products, with two different palettes, and the
 * customer's recognition brief (ADR-065 §Context) was measured against only one
 * of them. Dark is now a real product capability behind an explicit choice, and
 * ABSENCE of the attribute means LIGHT, on every operating system.
 *
 * The choice is stored in localStorage under `kind.tema` and applied to <html>
 * pre-paint by the inline bootstrap in templates/base.html. The bootstrap sits
 * OUTSIDE the patient a11y gate, so the clinician surface has the choice too
 * (ADR-065 §D6.1 punkt 2).
 */
html[data-kind-theme="dark"] {
    /* Classic+ DARK, derived from the light set by ADR-065 §D6.2, not invented:
       same cool blue-grey family (~210-215 deg), inverted lightness ramp,
       desaturated bearing surfaces so a large area does not glow, chroma kept in
       the accent, and the accent moves UP in lightness because #1769D2 is tuned
       to carry 4.5:1 against WHITE and is by construction wrong against
       near-black.

       WHAT THIS REPLACED, and why not "just fix the ratios": the previous set
       was warm near-black with a LIGHT CORAL accent, hue-matched to
       www.kind.app. Every one of those values PASSED its contrast floor. They
       were replaced for RECOGNITION, not for contrast: a clinician on a dark-OS
       laptop saw a coral product and a colleague on a light-OS laptop saw a blue
       one. `scripts/classic_plus_kontrast.py --selftest` keeps a control that
       re-measures the retired coral set and asserts it still passes, so nobody
       can later record "the dark theme failed AA" as the reason.

       NORMATIVE SOURCE FOR EVERY VALUE HERE: docs/design/classic-plus-
       kontrastmatris.md, section MORK NORMAL. Every ratio in the comments below
       is measured by that generator, not estimated. A requirement is NEVER
       lowered to fit a value; the value moves. */
    --kind-color-bg: #12161B;              /* page, text 15.30:1 */
    --kind-color-surface: #1A2028;         /* cards, lists, chat, text 13.81:1 */
    --kind-color-surface-muted: #232B34;   /* inset surface, text 12.06:1 */
    --kind-color-border: #7A8694;          /* FUNCTIONAL field edge. 4.42:1 on surface, 4.89:1 on bg (SC 1.4.11) */
    --kind-color-border-strong: #9BA6B4;   /* emphasised edge, 6.64:1 on surface */
    --kind-color-border-soft: #2C343D;     /* DECORATIVE hairline. NO contrast requirement, NEVER a field edge */
    --kind-color-text: #E8ECF1;            /* 15.30:1 on bg, 13.81:1 on surface */
    --kind-color-text-muted: #A7B2BF;      /* 8.44:1 on bg, 7.62:1 on surface */
    --kind-color-accent: #7FB2F2;          /* Classic+ blue lifted for dark. 8.26:1 on bg, 7.45:1 on surface */
    --kind-color-accent-hover: #A6C9F8;    /* 10.66:1 on bg */
    --kind-color-accent-soft: #1B2E45;     /* fill; accent on it 6.27:1, ink 11.61:1 */
    --kind-color-accent-bg: #141F2D;       /* section wash / active tab; accent on it 7.55:1 */
    --kind-color-text-on-accent: #0D1218;  /* darkest neutral ON the light accent, 8.55:1 (ADR-065 §D6.2 regel 4) */
    --kind-color-success: #5FCB97;         /* 9.05:1 on bg */
    --kind-color-success-bg: #173726;      /* success on it 6.50:1 */
    --kind-color-error: #FF8F97;           /* 8.32:1 on bg */
    --kind-color-error-bg: #3A1B1F;        /* error on it 7.09:1 */
    --kind-color-warning: #E8B24E;         /* 9.43:1 on bg */
    --kind-color-warning-bg: #3A2E14;      /* warning on it 6.90:1 */
    --kind-color-info: #7FB2F2;            /* ALIAS of the accent, same rule as light: never colour alone */
    --kind-color-info-bg: #141F2D;         /* ALIAS of --kind-color-accent-bg */
    --kind-focus-ring: 3px solid #7FB2F2;  /* 8.26:1 bg, 7.45:1 surface, 6.51:1 muted, 7.55:1 accent-bg */
    --kind-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --kind-shadow-md: 0 8px 28px rgba(0, 0, 0, 0.5);
    /* Decorative section-tints, dark so they do not glow on the near-black
     * canvas. Ink (--kind-color-text #E8ECF1) on each is >=10.9:1 (measured).
     * mint + blush alias the dark success/error tints, the same aliasing the
     * light set has; an alias that does not follow its source is a silent
     * divergence. */
    --kind-tint-lavender: #221F2E;   /* ink 13.57:1 */
    --kind-tint-butter:   #2A2617;   /* ink 12.75:1 */
    --kind-tint-mint:     #173726;   /* ink 10.98:1 ; == --kind-color-success-bg dark (alias) */
    --kind-tint-blush:    #3A1B1F;   /* ink 13.04:1 ; == --kind-color-error-bg dark (alias) */
}

/* ============ 1b. Patient accessibility preferences ============
 *
 * Owner: frontend-web. Drives the patient accessibility panel (W15-B2,
 * intake-gap row 25 / Q-NEW-AT-PT2). Two root-level controls:
 *
 *   1. Font scale. The whole type system is built on rem + the
 *      --kind-font-* / --kind-space-* tokens, and html is font-size: 100%.
 *      Scaling the html font-size therefore scales every rem proportionally
 *      (text, spacing, min-target sizes), which is the WCAG 1.4.4 / 1.4.10
 *      reflow-friendly way to zoom. Steps: normal 100, large 112.5,
 *      xlarge 125, xxlarge 150 (percent of the 100% browser default). These
 *      are deliberately gentler than the panel's "up to 200%" wording so that
 *      the 9-field forms still reflow without horizontal scroll; the panel
 *      labels stay patient-facing (Normal / Storre / Storst / Extra stor)
 *      while the underlying html scale stays layout-safe.
 *
 *   2. High contrast. Overrides the surface/text/border tokens with a
 *      black-on-white (or white-on-black in dark scheme) high-contrast set,
 *      raising every text pair well past 4.5:1 and every UI border past 3:1.
 *      prefers-contrast: more is honoured for users who set it at the OS
 *      level and have not touched the panel.
 *
 * The attributes live on <html> and are set by kind_a11y_panel.js from
 * localStorage on every patient page (and applied pre-paint via a tiny inline
 * bootstrap in base.html to avoid a flash of unscaled content).
 */

html[data-kind-font-scale="large"] { font-size: 112.5%; }
html[data-kind-font-scale="xlarge"] { font-size: 125%; }
html[data-kind-font-scale="xxlarge"] { font-size: 150%; }

/* LIGHT HIGH-CONTRAST. CP-03 (issue #88) repointed the accent family from the
 * deep marketplace coral to Classic+ deep blue (ADR-065 §D6.4), so the
 * high-contrast route is the same product as the normal one, only louder. The
 * structure is unchanged: text and borders go to pure black, decoration
 * recedes, and the focus ring is pure black and NEVER the accent (§D6.2 regel 6:
 * high-contrast always beats theme aesthetics).
 *
 * --kind-color-brand-coral is deliberately NOT overridden here any more. It is
 * the MARKETPLACE brand colour (kind.app), it appears in exactly one place (the
 * public landing's hero illustration, templates/_kind_icons.html), and it is
 * non-text decoration with no contrast requirement. Theming a brand mark per
 * contrast preference was an artefact of coral once being the accent; now that
 * the accent is blue, the coral has no accent role left to follow. */
html[data-kind-contrast="high"] {
  --kind-color-bg: #ffffff;
  --kind-color-surface: #ffffff;
  --kind-color-surface-muted: #f2f2f2;
  --kind-color-border: #000000;
  --kind-color-border-strong: #000000;
  --kind-color-border-soft: #000000;
  --kind-color-text: #000000;
  --kind-color-text-muted: #1c1c1c;        /* 17.04:1 on white */
  --kind-color-accent: #0B3E8F;            /* Classic+ deep blue, 10.00:1 on white */
  --kind-color-accent-hover: #082C66;      /* 13.44:1 on white */
  --kind-color-accent-soft: #E2ECFB;       /* accent on it 8.39:1, ink 17.62:1 */
  --kind-color-accent-bg: #EFF5FE;         /* accent on it 9.12:1, ink 19.16:1 */
  --kind-color-text-on-accent: #ffffff;    /* white on the deep blue, 10.00:1 */
  --kind-color-info: #0B3E8F;              /* ALIAS of the HC accent. Without this line info kept the
                                              NORMAL accent and the alias broke silently in HC only. */
  --kind-color-info-bg: #EFF5FE;           /* ALIAS of --kind-color-accent-bg */
  --kind-focus-ring: 3px solid #000000;    /* HC focus ring stays pure black, NEVER the accent */
  --kind-shadow-sm: 0 0 0 1px #000000;
  --kind-shadow-md: 0 0 0 2px #000000;
  /* Decorative tints flatten to white in high-contrast (max contrast wins,
   * decoration recedes; NIGHT-PASS 2026-06-04). */
  --kind-tint-lavender: #ffffff;
  --kind-tint-butter:   #ffffff;
  --kind-tint-mint:     #ffffff;
  --kind-tint-blush:    #ffffff;
}

/* kind_patient.css re-declares --kind-color-bg / -surface / -surface-muted on
   .kind-body--patient (warm cream). That body-level declaration is more
   specific than the html[data-kind-contrast] rule above for the variable
   cascade on the body subtree, so high-contrast would keep the cream surface.
   Re-assert the high-contrast surfaces at the body level so the patient page
   actually goes pure white in high-contrast mode. */
html[data-kind-contrast="high"] body.kind-body {
  --kind-color-bg: #ffffff;
  --kind-color-surface: #ffffff;
  --kind-color-surface-muted: #f2f2f2;
}

/* DARK HIGH-CONTRAST. CP-03 (issue #88): the dark half of the high-contrast
 * route. It is the reason ADR-065 §Option D (delete the dark blocks outright)
 * was rejected: throwing the block away would have taken dark high-contrast
 * with it, and that is an accessibility route, not an aesthetic. Two attributes
 * on <html>, so it beats both the plain dark set and the light HC set. */
html[data-kind-theme="dark"][data-kind-contrast="high"] {
    --kind-color-bg: #000000;
    --kind-color-surface: #000000;
    --kind-color-surface-muted: #141414;
    --kind-color-border: #ffffff;
    --kind-color-border-strong: #ffffff;
    --kind-color-border-soft: #ffffff;
    --kind-color-text: #ffffff;
    --kind-color-text-muted: #e8e8e8;        /* 17.13:1 on black */
    --kind-color-accent: #9CC0FA;            /* Classic+ light blue, 11.33:1 on black */
    --kind-color-accent-hover: #C2D8FC;      /* 14.52:1 on black */
    --kind-color-accent-soft: #0C1B33;       /* accent on it 9.28:1, white text 17.21:1 */
    --kind-color-accent-bg: #08111F;         /* accent on it 10.20:1, white text 18.91:1 */
    --kind-color-text-on-accent: #000000;    /* black on the light blue, 11.33:1 */
    --kind-color-info: #9CC0FA;              /* ALIAS of the HC-dark accent */
    --kind-color-info-bg: #08111F;           /* ALIAS of --kind-color-accent-bg */
    --kind-focus-ring: 3px solid #ffffff;    /* HC dark focus ring stays pure white, NEVER the accent */
    /* The light HC block above sets --kind-shadow-sm / -md to a BLACK ring, and
     * it is not overridden by the plain dark block (equal specificity, later in
     * source order), so before CP-03 dark high-contrast drew a black ring on a
     * black surface, i.e. no visible elevation at all for the users who need it
     * most. Inverted here. */
    --kind-shadow-sm: 0 0 0 1px #ffffff;
    --kind-shadow-md: 0 0 0 2px #ffffff;
    /* Decorative tints flatten to black in dark high-contrast (NIGHT-PASS
     * 2026-06-04). */
    --kind-tint-lavender: #000000;
    --kind-tint-butter:   #000000;
    --kind-tint-mint:     #000000;
    --kind-tint-blush:    #000000;
}
/* Same body-level re-assert as the light HC block above, and for the same
 * reason: kind_patient.css / kind_admin.css re-declare the bearing surfaces on
 * `.kind-body--patient` / `--admin`, and a declaration on the BODY wins for the
 * body subtree over any declaration on <html>, whatever their specificities,
 * because they are different elements and the mechanism is inheritance. */
html[data-kind-theme="dark"][data-kind-contrast="high"] body.kind-body {
  --kind-color-bg: #000000;
  --kind-color-surface: #000000;
  --kind-color-surface-muted: #141414;
}

/* OS-level preference fallback for patients who never open the panel. Only
   applies when the patient has not explicitly chosen (no data-kind-contrast). */
@media (prefers-contrast: more) {
  html:not([data-kind-contrast]) {
    --kind-color-border: #000000;
    --kind-color-border-soft: #6a6a6a;
    --kind-color-text-muted: #333333;
  }
}

/* ============ 2. Reset ============ */

*, *::before, *::after { box-sizing: border-box; }
html, body, h1, h2, h3, h4, h5, h6, p, ul, ol, li, figure, blockquote, dl, dd { margin: 0; padding: 0; }
ul, ol { list-style: none; }
img, svg, video { max-width: 100%; height: auto; display: block; }
button { font: inherit; cursor: pointer; }

/* ============ 3. Typography + base ============ */

html {
  font-size: 100%;
  -webkit-text-size-adjust: 100%;
}

body.kind-body {
  font-family: var(--kind-font-sans);
  font-size: var(--kind-font-base);
  line-height: var(--kind-line-height);
  color: var(--kind-color-text);
  background: var(--kind-color-bg);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* Display headings. ADR-065 §D4: --kind-font-serif RESOLVES to the sans stack
   (CP-02), and the SIZE + WEIGHT scale is CP-04's, landed here.

   Weights: 400 / 500 / 600, no 700. h1 and h2 ran 700 and are named explicitly
   by §D4 ("Dagens h1/h2 kör 700, det tas ned till 600"). Negative tracking is
   H1-only: a grotesk at 32px tolerates -0.01em, a 20 to 24px h2 does not gain
   from it and it costs a little legibility, so h2 goes back to 0.

   NOT swept in that first pass, and that was a decision rather than an
   oversight: the remaining weight-700 rules are EMPHASIS or STATE devices (nav
   aria-current, unread badges, chips, counters, step markers) or a brand
   wordmark, not members of the display type scale, and several carry meaning
   that colour does not also carry, so thinning them is a WCAG 1.4.1 question
   and a visual-emphasis redesign. It gets its own attributable change.

   THAT CHANGE IS PARTLY DONE (2026-08-05, CP-04 part 3/5), and the split is
   deliberate:

     MOVED, because they are the type scale by definition. Six classes carried
     by an actual <h1>..<h6> element in templates/ still declared 700
     (.kind-section-title, .kind-ko__bucket-heading,
     .kind-aktiviteter__section-heading, .kind-nu__title,
     .kind-more-section__title, .kind-mine-group__title). §D4's table names a
     weight for every heading level, so a heading at 700 contradicts it whatever
     its size. Plus `strong, b`, see the rule below.
     TVÅ AV DE SEX BÄRS INTE LÄNGRE AV NÅGON MALL, och det är avsiktligt
     redovisat i stället för tyst rättat: .kind-mine-group__title upplöstes med
     `Mina ärenden`-hubben (issue #163, beslut B1) och .kind-ko__bucket-heading
     togs bort med patientlistans hinkrubriker (agents#177, 2026-08-11). Listan
     ovan är alltså en HISTORISK uppräkning av vad CP-04 del 3 flyttade, inte en
     påstådd nulägesbild; den levande mängden härleds av
     tests/test_cp0405_typografi_form.py::_rubrikklasser ur templates/.

     NOT MOVED, and still open: the badges, chips, counters, step markers, nav
     aria-current state and wordmarks. .kind-badge--unread-egna documents its own
     700 as one of TWO non-colour carriers of "mine, act on it" (the other is the
     filled-versus-hollow shape), so thinning that set touches a written
     accessibility mitigation. Re-deciding it silently inside a type-scale commit
     is exactly the drift this comment was written to prevent. It needs persona
     review, and the rendered count is measured by
     e2e/cp0405-typografi-form-utfall.mjs (mått T5) so the debt is a number
     rather than a memory. */
h1, h2, h3 { font-family: var(--kind-font-serif); line-height: 1.2; }

/* Inline emphasis joins the scale. CP-04 (issue #89), brief §4.2 "Vikter
   sparsamt: normal, medium, semibold".

   `<strong>` and `<b>` render at the UA default `bolder`, which resolves to 700
   against a 400 parent, so every emphasised run in body copy, in article HTML
   and in chat messages sat OUTSIDE the three-weight scale. Measured on the
   rendered surfaces 2026-08-05: `strong` at 700 appeared on 8 of 13 swept
   surfaces, and it is the one 700 no component rule could reach, because it
   comes from the user agent and not from this stylesheet.

   600 keeps emphasis unmistakable against 400 body text (a 200-step contrast),
   so nothing that relied on `<strong>` to distinguish a run loses that
   distinction. Semantics are untouched: `<strong>` still conveys importance to
   assistive technology regardless of the weight it paints at. */
strong, b { font-weight: 600; }

/* ============ ISSUE #109: obrytbara svenska sammansättningar i rubriker ======
 *
 * Uppmätt på deployen 2026-08-05 (docs/qa/formatning-109-110-2026-08-05.md):
 * /admin/installningar/branding sköt ut 75px horisontellt vid 320px och
 * xxlarge textskala, 35 vid 360, 20 vid 375, 5 vid 390, 0 från 412. NORMAL
 * textskala låg redan på 0 vid alla bredder, alltså är detta en defekt som
 * bara den lågseende användaren ser, och det är precis den användaren den
 * patientnära vårdytan har mest av.
 *
 * ROTORSAKEN ÄR EN ENDA TEXTTOKEN, inte en breddeklaration. `h1` på ytan
 * innehåller ordet "välkomstmeddelande", uppmätt till 371px vid font-size 39px,
 * och computed style var `overflow-wrap: normal` + `hyphens: manual`, alltså
 * ingen tillåten brytpunkt inuti ordet. Modellen
 *
 *     överskott = max(0, 24px indrag + 371px token - viewportbredd)
 *
 * stämmer exakt på alla fyra mätpunkter. Kontrafaktiskt i SAMMA sidladdning:
 * `overflow-wrap: anywhere` på rubriken gav 0px, medan `nav { display: none }`
 * lämnade 75px OFÖRÄNDRAT. Navet är alltså inte inblandat trots att ett svep
 * efter "bredaste element" pekar dit (den är en egen skrollport med
 * overflow-x: auto, klipper, och når aldrig dokumentnivån).
 *
 * SVEPT VIDARE (regel 48 följdkrav b, kunden rapporterar det den ser, inte det
 * som finns): en genomsökning av templates/ hittade FEM rubriker med ord som är
 * LÄNGRE än det rapporterade. Värst är "Personuppgiftsbiträdesavtal", 27 tecken
 * mot rapporterade 18, alltså ~50 procent bredare token på en yta ingen
 * rapporterat. Därför sitter regeln på rubrikelementen generellt och inte på
 * #kind-branding-heading.
 *
 * Svepet fortsatte utanför rubrikerna och hittade 28 träffar till på
 * ETIKETTBÄRANDE element som INTE är h1-h6: `.kind-section__title` på `<div>`
 * ("Verksamhetsöversikt", "Artikelbibliotek", "Triageringsregler") och `<label>`
 * ("Välkomstmeddelande" på samma branding-sida som rapporterades,
 * "Inbjudningslänk", "Tilldelningsdatum"). En rubrikbunden regel hade lämnat
 * hela den mängden kvar, och just `.kind-section__title` är display-storlek,
 * alltså samma riskklass som en h2.
 *
 * Selektorlistan följer alltså svepets utfall och inte en känsla för vad som
 * "är en rubrik". Att skillnaden är verklig visades direkt: en handskriven
 * lista (rubriker + `<label>` + `.kind-section__title` + `.kind-field__label`)
 * såg heltäckande ut men lämnade FEM element kvar, och det var
 * drift-vakten tests/test_rubrik_ordbrytning_css.py som räknade upp dem
 * (`.kind-radio__label`, `.kind-checkbox__label`, `.kind-callout__title`,
 * `.kind-password-meter__label`, `.kind-stat-fig__label`). Vakten kör OM svepet
 * vid varje körning och blir röd, med fil och ord utskrivna, så fort ett långt
 * ord dyker upp på en elementtyp listan inte täcker.
 *
 * INTE hela `body`. `overflow-wrap: break-word` globalt vore försvarbart (den
 * gör bara något när ett ord ändå spiller över), men `hyphens: auto` globalt är
 * en synlig typografisk förändring av all brödtext i appen, alltså ett
 * designbeslut som inte hör hemma i en formateringsfix.
 *
 * VAL AV MEKANISM. `overflow-wrap: break-word` bryter ordet när det inte får
 * plats på en egen rad, deterministiskt och utan ordlista.
 *
 *   INTE `overflow-wrap: anywhere`, trots att förmätningens kontrafaktiska prov
 *   använde den: `anywhere` sätter också elementets MIN-CONTENT-bredd till noll,
 *   vilket ändrar hur rubriken storleksätts som flex- eller rutnätsobjekt på
 *   ytor som inte har med det här att göra. `break-word` rör bara radbrytning.
 *   Uppmätt: båda ger 0px överskott, alltså väljs den med minst blast radius.
 *
 * ================ ISSUE #158: `hyphens: auto` BORTTAGEN HÄRIFRÅN =============
 *
 * Regeln bar fram till 2026-08-10 även `hyphens: auto`, motiverad ovan med att
 * avstavning ger ett typografiskt korrekt brott i stället för en hård kapning.
 * Den motiveringen står sig, men deklarationen bar en sidoeffekt ingen mätte:
 * DEN GÖR EXAKT DET SOM STYCKET OVANFÖR AVVISAR `anywhere` FÖR.
 *
 * En avstavningspunkt är en LAGLIG brytpunkt, så den räknas MED när min-content
 * beräknas. Ett ord bidrar då med sin bredaste stavelse i stället för med hela
 * ordet. Uppmätt på driftsatt 2.3.4, samma sida, samma typsnitt:
 *
 *     "patienter"  width:min-content  hyphens:manual -> 62.3px, obrutet
 *     "patienter"  width:min-content  hyphens:auto   -> 23.1px, fyra rader
 *
 * `break-word` däremot räknas INTE med i min-content, vilket är hela skälet att
 * den valdes, så de två deklarationerna hade motsatt blast radius trots att de
 * stod i samma block.
 *
 * FÖLJDEN, uppmätt på tre katalogytor (/admin/katalog/artikel, /formular,
 * /vardresa). Cellens innehåll är en `label.kind-checkbox`, alltså en träff på
 * `label` ovan. Labeln låg på 93px, exakt sin egen min-content, cellen på 125px
 * (93 plus 2x16 cellpolstring) och tabellen på 438px i en 286px wrap, alltså
 * REDAN sidledsskroll. Ingenting klämde ihop cellen. Den var smal för att
 * labelns min-content var liten, och texten "Tilldela alla aktiva patienter"
 * renderades "pa-ti-en-ter" över fyra rader. Med avstavningen borta: labeln
 * 130px, radhöjden 371 -> 208px, noll delade vanliga ord.
 *
 * VARFÖR HELA DEKLARATIONEN OCH INTE ETT UNDANTAG PER YTA (regel 27 kor. 2).
 * Ett bärarsvep över 108 mätpunkter, 28 ytor, två roller, två bredder och två
 * textskalor letade efter MEKANISMEN och inte efter de rapporterade ytorna:
 * mät, slå av avstavningen, mät om, och låt de boxar som VÄXER peka ut vilka
 * boxar som var storleksatta av avstavning. Utöver de tre rapporterade ytorna
 * föll fyra till ut, samtliga via samma deklaration och ingen av dem
 * rapporterad: `admin/team-chat` (sex KOLLEGANAMN delade, "Lund-ström",
 * "Jo-han"), `patient/hem` (åtta boxar, "bok-ningar" över tre rader),
 * `patient/bokningar` (sidans h1). En fix per rapporterad yta hade lämnat alla
 * fyra kvar.
 *
 * AVSTAVNING FINNS KVAR där den mätts och scopats: `.kind-onboarding__card`,
 * `.kind-dorr__card` och `.kind-admin__card` :is(h1,h2) (raden nedan om
 * "Personuppgiftsbiträdesavtal"), `.kind-artikelrad__titel`,
 * `.kind-library-item__title`, `.kind-article__rubrikband h1` och
 * `.kind-formular-fill__heading`. Alla har högre specificitet än den här
 * regeln, så de rörs inte, och svepet visar noll växta boxar på dem: där fyller
 * elementet sin behållare i stället för att storleksättas av den, alltså får
 * man nyttan (ett snyggt radslut) utan skadan (en box som krymper till en
 * stavelse). Det är den skillnaden som avgör, inte elementtypen.
 *
 * DEN ANDRA DIMENSIONEN (minne `feedback-one-dimension-budget-moves-the-error`):
 * ett breddtak kan bli grönt medan text i stället KAPAS. Grinden
 * e2e/formatning-109-110-utfall.mjs mäter därför överskott OCH antal avkortade
 * element, och kräver noll av båda, så felet inte kan flyttas från rullning
 * till klippning och kallas löst. Samma disciplin gäller den här ändringen:
 * att ta bort avstavningen HÖJER min-content, alltså går priset åt andra
 * hållet, och det priset betalades på två ställen där avstavningen MASKERADE
 * en layoutdefekt i stället för att lösa den. Båda är åtgärdade i samma
 * ändring, se `.kind-section__title` (kind.css) och `.kind-deltagare__label`
 * (kind_admin.css). */
h1, h2, h3, h4, h5, h6,
label,
.kind-section__title, .kind-callout__title,
.kind-field__label, .kind-field__help,
.kind-radio__label, .kind-checkbox__label,
.kind-password-meter__label, .kind-stat-fig__label {
  overflow-wrap: break-word;
}
h1 { font-size: var(--kind-font-h1); font-weight: 600; line-height: 1.1; letter-spacing: -0.01em; margin-bottom: var(--kind-space-4); }
h2 { font-size: var(--kind-font-h2); font-weight: 600; letter-spacing: 0; margin-bottom: var(--kind-space-3); }
h3 { font-size: var(--kind-font-h3); font-weight: 600; margin-bottom: var(--kind-space-2); }
p { margin-bottom: var(--kind-space-3); }
p:last-child { margin-bottom: 0; }

a {
  color: var(--kind-color-accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}
a:hover { color: var(--kind-color-accent-hover); }
a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible, select:focus-visible {
  outline: var(--kind-focus-ring);
  outline-offset: var(--kind-focus-ring-offset);
  border-radius: 4px;
}

/* ============ 4. Layout + landmarks ============ */

.kind-header {
  background: var(--kind-color-surface);
  border-bottom: 1px solid var(--kind-color-border-soft);
  position: sticky;
  top: 0;
  z-index: 100;
}

.kind-header__inner {
  max-width: var(--kind-container-max);
  margin: 0 auto;
  padding: var(--kind-space-3) var(--kind-space-4);
  display: flex;
  align-items: center;
  gap: var(--kind-space-4);
  flex-wrap: wrap;
}

.kind-header__logo {
  color: var(--kind-color-text);
  text-decoration: none;
  display: flex;
  flex-direction: column;
  line-height: 1.05;
  /* #113 / ux-beslut 2 (2026-08-07): traffytan lyfts till 44px-golvet utan att
     kromhojden vaxer. Logotypen matte 25 till 39px (over WCAG 2.2 2.5.8:s
     24px-minimum men under husets golv). padding-block malar traffyta av dott
     utrymme, och den symmetriskt negativa margin-block neutraliserar
     layoutkostnaden: elementets YTTRE bidrag till raden ar oforandrat
     (border-box minus marginaler = innehallshojden), sa headerhojderna ror sig
     inte pa nagon matpunkt (villkor 2, #110-monotonicitetsvakten fortsatt
     gron). Asymmetrin ar avsiktlig: 12px uppat ar alltid sakert (dar ligger
     bara headerns egen padding och viewportkanten), 7px nedat ar mindre an
     minsta radgap till naven i det staplade mobillaget, sa ingen granne
     overlappas (villkor 3, elementFromPoint-kontroll i
     e2e/a11y-113-utfall.mjs, rodbevisad mot padding 0). Fasta px, inte em:
     vid storre textskala vaxer innehallet sjalvt forbi 44 och utstickningen
     ska da inte vaxa med (mindre overlappsrisk). Samma familj som
     .kind-safety__tel-spaken (Z1). */
  padding-block: 12px 7px;
  margin-block: -12px -7px;
}
.kind-header__logo:hover { color: var(--kind-color-text); }
/* KIND wordmark in the product chrome. ADR-065 §D4: sans, like the rest of the
   application UI. The serif "Kind" mark belongs to the marketplace surface
   (www.kind.app), not to the logged-in product. The token reference is kept so
   the wordmark follows the display family wherever it goes next. */
.kind-header__logo-mark {
  font-family: var(--kind-font-serif);
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.kind-header__logo-sub {
  font-size: 0.8125rem;  /* 13px, husets absoluta golv (CP-04, ADR-065 §D4) */
  color: var(--kind-color-text-muted);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 600;
}
/* #12 (2.2): per-org logo image slot (replaces the KIND wordmark when an org has
   set a logo URL). Capped height to fit the header; width auto-scales. */
.kind-header__logo-img {
  height: 28px;
  width: auto;
  max-width: 180px;
  object-fit: contain;
  display: block;
}

/* Role-aware nav lives in base.html; this is its styling. Pill links, the active
   one fills with the accent wash. The nav grows to fill the space between the
   wordmark (left) and the user menu (right) like kind.app's bar. */
.kind-nav { display: flex; gap: var(--kind-space-1); flex: 1; flex-wrap: wrap; align-items: center; }
.kind-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;           /* WCAG 2.5.5 touch target (older patient surface) */
  color: var(--kind-color-text);
  text-decoration: none;
  padding: var(--kind-space-2) var(--kind-space-3);
  border-radius: var(--kind-radius-pill);
  font-weight: 500;
  line-height: 1.2;
  white-space: nowrap;
}
.kind-nav a:hover { background: var(--kind-color-surface-muted); }
.kind-nav a[aria-current="page"] {
  background: var(--kind-color-accent-bg);
  color: var(--kind-color-accent);
  font-weight: 700;
}

/* 2.1 UX pivot D5: pending-count badge on the "Formulär" nav item. The number
   is decorative (aria-hidden); the count is announced via a visually-hidden
   span next to it, so a screen reader hears "Formulär, 2 formulär att fylla i".
   The pill uses the accent fill with white text (>=4.5:1, --kind-color-accent
   is 5.34:1 on white, inverted here as white-on-accent which is the same ratio).
   Non-text contrast of the pill against the bar is >=3:1 (WCAG 1.4.11). */
.kind-nav__badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.5rem;
  height: 1.5rem;
  margin-left: var(--kind-space-2);
  padding: 0 0.4rem;
  border-radius: var(--kind-radius-pill);
  background: var(--kind-color-accent);
  color: var(--kind-color-text-on-accent);
  font-size: 0.8125rem;
  font-weight: 700;
  line-height: 1;
}

/* 2.1 UX pivot D2: the "Mer" secondary menu. A native <details> disclosure so
   it is keyboard-reachable + works with NO JavaScript (the panel is just
   open/closed markup). The panel floats over content on wide screens and stacks
   inline on narrow ones (it is in normal flow there, no clipping). */
.kind-nav__more { position: relative; }
.kind-nav__more-toggle {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: var(--kind-space-2) var(--kind-space-3);
  border-radius: var(--kind-radius-pill);
  color: var(--kind-color-text);
  font-weight: 500;
  line-height: 1.2;
  cursor: pointer;
  list-style: none;            /* hide the default disclosure triangle */
  white-space: nowrap;
}
.kind-nav__more-toggle::-webkit-details-marker { display: none; }
.kind-nav__more-toggle::after {
  content: "";
  width: 0.5rem;
  height: 0.5rem;
  margin-left: 0.4rem;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translateY(-1px);
}
.kind-nav__more[open] > .kind-nav__more-toggle::after {
  transform: rotate(-135deg) translateY(1px);
}
.kind-nav__more-toggle:hover { background: var(--kind-color-surface-muted); }
.kind-nav__more-toggle:focus-visible {
  outline: var(--kind-focus-ring);
  outline-offset: 2px;
}
.kind-nav__more-panel {
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-1);
}
/* On wide screens the panel floats so it does not push the bar height. On
   narrow screens (the patient surface skews narrow + high-zoom) it stacks in
   normal flow with a full-width hairline card so nothing is clipped offscreen. */
@media (min-width: 720px) {
  .kind-nav__more-panel {
    position: absolute;
    top: calc(100% + var(--kind-space-1));
    right: 0;
    min-width: 12rem;
    padding: var(--kind-space-2);
    background: var(--kind-color-surface);
    border: 1px solid var(--kind-color-border-soft);
    border-radius: var(--kind-radius);
    box-shadow: var(--kind-shadow-md);
    z-index: 20;
  }
}
@media (max-width: 719.98px) {
  .kind-nav__more { width: 100%; }
  .kind-nav__more-panel {
    margin-top: var(--kind-space-1);
    padding-left: var(--kind-space-3);
  }
}

/* Clustered clinician nav (C1, 2026-06-24). The admin bar groups its
   low-frequency + content items into two labelled <details> disclosures
   ("Bibliotek", "Mer") that reuse the .kind-nav__more pattern above. The links
   INSIDE a disclosure panel are styled like the primary pill links so the bar
   reads as one consistent surface: same 44px target, pill radius, hover wash and
   accent active-state. A label that contains the active page renders with an
   accent-tinted summary so the user can see which group holds the current item
   even before they open it. */
.kind-nav__group > .kind-nav__more-panel a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;            /* WCAG 2.5.5 touch target */
  color: var(--kind-color-text);
  text-decoration: none;
  padding: var(--kind-space-2) var(--kind-space-3);
  border-radius: var(--kind-radius-pill);
  font-weight: 500;
  line-height: 1.2;
  white-space: nowrap;
}
.kind-nav__group > .kind-nav__more-panel a:hover {
  background: var(--kind-color-surface-muted);
}
.kind-nav__group > .kind-nav__more-panel a[aria-current="page"] {
  background: var(--kind-color-accent-bg);
  color: var(--kind-color-accent);
  font-weight: 700;
}
/* When the active page lives inside a group, tint the (closed-or-open) summary so
   the active cluster is discoverable. Uses :has() where supported; the disclosure
   also opens via the `open` attribute in markup, so this is purely an extra cue
   and degrades gracefully where :has() is absent. */
.kind-nav__group[open] > .kind-nav__more-toggle,
.kind-nav__group:has(a[aria-current="page"]) > .kind-nav__more-toggle {
  color: var(--kind-color-accent);
  font-weight: 700;
}

/* ============ #73: kompakt admin-sitechrome vid smal viewport ============
 *
 * qa (deploy-verify d9a037f punkt 3 + a11y-svep K1a, 2026-07-12): vid 320px
 * radbryts admins huvudnav till en VERTIKAL lista och den sticky headern
 * blaser upp till ~445px; vid 320x568 ligger den zonade chattloggens hela
 * fonster under headerbandet (fokuserade tradelement 10/10 provpunkter
 * SITEHEADER = WCAG 2.4.11 Focus Not Obscured AA-miss), och mushjul over
 * headern kedjar till sidscroll.
 *
 * Fix (CSS-only, ingen ny JS, CSP-oberoerd): under 900px (samma brytpunkt
 * som adminlayoutens egen stackning: .kind-arbetsvy + .kind-chatt-layout i
 * kind_admin.css) kollapsar huvudnaven till EN horisontellt skrollbar
 * pillerrad, ett etablerat monster for smala verktygsfalt (scrollable tabs).
 * Tangentbord fungerar utan extra kod: lankarna ar vanliga tabbables och
 * browsern skrollar den fokuserade pillen synlig i skrollporten (2.1.1);
 * padding-block ger fokusringen (3px + 2px offset) plats INUTI skrollporten
 * sa den inte klipps vertikalt (2.4.7).
 *
 * Reglerna bor i kind.css (inte kind_admin.css) darfor att sitechromen ar
 * BAS-krom: ett par admin-sidor (t.ex. verksamheter.html) lankar inte
 * kind_admin.css men renderar samma nav. Allt ar scopat pa .kind-body--admin
 * sa patient/publika ytor ar oberorda (patienten har ingen toppnav alls).
 *
 * Berakning 320px (footprint fore/efter): fore = ~445px uppmatt. Efter =
 * padding-block 2x8 + rad 1 (logga 38px, men 44px-golvet fran Logga
 * ut-knappen + Aa-triggern dominerar) 44 + row-gap 8 + navrad (44px-pill +
 * 2x6 ringmarginal) 56 + border 1 = ~125px, -72%. Pinnad av
 * tests/test_admin_compact_nav_css.py; qa:s geometriska deploy-verifiering
 * (elementFromPoint + oforcerade klick per #72-disciplinen) ar den
 * stangande evidensen, dessa rendertester bevisar INTE geometri. */
@media (max-width: 900px) {
  /* Radrytm: tva deterministiska rader. Blockpadding + row-gap dras ner ett
     steg sa den sticky footprinten haller budgeten ovan.

     ---- ISSUE #110 (2.2), RADRAKNINGEN VAR FEL -------------------------------
     Kommentaren har sa "tva deterministiska rader (rad 1 = logga +
     anvandarmeny + Aa, rad 2 = navskrollaren)". Uppmatt pa deployen 2026-08-04
     vid 320x664 renderade blocket TRE rader: logga y=8..47, nav y=55..111,
     anvandarmeny y=119..172, alltsa 181px normal skala och 251px vid xxlarge.
     Orsaken ar `flex: 1 1 100%` pa naven nedan: en flexrad som fyller hela
     bredden bryter raden BADE fore och efter sig, sa anvandarmenyn (som ligger
     EFTER naven i DOM) trycktes ned till en tredje rad. Kommentaren beskrev
     avsikten, inte utfallet. Kostnaden bars av VARJE vardgivaryta, eftersom
     sidhuvudet ar delat krom.

     VARFOR INTE `order`. Att lyfta anvandarmenyn upp till rad 1 med `order`
     hade gett tva rader, men da avviker den visuella ordningen fran DOM- och
     fokusordningen (WCAG 2.2 AA SC 2.4.3 Focus Order, och SC 1.3.2 Meaningful
     Sequence). Samma invandning galler explicit grid-placering som flyttar ett
     element forbi ett annat.

     LOSNINGEN: ett tvakolumnsrutnat med AUTOPLACERING, alltsa placering i
     DOM-ordning. Adminsidhuvudet har exakt tre barn (logga, nav,
     anvandarmeny; Aa-triggern renderas inte pa den har portalen,
     `a11y_enabled` ar falsk under templates/admin/, uppmatt), sa autoflodet
     ger logga (1,1), nav (1,2), anvandarmeny (2,1). Last vansterifran och
     uppifran ar det EXAKT DOM-ordningen, alltsa ingen omkastning och ingen
     2.4.3-fraga: rutnatet BRYTER raden, det FLYTTAR ingenting.

     `:not(:has(.kind-workspace-switch))`: multi-org-vaxlaren ar ett FJARDE
     barn mellan loggan och naven, och med den i rutnatet hamnar naven i den
     smala forsta kolumnen. Den ytan behaller darfor dagens flexbeteende
     (tre rader). `:has()` finns redan i den har filen (.kind-nav__group), och
     en webblasare utan stod gor hela selektorn ogiltig, alltsa exakt dagens
     layout. Degraderingen ar tyst och saker at ratt hall.

     UPPMATT EFTER (samma deploy-fixtur, 320x664): 181 -> 134px vid normal
     skala och 251 -> 181px vid xxlarge. Talen star i tests/
     test_admin_compact_nav_css.py och i grindens utdata (e2e/
     matt5-chattgrind.mjs rapporterar headerhojd per matpunkt). */
  .kind-body--admin .kind-header__inner {
    padding-top: var(--kind-space-2);
    padding-bottom: var(--kind-space-2);
    row-gap: var(--kind-space-2);
  }
  .kind-body--admin .kind-header__inner:not(:has(.kind-workspace-switch)) {
    display: grid;
    /* Kolumn 1 sizear till loggan, kolumn 2 tar resten och far krympa till
       noll sa navens egen skrollport tar over vid trangsel. */
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    column-gap: var(--kind-space-3);
  }
  /* Anvandarmenyn spanner HELA rad 2 i stallet for att sta i kolumn 1.
     Skalet ar bredd, inte estetik: en `auto`-kolumn sizear till max-content av
     ALLA sina objekt, sa "Logga ut" (~175px vid xxlarge) drog kolumn 1 bred och
     lamnade navskrollaren 85px av 288 (uppmatt 2026-08-04 vid 320 xxlarge). Med
     spannet sizear kolumn 1 bara till ordmarket och navporten blir ~200px.

     Detta ar INTE en omflyttning: menyn ar sist i DOM och ligger kvar sist
     visuellt, den blir bara bredare. Fokusordningen ar orord (SC 2.4.3), och
     `grid-column: 1 / -1` ar det ENDA placeringsvarde testet slapper igenom,
     just for att ett spann inte kan passera nagot annat element. */
  .kind-body--admin .kind-header__inner:not(:has(.kind-workspace-switch)) .kind-user-menu {
    grid-column: 1 / -1;
  }
  /* ===== ISSUE #157 (2.2): RUTNATET RAKNADE MED TRE BARN, DET ARVER FYRA =====
   *
   * Kommentaren ovan skriver ut sin egen premiss: "Adminsidhuvudet har exakt
   * tre barn (logga, nav, anvandarmeny; Aa-triggern renderas inte pa den har
   * portalen, `a11y_enabled` ar falsk under templates/admin/, uppmatt)".
   *
   * Den premissen foll med #142, driftsatt 2026-08-09. `base.html` satter
   * numera `a11y_surface = (a11y_enabled|trim) or ('kind-body--admin' in
   * _body_class)`, alltsa renderas Aa-triggern pa VARJE vardgivaryta. Med ett
   * fjarde barn i ett tvakolumnsrutnat lagger autoflodet den i en EGEN TREDJE
   * RAD, och den raden bars av allt delat vardgivarkrom utan att nagon matte
   * den.
   *
   * UPPMATT PA 8834621, /admin/arbetsvy vid 320x664, tyngsta rimliga
   * tillstandet (e2e/dokskroll-matning/kromsbudget-fore.json):
   *
   *     skala      vaddering  rad1 nav  gap x2  rad2 anv  rad3 Aa  kant  SUMMA
   *     normal        16        56       16      53,19      44      1   186,19
   *     large         18        56       18      59,59      44      1   196,59
   *     xlarge        20        56       20      66,00      44      1   207,00
   *     xxlarge       24        64,80    24      78,80      49,63   1   242,23
   *
   * Rad 3 plus dess radgap kostar alltsa 52,00 / 53,00 / 54,00 / 61,63 px.
   *
   * ATGARDEN: en TREDJE KOLUMN, sa Aa-triggern delar rad med anvandarmenyn i
   * stallet for att aga en egen. Bredden ar gratis, uppmatt och inte antagen:
   * kolumn 1 sizear till LOGGANS max-content (84,02 vid 320 xxlarge) och
   * Aa-triggerns egen max-content ar 66,83, alltsa har triggern aldrig varit
   * det som satte kolumn 1. Naven spanner 2/-1 och behaller darfor exakt sin
   * nuvarande port (169,98px vid 320 xxlarge), och anvandarmenyn spanner 1/-2
   * och far 187,17px mot sitt max-content-krav 169,31, alltsa bryter den inte
   * till en extra intern rad.
   *
   * ORDNINGEN AR OFORANDRAD, och det ar hela poangen med placeringsvardena
   * nedan. Ingen `grid-row` och ingen `grid-area`: autoplaceringens markor ger
   * logga (1,1), nav (1, 2-3), anvandarmeny (2, 1-2), Aa (2,3), alltsa last
   * vansterifran och uppifran EXAKT DOM-ordningen. SC 2.4.3 och SC 1.3.2 rors
   * inte. Spannen `2 / -1` och `1 / -2` ar valda just for att de inte kan
   * flytta ett element FORBI ett annat, de gor det bara bredare eller smalare.
   * Geometrin bevisas i webblasare av e2e/kromsbudget-grind.mjs, som laser
   * lasordningen ur de renderade rektanglarna; stilarkstestet nedan kan bara
   * pinna deklarationerna.
   *
   * `.kind-a11y-ready` I SELEKTORN AR LOAD-BEARING. Utan JS ar triggern
   * `display: none` (regeln vid .kind-a11y-trigger), och ett dolt barn far
   * ingen cell. Kolumn 3 hade da blivit noll bred men rutnatets `column-gap`
   * hade anda tagits ut, alltsa 18px av navets port vid xxlarge for en tom
   * kolumn. Kroppsklassen sats av samma JS som visar triggern, sa
   * tre-kolumnsformen galler exakt nar det finns ett fjarde barn att placera.
   */
  .kind-a11y-ready.kind-body--admin .kind-header__inner:not(:has(.kind-workspace-switch)) {
    grid-template-columns: auto minmax(0, 1fr) auto;
  }
  .kind-a11y-ready.kind-body--admin .kind-header__inner:not(:has(.kind-workspace-switch)) .kind-nav {
    grid-column: 2 / -1;
  }
  .kind-a11y-ready.kind-body--admin .kind-header__inner:not(:has(.kind-workspace-switch)) .kind-user-menu {
    grid-column: 1 / -2;
  }
  /* ISSUE #157, TERM 2: navlankens vaddering OVER traffytegolvet.
   *
   * Fragan stalls per term, inte per total. `.kind-nav a` och
   * `.kind-nav__more-toggle` bar `min-height: 44px` (WCAG 2.2 SC 2.5.8 anger
   * traffytor i CSS-PIXLAR, alltsa SKALAR DET GOLVET INTE) plus en vaddering
   * i `--kind-space-2` som SKALAR med rotens font-size. Lankens hojd ar
   * darfor `max(44, linjebox x s + vaddering x s)` = `max(44, 35,2s)`:
   *
   *     normal   s=1,000   max(44; 35,20) = 44      golvet binder
   *     large    s=1,125   max(44; 39,60) = 44      golvet binder
   *     xlarge   s=1,250   max(44; 44,00) = 44      exakt jamnt
   *     xxlarge  s=1,500   max(44; 52,80) = 52,80   vadderingen binder
   *
   * Vid xxlarge betalar alltsa raden 8,80px for vaddering ovanpa ett golv som
   * redan ar uppfyllt. Med `--kind-space-1` blir uttrycket `max(44; 27,2s)`,
   * som ger 44 vid SAMTLIGA fyra skalor, alltsa noll andring under xxlarge och
   * -8,80px dar.
   *
   * TRAFFYTAN ROR SIG INTE: `min-height: 44px` star kvar och lanken ar
   * `inline-flex`, sa boxen ar fortsatt 44px hog vid varje skala och
   * bakgrundspillret ser likadant ut. Det som krymper ar innehallslaadan, och
   * bara i det lage dar den var storre an golvet. */
  .kind-body--admin .kind-nav a,
  .kind-body--admin .kind-nav__more-toggle {
    padding-block: var(--kind-space-1);
  }
  /* ISSUE #157, TERM 3: SAMMA MEKANISM, ANDRA BARAREN.
   *
   * Rad 2 i rutnatet sizear till utloggningsknappen, som ar en `.kind-btn`
   * med `min-height: 44px` och `padding: var(--kind-space-3) var(--kind-space-5)`.
   * Alltsa exakt samma form som navlanken ovan: ett traffytegolv i CSS-pixlar
   * som INTE skalar, plus en vaddering som gor det.
   *
   *     radhojd 1,7 x 1rem = 27,2s
   *     vaddering 2 x --kind-space-3 = 24s
   *     kant 2px, SKALAR INTE
   *     rad 2 = max(44; 51,2s + 2)
   *
   *     normal   53,19   large 59,59   xlarge 66,00   xxlarge 78,80
   *
   * Uppmatt pa 8834621 vid 320x664: 53,19 / 59,59 / 66,00 / 78,80, alltsa
   * modellen exakt. Golvet binder aldrig, vadderingen binder alltid.
   *
   * Med `--kind-space-1` blir uttrycket `max(44; 35,2s + 2)`:
   *
   *     normal   44,00   large 44,00   xlarge 46,00   xxlarge 54,80
   *
   * alltsa -9,19 / -15,59 / -20,00 / -24,00 px. Traffytan ar ORORD, `min-height:
   * 44px` star kvar och knappen ar `inline-flex`, och `padding-inline` rors inte
   * alls, sa knappens BREDD (169,31px max-content vid 320 xxlarge) och darmed
   * kolumnbredderna ar oforandrade.
   *
   * SKOPAT TILL SIDHUVUDETS ANVANDARMENY. `.kind-user-menu` finns bara i
   * sidhuvudet, sa ingen annan `.kind-btn` i produkten rors, och regeln ligger
   * inuti smalskarmsfragan sa desktop ar per konstruktion 0 diffar. */
  .kind-body--admin .kind-user-menu .kind-btn {
    padding-block: var(--kind-space-1);
  }
  /* ISSUE #157, TERM 4: ETT STAPELMELLANRUM MOT ETT OSYNLIGT SYSKON.
   *
   * Efter term 3 var utloggningsknappen 44px vid varje skala, men rad 2 mattes
   * till 52 / 53 / 54 / 56. Skillnaden ar EXAKT `--kind-space-2` per skala
   * (8 / 9 / 10 / 12), och den sitter som `margin-top` PA KNAPPEN.
   *
   * Kallan ar `.kind-stack-2`s `> * + *`-mellanrum. Formulárets forsta barn ar
   * Flask-WTF:s dolda CSRF-falt, som ar `display: none` och alltsa INTE
   * genererar nagon box, men det ar fortfarande ett SYSKONELEMENT, sa
   * `+`-kombinatorn traffar knappen. Mellanrummet skiljer knappen fran
   * ingenting.
   *
   * Regeln nedan namnger just den situationen i stallet for att nolla stapeln
   * generellt: mellanrummet tas bort NAR det narmast foregaende syskonet ar ett
   * dolt falt. Skopat till sidhuvudets anvandarmeny och till smalskarmsfragan,
   * sa desktop ar 0 diffar och ingen annan `.kind-stack-2` i produkten rors.
   * (Att mellanrummet ar dott aven pa desktop ar bokfort som en oppen punkt,
   * inte tyst atgardad har.) */
  .kind-body--admin .kind-user-menu input[type="hidden"] + * {
    margin-top: 0;
  }
  /* Portaletiketten under ordmärket ("Vårdgivarportal") låg HÄR fram till #166.
     Den är nu OBETINGAD på vårdgivarytan, se blocket efter den här
     mediefrågan. Skälet står där, och det är samma skäl som lyfte ut
     navskrollaren i #110: den behövdes vid ALLA bredder, inte bara under
     900px. Regeln är borttagen härifrån och inte duplicerad, så det bara finns
     ETT ställe som beslutar saken (regel 27). */
  /* Naven blir en enradig horisontell skrollare i stallet for att radbrytas
     vertikalt. `flex: 1 1 100%` ar kvar som FALLBACK for de tva lagen som inte
     far rutnatet (multi-org-vaxlaren, och en webblasare utan `:has()`); i
     rutnatet ar deklarationen inert.
     SKROLLAREN SJALV (flex-wrap, overflow-x, overscroll-behavior,
     scroll-padding-inline, fokusringens padding) och disclosure-panelernas
     forankring LAG HAR till issue #110 (2.2) och ar nu OBETINGADE, se blocket
     efter den har mediefragan. Skalet: de behovdes vid ALLA bredder, inte bara
     under 900px, och den har mediefragan var sjalv brytpunkten som lamnade
     spannet 901 till 1150px trasigt. Kvar har ar bara det som ar GENUINT
     smalskarmsspecifikt: att naven far en EGEN RAD. */
  .kind-body--admin .kind-nav {
    flex: 1 1 100%;
  }
  /* Rad 1-kompaktion: det passiva klinikmärket låg HÄR fram till #166 och är
     nu OBETINGAT på vårdgivarytan, se blocket efter den här mediefrågan.
     Villkoret för döljandet är oförändrat och står kvar där (V1: aktiv
     mottagning finns som "Mottagning"-raden på /admin/profil, pinnad i
     tests/test_admin_profil_render.py, och multi-org behåller
     workspace-switchern synlig). */
  /* Aa-knappens synliga etikett doljs numera OBETINGAT for vardgivarytan, se
     #142-blocket langre ned i den har filen (intill .kind-a11y-trigger). Den
     smalskarmsregel som lag har var en delmangd av den och ar borttagen sa det
     inte finns tva stallen som beslutar samma sak (regel 27). */
  /* 2.4.11-reserverna foljer den kompakta headern: bas-reserven i
     kind_admin.css (5rem) ar kalibrerad mot desktop-headerns ~78px och
     racker inte har, och patientfilens fokusregel for .kind-chat__log-list
     (scroll-margin-top: var(--kind-header-height), ~69px) vinner
     specificitetsduellen pa de zonade admin-ytorna vid smal bredd dar
     kolumnen ar statisk (se kind_admin.css #73-blocket). Bada tokens satts
     darfor till SAMMA varde har, intill kompaktionen de maste folja.

     Selektorn ar body.kind-body--admin, INTE bara .kind-body--admin
     (reviewer P2, 2026-07-12): kind_admin.css:s oscopade 5rem-bas star pa
     `.kind-body--admin` med samma specificitet (0,1,0) och laddas EFTER
     denna fil (base.html: kind.css fore per_domain_css-blocket), och en
     @media-omslutning paverkar inte kaskadvikten, sa en oprefixad bump har
     FORLORAR pa kalladsordning och lamnar [tabindex]-grenen i basregeln pa
     5rem = 80px < 125px-headern (latent tyst 2.4.11-regression for nasta
     roving-tabindex-monster, trots att Tab-vagen raddas av
     --kind-header-height + patientfilens focus-visible-regel).
     Elementprefixet ger (0,1,1) som vinner oavsett filordning; den
     effektiva vinnaren pinnas i tests/test_admin_compact_nav_css.py
     tillsammans med att kind_admin.css har exakt EN oscopad basdeklaration.

     Vardet: 10rem = 160px >= 125px-budgeten ovan + 35px buffert (tacker en
     klassisk scrollbar-gutter och det mesta av en oforutsedd radbrytning;
     en multiorg-switcher som radbryter rad 1 vid 320px kan ge partiell
     skymning, vilket 2.4.11 Minimum tillater). Overskottet ar ofarligt: i
     loggens interna skrollport ger det bara en lagre viloplats for
     Shift+Tab-fokus (160 + 44 < 256px-golvet for loggfonstret). */
  body.kind-body--admin {
    --kind-admin-chat-focus-reserve: 10rem;
    --kind-header-height: 10rem;
  }
}
/* ==== ISSUE #110 (2.2): navskrollaren galler VID ALLA BREDDER, inte <=900px ===
 *
 * `825b819` fixade det RAPPORTERADE felet, tre rader vid <=900px, och lamnade
 * ett storre kvar. Uppmatt pa deployen 2026-08-05
 * (docs/qa/formatning-109-110-2026-08-05.md):
 *
 *     bredd   normal      xxlarge
 *      1440   78px / 1    149px / 3
 *      1280   78px / 1    207px / 3
 *      1150  117px / 2    266px / 5
 *      1024  117px / 2    443px / 7      <- varsta punkten i hela svepet
 *       950  117px / 2    251px / 4
 *       901  165px / 3    251px / 4
 *       900  134px / 2    181px / 2      <- fixens brytpunkt
 *
 * Brytpunkten ar EXAKT 901px, alltsa `max-width: 900px` sjalv. Riktningen ar
 * den OMVANDA mot issuetexten: smalt ar gront, spannet 901 till 1150 ar rott.
 * 443px header vid 1024 och xxlarge ar 2,4 ganger den mobildefekt issuen
 * rapporterade, och den ar 55 procent av en 800px hog viewport innan en enda
 * patientrad syns. En vakt som bara asserterar <=900px kan aldrig bli rod pa
 * det (regel 49a), vilket ar exakt hur spannet kunde sta oadresserat.
 *
 * ORSAKEN ar att naven over 900px ar `flex-wrap: wrap` med `flex: 1`, alltsa
 * OBEGRANSAD vertikal tillvaxt: nar pillrarna inte far plats radbryter de
 * inuti naven och headern vaxer med dem. Vid xxlarge ar varje pill ~50 procent
 * bredare, sa spannet 901 till 1150 ar precis dar naven inte langre far plats
 * pa en rad men annu inte fatt den smala layoutens skrollare.
 *
 * FIXEN ar att LYFTA UT skrollaren ur mediefragan i stallet for att flytta
 * brytpunkten. En hojd brytpunkt (t.ex. 1150px) hade bara flyttat kanten och
 * lamnat 1280 xxlarge pa 207px och 1440 xxlarge pa 149px, alltsa samma defekt
 * en bit bort; svepet visar att tillvaxten INTE ar ett smalskarmsfenomen utan
 * en funktion av textskala gange antal navposter. En enda regim for naven,
 * bunden overallt, ar darfor bade enklare och starkare. Vid bredder dar naven
 * REDAN far plats andrar regeln ingenting (1440 normal star kvar pa en rad),
 * sa blast radius ar begransad till de trasiga tillstanden.
 *
 * KOMPROMISSEN, redovisad: `overflow-x: auto` gor naven till en skrollport
 * aven pa desktop. Pa en plattform med klassiska (icke-overlay) rullningslister
 * kan en horisontell list synas nar innehallet spiller over, alltsa exakt i de
 * lagen alternativet var en 443px header. Tangentbordet ar oforandrat: lankarna
 * ar vanliga tabbables och browsern rullar den fokuserade pillen synlig
 * (SC 2.1.1), `padding: 6px` haller fokusringen (3px + 2px offset) INUTI
 * skrollporten sa den inte klipps vertikalt (SC 2.4.7), och
 * `scroll-padding-inline` haller den fri fran kanten. Ingen `order`, ingen
 * omflyttning, sa visuell ordning ar fortsatt fokusordning (SC 2.4.3, 1.3.2).
 *
 * Disclosure-panelerna maste folja med ut, annars klipps de av skrollporten:
 * `position: static` pa wrappern flyttar containing block till narmsta
 * positionerade forfader, `.kind-header` (position: sticky ar positionerad),
 * sa panelen ritas UNDER headern i stallet for inuti navens overflow. Det ar
 * samma resonemang som redan galler under 900px, nu bara obetingat.
 * Kravforutsattning: `.kind-header` behaller `position: sticky`, en premiss
 * som pinnas i tests/test_admin_compact_nav_css.py. */
.kind-body--admin .kind-nav {
  min-width: 0;
  flex-wrap: nowrap;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-padding-inline: var(--kind-space-3);
  /* 6px = fokusringens 3px + 2px offset + 1px marginal; literal för att ringen
     exakt ska rymmas i skrollporten (a11y-driven konstant).
     #166: literalen gällde bara BLOCKAXELN. Inline-axeln bar
     `var(--kind-space-1)` = 4px, alltså 1px UNDER ringens 5px, och uppmätt med
     riktiga tabbtryck vid 1000px klipptes ringen på 3 av 7 toppnivåposter
     (Patienter 4px fritt, Kollegor 1,5px, Mer 4,2px). Border-boxen drogs in på
     7 av 7, så en mätning som bara läser elementets rect ser ingenting.
     Samma härledda 6:a på båda axlar nu; kostnaden är 4px av portens
     innehållsbredd och noll höjd. */
  padding: 6px;
  /* #166-ringmarginal */
}
/* ==== ISSUE #166 (2.2): KOMPAKTIONEN LÅG I FEL BAND ========================
 *
 * `.kind-header__inner` är en flexrad där navet är den UTSEDDA krympytan
 * (`.kind-nav { flex: 1 }`, alltså basis 0: navet tar det som blir över). Följden
 * är att varje passivt element i raden betalas av NAVIGATIONEN, och att
 * användarmenyn aldrig krymper, eftersom behållaren aldrig hamnar i underskott.
 *
 * Kompaktionen som löser det FANNS redan, men låg inne i
 * `@media (max-width: 900px)`, alltså i exakt det spann där navet redan fått en
 * egen rad och inte behöver hjälpen. Det är samma miss som #110-kommentaren
 * ovan själv beskriver: skrollaren lyftes ut ur mediefrågan, kompaktionen
 * lämnades kvar (regel 27 korollarium 2, svepet nådde inte hela vägen).
 *
 * VARFÖR OBETINGAT OCH INTE "en högre brytpunkt". Issuen föreslog att flytta
 * brytpunkten till strax över 1280px. Mätningen underkände den formen, och
 * skälet är ett tal ingen tidigare läst:
 *
 *   `.kind-header__inner` har `max-width: var(--kind-container-max)`, vilket är
 *   1280px vid normal textskala. Headerns innehåll blir alltså ALDRIG bredare
 *   än så, hur brett fönstret än är.
 *
 * Vid det taket, med seed-namnet "Vårdcentralen Liljeholmen AB", fyller navets
 * innehåll sin port EXAKT: 643,5 av 643,5px, alltså noll marginal. Uppmätt på
 * bas bbce2c3 (`e2e/diag-nav166-breddfordelning.mjs`):
 *
 *     namn         1440   1280   1200   1100   1000    900
 *     seed            0      0     70    170    270      0
 *     52 tecken     173    173    253    353    453      0
 *
 * Ett 52-teckens kliniknamn är alltså trasigt vid SAMTLIGA desktopbredder,
 * inklusive 1440, för att containertaket gör bredare fönster verkningslösa. En
 * brytpunkt satt "strax över 1280" hade varit grön på seed-datat och röd hos
 * varje klinik med ett längre namn, alltså precis den fix som löser den yta som
 * råkade rapporteras (regel 48 följdkrav b). Det finns ingen bredd över vilken
 * märket bevisligen får plats, så det finns ingen ärlig brytpunkt att sätta.
 *
 * UPPMÄTT EFTER, samma substrat, alla tre namntillstånd: 0 överflöd och 7 av 7
 * hela poster vid 1440, 1280, 1200, 1150, 1100, 1050, 1000 och 950. Vid
 * xxlarge sjunker överflödet vid 1000 från 845 till 360 och når 0 från 1366.
 *
 * VILLKORET FÖR DÖLJANDET ÄR OFÖRÄNDRAT, bara bandet är det inte. Båda
 * elementen är ren wayfinding utan interaktion:
 *   - Aktiv mottagning finns som "Mottagning"-raden under Uppgifter på
 *     /admin/profil (villkor V1, ux-review
 *     docs/reviews/ux-73-kompaktnav-2026-07-12.md, GODKÄNN-MED-VILLKOR).
 *     Döljandet VILAR på att den raden finns kvar, pinnad i
 *     tests/test_admin_profil_render.py.
 *   - För multi-org bärs den aktiva mottagningen dessutom av
 *     `.kind-workspace-switch`, som BEHÅLLS SYNLIG (den är en affordance, inte
 *     wayfinding).
 *   - Portaletikettens information bärs av länkens tillgängliga namn
 *     ("KIND, till startsidan") och av sidans <title> ("... KIND
 *     Vårdgivarportal"), så AT förlorar ingenting.
 *
 * Patientsidhuvudet är en egen gren (`.kind-header__inner--patient`) och rörs
 * inte av någon av selektorerna.
 *
 * ÖPPEN PUNKT, redovisad och inte tyst: att märket nu är borta ÄVEN på en bred
 * skärm där det bevisligen fick plats med seed-namnet är en UX-avvägning, inte
 * en mätfråga. Den ligger som `[needs: ux]`. Vill man ha tillbaka det på
 * desktop måste det bäras av något som är okänsligt för namnlängd, alltså inte
 * av en breddbrytpunkt.
 * ======================================================================== */
/* #166: KOMPAKTIONEN ÄR OBETINGAD PÅ VÅRDGIVARYTAN */
.kind-body--admin .kind-header__logo-sub,
.kind-body--admin .kind-admin-context {
  display: none;
}
/* #166: slut på den obetingade kompaktionen */
/* ===========================================================================
 * SKROLLEDTRAD PA VAGRATA SKROLLPORTAR (#140, #145 visuella halva)
 *
 * EN regel, TVA selektorer, for att defekten bor pa TVA DELADE NODER och inte
 * pa de ytor som rakade rapporteras (regel 27 korollarium 2). Svepet 2026-08-08
 * matte tio vagrata skrollportar over sex vardgivarytor vid 390px, och de foll
 * ut pa exakt tva noder: NAV.kind-nav overflodade pa 6 av 6 ytor, och
 * DIV.kind-table-wrap pa 4 av 6. En ledtrad byggd bara pa naven hade lamnat
 * fyra tabellytor trasiga med identisk mekanism. En TREDJE vagrat skrollport
 * som tillkommer senare ansluter genom att laggas till i selektorlistan HAR,
 * inte genom att kopiera gradientstacken (regel 51: artefakten ska bara
 * beslutet).
 *
 * DEFEKTEN VAR UPPTACKBARHET, INTE NABARHET. 70 oforcerade traffester
 * (2 roller x 5 bredder x 7 poster) gav 0 misslyckanden, alla poster ar
 * nabara. Testarrapportens matvarde (dokumentbredden) ar blint for en nastlad
 * skrollport PER KONSTRUKTION, eftersom overscroll-behavior-x: contain ar just
 * det som hindrar navets skroll fran att kedjas till dokumentet. Darfor byggs
 * INGEN hamburgermeny och `contain` ror vi inte: det som saknades var en
 * SYNLIG ledtrad om att raden fortsatter. I 419 616 byte driftsatt CSS fanns
 * 0 traffar pa ::-webkit-scrollbar, scrollbar-width, scrollbar-color,
 * mask-image eller nagon scroll-shadow-variant, och rullningslistens spar
 * upptog 0px (overlay-listor malar ingenting forran anvandaren redan skrollar,
 * alltsa precis nar ledtraden inte langre behovs).
 *
 * VARFOR LAGRADE BAKGRUNDER OCH INTE EN PERMANENT RULLNINGSLIST. Alternativ 2
 * i #140 (`scrollbar-width: thin` plus `scrollbar-color`) LEVERERAR INTE
 * "synlig vid vila" pa de plattformar det galler: med overlay-listor forblir
 * listen osynlig tills man skrollar, och det verktyg som DOCK tvingar fram en
 * klassisk list (::-webkit-scrollbar) ar icke-standard, saknas i Firefox och
 * TAR LAYOUTUTRYMME, alltsa hojdandring pa en sticky header med egna
 * pixelbudgetar. Den har losningen ar layoutneutral (bara bakgrunder) och
 * pekar-neutral (bakgrunder tar aldrig emot klick), sa den uppmatta
 * nabarheten pa 7/7 kan inte forsamras av konstruktion. Utan JavaScript
 * fungerar den likadant.
 *
 * MEKANIKEN, fyra lager plus en bottenfarg:
 *   1-2 TACKARNA ar ogenomskinliga och ligger `local`, alltsa de SKROLLAR MED
 *       innehallet. Vid vila ligger starttackaren over startledtraden och
 *       doljer den, for det finns inget mer at det hallet. Skrollar man bort
 *       glider tackaren ut ur porten och ledtraden framtrader.
 *   3-4 LEDTRADARNA ligger `scroll`, alltsa fastnitade vid porten. De ar
 *       darmed korrekta i BADA riktningar samtidigt och tal att man redan star
 *       vid ena anden.
 * Tackarna (22px) ar bredare an ledtradarna (20px) sa de doljer dem helt, med
 * 2px marginal mot delpixelavrundning. FOLJDEN, redovisad: en skrollport vars
 * overflod ar MINDRE an tackarbredden kan bara visa en DEL av ledtraden, och
 * vid nagra fa pixlars overflod ingen alls. Det ar konstruktionens upplosning
 * och inte en bugg att slappa en troskel for: vakten rapporterar de fallen
 * separat med sitt uppmatta overflod i stallet for att tiga om dem.
 * Bakgrunder malas BAKOM elementets eget innehall, sa varken tackare eller
 * ledtrad kan dolja en navlank eller en tabellcell.
 *
 * KONTRAST (SC 1.4.11). Ledtraden bar information om ett komponenttillstand,
 * sa den behover en del med minst 3:1. En ren toning har per definition ingen
 * sadan punkt, darfor de forsta 2px i --kind-color-border, som ar husets
 * FUNKTIONELLA kantfarg och redan dokumenterad som 3.34:1 mot vitt och 4.42:1
 * mot mork yta. Resten ar en mjuk toning som bar sjalva "innehallet
 * fortsatter"-kanslan. Tokens, inte literaler, sa mork- och
 * hogkontrastlagena foljer med automatiskt.
 * ======================================================================== */
.kind-body--admin .kind-nav,
.kind-body--admin .kind-table-wrap,
.kind-body--admin .kind-bars {
  /* Tackarna maste ha SAMMA farg som noden de ligger pa, annars syns de som en
     platta. Darfor en variabel och inte en literal: en skrollport med en annan
     yta ansluter genom att satta om den, se .kind-bars nedan. */
  --kind-cue-yta: var(--kind-color-surface);
  /* Ledtradens 2px-linje ar kontrastbararen (SC 1.4.11), sa den maste ha minst
     3:1 mot NODENS yta och inte mot vitt i allmanhet. Variabel av samma skal
     som ytan: en skrollport pa en annan bakgrund byter bada. */
  --kind-cue-linje: var(--kind-color-border);
  background:
    /* 1. tackare vid startkanten, skrollar med innehallet */
    linear-gradient(var(--kind-cue-yta), var(--kind-cue-yta)) left center / 22px 100% no-repeat local,
    /* 2. tackare vid slutkanten */
      linear-gradient(var(--kind-cue-yta), var(--kind-cue-yta)) right center / 22px 100% no-repeat local,
    /* 3. ledtrad vid startkanten, fastnitad vid porten */
      linear-gradient(
        to right,
        var(--kind-cue-linje) 0 2px,
        color-mix(in srgb, var(--kind-cue-linje) 32%, transparent) 2px,
        transparent 100%
      )
      left center / 20px 100% no-repeat scroll,
    /* 4. ledtrad vid slutkanten */
      linear-gradient(
        to left,
        var(--kind-cue-linje) 0 2px,
        color-mix(in srgb, var(--kind-cue-linje) 32%, transparent) 2px,
        transparent 100%
      )
      right center / 20px 100% no-repeat scroll,
    var(--kind-cue-yta);
}
/* Insiktsdiagrammet (/admin/analys, FEATURE_ANALYTICS_DASHBOARDS) ar den TREDJE
   vagrata skrollporten i vardgivarportalen. Den star inte i #140 eller #145,
   den foll ut av ett svep efter alla barare av mekanismen, och den ar live pa
   deployen (bada flaggorna PA, vilket syns pa att "Mer" har 11 poster). Att
   atgarda de tva rapporterade och lamna den hade varit exakt den miss #145
   handlar om.

   Egen yta, alltsa egen tackarfarg OCH egen linjefarg. --kind-color-border pa
   den nedtonade ytan mattes till 2.93:1 i den renderade bilden, alltsa UNDER
   SC 1.4.11:s 3:1, vilket ett CSS-narvarotest aldrig hade sett eftersom regeln
   var precis lika narvarande da. --kind-color-text-muted ar 4.62:1 mot muted
   enligt tokenens egen dokumentation (kind.css rad 93). */
.kind-body--admin .kind-bars {
  --kind-cue-yta: var(--kind-color-surface-muted);
  --kind-cue-linje: var(--kind-color-text-muted);
}
/* Pa papper finns ingen skroll att antyda, och kind_admin.css satter dessutom
   overflow: visible pa wrappen dar, sa ledtraden vore en ren felaktighet.
   Samma specificitet som regeln ovan, annars vinner den. */
@media print {
  .kind-body--admin .kind-nav,
  .kind-body--admin .kind-table-wrap,
  .kind-body--admin .kind-bars {
    background: none;
  }
}
.kind-body--admin .kind-nav__more {
  position: static;
  width: auto;
}
.kind-body--admin .kind-nav__more-panel {
  position: absolute;
  top: 100%;
  left: auto;
  right: var(--kind-space-2);
  margin-top: 0;
  min-width: 12rem;
  max-width: calc(100vw - 2 * var(--kind-space-2));
  /* Egen skrollport sa en lang grupp (Mer = upp till 9 poster for
     klinik-admin) aldrig vaxer forbi vecket pa en 568px-skarm; contain stoppar
     kedjning till sidan nar panelens egen skroll tar slut. */
  max-height: 60dvh;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--kind-space-2);
  background: var(--kind-color-surface);
  border: 1px solid var(--kind-color-border-soft);
  border-radius: var(--kind-radius);
  box-shadow: var(--kind-shadow-md);
  z-index: 30;
}
/* Over 900px ar sidhuvudets rad EN rad, och trycket fordelas genom KRYMPNING i
 * stallet for att radbrytas.
 *
 * Utan `nowrap` radbryter anvandarmenyn ned till rad tva sa fort loggan plus
 * menyn inte far plus bredvid varandra: uppmatt 2026-08-05 med ett
 * 52-teckens verksamhetsnamn blev det 205px i tva rader vid 901, 950 och 1024
 * vid xxlarge, alltsa over 900px-referensens 181. Skalet ar att en
 * flexbehallare bestammer radbrytning pa objektens HYPOTETISKA storlek
 * (flex-basis, alltsa innehallsbredden) INNAN nagon krympning sker. Sa lange
 * radbrytning ar tillgangligt tas den vagen, och ingen krympning hinner ske.
 *
 * Med `nowrap` blir krympning enda utvagen, och den landar i ratt ordning av
 * sig sjalv: naven har `flex: 1` med basis 0 och ar darmed den utsedda
 * krympytan, den gar till noll (och blir skrollare) innan nagot tryck alls nar
 * verksamhetsnamnet. Kvar okrympbart ar ordmarket och Logga ut-knappen,
 * tillsammans ~230px vid xxlarge, alltsa med god marginal inom 901px.
 *
 * INGEN ELLIPS PA VERKSAMHETSMARKET, och det ar ett matresultat och inte en
 * smaksak. Forsta forsoket kapade namnet med `max-width: 22ch`, vilket holl
 * varje hojdtak gront men kapade seed-namnet "Vardcentralen Liljeholmen AB"
 * vid SAMTLIGA bredder inklusive 1440 dar det finns gott om plats: ett
 * endimensionellt breddtak som flyttar felet fran tillvaxt till KLIPPNING i
 * stallet for att losa det (minne
 * `feedback-one-dimension-budget-moves-the-error`), synligt bara for att
 * avkortning mats som eget utfall. Andra forsoket var en efterfragestyrd ellips
 * (`min-width: 0` plus `text-overflow`), men med `nowrap` pa plats visade
 * mutationen `b2-utan-namntak` att den bar INGENTING: 145px med och 145px utan,
 * noll overskott bada vagarna. En mekanism som inte bar sitt utfall men kostar
 * information ska bort, inte skeppas, sa namnet star nu okapat.
 *
 * `min-width: 0` ar KVAR, och ar arligt redovisad som INERT i dag. Den ar
 * foljeslagaren till `nowrap`: ett flexobjekt vagrar som standard krympa under
 * sin min-content-storlek, sa nar innehallet inte KAN radbrytas gor `nowrap` om
 * radbrytningen till horisontellt overskott i stallet, alltsa samma fel flyttat
 * till en annan axel. Det ar uppmatt, inte befarat: mutationen
 * `b2-utan-menykrymp` gav 155px overskott vid 901 xxlarge, 106 vid 950 och 32
 * vid 1024 SA LANGE ellipsens `white-space: nowrap` gjorde markets min-content
 * till hela strangens bredd. Med ellipsen borta radbryter namnet, min-content
 * blir bara det bredaste ORDET, och mutationen ar gron aven pa det tyngsta
 * tillstand som gar att framkalla (ett 27-teckens enordsnamn,
 * "Rehabiliteringsmottagningen"). Deklarationen behalls anda, och skalet ar
 * asymmetrin i kostnad: ellipsen kostade SYNLIG information och gav noll, medan
 * den har kostar noll rendering i varje uppmatt tillstand och stanger ett
 * dokumenterat overflodeslage som `nowrap` sjalv oppnar. Skulle market nagon
 * gang bli obrytbart igen ar den skillnaden mellan en krympt rad och en
 * horisontell rullningslist.
 *
 * SCOPAD OVER 900px MED FLIT. Under 900px ar sidhuvudet ett rutnat (blocket
 * ovan) dar `flex-wrap` ar inert, MEN fallback-lagena (multi-org-vaxlaren, och
 * en webblasare utan `:has()`) ar fortfarande flex och far navens egen rad via
 * `flex: 1 1 100%`, vilket KRAVER wrap. En oscopad `nowrap` hade tyst brutit
 * just de tva lagen, alltsa de som redan ar undantagna och minst testade. */
@media (min-width: 900.02px) {
  .kind-body--admin .kind-header__inner {
    flex-wrap: nowrap;
  }
  .kind-body--admin .kind-user-menu,
  .kind-body--admin .kind-admin-context {
    min-width: 0;
  }
}

.kind-user-menu {
  display: flex;
  align-items: center;
  gap: var(--kind-space-3);
  color: var(--kind-color-text-muted);
  font-size: var(--kind-font-small);
}

.kind-main {
  flex: 1;
  width: 100%;
  max-width: var(--kind-container-max);
  margin: 0 auto;
  padding: var(--kind-space-5) var(--kind-space-4);
}
.kind-main:focus { outline: none; }

.kind-section { margin-bottom: var(--kind-space-6); }
/* Rubrikrad plus "Se alla X"-länk på samma rad. `flex-wrap: wrap` är INTE
   kosmetik utan den layoutdefekt som `hyphens: auto` maskerade fram till #158.
   Raden var `nowrap`, så dess min-content är SUMMAN av rubrikens och länkens,
   och avstavningen höll rubriken konstlat smal. När avstavningen togs bort
   sköt /patient/dashboard ut dokumentet 30px vid 320px och xxlarge textskala,
   och de två elementen utanför kanten var exakt "Se alla vårdresor" och "Se
   alla bokningar". Med `wrap` blir radens min-content MAX i stället för SUMMA,
   länken faller ned på egen rad när den inte får plats, och dokumentets
   sidledsöverskott är 0 vid varje mätpunkt i svepet. Att i stället backa
   avstavningsfixen hade löst höjdaxeln och lämnat breddaxeln trasig. */
.kind-section__title { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--kind-space-3); }

.kind-grid {
  display: grid;
  gap: var(--kind-space-4);
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}

/* kind.app-style calm LIGHT footer (muted surface, brand wordmark + tagline,
   legal line, entity copyright). Light over a dark footer for the demo per the
   spec (less contrast risk). */
.kind-footer {
  background: var(--kind-color-surface-muted);
  border-top: 1px solid var(--kind-color-border-soft);
  margin-top: auto;
}
.kind-footer__inner {
  max-width: var(--kind-container-max);
  margin: 0 auto;
  padding: var(--kind-space-6) var(--kind-space-4);
  color: var(--kind-color-text-muted);
  font-size: var(--kind-font-small);
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-3);
}
.kind-footer__brand { display: flex; align-items: baseline; gap: var(--kind-space-3); flex-wrap: wrap; }
.kind-footer__mark {
  font-family: var(--kind-font-serif);
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--kind-color-text);
}
/* .kind-footer__tagline: REGELN ÄR BORTTAGEN 2026-08-22 (#292). Sidfotens
   tagline finns inte längre i base.html, så selektorn hade ingen bärare. */
.kind-footer__legal { margin: 0; max-width: 60ch; }
.kind-footer__copy { margin: 0; color: var(--kind-color-text-muted); }
/* App-version string (C1, 2026-06-24): a small, muted support affordance. Uses
   the monospace stack so a version like 2.0.0-nordiccare-w22 is easy to read
   aloud to support. --kind-color-text-muted (#6b5d5a) is 5.25:1 on the footer
   surface (--kind-color-surface-muted), so it passes WCAG 1.4.3 AA as small text. */
.kind-footer__version {
  margin: 0;
  color: var(--kind-color-text-muted);
  font-family: var(--kind-font-mono, ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace);
  font-size: var(--kind-font-small);
}

/* ============ 5. Forms + buttons ============ */

.kind-form { display: flex; flex-direction: column; gap: var(--kind-space-4); }
.kind-form--narrow { max-width: var(--kind-container-narrow); }

/* Action row: primary + secondary actions sit side by side and wrap on narrow
   screens. Each button keeps its own 44px target (from .kind-btn). */
.kind-form__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--kind-space-3);
  align-items: center;
}

.kind-field { display: flex; flex-direction: column; gap: var(--kind-space-2); }
/* [hidden]-gard: `display: flex` ovan slar UA-lagrets `[hidden]{display:none}`.
   templates/admin/formular_form.html:247 renderar alternativlistan med `hidden`
   och kind_formular_builder.js vaxlar den pa fragetypen "flerval", alltsa var
   alternativfaltet synligt for VARJE fragetyp fore den har raden. */
.kind-field[hidden] { display: none; }
.kind-field__label {
  font-weight: 600;
  color: var(--kind-color-text);
  font-size: var(--kind-font-small);
}
.kind-field__help {
  font-size: var(--kind-font-small);
  color: var(--kind-color-text-muted);
}
.kind-field__error {
  font-size: var(--kind-font-small);
  color: var(--kind-color-error);
  font-weight: 600;
}
.kind-field__input,
.kind-field__textarea,
.kind-field__select {
  width: 100%;
  padding: var(--kind-space-3) var(--kind-space-4);
  background: var(--kind-color-surface);
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius);
  color: var(--kind-color-text);
  font: inherit;
  font-size: var(--kind-font-base);
  min-height: 44px;          /* WCAG 2.5.5 target size */
}
.kind-field__textarea { min-height: 8rem; resize: vertical; }
.kind-field__input[aria-invalid="true"],
.kind-field__textarea[aria-invalid="true"] {
  border-color: var(--kind-color-error);
  border-width: 2px;
}

.kind-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  min-width: 44px;
  padding: var(--kind-space-3) var(--kind-space-5);
  /* CP-05 (#90), brief §4.3 "Undvik stora kapslar som standardform". This is
     the product's DEFAULT button, so a 999px radius here made the capsule the
     standard form of every action on every surface. Measured 1011 pill-shaped
     elements at least 40px tall across 13 surfaces before this change, and
     .kind-btn was the single largest contributor. Chips, badges and avatars
     keep --kind-radius-pill; a full-height action does not. */
  border-radius: var(--kind-radius);
  font-weight: 600;
  text-decoration: none;
  border: 1px solid transparent;
  background: var(--kind-color-surface);
  color: var(--kind-color-text);
  cursor: pointer;
  font-size: var(--kind-font-base);
  line-height: 1.2;
}
/* [hidden]-gard pa BASKLASSEN, sa varje knapp arver den.
 *
 * `display: inline-flex` ovan slar UA-lagrets `[hidden] { display: none }` pa
 * ursprungsprecedens, alltsa var `hidden` inert pa varenda `.kind-btn`. Fem
 * mallar renderar en knapp med `hidden` och trodde att den var dold:
 *
 *   templates/patient/formular_fill.html:158,181  "Rensa" pa en obesvarad
 *                                                 radiogrupp (kind_formular_radio_clear.js
 *                                                 satter btn.hidden = !anyChecked)
 *   templates/portal/bankid_collect.html:56       "Forsok igen" fore ett fel
 *   templates/portal/siths_collect.html:61        samma, SITHS-tvillingen
 *   templates/admin/patient.html:1562             videolanken fore mote
 *   templates/_push_notifications.html:62         push-vaxeln fore stod-koll
 *
 * Emoji- och formatknapparna hade redan var sin egen gard
 * (kind_admin.css:3013/3096, kind_patient.css:2129/2358) och deras kommentarer
 * argumenterar uttryckligen om precis den har precedensen. Basklassen missades.
 * Garden har ar (0,2,0) och slar `.kind-btn` (0,1,0); de befintliga
 * komponentgarderna ar ocksa (0,2,0) och satter samma varde, sa de kolliderar
 * inte. Hittad av scripts/svep_hidden_display.py, verifierad mot den riktiga
 * kaskaden av e2e/hidden-probe.mjs. */
.kind-btn[hidden] { display: none; }
.kind-btn:hover { background: var(--kind-color-surface-muted); }

.kind-btn--primary {
  background: var(--kind-color-accent);
  color: var(--kind-color-text-on-accent);
  border-color: var(--kind-color-accent);
}
.kind-btn--primary:hover {
  background: var(--kind-color-accent-hover);
  border-color: var(--kind-color-accent-hover);
  color: var(--kind-color-text-on-accent);
}

.kind-btn--secondary {
  background: transparent;
  color: var(--kind-color-accent);
  border-color: var(--kind-color-accent);
}
.kind-btn--secondary:hover {
  background: var(--kind-color-accent-bg);
  color: var(--kind-color-accent);
}

.kind-btn--ghost { background: transparent; }
.kind-btn[disabled] { opacity: 0.55; cursor: not-allowed; }

/* B7 (snabbtest): "Rensa svar" deselect control for an optional radio question
   in the patient formulär. Compact ghost button (smaller font + tighter inline
   padding) that sits under its radio group; the base .kind-btn min-height /
   min-width 44px is RETAINED so the touch target stays WCAG 2.1 AA 2.5.5
   compliant. JS reveals it (hidden by default), so no-JS patients never see a
   dead control. The accent text + underline read it as a low-emphasis action. */
.kind-radio-clear {
  margin-top: var(--kind-space-2);
  padding-inline: var(--kind-space-3);
  font-size: var(--kind-font-small);
  color: var(--kind-color-accent);
  text-decoration: underline;
}
.kind-radio-clear:hover { background: var(--kind-color-accent-bg); }

/* W8-04 (PM-004 §3 / Q-NEW-B Gap 2-3) patient-portal landing action group.
   The landing page stacks primary + ring-mig-istället CTAs with breathing
   room and surfaces the ring-mig help text below the button. Spacing tokens
   reuse the existing scale so a future design-tokens audit (W11) does not
   pick this up as a one-off. */
.kind-portal-landing__lede {
  font-size: var(--kind-font-large, 1.125rem);
  line-height: 1.5;
  max-width: 60ch;
  margin-bottom: var(--kind-space-5);
}
.kind-portal-landing__actions {
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-3);
  margin-bottom: var(--kind-space-5);
  max-width: 60ch;
}
.kind-portal-landing__ring-mig {
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-2);
  margin: 0;
}
.kind-portal-landing__help {
  font-size: var(--kind-font-small, 0.875rem);
  color: var(--kind-color-text-muted);
  margin: 0;
  max-width: 50ch;
}
.kind-portal-landing__note {
  color: var(--kind-color-text-muted);
  font-size: var(--kind-font-small, 0.875rem);
  max-width: 60ch;
  margin-top: var(--kind-space-6, 2rem);
}

/* BankID login affordance (ADR-021 Fas 3, hosted-redirect web). The BankID
   button is the conventional dark fill with white text so it reads as the
   distinct e-id action (not the coral primary CTA); the dark fill
   (--kind-color-text) with white text is far past WCAG 2.2
   AA 1.4.3 (4.5:1). Inherits the base .kind-btn 44x44 min target (2.5.5) and
   the global :focus-visible ring (2.4.7). The "BankID" wordmark span is a text
   mark (aria-hidden) so screen readers hear only the button's accessible name
   ("Logga in med BankID"); we deliberately do not ship a raster BankID logo
   asset (no binary in repo, and the text mark stays crisp at 200% zoom). */
.kind-portal-landing__bankid {
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-2);
  margin: 0;
}
/* CP-03 (issue #88): the label was a hardcoded #ffffff on a TOKEN fill. In the
 * light theme --kind-color-text is #20252B and white reads 15.43:1, which is
 * why nobody noticed; in the dark theme the same token is #E8ECF1 and white on
 * near-white is 1.09:1, i.e. an INVISIBLE BankID button on the login surface.
 * The inverse of the ink token is the surface token, so the pair flips with the
 * theme and the light rendering is byte-identical (#FFFFFF either way). This is
 * one of the three literal-colour rules the light contrast matrix listed under
 * "Vad matrisen INTE tacker": a token measurement cannot see a literal. */
.kind-btn--bankid {
  background: var(--kind-color-text);
  color: var(--kind-color-surface);
  border-color: var(--kind-color-text);
  gap: var(--kind-space-2);
}
.kind-btn--bankid:hover {
  background: #000000;
  border-color: #000000;
  color: #ffffff;
}
/* Hover raises contrast by moving the fill to the extreme end of the ramp, and
 * "the extreme end" is black in light and white in dark. There is no token for
 * that, and inventing one for a single button is worse than declaring the dark
 * end here, next to the light end it mirrors. Both are 21:1. */
html[data-kind-theme="dark"] .kind-btn--bankid:hover {
  background: #ffffff;
  border-color: #ffffff;
  color: #000000;
}
.kind-btn--bankid__mark {
  font-weight: 700;
  letter-spacing: 0.01em;
  /* Small leading wordmark; decorative styling only, the accessible name comes
     from the adjacent text span. */
  padding-inline-end: var(--kind-space-1, 0.25rem);
  /* CP-03: was rgba(255,255,255,0.4), a white hairline that vanished once the
     label above stopped being white in dark. currentColor follows the label in
     both themes and resolves to exactly the same rgba in light, so the light
     rendering is unchanged. A browser without color-mix drops the declaration
     and loses a decorative separator, which is the right thing to lose. */
  border-inline-end: 1px solid color-mix(in srgb, currentColor 40%, transparent);
}
.kind-btn--bankid[aria-busy="true"] { opacity: 0.7; }
.kind-portal-landing__bankid-error {
  color: var(--kind-color-error);
  font-size: var(--kind-font-small, 0.875rem);
  margin: 0;
  max-width: 50ch;
}

/* BankID collect landing / error surface (ADR-021 Fas 3). The page the hosted
   redirect lands on; shows progress then one terminal result. The error block
   reuses the error token (--kind-color-error, floor asserted in the token guard) and the
   shared .kind-btn CTAs. tabindex=-1 on the error block lets the JS move focus
   there so the outcome is announced (2.4.3 focus order). */
.kind-portal-bankid {
  max-width: 60ch;
}
.kind-portal-bankid__lede {
  font-size: var(--kind-font-large, 1.125rem);
  line-height: 1.5;
  margin-bottom: var(--kind-space-5);
}
.kind-portal-bankid__error {
  margin-top: var(--kind-space-4, 1rem);
}
.kind-portal-bankid__error:focus-visible {
  outline: var(--kind-focus-ring);
  outline-offset: 4px;
}
.kind-portal-bankid__error-title {
  color: var(--kind-color-error);
  margin-bottom: var(--kind-space-2);
}
.kind-portal-bankid__error-text {
  line-height: 1.5;
  margin-bottom: var(--kind-space-4, 1rem);
  max-width: 60ch;
}
.kind-portal-bankid__actions {
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-3);
  max-width: 40ch;
}
.kind-portal-bankid__note {
  color: var(--kind-color-text-muted);
  font-size: var(--kind-font-small, 0.875rem);
  max-width: 60ch;
  margin-top: var(--kind-space-6, 2rem);
}

/* ============ 6. Cards + lists + tables ============ */

/* DESIGNREGEL (ADR-065 / kontrastmatrisen, det första strukturella
 * underkännandet): en funktionell avgränsning ritas ALDRIG med enbart
 * fyllnadsskillnad.
 *
 * The content surface #FFFFFF against the page #F5F7FA is 1.07:1. That is not a
 * subtle boundary, it is no boundary: the card edge is invisible. As long as a
 * card only GROUPS text it is not a WCAG violation, because SC 1.4.11 governs
 * what is needed to IDENTIFY a component or a state. But the moment the card
 * edge is the only marker of something functional, a selectable row, an input
 * container, an active state, 1.07:1 is an AA miss, and in this product the card
 * IS the interactive unit on most surfaces (a patient row, a booking, an
 * article). This cannot be fixed by darkening the page background: the matrix
 * generator tried exactly that in its first version and #7C96BD failed seven
 * other pairs. A proposal that makes the whole worse is not a proposal.
 *
 * So the boundary is carried by the BORDER and not by the fill, and the border
 * is the FUNCTIONAL token, which clears 3:1 against both bearing surfaces
 * (3.34:1 on white, 3.11:1 on the page). --kind-color-border-soft stays where it
 * belongs: a decorative divider INSIDE a container, never the container's own
 * edge, and never a field edge (WATCH-ITEM 1 in §1 Tokens).
 *
 * Visual weight of the resulting line is CP-05's business (radius + density).
 * The 3:1 floor is not, and must not be traded for a lighter look. */
.kind-card {
  background: var(--kind-color-surface);
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius);
  padding: var(--kind-space-5);
  box-shadow: var(--kind-shadow-sm);
}
.kind-card__title { font-family: var(--kind-font-serif); margin-bottom: var(--kind-space-3); }

/* Message preview (Finding C, UAT 2026-06-28). The dörr aktiveringsmeddelande
   preview renders the body in a <pre> so the greeting newlines are preserved.
   Without this rule the <pre> fell back to the browser default white-space:pre
   (no wrap) + monospace, so the long body sentence + the activation URL overflowed
   off the right edge ("ser konstigt ut"). pre-wrap keeps the authored newlines AND
   wraps long lines; overflow-wrap:anywhere lets a long unbroken URL break inside
   the box rather than push the layout wide. The font is repointed to the body sans
   (this is patient-facing prose, not code) and the box gets the same muted-inset
   surface + hairline + padding the rest of the UI uses for read-only content. */
.kind-message-preview {
  margin: 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font-family: var(--kind-font-sans);
  font-size: var(--kind-font-base);
  line-height: var(--kind-line-height);
  color: var(--kind-color-text);
  background: var(--kind-color-surface-muted);
  border: 1px solid var(--kind-color-border-soft);
  border-radius: var(--kind-radius);
  padding: var(--kind-space-4);
}

.kind-list { display: flex; flex-direction: column; gap: var(--kind-space-2); }
/* A list row is a SELECTABLE unit on most surfaces (the whole row is a block
   link, see the rule below), so its edge is functional, not decoration. Same
   design rule as .kind-card above. */
.kind-list__item {
  padding: var(--kind-space-3);
  border-radius: var(--kind-radius);
  background: var(--kind-color-surface);
  border: 1px solid var(--kind-color-border);
}
/* A11Y-2 (2026-06-20): exclude .kind-btn anchors. This row-link rule (whole list
   row as a dark, no-underline block link) is more specific than .kind-btn--primary
   (single class), so without :not(.kind-btn) it overrode button anchors nested in a
   .kind-list__item to color:--kind-color-text + display:block. On the primary button
   that is --kind-color-text on the accent fill = 2.93:1 after Classic+, below the
   WCAG 2.2 AA 4.5:1 floor. Excluding .kind-btn lets buttons keep their own token
   (--kind-color-text-on-accent, white on accent = 5.34:1) and inline-flex shape
   everywhere a button sits inside a list item. */
.kind-list__item a:not(.kind-btn) { text-decoration: none; color: var(--kind-color-text); display: block; }
.kind-list__item a:not(.kind-btn):hover { color: var(--kind-color-accent); }
.kind-list__meta { color: var(--kind-color-text-muted); font-size: var(--kind-font-small); }

.kind-empty {
  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;
}

/* ============ F-02: BRYTREGEL FÖR TEXT ANVÄNDAREN SJÄLV SKRIVIT ============
 *
 * DEFEKTEN. En sökträffrad citerar användarens egen söksträng. Skriver hen en
 * lång sträng utan mellanslag finns ingen tillåten brytpunkt i den, och texten
 * sprängde dokumentets bredd. Uppmätt av testaren mot deploy fcdd641a,
 * `/patient/artiklar`, 120 tecken `x`, viewport 390: `documentElement`
 * scrollWidth 972 vid normal textstorlek och 1459 vid extra stor text plus hög
 * kontrast, mot clientWidth 390.
 *
 * ÖVERSPILLET ÄR OBUNDET. Det är inte ett kantfall vid stor textskala, det
 * skalar linjärt med inmatningen och sker redan vid normal textstorlek. En
 * tidigare rapport av samma defekt mätte 434px, alltså en HELT annan siffra för
 * samma scenario, och skillnaden var stränglängden. Därför är åtgärden en
 * brytregel och inte ett breddtak: ett tak hade bara flyttat gränsen.
 *
 * VARFÖR EN EGEN KLASS OCH INTE EN REGEL PÅ BÄRARNA. Ett bärarsvep efter
 * MEKANISMEN, alltså "yta som återger användarens egen fritext", inte efter den
 * rapporterade ytan (regel 27 kor. 2), gav fem echo-platser i två mallar och
 * TRE skilda klasser:
 *
 *     patient/artiklar.html:436   .kind-library__count       (rapporterad)
 *     admin/patienter.html:775    .kind-empty                q-sök, tomtillstånd
 *     admin/patienter.html:761    .kind-empty                taggsök, tomtillstånd
 *     admin/patienter.html:388    .kind-list__meta           taggsök, räknare
 *     admin/patienter.html:470    ...__sokfilter-tillstand   aktivt filter
 *     admin/patienter.html:641    ...__sokfilter-tillstand   aktiv verksamhet
 *
 * `.kind-empty`, `.kind-list__meta` och `.kind-library__count` är GENERELLA
 * klasser. `.kind-empty` bär ensam över 30 tomtillstånd som aldrig återger
 * någon inmatning, och `.kind-list__meta` sitter bland annat i triagetabellens
 * celler där kolumnbredden härleds ur min-content. En regel på dem hade alltså
 * ändrat storleksättningen på ytor som inte har med defekten att göra. Klassen
 * här namnger i stället MEKANISMEN, så en framtida echo-plats täcks genom att
 * bära den och vakten `tests/test_f02_soktext_brytregel.py` räknar upp platserna.
 *
 * VAL AV MEKANISM, MÄTT OCH INTE ANTAGET. Bärarna delar symtom men INTE orsak,
 * och det avgjorde valet. Mätt på stub-renderade ytor, 320 och 430, tomt
 * dokumentöverspill i px:
 *
 *   barare                              ingen  break-word  anywhere
 *   .kind-library__count                  636       0          0
 *   .kind-empty                           703       0          0
 *   .kind-list__meta (taggsök)            705     595          0
 *   ...__sokfilter-tillstand              703     595          0
 *
 * De två första är BLOCK i normalt flöde: boxen är redan rätt bred (288px vid
 * 320) och det är bara texten som spiller över, alltså räcker `break-word`.
 * De två sista är FLEXOBJEKT med `flex: 1 1 100%` och `min-width: auto` i en
 * krympande kedja: deras automatiska minsta storlek ÄR min-content, alltså
 * växte själva boxen till 875px och sköt ut sin flexbehållare. `break-word`
 * räknas per definition INTE med i min-content (det är precis skälet som anges
 * för rubrikregeln längre upp i den här filen, issue #158), så den kan inte
 * lösa det fallet, och mätningen visar det: 595px kvar.
 *
 * DÄRFÖR `anywhere` OCH INTE `break-word` HÄR, tvärtemot rubrikregeln ovan.
 * `anywhere` nollställer min-content, vilket är exakt det som behövs för att
 * krympningen ska propagera uppåt genom flexkedjan. Rubrikregelns motivering
 * att undvika `anywhere` gällde en BRED selektorlista över hela appen, där en
 * nollställd min-content ändrar storleksättning på orelaterade ytor. Här är
 * selektorn en klass som bara sitter på echo-platser, och för dem är en smal
 * box precis vad vi vill ha framför en utsprängd.
 *
 * ALTERNATIVET SOM VALDES BORT: `break-word` plus `min-width: 0` på bäraren och
 * dess tre förfäder mätte också 0px, men kräver fyra extra deklarationer på
 * strukturella behållare och gör regeln beroende av DOM-djupet, alltså tyst
 * trasig så fort någon lägger till ett lager.
 *
 * DEN ANDRA RIKTNINGEN (regel 49f2). Varje mätpunkt körs också med en NORMAL
 * sökfras, och kravet är noll överspill OCH noll brutna ordinarie ord i det
 * läget, så regeln inte kan börja bryta ord den inte skulle brutit. Uppmätt
 * över tio kombinationer per bärare, fem bredder gånger två textstorlekar:
 * noll brutna ord. Mätaren är `e2e/f02-soktext-matning.mjs`. */
.kind-sokecho {
  overflow-wrap: anywhere;
}

/* ============ 7. Flash / messages / errors ============ */

.kind-flash-stack { display: flex; flex-direction: column; gap: var(--kind-space-2); margin-bottom: var(--kind-space-4); }
.kind-flash {
  padding: var(--kind-space-3) var(--kind-space-4);
  border-radius: var(--kind-radius);
  border-left: 4px solid var(--kind-color-info);
  background: var(--kind-color-info-bg);
  color: var(--kind-color-text);
}
.kind-flash__text { margin: 0; }
.kind-flash--success { background: var(--kind-color-success-bg); border-left-color: var(--kind-color-success); }
.kind-flash--error { background: var(--kind-color-error-bg); border-left-color: var(--kind-color-error); }
.kind-flash--warning { background: var(--kind-color-warning-bg); border-left-color: var(--kind-color-warning); }

/* web#1077 kriterium 4: felbeskedet vid misslyckad borttagning av en vardresa.
   Den star i formuläret pa patientsidan och STAR KVAR tills vardgivaren
   stänger den (gamla KIND `dissolveAfter: -1`). Darfor finns HAR medvetet
   ingen `animation`, ingen `transition` mot `opacity`/`visibility` och ingen
   tidsstyrd gom-regel -- det enda som gommer ytan igen ar `hidden`, som bara
   Stäng-knappen i `kind_unassign_confirm.js` sätter. Lägg inte till en. */
.kind-stoppfel {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--kind-space-3);
  margin-top: var(--kind-space-3);
}
.kind-stoppfel[hidden] { display: none; }
.kind-stoppfel__text { flex: 1 1 auto; }
.kind-stoppfel__stang { flex: 0 0 auto; }

/* DD-ERROR-FOCUS-A11Y-PT (digital-dörr intake error summary). The summary is a
   tabindex="-1" region that JS focuses on a failed-submit re-render so a
   keyboard / screen-reader user lands on the error. It receives focus
   PROGRAMMATICALLY, which fires :focus (not always :focus-visible), so the
   focus ring is set explicitly here to stay visible (WCAG 2.4.7). Contrast: ink
   --kind-color-text on --kind-tint-blush is far past 4.5:1; the focus ring is
   4.98:1 on the warm bg (past the 3:1 non-text floor). */
.kind-dorr__error-summary { outline: none; }
.kind-dorr__error-summary:focus {
  outline: var(--kind-focus-ring);
  outline-offset: var(--kind-focus-ring-offset);
}
.kind-dorr__error-summary .kind-flash__heading {
  font-size: var(--kind-font-h3, 1.125rem);
  font-weight: 700;
  margin: 0 0 var(--kind-space-2) 0;
  color: var(--kind-color-text);
}
.kind-dorr__error-summary .kind-flash__text { margin: 0 0 var(--kind-space-2) 0; }
.kind-dorr__error-summary .kind-flash__link { margin: 0; }
.kind-dorr__error-summary .kind-flash__link a { color: var(--kind-color-error); font-weight: 600; }

/* UAT P6 (Katarina 2026-06-08): "svårt att se svaret man får i den ljusgröna
   bannern högst upp" on the form-fill flow. The success banner's CONTRAST is
   fine (--kind-color-text on --kind-tint-mint, well past WCAG 2.2 AA
   4.5:1), so this is not a colour fix. The real issue is PROMINENCE: the routing
   answer ("ditt ärende är väglett till: ...") sits in a plain body-weight
   sentence at the top of the page with no visual cue, so it is easy to skim
   past, "svårt att se" = hard to SPOT, not hard to read. We add a leading
   checkmark cue and a slightly heavier body weight so the answer surface draws
   the eye. Scoped to --success only; the text colour is unchanged so contrast
   stays 15.64:1. The icon is decorative (the flash text carries the meaning and
   the banner already has role=status aria-live=polite), so it is not announced. */
.kind-flash--success {
  display: flex;
  align-items: flex-start;
  gap: var(--kind-space-3);
}
.kind-flash--success::before {
  content: "";
  flex: 0 0 auto;
  width: 1.5rem;
  height: 1.5rem;
  margin-top: 0.1rem;
  background-color: var(--kind-color-success);
  /* inline checkmark, masked so it tints with the success token (5.28:1 on
     white, 4.66:1 on the mint banner, both past the 3:1 non-text floor) */
  -webkit-mask: var(--kind-icon-check) center / contain no-repeat;
  mask: var(--kind-icon-check) center / contain no-repeat;
}
.kind-flash--success .kind-flash__text { font-weight: 600; }

/* ==== obrytbart referensnummer på felsidorna (2026-08-09) ====================
 *
 * Uppmätt på deployen 2.3.1-nordiccare-w32: `/admin/akut` sköt ut 107px
 * horisontellt vid 320px och xxlarge textskala, 52 vid 375, 37 vid 390, 15 vid
 * 412 och 0 vid 430, samt 36px vid 320 och XLARGE. Normal textskala låg på 0
 * vid alla bredder. Alltså WCAG 2.2 AA SC 1.4.10 (Reflow), och en defekt bara
 * den lågseende användaren ser. Sedan tillgänglighetspanelen finns på
 * vårdgivarytan kan en kliniker själv välja den skalan, så den är nåbar.
 *
 * ROTORSAKEN ÄR EN ENDA TEXTTOKEN. `.kind-error-page__ref` renderar
 * "Referensnummer för support: <request_id>", och `request_id` är på deployen
 * ingressens `X-Request-ID`, en 32 tecken lång hex-token utan en enda
 * brytpunkt. Computed style var `overflow-wrap: normal` + `word-break: normal`
 * + `hyphens: manual`, alltså noll tillåtna brytpunkter inuti token. Modellen
 *
 *     överskott = max(0, 24px indrag + 403px tokenbläck - viewportbredd)
 *
 * stämmer exakt på alla fem uppmätta bredder. Elementets EGEN border-box
 * stannar innanför viewporten, det är bläcket som ritas utanför, så ett svep
 * efter "bredaste element" ger en TOM bovlista vid bevisat överskott
 * (minne `feedback-rect-sweep-misses-text-ink-overflow`).
 *
 * DELAD NOD, INTE DEN RAPPORTERADE YTAN (regel 27 korollarium 2). Raden
 * renderas av NIO mallar: 400, 401, 403, 404, 413, 429, 500, ogiltig_period
 * och loggutdrag_avbrutet. Ett svep av 35 vårdgivarytor vid xxlarge hittade
 * bristen på 16 av dem, och 14 av de 16 är HELT VANLIGA rutter som bara
 * renderar 403 för en roll utan behörighet. Kunden rapporterade en, för det
 * var den den såg.
 *
 * Issue #109 (rad 601 ovan) åtgärdade EXAKT den här mekanismen 2026-08-05 och
 * scopade den till rubrik- och etikettbärande element. `.kind-error-page__ref`
 * är ett `<p>` och föll utanför. Den kommentaren är alltså kvittot på att
 * mekanismen var förstådd men tillämpad smalt.
 *
 * REGELN SITTER PÅ SEKTIONEN, inte på `__ref`. `overflow-wrap` ärvs, så en
 * enda deklaration täcker koden, rubriken, brödtexten, knappen och
 * referensraden, och överlever att någon senare lägger till ett id, ett
 * filnamn eller en URL på felsidan. Det är den delade noden för hela felytan.
 *
 * `break-word` och INTE `anywhere`: båda ger 0px, men `anywhere` nollar även
 * elementets min-content-bredd och ändrar därmed hur det storleksätts som
 * flex- eller rutnätsobjekt. Samma avvägning som #109 gjorde, av samma skäl.
 * INTE heller `word-break: break-all` (som `.kind-admin__id` använder): den
 * fyller raden girigt och skulle bryta "Referensnummer" mitt i ordet även när
 * en mellanslagsbrytning fanns. `break-word` träder in FÖRST när ordet inte
 * får plats på en egen rad, så den svenska etiketten bryts vid mellanslag och
 * bara hex-token kapas.
 *
 * Vakt: e2e/hskroll-felsidor-grind.mjs (mäter bläck, inte förekomst av en
 * CSS-regel) plus tests/test_felsida_ordbrytning_css.py (driftvakt som kör om
 * svepet och blir röd när en ny felsidesmall hamnar utanför selektorn). */
.kind-error-page {
  max-width: var(--kind-container-narrow);
  margin: var(--kind-space-7) auto;
  text-align: center;
  overflow-wrap: break-word;
}
.kind-error-page__ref {
  font-size: var(--kind-font-small);
  color: var(--kind-color-text-muted);
  margin-top: var(--kind-space-5);
  font-family: var(--kind-font-mono);
}
.kind-error-page__actions {
  display: flex;
  justify-content: center;
  gap: var(--kind-space-3);
  flex-wrap: wrap;
  margin-top: var(--kind-space-4);
}

/* ============ 8. Utilities ============ */

.kind-skip-link {
  position: absolute;
  top: -100px;
  left: 0;
  padding: var(--kind-space-3) var(--kind-space-4);
  background: var(--kind-color-accent);
  color: var(--kind-color-text-on-accent);
  text-decoration: none;
  font-weight: 600;
  z-index: 1000;
  border-radius: 0 0 var(--kind-radius) 0;
}
/* #113 punkt 2: top 5px, inte 0. Vid top: 0 klipps fokusringen (3px kontur
   plus 2px offset = 5px utstick) av viewportkanten pa varje bredd. Elementet
   sjalvt var 100 procent synligt, sa SC 2.4.11 höll, men ringen var beskuren.
   scroll-margin-top ar VERKNINGSLOST har: elementet ar absolutpositionerat vid
   viewporttoppen och nas via klick/Tab, inte via en scroll-into-view, sa det
   finns ingen skrollmarginal att konsumera. Verifieras med riktig Tab plus
   ringgeometri i e2e/a11y-113-utfall.mjs (rodbevisad mot top: 0). */
.kind-skip-link:focus { top: 5px; }

.kind-visually-hidden,
.kind-sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}

.kind-stack-2 > * + * { margin-top: var(--kind-space-2); }
.kind-stack-3 > * + * { margin-top: var(--kind-space-3); }
.kind-stack-4 > * + * { margin-top: var(--kind-space-4); }

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* ============ 9. Patient accessibility panel ============
 *
 * The trigger lives in the header (right of the user menu). The panel is a
 * <dialog> opened with showModal() so the browser gives us the focus trap +
 * Escape-to-close + backdrop for free (same pattern as kind_radera_konto.js).
 * Everything below degrades gracefully: with no JS the trigger is hidden, the
 * <dialog> is display:none by the UA, and the base page is untouched.
 */

.kind-a11y-trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--kind-space-2);
  min-height: 44px;
  min-width: 44px;
  padding: var(--kind-space-2) var(--kind-space-3);
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius-pill);
  background: var(--kind-color-surface);
  color: var(--kind-color-text);
  font-size: var(--kind-font-small);
  font-weight: 600;
  line-height: 1.2;
}
.kind-a11y-trigger:hover { background: var(--kind-color-surface-muted); }
.kind-a11y-trigger__icon { font-size: 1.125em; line-height: 1; }

/* #142: pa VARDGIVARYTAN bar knappen bara sin "Aa"-ikon, aldrig den synliga
   ordetiketten, vid ALLA bredder. Den etiketten doldes tidigare bara under
   900px; den regeln lag i den kompakta nav-mediefragan ovan och ar flyttad hit
   sa det finns EN plats som beslutar saken.
   MOTIVERINGEN AR MATT, inte estetisk (riktig Chromium mot den efemara
   matmiljon, 2026-08-09, patientlistan och triagevyn, 192 matpunkter):
     Med etiketten synlig ar knappen 146px bred vid 1280 normal, och navets
     synliga port gar 705 -> 543px mot ett navinnehall pa 633px. Alltsa BORJAR
     naven skrolla pa en yta dar den forut rymdes helt, och fyra destinationer
     hamnar utanfor synfaltet for varje kliniker hela arbetsdagen.
     Utan etiketten ar knappen 46px och porten 643px, alltsa over 633: naven
     skrollar inte. Marginalen ar 10px, sa en framtida navpost aterskapar
     problemet och da ar det navets budget som ska ses over, inte den har
     regeln. Vid stor textskala skrollar naven anda (innehallet vaxer fortare
     an porten), men knappen kostar da 91px i stallet for 233px.
   TILLGANGLIGHETEN AR OFORANDRAD: knappens tillgangliga namn bars av dess
   aria-label ("Tillganglighet, anpassa text och kontrast"), som vinner over
   innehall enligt namnberakningen, sa SC 4.1.2 paverkas inte. Etiketten doljs
   VISUELLT och tas inte bort ur tillganglighetstradet. "Aa" star kvar som
   synlig affordans, och traffytan ar matt 46x44 vid normal och 67x50 vid
   xxlarge, alltsa over 44px-golvet i bada.
   PATIENTYTAN ROR SIG INTE: den har sin egen gren
   (.kind-a11y-trigger--patient i kind_patient.css) och sin egen oppna
   ux-fraga om synlig etikett (CP-06 E-1, se templates/base.html). */
.kind-body--admin .kind-a11y-trigger > span:not(.kind-a11y-trigger__icon) {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* JS adds .kind-a11y-ready to <body> once it has wired the panel. Until then
   the trigger is hidden so no-JS patients never see a dead control. */
.kind-body:not(.kind-a11y-ready) .kind-a11y-trigger { display: none; }

.kind-a11y-panel {
  width: min(28rem, calc(100vw - 2 * var(--kind-space-4)));
  max-width: 100%;
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius);
  padding: 0;
  background: var(--kind-color-surface);
  color: var(--kind-color-text);
  box-shadow: var(--kind-shadow-md);
}
.kind-a11y-panel::backdrop { background: rgba(0, 0, 0, 0.45); }
.kind-a11y-panel__inner { padding: var(--kind-space-5); }

.kind-a11y-panel__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--kind-space-3);
  margin-bottom: var(--kind-space-2);
}
.kind-a11y-panel__title { margin: 0; font-size: var(--kind-font-h3); }
.kind-a11y-panel__lede {
  color: var(--kind-color-text-muted);
  font-size: var(--kind-font-small);
  margin-bottom: var(--kind-space-5);
}

.kind-a11y-group { border: 0; padding: 0; margin: 0 0 var(--kind-space-5) 0; }
.kind-a11y-group__legend {
  padding: 0;
  font-weight: 600;
  font-size: var(--kind-font-base);
  margin-bottom: var(--kind-space-2);
}
.kind-a11y-group__help {
  color: var(--kind-color-text-muted);
  font-size: var(--kind-font-small);
  margin-bottom: var(--kind-space-3);
}

/* Font-scale options: a row of segmented buttons. aria-pressed carries state. */
.kind-a11y-fontscale {
  display: flex;
  flex-wrap: wrap;
  gap: var(--kind-space-2);
}
.kind-a11y-fontscale__btn {
  flex: 1 1 auto;
  min-height: 44px;
  padding: var(--kind-space-2) var(--kind-space-3);
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius);
  background: var(--kind-color-surface);
  color: var(--kind-color-text);
  font-weight: 600;
  line-height: 1.2;
}
.kind-a11y-fontscale__btn:hover { background: var(--kind-color-surface-muted); }
.kind-a11y-fontscale__btn[aria-pressed="true"] {
  background: var(--kind-color-accent-bg);
  border-color: var(--kind-color-accent);
  color: var(--kind-color-accent);
}

/* ---- Theme picker (CP-03, issue #88) ------------------------------------
 * Rendered by templates/_theme_picker.html on BOTH profil pages, so the rules
 * live in the shared stylesheet and not in a per-domain one. It borrows the
 * segmented-control language of .kind-a11y-fontscale above so the two display
 * preferences read as one family, but keeps its own class: the a11y panel is
 * patient-only and this control is not, and sharing the class would make a
 * future patient-scoped tweak silently reshape the clinician surface.
 *
 * The section's own margin is declared here because .kind-profile-section is
 * defined in kind_admin.css only. The patient profil page includes the same
 * partial and would otherwise get an unspaced block. */
.kind-theme-picker { margin-bottom: var(--kind-space-5); }
.kind-theme-picker__choices {
  display: flex;
  flex-wrap: wrap;
  gap: var(--kind-space-2);
  margin-top: var(--kind-space-3);
}
.kind-theme-picker__btn {
  flex: 1 1 auto;
  /* 44px is the patient-surface target floor (SC 2.5.5 asks 24px; this product
     holds the older/lower-vision floor everywhere). */
  min-height: 44px;
  padding: var(--kind-space-2) var(--kind-space-3);
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius);
  background: var(--kind-color-surface);
  color: var(--kind-color-text);
  font-family: inherit;
  font-size: var(--kind-font-base);
  font-weight: 600;
  line-height: 1.2;
  cursor: pointer;
}
.kind-theme-picker__btn:hover { background: var(--kind-color-surface-muted); }
/* State is NOT colour-only (SC 1.4.1): the pressed button also gains a heavier
 * border, and aria-pressed carries it for assistive tech. */
.kind-theme-picker__btn[aria-pressed="true"] {
  background: var(--kind-color-accent-bg);
  border: 2px solid var(--kind-color-accent);
  color: var(--kind-color-accent);
}

/* High-contrast + TTS controls share a labelled toggle/action row. */
.kind-a11y-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--kind-space-2);
  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;
}
.kind-a11y-toggle:hover { background: var(--kind-color-surface-muted); }
.kind-a11y-toggle[aria-pressed="true"] {
  background: var(--kind-color-accent-bg);
  border-color: var(--kind-color-accent);
  color: var(--kind-color-accent);
}
.kind-a11y-toggle__state { font-weight: 700; }

.kind-a11y-panel__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--kind-space-3);
  flex-wrap: wrap;
  border-top: 1px solid var(--kind-color-border-soft);
  padding-top: var(--kind-space-4);
}
.kind-a11y-panel__save-note {
  color: var(--kind-color-text-muted);
  font-size: var(--kind-font-small);
  margin: 0;
}

/* TTS control is hidden by JS when speechSynthesis is unavailable. The
   data-attribute default-hides it so the unsupported path never flashes a
   non-working button before JS runs. */
.kind-a11y-tts[hidden] { display: none; }

/* ============ 10. Self-serve onboarding + PUB-avtal surfaces (WS-D / ADR-028) ============
 *
 * Public clinic self-registration form + success page, the PUB-avtal-gated
 * closed-intake page, and the platform-flip confirmation page. All four sit on
 * a single centred card over the warm page bg (the same card token language as
 * .kind-card: white surface, soft hairline border, sm shadow, generous radius).
 * The form reuses the shared .kind-form / .kind-field / .kind-field__input /
 * .kind-btn primitives, so only the wrapper + a few onboarding-specific blocks
 * are defined here. Tokens only; every colour pair is checked against WCAG 2.2
 * AA (the page ink --kind-color-text clears 4.5:1 on every tint in :root; the
  * token guard measures each of those pairs).
 */

.kind-onboarding,
.kind-dorr--stangd,
.kind-admin--pub-avtal {
  max-width: var(--kind-container-narrow);
  margin: 0 auto;
}

.kind-onboarding__card,
.kind-dorr__card,
.kind-admin__card {
  background: var(--kind-color-surface);
  border: 1px solid var(--kind-color-border-soft);
  border-radius: var(--kind-radius);
  padding: var(--kind-space-6);
  box-shadow: var(--kind-shadow-sm);
}

/* The long Swedish compound headings on these surfaces
   ("Personuppgiftsbiträdesavtal", "Organisationsnummer") are single words wider
   than a narrow card, so they must break rather than force horizontal page
   scroll. Hyphenation gives a cleaner break than break-word where the browser
   supports the sv dictionary. Scoped to these card surfaces; the global h1 rule
   is untouched. */
.kind-onboarding__card :is(h1, h2),
.kind-dorr__card :is(h1, h2),
.kind-admin__card :is(h1, h2) {
  overflow-wrap: break-word;
  hyphens: auto;
}

.kind-onboarding__eyebrow {
  font-size: var(--kind-font-small);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--kind-color-accent);
  margin-bottom: var(--kind-space-2);
}

.kind-onboarding__intro,
.kind-dorr--stangd .kind-dorr__intro {
  font-size: var(--kind-font-large, 1.125rem);
  line-height: 1.55;
  color: var(--kind-color-text);
  max-width: 60ch;
  margin-bottom: var(--kind-space-5);
}

.kind-onboarding__error { margin-bottom: var(--kind-space-5); }

/* The onboarding form sits a touch tighter than a full-page form; the action
   row gets extra top breathing room so the single primary action is clearly the
   end of the flow. */
.kind-onboarding__form { gap: var(--kind-space-5); }
.kind-onboarding__form .kind-form__actions { margin-top: var(--kind-space-2); }
.kind-onboarding__form .kind-btn--primary { width: 100%; }
@media (min-width: 30rem) {
  .kind-onboarding__form .kind-btn--primary { width: auto; min-width: 14rem; }
}

/* Success page: a coral check badge above the heading reinforces the positive
   outcome. The badge is decorative (aria-hidden in the template); the heading
   carries the meaning. The mark tints with the success token so it stays >=3:1
   non-text contrast on the white card. */
.kind-onboarding__success-badge,
.kind-admin__success-badge {
  width: 3rem;
  height: 3rem;
  border-radius: var(--kind-radius-pill);
  background: var(--kind-color-success-bg);
  margin-bottom: var(--kind-space-4);
  position: relative;
}
.kind-onboarding__success-badge::before,
.kind-admin__success-badge::before {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 1.75rem;
  height: 1.75rem;
  background-color: var(--kind-color-success);
  -webkit-mask: var(--kind-icon-check) center / contain no-repeat;
  mask: var(--kind-icon-check) center / contain no-repeat;
}

/* Invite-link block: the absolute admin-activation link is the load-bearing
   output of the success page (it gets copied + relayed), so it gets a clearly
   bounded, monospaced, fully-selectable surface that wraps long URLs rather than
   overflowing the card. */
.kind-onboarding__invite-link {
  background: var(--kind-color-surface-muted);
  border: 1px solid var(--kind-color-border-soft);
  border-radius: var(--kind-radius);
  padding: var(--kind-space-5);
  margin-bottom: var(--kind-space-5);
}
.kind-onboarding__invite-link > *:not(:last-child) { margin-bottom: var(--kind-space-3); }
.kind-onboarding__invite-title { font-size: var(--kind-font-h3); margin-bottom: var(--kind-space-2); }
.kind-onboarding__link-row { margin: 0; }
.kind-onboarding__link-value {
  display: block;
  width: 100%;
  padding: var(--kind-space-3) var(--kind-space-4);
  background: var(--kind-color-surface);
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius);
  font-family: var(--kind-font-mono);
  font-size: var(--kind-font-small);
  color: var(--kind-color-text);
  line-height: 1.5;
  /* The whole URL must be copyable + readable: wrap rather than truncate, and
     break at any character so a long token never spills out of the card. */
  word-break: break-all;
  overflow-wrap: anywhere;
  -webkit-user-select: all;
  user-select: all;
}

/* PUB-avtal note: an informational sidebar token (info wash + slate-blue left
   rule), distinct from the success surface so the "intaket är inte öppet ännu"
   caveat reads as neutral information, not an error and not a confirmation. */
.kind-onboarding__pub-avtal-note {
  background: var(--kind-color-info-bg);
  border-left: 4px solid var(--kind-color-info);
  border-radius: var(--kind-radius);
  padding: var(--kind-space-5);
}
.kind-onboarding__pub-avtal-note h2 {
  font-size: var(--kind-font-h3);
  margin-bottom: var(--kind-space-2);
}
.kind-onboarding__pub-avtal-note p { margin: 0; max-width: 60ch; }

/* Closed-intake (403) akut banner. The dörr wrappers had no CSS before WS-D, so
   the akut safety note is defined here for the closed-intake page. A warning
   wash + left rule reads as "important, act on this" without alarm-red; the
   112/1177 tel: links inherit the global accent-link styling. */
.kind-dorr--stangd .kind-dorr__akut {
  background: var(--kind-color-warning-bg);
  border-left: 4px solid var(--kind-color-warning);
  border-radius: var(--kind-radius);
  padding: var(--kind-space-5);
}
.kind-dorr--stangd .kind-dorr__akut h2 {
  font-size: var(--kind-font-h3);
  margin-bottom: var(--kind-space-2);
}
.kind-dorr--stangd .kind-dorr__akut p { max-width: 60ch; }
.kind-dorr--stangd .kind-dorr__akut p:last-child { margin-bottom: 0; }

/* OPEN intake (public form) akut banner + captcha. The open intake had no dörr
   CSS before this a11y pass, so the safety banner read as plain body text. A
   warning wash + left rule makes the 112/1177 safety note visually distinct for
   the older / lower-vision public audience (DD a11y pair). Same token pair as
   the closed-intake banner above (warning ink is checked >=4.5:1 on the wash). */
.kind-dorr:not(.kind-dorr--stangd) .kind-dorr__akut {
  background: var(--kind-color-warning-bg);
  border-left: 4px solid var(--kind-color-warning);
  border-radius: var(--kind-radius);
  padding: var(--kind-space-5);
  margin-bottom: var(--kind-space-5);
}
.kind-dorr:not(.kind-dorr--stangd) .kind-dorr__akut h2 {
  font-size: var(--kind-font-h3);
  margin-bottom: var(--kind-space-2);
}
.kind-dorr:not(.kind-dorr--stangd) .kind-dorr__akut p { max-width: 60ch; }
.kind-dorr:not(.kind-dorr--stangd) .kind-dorr__akut p:last-child { margin-bottom: 0; }

/* Captcha image (DD-CAPTCHA-A11Y-PT safe-markup pass). Constrain the SVG so it
   never forces horizontal scroll at 320px (WCAG 1.4.10 Reflow), with a white
   plate so the distorted glyphs keep contrast regardless of the SVG background.
   The image is a complement to the typed answer; the honest alt + the
   aria-describedby instruction carry the how-to for non-sighted users. */
.kind-field--captcha .kind-captcha__img {
  display: block;
  max-width: 100%;
  height: auto;
  margin: var(--kind-space-2) 0 var(--kind-space-3) 0;
  background: #ffffff;
  border: 1px solid var(--kind-color-border-soft);
  border-radius: var(--kind-radius-sm, 8px);
  padding: var(--kind-space-2);
}

/* Dorrens honungsfalla (web#619). Doljs for manniskor; ingen automat laser CSS.
   `display: none` ar avsiktligt (inte off-screen-positionering): faltet ska
   inte na skarmlasare heller, och det ar redan aria-hidden + tabindex="-1" i
   mallen, sa ingen tangentbordsanvandare kan snubbla in i det. */
.kind-dorr__fallgrop { display: none; }

/* Arbetsytans egen bild overst pa dorren (web#619 punkt 7). Serveras alltid
   fran egen origin (V12), sa den kan inte bli en utlamning till tredje part.
   Begransad hojd sa en stor uppladdning inte trycker ner akutbannern under
   vikningen pa en telefon: 112-raden ar det som maste synas forst. */
.kind-dorr__media {
  display: block;
  max-width: 100%;
  max-height: 180px;
  width: auto;
  height: auto;
  margin-bottom: var(--kind-space-4);
  border-radius: var(--kind-radius);
}

/* Admin PUB-avtal-confirmed landing. */
.kind-admin__lede {
  font-size: var(--kind-font-large, 1.125rem);
  line-height: 1.55;
  max-width: 60ch;
  margin-bottom: var(--kind-space-5);
}
.kind-admin__meta { color: var(--kind-color-text-muted); margin: 0; }
.kind-admin__id {
  font-family: var(--kind-font-mono);
  font-size: var(--kind-font-small);
  padding: 0.1em 0.4em;
  background: var(--kind-color-surface-muted);
  border-radius: 6px;
  word-break: break-all;
}

/* Web Push "Slå på notiser" settings section (Step-1, _push_notifications.html).
   Shared by both profil pages, so it lives in the shared sheet (not the
   per-portal admin/patient sheets). The toggle uses .kind-btn; only the live
   status line needs its own rule. Full-ink (--kind-color-text 16.55:1) not
   muted: the on/off/blocked status is load-bearing copy a low-vision patient
   must read clearly, so it does not get the muted-grey help-text treatment. */
.kind-push__status {
  margin: var(--kind-space-3) 0 var(--kind-space-4);
  color: var(--kind-color-text);
  line-height: 1.5;
}

/* 112/1177 patient-safety disclaimer (nordic-care 2.0 #8). Shared component used
   on the chat composer, login, formulär-fill, and the "Be om en tid" overlay
   (templates/_safety_disclaimer.html). Lives in the shared sheet because all four
   surfaces are patient-facing and load this file via base.html.

   a11y / contrast (light theme, floor WCAG 2.2 AA 1.4.3 = 4.5:1 text):
   - all text is --kind-color-text full-ink, never muted; on the calm
     muted inset (--kind-color-surface-muted) far past AA, on the heightened
     amber wash (--kind-color-warning-bg #fcf2dc) ~15:1, both far past AA, chosen
     full-strength for the older / lower-vision patient floor.
   - the phone glyph is decorative (aria-hidden); the meaning is in the text, so
     colour is never the sole carrier (1.4.1).
   - the tel: links are underlined (link default), not distinguished by colour
     alone (1.4.1), and are real <a> so keyboard-/tap-reachable. */
.kind-safety {
  display: flex;
  align-items: flex-start;
  gap: var(--kind-space-3);
  margin: var(--kind-space-3) 0;
  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-muted);
  color: var(--kind-color-text);
  line-height: 1.5;
}
.kind-safety__icon {
  display: inline-flex;
  flex: 0 0 auto;
  margin-top: 0.15rem;
  color: var(--kind-color-text);
}
.kind-safety__body { min-width: 0; }
.kind-safety__rubrik { margin: 0; }
.kind-safety__lede { margin: var(--kind-space-1) 0 0; }
.kind-safety__text { margin: var(--kind-space-1) 0 0; }
.kind-safety__tel {
  color: var(--kind-color-text);
  text-decoration: underline;
  font-weight: 600;
  /* Träffytespaken för fullvariantens tel:-länkar (defekt B, Z1 i
     akutnummer-fixram-2026-08-07): padding-block på ett ICKE-ERSATT
     inline-element målas och träffas men bidrar INTE till radboxens höjd
     (MDN CSS box model, hämtat 2026-08-07), så träffytan växer medan
     radantalet och bandhöjden står stilla. Em-baserad så den följer
     textskalan (xxlarge = 150 procent).

     TAKET är X4, inte 44px (Z4): tel:112 och tel:1177 får ALDRIG överlappa
     i träffprovet (oforcerat elementFromPoint, e2e/akutnummer-utfall.mjs
     mäter varje mätpunkt och mutationsbevisar båda riktningarna). Radluckan
     är cirka 0.3em (1.5 line-height minus cirka 1.2em glyfbox), så 0.15em
     per sida är den största utökning som inte låter angränsande raders
     målade boxar skära varandra. Öka INTE utan att köra om matrisen; byt
     ALDRIG till inline-block/block/min-height (Z3: det river
     2.5.8-Inline-undantaget OCH ökar bandhöjden). Kompaktvarianten rör
     detta inte, den har sin egen ::after-träffyta nedan. */
  padding-block: 0.15em;
  padding-inline: 0.1rem;
}
.kind-safety__tel:hover,
.kind-safety__tel:focus-visible { text-decoration: none; }

/* Heightened (clinic likely closed) variant: warmer amber wash + a stronger left
   accent so the safety message is more prominent out of hours. Text stays
   full-ink (--kind-color-text on --kind-color-warning-bg, well past AA). */
.kind-safety--closed {
  background: var(--kind-color-warning-bg);
  border-color: var(--kind-color-warning);
  border-left-width: 4px;
}
.kind-safety--closed .kind-safety__icon { color: var(--kind-color-warning); }

/* #49 Fas 1 cluster B: the compact, always-visible 112/1177 emergency row used in
   the patient sticky header. Calm LIGHT-YELLOW (the existing --kind-color-warning-bg
   #fcf2dc token, reused, never a net-new hex), one row, never alarmist.
   Contrast (measured on the LIVE render with axe, light theme):
   - text (--kind-color-text ink) on --kind-color-warning-bg: far past the
     4.5:1 floor (1.4.3).
   - the tel: links are --kind-color-text ink + underline (never colour-alone,
     1.4.1) so they meet the SAME 14.9:1.
   - non-text (1.4.11 >= 3:1): the top hairline uses --kind-color-warning
     (border/icon vs the #fcf2dc yellow ~3.4:1); the phone icon is warning-amber
     too. Colour is never the only signal: the "Vid akut fara" text label + the
     icon carry the meaning.
   The row sits ABOVE the mottagning row's border; the parent header owns the
   stickiness (see kind_patient.css). Token-driven, so dark-theme + forced-colors
   overrides in :root track for free (the 112 text can never disappear). */
.kind-safety--kompakt {
  align-items: center;
  gap: var(--kind-space-2);
  margin: 0;
  padding: var(--kind-space-2) var(--kind-space-4);
  border: 0;
  border-top: 1px solid var(--kind-color-warning);
  border-radius: 0;
  background: var(--kind-color-warning-bg);
  color: var(--kind-color-text);
  font-size: var(--kind-font-small);
  /* 2.1c refinement (#49, qa 375px overflow): the visible compact copy is now a
     SHORT one-liner ("Akut? Ring 112. Rådgivning 1177."), so it fits ONE line at
     375px and at most two calm lines at 320px. The line-height drops from the old
     defensive 5 (~70px pitch, which made the band ~230px tall at 375px) to a
     normal calm 1.6. The two tel: tap boxes keep their >=44px height (below) and a
     small vertical margin so that IF they wrap onto adjacent lines at 320px the
     hit areas still keep >=24px clear vertical separation (WCAG 2.5.8,
     patient-safety: a shaky older hand must never tap 112 when reaching for 1177).
     Because the visible sentence is short + the two links are separated by the
     "Ring" / "Rådgivning" words, they sit on one line at 375px and never overlap
     horizontally either. */
  line-height: 1.6;
}
.kind-safety--kompakt .kind-safety__icon {
  margin-top: 0;
  color: var(--kind-color-warning);
}
/* The compact line lets its content wrap at FLEX level only: the label + the two
   nowrap SEGMENTS (one tel: link each, see _safety_disclaimer.html) are the flex
   items, so a wrap always moves a WHOLE segment to the next line. The row-gap
   (only paid when it wraps) is sized so two stacked 44px hit areas (the ::after
   overlays below) keep vertical clearance: line box ~22.4px (14px x 1.6) +
   row-gap 24px (--kind-space-5) = 46.4px line pitch > 44px target height, so the
   112 and 1177 targets can never overlap even wrapped. The sr-only full sentence
   is out of flow (visually-hidden). */
.kind-safety--kompakt .kind-safety__kompakt-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--kind-space-5) var(--kind-space-2);
  margin: 0;
  min-width: 0;
}
/* P3 (UAT 2026-07-02, 320px): each half-sentence segment is an unbreakable unit
   ("Ring 112." / "Rådgivning 1177."), so a text wrap can never split a verb from
   its number or land the two tel: targets at an arbitrary 2D offset. At 320px the
   SWEDISH whole line (icon 20 + gaps 16 + label ~34 + segments ~65 + ~112 =
   ~247px) fits the 288px content box (320 - 2 x 16px padding) on ONE line.
   The COMPLIANCE-BOUND en copy is ~25% longer and does NOT fit at 14px (UAT
   deployed measure 2026-07-03: 2 lines, row 85.8px); the html[lang="en"]
   <=360px block below (SU-1 follow-up) compresses it typographically, copy
   unchanged, so en also holds one line while sv rendering stays untouched. */
.kind-safety__kompakt-seg {
  flex: 0 0 auto;
  white-space: nowrap;
}
/* B4b-segmentet (stangt-lage) ar UNDANTAGET fran nowrap, och det ar avsiktligt
   enligt compliance-utslaget 2026-07-30: "Ett textsegment bar inget tel:-mal, sa
   det kan inte skapa den 2D-overlappning P3-segmenteringen finns for att
   forhindra. Segmentmonstret ateranvands bara for radbrytningsbeteendet."

   Skalet att undantaget BEHOVS: uppmatt vid 320px och xxlarge ar meningen 304px
   bred i en 226px foralder, sa nowrap gav 6 KLIPPTA tecken, alltsa
   informationsforlust (U2, binart) i den enda kanal som baR stangt-informationen
   for seende. Att lata den brytas kostar hojd (U1, redan rott) men bevarar
   innehallet, och kontraktets slutklausul ar entydig: tillganglighet vinner vid
   konflikt.

   Alternativet var compliance-forhandsgodkanda kortformen "Svar kan droja.", men
   den primara lydelsen ar den foredragna och behovde inte offras nar radbrytning
   loser problemet utan att tappa ett ord. */
.kind-safety__kompakt-seg.kind-safety__kompakt-stangt {
  white-space: normal;
  flex: 1 1 100%;
}
/* The heightened (clinic closed) compact variant keeps the same calm yellow (it
   must never "scream", it is always on), just a slightly stronger top rule so the
   out-of-hours prominence is preserved without changing colour. */
.kind-safety--kompakt.kind-safety--closed {
  border-top-width: 3px;
  background: var(--kind-color-warning-bg);
}
.kind-safety__kompakt-label {
  /* the always-there label ("Akut?"). It is a flex item now, so the parent gap
     owns the spacing before the text (no margin / injected separator needed). */
  flex: 0 0 auto;
}
.kind-safety--kompakt .kind-safety__tel {
  /* The two tel: links are the emergency-dial affordance and MUST NOT be
     mis-tapped (112 livshotande vs 1177 rådgivning): each keeps a >=44x44px
     POINTER TARGET, the engagement floor (above WCAG 2.5.8's 24px minimum), on
     the most safety-critical target in the app.

     P3 (UAT 2026-07-02, 320x800): the PREVIOUS mechanism was a 44px-tall padded
     block box (padding 0.85rem), which pitched every line to ~46px and stacked
     the header to ~123px (safety row ~66px) at 320px. The 44px floor is now an
     ::after OVERLAY HIT AREA (below) that hit-tests as part of the link without
     participating in layout, so the LAYOUT box is a compact inline-flex
     (14px x 1.2 = 16.8px line + 2 x 0.1rem = 3.2px padding ~ 20px) and the whole
     safety row is padding 2 x 8px + line ~22.4px ~ 38-40px, one calm line.

     Mis-tap separation is preserved structurally, not by tall padding:
     - one line (the 320px sv+en case): the two 44px targets are separated
       horizontally by the "Rådgivning"/"Advice" word (~65px clear between the
       expanded edges);
     - wrapped (extreme zoom / a longer locale): the nowrap segments put ONE
       whole segment per flex line and the 24px row-gap makes the line pitch
       ~46.4px > 44px, so the stacked targets never overlap vertically. */
  position: relative;
  display: inline-flex;
  align-items: center;
  padding: 0.1rem 0.15rem;
  margin: 0;
  line-height: 1.2;
}
.kind-safety--kompakt .kind-safety__tel::after {
  /* The invisible >=44x44px hit area, centered on the link. A pseudo-element of
     a link hit-tests as the link (pointer events land on the anchor), so the
     tap target is 44px tall and >=44px wide (width:100% of the padding box with
     a 44px minimum) while the painted row stays ~40px. It bleeds ~2-3px past
     the row edge; the neighbouring targets (the mottagning home link above,
     page content below) are >=7px away, and the 112-vs-1177 separation is
     handled structurally (see the comment above). */
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  min-width: 44px;
  height: 44px;
  transform: translate(-50%, -50%);
}

/* SU-1 P3 follow-up (UAT deployed verify 2026-07-03, en at 320x800): the compact
   band fits ONE line at 320px in sv (measured 39.4px row / 84.4px header, PASS),
   but the COMPLIANCE-BOUND en strings ("Emergency?" / "Call 112." / "Health
   advice 1177.", verbatim per the ADR-042 en compliance review, see
   docs/reviews/compliance-i18n-en-expansion-2026-07-03.md in the agents repo)
   are ~25% longer and wrapped to two lines (measured 85.8px row / 130.8px
   header, FAIL, worse than the pre-P3 123px baseline). The msgstr text CANNOT
   change, so the fix is purely TYPOGRAPHIC and scoped html[lang="en"] (base.html
   renders <html lang> per locale) so the PASSING sv render is byte-for-byte
   unchanged at every width.

   Levers at <=360px, en only: font drops 14 -> 13px (0.8125rem, above the ~12px
   readability floor), the inline padding drops --kind-space-4 -> 2 (16 -> 8px
   per side, content box 288 -> 304px; block padding stays 8px), the decorative
   phone icon drops 20 -> 16px with a 4px icon gap. CSS width math at 320px
   (Inter advance widths at 13px; the deployed system-ui fallbacks measure
   slightly narrower, so this is the conservative bound):
     icon 16 + icon gap 4
     + "Emergency?" bold ~75.3 + gap 8
     + "Call 112." ~51.4 + link padding 4.8 + gap 8
     + "Health advice 1177." ~115.4 + link padding 4.8
     = ~287.7px <= 304px content box, ONE line with ~16px slack.
   Row height: 2 x 8px block padding + line box (13 x 1.6 = 20.8px) + 1px
   border-top = ~37.8px (<= the 48px band budget); header total = ~45px top row
   (measured 2026-07-03) + ~38px = ~83px, inside the <=100px P3 bar and on par
   with the passing sv 84.4px.

   Invariants preserved, never relaxed (P2-4 + the ::after overlay mechanism
   above):
   - the 44x44px ::after OVERLAY hit areas are untouched (fixed px, decoupled
     from font-size), so both tel: targets keep the >=44px floor;
   - wrapped fallback (extreme zoom / user font scaling): the row-gap RISES
     24 -> 26px so line pitch = 20.8 + 26 = 46.8px > 44px and the stacked
     112/1177 targets can never overlap (at the base 24px row-gap the smaller
     13px line box would leave only 0.8px clearance, too thin);
   - tel LAYOUT box 13 x 1.2 + 3.2 = 18.8px <= the 20.8px line box (no line
     pitch inflation);
   - colours untouched: contrast stays ~14.9:1 and the 1.4.3 requirement at
     13px text is still 4.5:1, far exceeded. */
@media (max-width: 360px) {
  html[lang="en"] .kind-safety--kompakt {
    padding: var(--kind-space-2);
    gap: var(--kind-space-1);
    font-size: 0.8125rem;  /* 13px */
  }
  html[lang="en"] .kind-safety--kompakt .kind-safety__icon svg {
    /* CSS wins over the SVG width/height="20" presentation attributes; the
       icon is aria-hidden decoration, the text label carries the meaning. */
    width: 16px;
    height: 16px;
  }
  html[lang="en"] .kind-safety--kompakt .kind-safety__kompakt-line {
    /* row-gap 26px keeps the wrapped 44px-target pitch safe at the smaller
       13px line box (20.8 + 26 = 46.8px > 44px); the 8px column gap keeps a
       clear word gap between the two tap targets on the one line. */
    gap: 1.625rem var(--kind-space-2);
  }
}

/* ---------------------------------------------------------------------------
   Proxy banner (Wave-2b UI, ADR-049 #9 + ADR-051 #22)
   Persistent, high-visibility "du agerar som <namn>" shown at the top of <main>
   whenever the session carries an acting_on_behalf_of carrier. role="alert" +
   aria-live="assertive" in the template announce the proxy capacity. Amber
   (warning palette) signals "you are in a special mode", distinct from the page
   chrome, without the alarm of error-red. Inert on the dark deploy (the partial
   only renders when proxy_banner is truthy).
   Contrast: --kind-color-text on --kind-color-warning-bg is far past AA.
   --------------------------------------------------------------------------- */
.kind-proxy-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--kind-space-3);
  margin: 0 0 var(--kind-space-5) 0;
  padding: var(--kind-space-4) var(--kind-space-5);
  background: var(--kind-color-warning-bg);
  border: 1px solid var(--kind-color-warning);
  border-left-width: 6px;
  border-radius: var(--kind-radius);
  color: var(--kind-color-text);
}
.kind-proxy-banner__icon {
  font-size: 1.5rem;
  line-height: 1;
  flex: 0 0 auto;
}
.kind-proxy-banner__text {
  flex: 1 1 16rem;
  min-width: 0;
  font-weight: 700;
}
.kind-proxy-banner__sub {
  display: block;
  margin-top: var(--kind-space-1);
  font-weight: 400;
  font-size: 0.9375rem;
  color: var(--kind-color-text-muted);
}
/* CR-2: the exit is a CSRF POST form (POST-only /auth/avsluta-ombud), styled so
   the button reads exactly like the prior ghost link. The form is a layout
   passthrough; the button carries the >=44px target + focus ring from .kind-btn. */
.kind-proxy-banner__exit-form {
  flex: 0 0 auto;
  margin: 0;
}
.kind-proxy-banner__exit {
  flex: 0 0 auto;
}
@media (max-width: 32rem) {
  .kind-proxy-banner__exit-form {
    flex: 1 1 100%;
  }
  .kind-proxy-banner__exit {
    width: 100%;
  }
}

/* ----------------------------------------------------------------------------
 * 2.2 SHARED proxy / delegation / consent primitives (both portals), dark behind
 * the 2.2 flags. Tokens only so the dark colour-scheme + high-contrast mode are
 * free. Targets >= 44px; status is always conveyed by text, never colour alone.
 * -------------------------------------------------------------------------- */
.kind-section-title {
  margin: var(--kind-space-5) 0 var(--kind-space-3) 0;
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--kind-color-text);
}
.kind-divider {
  border: 0;
  border-top: 1px solid var(--kind-color-border);
  margin: var(--kind-space-5) 0;
}

/* Native checkbox/radio groups styled to the same 44px target as .kind-radio.
 * Used by the patient consent scope-picker (#22) AND the clinician guardian
 * intygande (#9), so they are shared. */
.kind-checkbox-group, .kind-radio-set { display: flex; flex-direction: column; gap: var(--kind-space-2); }
.kind-checkbox {
  display: flex;
  align-items: flex-start;
  gap: var(--kind-space-3);
  min-height: 44px;
  padding: var(--kind-space-3);
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius);
  cursor: pointer;
}
.kind-checkbox:hover { background: var(--kind-color-surface-muted); }
.kind-checkbox input[type="checkbox"],
.kind-checkbox input[type="radio"] {
  width: 1.25rem;
  height: 1.25rem;
  margin-top: 0.125rem;
  flex: 0 0 auto;
}
.kind-checkbox__body { display: flex; flex-direction: column; gap: 2px; }
.kind-checkbox__label { font-weight: 600; color: var(--kind-color-text); }
.kind-checkbox__help { font-size: 0.875rem; color: var(--kind-color-text-muted); }
/* The sensitive scope ("Provsvar och vårddokument") is visually set apart and
 * marked, so nobody shares more than intended. Never pre-checked. */
.kind-checkbox--sensitive { border-color: var(--kind-color-warning); border-left-width: 4px; }
.kind-checkbox--full { margin-top: var(--kind-space-3); border-top: 1px solid var(--kind-color-border); }

/* The honest-assurance line ("Kind kontrollerar inte er relation" /
 * "Du intygar ...") must be visible, never behind a "läs mer". */
.kind-assurance-line {
  margin: var(--kind-space-3) 0;
  padding: var(--kind-space-3);
  border-left: 4px solid var(--kind-color-accent);
  background: var(--kind-color-surface-muted);
  color: var(--kind-color-text);
  font-size: 0.9375rem;
}

/* ============================================================================
 * Säker fallback för omslagsbild (agents#102, CP-17)
 *
 * static/js/kind_omslag_fallback.js ERSÄTTER en <img data-kind-omslag-img> som
 * inte gick att ladda med ett <span> som bär bildens EGNA klasser plus den här.
 * Det är därför regeln inte behöver känna till någon enskild yta: boxen (56x56 i
 * patientbiblioteket, 44x44 i vårdgivarlistan, 200px i förhandsvisningen) kommer
 * från bildens egen klass, och det här arket lägger bara på det neutrala
 * utseendet ovanpå.
 *
 * Varför i BASARKET och inte i kind_patient.css / kind_admin.css: kind.css
 * laddas på varje sida, så samma regel når alla tre ytorna utan dubblering.
 *
 * Ett elementBYTE, inte en gömd bild: en trasig <img> ritar sin trasig-bild-ikon
 * ovanpå allt bakom sig, så ett lager under hade inte tagit bort ikonen. Bytet
 * gör dessutom ::after möjlig, vilket en <img> som ersatt element inte stöder.
 */
.kind-omslag-fallback {
  position: relative;
  box-sizing: border-box;
  /* Biter bara när en dimension är auto, alltså enbart i vårdgivarens
     förhandsvisning (.kind-omslag__preview-img har height: auto). I de två
     listorna är båda måtten satta och aspect-ratio ignoreras, så radgeometrin
     är oförändrad. */
  aspect-ratio: 1 / 1;
  min-height: 44px;
  background-color: var(--kind-color-accent-soft);
}
.kind-omslag-fallback::after {
  content: "";
  position: absolute;
  inset: 18%;
  background-color: var(--kind-color-accent);
  -webkit-mask: var(--kind-icon-bok) center / contain no-repeat;
  mask: var(--kind-icon-bok) center / contain no-repeat;
}

/* ==========================================================================
 * DEN DELADE ARTIKELRADEN, CP-11 (#96) och CP-12 (#97).
 *
 * Markup: templates/_artikelrad.html. Konsumenter: vårdgivarens
 * artikelbibliotek (templates/admin/artiklar.html) och artikelväljaren i
 * skrivmodulen (templates/admin/_chat_composer.html).
 *
 * VARFÖR I BASARKET OCH INTE I kind_admin.css. Samma skäl som
 * `.kind-omslag-fallback` några block upp: raden är avsedd att på sikt bäras av
 * BÅDE patient- och vårdgivarytorna (#96: "bygg den inte tre gånger"), och en
 * regel som ligger i ett domänark måste flyttas den dagen, vilket är precis den
 * sorts flytt som glöms. Basarket laddas på varje sida, så komponenten är
 * nåbar överallt utan att dupliceras.
 *
 * FORMEN ÄR CP-09:s, MED FLIT. `.kind-library-item` i kind_patient.css bär
 * samma informationshierarki och samma 56px-omslag
 * (docs/design/bibliotek-cp09-cp10.md §7). Avvikelser mot den formen ska
 * motiveras här, inte upptäckas.
 *
 * OMSLAGET ÄR 56px, ALDRIG EN HERO. Låst nedan och vaktat av
 * tests/test_cp11_artikelbibliotek.py. Ett omslag som får växa äter första
 * viewporten, alltså blir delkravet uppfyllt medan utfallet blir sämre.
 * ========================================================================== */
.kind-artikelrad-lista {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-2);
}
.kind-artikelrad { margin: 0; }
/* HELA RADEN ÄR TRÄFFYTAN, ett tabbstopp och en 56px-hög yta.
 *
 * Uppmätt före CP-11: den gamla tabellen hade 40 "Redigera"-textlänkar à 18px,
 * alltså 40 brott mot både WCAG 2.2 AA 2.5.8 (24px) och vårt strängare
 * 44px-golv, på EN sida. Att göra raden till länken tar bort alla 40 på en
 * gång i stället för att förstora fyrtio små länkar. */
.kind-artikelrad__link,
.kind-artikelrad__val {
  display: flex;
  align-items: center;
  gap: var(--kind-space-3);
  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-artikelrad__link:hover,
.kind-artikelrad__val:hover { background: var(--kind-color-surface-muted); }
.kind-artikelrad__link:focus-visible {
  outline: var(--kind-focus-ring);
  outline-offset: 2px;
}
/* Väljarraden fokuseras via sin radioknapp, inte via <label>, så fokusringen
   ritas på raden när kontrollen inuti har fokus. :focus-within och inte en
   JS-satt klass: tillståndet ÄR fokus, och webbläsaren äger det. */
.kind-artikelrad__val:focus-within {
  outline: var(--kind-focus-ring);
  outline-offset: 2px;
}
.kind-artikelrad__val input[type="radio"] {
  flex: 0 0 auto;
  margin: 0;
  width: 20px;
  height: 20px;
  accent-color: var(--kind-color-accent);
}
.kind-artikelrad__body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
/* Brytreglerna är CP-09:s, av samma uppmätta skäl: 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.
   `<html lang="sv">` gör `hyphens: auto` verksam. */
.kind-artikelrad__titel {
  font-family: var(--kind-font-serif);
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--kind-color-text);
  overflow-wrap: break-word;
  hyphens: auto;
  /* #158: avstavningen får BARA gälla de långa sammansättningarna den skrevs
     för. `hyphens: auto` avstavar när det förbättrar radutfyllnaden, inte bara
     när ordet måste brytas, så den delade "ef-ter", "om-slag" och "fun-gerar"
     i titlar som hade gott om plats (uppmätt 2026-08-10 på driftsatt 2.3.4).
     12 tecken är golvet: varje vanligt svenskt ord upp till 11 tecken slutar
     avstavas, medan "knäoperation" (12), "artikelfunktionen" (17) och
     "Egenvårdsrekommendationer" (24) behåller sin avstavning och därmed sitt
     bindestreck, vilket är ett bättre brott än break-words hårda kapning.
     3 före/efter i stället för 4, annars förbjuds "knä-operation".
     Till skillnad från den delade brytregeln (se #158-blocket längre upp)
     KRYMPER avstavningen inte den här boxen: `.kind-artikelrad__body` är
     `flex: 1 1 auto; min-width: 0`, alltså storleksatt av sin behållare och
     inte av sitt innehåll, och bärarsvepet mätte noll växta boxar här.
     Där stödet saknas faller egenskapen tyst tillbaka på dagens beteende. */
  hyphenate-limit-chars: 12 3 3;
}
.kind-artikelrad__meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--kind-space-2);
  font-size: var(--kind-font-small);
  color: var(--kind-color-text-muted);
  overflow-wrap: break-word;
}
.kind-artikelrad__datum { white-space: nowrap; }
/* TAGGCHIPSEN (briefens §7.5, migration 0077).

   INGEN EGEN RAD. Behållaren är `display: contents`, alltså har den ingen egen
   låda: chipsen blir direkta flex-barn till `.kind-artikelrad__meta` och lägger
   sig efter status och datum på SAMMA rad. Ryms de kostar de noll höjd; ryms de
   inte bryter metaraden, precis som den redan gör för status plus datum på de
   smalaste bredderna. En egen `<span>`-låda hade i stället alltid lagt en ny
   rad per artikelrad, på en rad vars underkant vid 320 xxlarge redan låg åtta
   pixlar över taket (docs/design/vardgivarklustret-cp11-cp12-cp14.md §4).

   Chippet är TEXT och inte en kontroll: det ligger inuti radens länk respektive
   label, är inte ett eget tabbstopp och behöver därför inget 44px-golv (samma
   resonemang som åtgärdsmärket nedan). Färgerna är befintliga tokens, inga nya
   värden: `--kind-color-text-muted` på `--kind-color-surface-muted` är samma par
   som metaraden redan använder. */
.kind-artikelrad__taggar { display: contents; }
/* ---- OCH VARFÖR DE ÄNDÅ INTE SYNS VID MOBILSTACKNING -------------------

   UPPMÄTT, inte uppskattat. Med chipsen synliga på alla bredder föll antalet
   HELA artikelrader i första viewporten på SEX av tio mobila mätpunkter
   (375 normal 2->1, 375 xxlarge 1->0, 390 normal 2->1, 390 xxlarge 1->0,
   412 normal 2->1, 430 normal 2->1), medan desktoptalen var oförändrade
   (1280 normal 5, 1280 xxlarge 2, 1440 normal 6, 1440 xxlarge 3). Vid smal
   bredd ryms chipsen inte på metaraden, så den bryter och varje rad blir
   drygt en textrad högre. Det är exakt #56-felet: delkravet "taggarna syns"
   uppfyllt medan UTFALLET, hur många artiklar man ser utan att skrolla, blev
   sämre. Kunden bad om att hitta rätt artikel snabbare.

   SÖKNINGEN PÅVERKAS INTE. `data-artikel-sok` byggs av servern och bär alla
   taggar oavsett bredd, så "sök på titel och tagg" (briefens §7.5) gäller
   ordagrant lika på 320px som på 1440px. Det som utelämnas vid smal bredd är
   den visuella upprepningen av något användaren redan kan söka på.

   Brytpunkten 900px är samma som bibliotekets sök- och filterpanel redan
   fäller ihop på, inte ett nytt tal.

   Att i stället visa ETT chip vid smal bredd prövades inte, eftersom en enda
   lång svensk sammansättning ("graviditetsuppföljning") ensam fyller
   metaradens återstående bredd vid 320px och därmed ger samma radbrytning. */
@media (max-width: 900px) {
  .kind-artikelrad__taggar { display: none; }
}
.kind-artikelrad__tagg {
  display: inline-block;
  padding: 0 var(--kind-space-2);
  border-radius: var(--kind-radius-pill);
  background: var(--kind-color-surface-muted);
  color: var(--kind-color-text-muted);
  font-size: var(--kind-font-small);
  line-height: 1.6;
  /* Ett chip bryter aldrig mitt i ett ord: en avbruten "graviditetsuppföljning"
     är oläsbar som etikett. Bryter det inte får metaraden i stället wrappa,
     vilket är det billigare felet. */
  white-space: nowrap;
  /* Taket är en TREDJEDEL av radbredden. En enskild extremt lång sammansättning
     får alltså inte ensam spränga raden; den kapas med ellips, och hela värdet
     finns kvar i sökningen (data-artikel-sok) och i `+N`-märkets title. */
  max-width: 33%;
  overflow: hidden;
  text-overflow: ellipsis;
}
.kind-artikelrad__tagg--fler { font-variant-numeric: tabular-nums; }
/* Förhandsgranskningen (CP-12) är TVÅ rader, inte fri höjd. En obegränsad
   förhandsgranskning gör varje rad olika hög och förstör skannbarheten, som är
   hela poängen med väljaren. `line-clamp` är avkortning och INTE hopfällning,
   vilket är tillåtet just här: texten är ett utdrag ur artikeln och inte ett
   informationsbärande värde, och hela artikeln nås genom att välja raden. */
.kind-artikelrad__preview {
  font-size: var(--kind-font-small);
  color: var(--kind-color-text-muted);
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
}
/* [hidden]-gard: `display: -webkit-box` slar UA-lagrets `[hidden]`.
   Prototypen i templates/_artikelrad.html:297 renderar slotten `hidden` och
   kind_artikelvaljare.js tander den forst nar artikeln BAR ett utdrag. Utan
   garden hade en tom slot varit malad; att den inte syns i dag beror pa att
   skriptet tar bort noden i else-grenen, alltsa pa en andra mekanism och inte
   pa att `hidden` fungerar. */
.kind-artikelrad__preview[hidden] { display: none; }
/* K10 (#197, 2026-08-12): HÄR STOD `.kind-artikelrad__redigera`, åtgärdsmärket i
   biblioteksraden. Märket är borttaget ur mallen (hela raden är redan länken
   till redigeringsvyn, så märket namngav radens åtgärd en andra gång och kostade
   8 av de 29 tecken per rad kunden reagerade på), och INGEN yta renderar klassen
   längre: väljarens prototyp har aldrig burit den. Regeln togs därför bort i
   samma ändring i stället för att bli en död selektor.
   Kontrasten den motiverade finns kvar i ADR-065:s normerande matris, den var
   aldrig ett eget tokenvärde. */
.kind-artikelrad__omslag {
  flex: 0 0 auto;
  width: 56px;
  height: 56px;
  border-radius: var(--kind-radius);
  /* Laddningstillståndet: den neutrala rutan syns tills bilden kommit fram.
     `loading="lazy"` gör att en rad långt ned aldrig hämtar sitt omslag alls,
     så rutan är det permanenta tillståndet för det som inte skrollats fram. */
  background: var(--kind-color-surface-muted);
  overflow: hidden;
}
.kind-artikelrad__omslag--standard {
  display: flex;
  align-items: center;
  justify-content: center;
  /* Plattan läses ur `--kind-omslag-platta`, som variantregeln nedan sätter.
     Fallbacken är den gamla accentfärgen, så en wrapper UTAN variantklass
     renderar byte för byte som före #199. */
  background: var(--kind-omslag-platta, var(--kind-color-accent-soft));
}
/* K10 (#199): HÄRLEDD OMSLAGSPALETT för artiklar utan egen omslagsbild.
 *
 * Fallbacken var identisk på varje rad, och med 11 av 14 rader i fallback läste
 * omslagskolumnen som en repeterande textur i stället för det kunden berömde i
 * nuvarande KIND ("Och så en fin bild", Annica 2026-08-11). Varianten härleds
 * ur artikelns id i app/shared/omslagsvariant.py; HÄR bor bara utseendet.
 *
 * VARJE PAR ÄR BEFINTLIGA TOKENS, aldrig en ny hex. Det är vad som gör att
 * temaväxling, mörkt läge och high-contrast följer med gratis: i high-contrast
 * plattar tinterna ut till vitt respektive svart (max kontrast vinner,
 * dekoration drar sig undan, NIGHT-PASS 2026-06-04), alltså slutar varianterna
 * skilja sig åt just där, vilket är avsiktligt och inte en miss.
 *
 * KONTRAST ÄR MÄTT, INTE GISSAD. tests/test_omslagsvariant.py mäter varje
 * variant mot ALLA FYRA tokenuppsättningarna (ljus, mörk, ljus HC, mörk HC) och
 * i TVÅ par per uppsättning, streck mot sidfyllningen och streck mot plattan,
 * alltså 48 mätpunkter, mot golvet 3:1 för grafiska objekt (WCAG 2.2 AA 1.4.11,
 * W3C Recommendation 2023-10-05). Lägsta uppmätta värde är 4.42:1. Golvet hålls
 * trots att bilden är DEKORATIV och därmed formellt undantagen från 1.4.11:
 * kravet är "en fin bild", och en teckning som inte går att se är inte det.
 *
 * ---- EN PALETT, TVÅ BÄRARE, NOLL KASKADSTRID (#201, 2026-08-12) ----------
 *
 * Mekanismen har tre bärare: vårdgivarens biblioteksrad (`.kind-artikelrad__
 * omslag`, kind.css), patientens biblioteksrad (`.kind-library-item__thumb`,
 * kind_patient.css) och delningsväljarens klonade prototyp (som bär
 * vårdgivarens klass). #199 åtgärdade den första. Att lägga en ANDRA
 * uppsättning färgregler i kind_patient.css hade varit exakt den dubblering
 * det här arbetet finns för att ta bort, och vakten nedan läser bara kind.css,
 * alltså hade driften dessutom varit tyst. Regeln bär därför BÅDA selektorerna
 * och deklarationerna står EN gång.
 *
 * VARFÖR REGELN SÄTTER TVÅ CUSTOM PROPERTIES I STÄLLET FÖR `background`.
 * base.html laddar kind.css FÖRE `per_domain_css`, alltså före
 * kind_patient.css. Skrev variantregeln `background` direkt hade
 * `.kind-library-item__thumb--default` (samma specificitet 0-1-0, SENARE
 * stilmall) vunnit på KÄLLORDNING och plattan hade blivit identisk på varje
 * patientrad medan bara strecket varierade, alltså en HALV fix som ser hel ut.
 * Företrädet avgörs här av ursprung och ordning, inte av specificitet (W3C CSS
 * Cascading and Inheritance Level 5, Cascade Sorting Order). Med indirektionen
 * finns `--kind-omslag-platta` bara i EN regel, och `background`-deklarationen
 * bor i respektive blocks basklass, så de två stilmallarna konkurrerar inte
 * alls. Det gör också ordningen mellan `--standard` och varianterna
 * OVIDKOMMANDE, till skillnad från före #201.
 *
 * Lägger du till en variant: lägg namnet i OMSLAGSVARIANTER i samma ändring,
 * och skriv BÅDA selektorerna i den ordning som står nedan. Vakten
 * (`tests/test_omslagsvariant.py`) läser paletten ur en regex som kräver just
 * det paret, och jämför namnmängderna i BÅDA riktningar mot Python-listan, så
 * en variant utan färger, en död CSS-regel och en variant som bara finns på
 * den ena ytan är lika omöjliga. */
.kind-artikelrad__omslag--accent,
.kind-library-item__thumb--accent {
  --kind-omslag-platta: var(--kind-color-accent-soft);
  --kind-omslag-strec: var(--kind-color-accent);
}
.kind-artikelrad__omslag--lavendel,
.kind-library-item__thumb--lavendel {
  --kind-omslag-platta: var(--kind-tint-lavender);
  --kind-omslag-strec: var(--kind-color-accent-hover);
}
.kind-artikelrad__omslag--mynta,
.kind-library-item__thumb--mynta {
  --kind-omslag-platta: var(--kind-tint-mint);
  --kind-omslag-strec: var(--kind-color-success);
}
.kind-artikelrad__omslag--smor,
.kind-library-item__thumb--smor {
  --kind-omslag-platta: var(--kind-tint-butter);
  --kind-omslag-strec: var(--kind-color-warning);
}
.kind-artikelrad__omslag--rodnad,
.kind-library-item__thumb--rodnad {
  --kind-omslag-platta: var(--kind-tint-blush);
  --kind-omslag-strec: var(--kind-color-error);
}
.kind-artikelrad__omslag--skiffer,
.kind-library-item__thumb--skiffer {
  --kind-omslag-platta: var(--kind-color-surface-muted);
  --kind-omslag-strec: var(--kind-color-border-strong);
}
.kind-artikelrad__omslag-bild,
.kind-artikelrad__omslag-img {
  display: block;
  width: 100%;
  height: 100%;
}
.kind-artikelrad__omslag-img { object-fit: cover; }
/* Vid mycket smal yta bryter raden hellre än att texten kläms ihop till en
   kolumn på tre tecken. Radens hierarki är densamma, den är bara staplad, och
   ingen `order` används: DOM-ordningen ÄR den visuella ordningen även efter
   brytningen (titel och metarad först, sedan omslaget; åtgärdsmärket som stod
   här emellan togs bort i K10/#197). */
@media (max-width: 400px) {
  .kind-artikelrad__link,
  .kind-artikelrad__val {
    flex-wrap: wrap;
  }
  .kind-artikelrad__body { flex: 1 1 100%; }
}
/* ---- OCH VARFÖR BRYTPUNKTEN INTE KAN VARA ETT ENDA TAL ------------------

   VARFÖR: brytpunkten ovan är ett FAST pixeltal, medan storheten den vaktar,
   titelkolumnens bredd, är rem-baserad så när som på omslagets 56px. Kromet
   kring titeln kostar 206px vid normal skala och 276px vid xxlarge, alltså kan
   samma tal inte vara rätt vid båda. Vid 401px och xxlarge slutade regeln gälla
   och titelkolumnen kollapsade från 302px till 125px medan viewporten VÄXTE en
   pixel: uppmätt 2026-08-08 bröts titeln teckenvis, "Sömnsvår / igheter och /
   återhämtn / ing", alltså exakt det kommentaren ovan säger att regeln finns
   för att förhindra. Frågan var ställd i VIEWPORT-bredd medan svaret hänger på
   TILLGÄNGLIG KOLUMNBREDD.

   VARFÖR 580 OCH INTE 900: uppmätt, inte uppskattat
   (`e2e/diag-artikelrad-brytpunkt.mjs`, finsvep 400-640px i steg om 10px, 40
   artiklar i tyngsta tillståndet). Vid xxlarge är det staplade läget lägre än
   enradsläget upp till 510px på medelhöjd och 590px på maxhöjd; först vid 600px
   vinner enradsläget klart (143,8 mot 190,5px medel). 580 är den sista bredd
   där staplat fortfarande vinner på max och medelskillnaden är 3,2px, och den
   ligger över de 566px samma titelbredd i EM som basregeln garanterar skulle
   kräva. Att i stället flytta 400 till 900 hade tvingat staplat läge även vid
   NORMAL skala mellan 401 och 900, där enradsläget är 19px KORTARE per rad
   (146,4 mot 164,6 vid 412), alltså slösad höjd på varenda rad utan att lösa
   något. Basregeln ovan är därför orörd och normal skala beter sig exakt som
   före den här ändringen.

   VARFÖR BARA xxlarge: också ett mätt bortval. Vid xlarge och 412px är lägena
   likvärdiga (staplat 186px medel mot enradigt 180,5px, alltså 5,5px till
   enradslägets fördel på det mått som styr hur många rader som ryms), och vid
   large vinner enradsläget redan från 400px. Att stapla där hade kostat höjd i
   ett band ingen mätning täcker. Talen står i
   docs/design/vardgivarklustret-cp11-cp12-cp14.md §12.

   VARFÖR SELEKTOR OCH INTE CONTAINER QUERY: en `@container`-fråga i `em` hade
   varit den rena lösningen, eftersom `em` i en containerfråga löses mot
   containerns egen teckenstorlek och därmed skalar av sig själv (en
   media-fråga kan det inte: dess `em` och `rem` löses mot webbläsarens
   ursprungsvärde och ser aldrig vår skalning). Den kräver dock `container-type:
   inline-size` på artikelraden, som är EN komponent delad mellan biblioteket
   och artikelväljaren i skrivmodulen, alltså en ändring av layoutberäkningen
   för allt inuti båda ytorna. Samma avvägning gjordes redan två gånger i
   kind_admin.css (rad 926 och 6217) med samma utfall. Selektormekaniken nedan
   är husets form (kind_admin.css rad 5723) och har noll blastradie utanför sin
   egen skala.

   VAKT: `e2e/artikelrad-brytpunkt.mjs` mäter utfallet i den riktiga kaskaden,
   och `tests/test_cp11_artikelbibliotek.py` håller talen i synk. */
@media (max-width: 580px) {
  html[data-kind-font-scale="xxlarge"] .kind-artikelrad__link,
  html[data-kind-font-scale="xxlarge"] .kind-artikelrad__val {
    flex-wrap: wrap;
  }
  html[data-kind-font-scale="xxlarge"] .kind-artikelrad__body { flex: 1 1 100%; }
}

/* ---------------------------------------------------------------------------
   web#225: ARTIKELBILAGOR, listraden.

   EN komponent för fyra ytor: vårdgivarens artikelformulär (både de SPARADE
   raderna och de VALDA-men-osparade som `kind_artikel_bilagor.js` ritar),
   vårdgivarens läsläge, och patientens artikel. Alex text beskriver samma rad
   på alla: "en rad med en ikon för filtypen, filnamnet och ett kryss". En
   gemensam regel är därför inte snålhet, det är vad kravet säger.

   Den ligger i `kind.css` och inte i `kind_admin.css` eller `kind_patient.css`
   av precis det skälet: den bärs av BÅDA portalerna, och en kopia i vardera
   hade kunnat drifta isär i en yta ingen tittar på.

   Ingen egen färgpalett och inga nya tokens: raden ärver husets typografi och
   knappstilar, så den följer kontrast- och textskalningsinställningarna som
   allt annat. Ikonen är dekorativ (`aria-hidden` i markupen) och bär aldrig
   typinformationen ensam — den skärmläsarlästa raden har typnamnet i klartext.
   --------------------------------------------------------------------------- */
.kind-bilagelista {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
}

/* web#225 (underkännandet 2026-09-25): "Ladda upp bilaga" i SKAPANDELÄGET.
   Knappen är en `<label for>` över filfältet, inte en `<button>`, så den
   öppnar filväljaren utan en rad JavaScript — se mallens not i
   `templates/admin/artikel_form.html`.

   TVÅ LÄGEN, OCH BÅDA ÄR AVSIKTLIGA:
   * utan skript ligger den inbyggda filkontrollen kvar SYNLIG under knappen,
     eftersom webbläsarens egen "3 filer"-text då är den enda återkopplingen
     på vad som valts;
   * med skript sätter `kind_artikel_bilagor.js` klassen
     `kind-bilagevaljare--js`, den inbyggda kontrollen göms visuellt (men
     ligger kvar i tabbordningen och i tillgänglighetsträdet, samma teknik som
     `.kind-visually-hidden`), och raderna med ikon + filnamn + "Ta bort" tar
     över återkopplingen.

   Fokusringen får inte försvinna med kontrollen: den gömda inputen behåller
   fokus, så ringen flyttas till knappen med en syskonselektor. Ordningen
   input-före-label i markupen är därför load-bearing. */
.kind-bilagevaljare {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.5rem;
}

.kind-bilagevaljare__knapp {
  cursor: pointer;
}

.kind-bilagevaljare--js .kind-bilagevaljare__input {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
  min-height: 0;
}

.kind-bilagevaljare--js .kind-bilagevaljare__input:focus + .kind-bilagevaljare__knapp,
.kind-bilagevaljare--js .kind-bilagevaljare__input:focus-visible + .kind-bilagevaljare__knapp {
  outline: var(--kind-focus-ring);
  outline-offset: 2px;
}

.kind-bilagelista__rad {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.35rem 0;
  border-bottom: 1px solid var(--kind-border, #e2e2e2);
}

.kind-bilagelista__rad:last-child {
  border-bottom: 0;
}

.kind-bilagelista__ikon {
  flex: 0 0 auto;
  font-size: 1.1em;
  line-height: 1;
}

/* Filnamnet får ta plats och bryta: det är användarstyrd text och kan vara
   långt. `min-width: 0` är det som gör att flexbarnet FÅR krympa i stället för
   att trycka ut borttagningsknappen ur raden. */
.kind-bilagelista__namn {
  flex: 1 1 auto;
  min-width: 0;
  overflow-wrap: anywhere;
}

.kind-bilagelista__ta-bort {
  flex: 0 0 auto;
}

/* Bilageräknaren under artikelns titel ("3 bilagor"), patientens läsvy. */
.kind-article__bilagerakning {
  margin: 0.25rem 0 0;
}

.kind-article__bilagor {
  margin-top: 1.5rem;
}

.kind-article__bilagor-rubrik {
  font-size: 1rem;
  margin-bottom: 0.25rem;
}

/* Uppspelningssidan. `max-width: 100%` håller videon inne på smala skärmar;
   höjden får följa materialets proportioner i stället för en fast ruta. */
.kind-bilaga-video {
  display: block;
  width: 100%;
  max-width: 100%;
  height: auto;
  background: #000;
}

/* ============================================================================
 * web#627 skiva 1 -- vårdgivarens arbetsytelåda ("Workspaces")
 * ----------------------------------------------------------------------------
 * Kontrollen som öppnar lådan ÄR `.kind-workspace-switch` (samma slot, samma
 * klass som textlänken den ersätter, se templates/admin/_arbetsytelada.html),
 * så dess korgchrome kommer fortsatt från kind_admin.css. Det som behövs här
 * är dels knappåterställningen (`<button>` ärver inte font/align som ett
 * `<a>`), dels loggan/initialen i kontrollen, dels hela lådan.
 *
 * HÄR och inte i kind_admin.css: `kind_admin.css` laddas per mall via
 * `{% block per_domain_css %}` och saknas på ett par vårdgivarytor (bl.a.
 * templates/admin/support.html och kollegielista.html), medan lådan ligger i
 * det DELADE sidhuvudet och alltså renderas på dem alla. En låda vars panel
 * saknar `position: fixed` hade blivit en lång lista mitt i sidhuvudet.
 * ========================================================================== */

/* Knappåterställning: kontrollen var ett <a> och är nu ett <button>. */
.kind-workspace-switch--lada {
  font: inherit;
  text-align: left;
  cursor: pointer;
}

/* Arbetsytans logga respektive dess initial, i kontrollen. Initialen är gamla
   KIND:s reserv när arbetsytan saknar logga: namnets första bokstav som
   versal, i samma rundel som ikonen hade. */
.kind-workspace-switch__logga,
.kind-workspace-switch__initial {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: var(--kind-radius-pill);
  object-fit: cover;
  background: var(--kind-color-accent-bg);
  color: var(--kind-color-accent);
  font-size: 1rem;
  font-weight: 700;
  line-height: 1;
}

/* Lådan ligger över sidan, inte i sidhuvudets flöde. Utan JS är den `hidden`,
   och `[hidden]`-regeln nedan vinner över `display: flex` eftersom den står
   senare med samma specificitet.

   STAPLINGEN ÄR MÄTT, INTE GISSAD (PR #1061, granskning 2026-10-06). Lådans
   första talval (60/61) gjorde fotraden OKLICKBAR: `tvaflikar-121` fällde på
   att `<nav class="kind-vardnav">` avlyssnade klicket på "Logga ut".
   Vårdgivarens chrome har två FASTA ytor som båda ligger vid skärmkanten och
   båda står i `kind_admin.css`, inte här:

     .kind-vardnav      position: fixed; bottom: 0;  z-index: 200
     .kind-vardnav__ark position: fixed;             z-index: 210

   Det undre bandet är 80px högt och fäst mot `bottom: 0` -- alltså exakt där
   lådans fot ("Logga ut" till vänster, "Inställningar" till höger) sitter, och
   lådan är `inset-block: 0`, så överlappet är oundvikligt i varje geometri.
   Med 61 < 200 ritades foten UNDER bandet och bandet tog emot pekaren.

   Därför ligger lådan över BÅDA: overlayen på 220 och panelen på 221, alltså
   över 210 med marginal, och panelen ett steg över sin egen overlay. Overlayen
   måste också ligga över bandet -- den är en `aria-modal`-dialogs modala skikt,
   så vårdnavigeringen ska inte kunna klickas bakom en öppen låda.

   TALEN BETYDER INGENTING UTAN DOM-PLATSEN, och det är den andra halvan av
   samma defekt: dialogen renderades först INUTI `<header class="kind-header">`,
   som är `position: sticky` och därmed alltid en egen staplingskontext. Allt
   inuti sidhuvudet jämförs med resten av sidan som EN ruta på sidhuvudets eget
   `z-index: 100` -- så 221 inuti sidhuvudet förlorar fortfarande mot ett band
   på 200 på body-nivå, och `tvaflikar-121` fällde en andra gång, nu på
   "Inställningar". Dialogen renderas sedan dess efter `</header>`, som syskon
   till bandet (templates/base.html), medan kontrollen stannar i sidhuvudet.
   Den placeringen är pinnad av
   tests/test_627_arbetsytelada_vardgivare.py
   ::test_ladan_ligger_utanfor_det_sticky_sidhuvudets_staplingskontext, som
   mäter den RENDERADE markupen.

   TALEN ÄR ETT FÖRHÅLLANDE ÖVER FILGRÄNSEN, och det förhållandet är pinnat i
   tests/test_627_arbetsytelada_vardgivare.py
   ::test_ladan_staplar_over_varje_fast_yta_i_vardgivarens_chrome, som läser
   BÅDA stilmallarna och faller om någon fast yta i chromet får ett högre tal
   än lådan. Ändra inte ett av talen utan att läsa det provet: en siffra som
   bara stämmer när båda filerna råkar ha dagens värden är precis den
   ömtålighet granskningen pekade på. */
.kind-vardlada__overlay {
  position: fixed;
  inset: 0;
  z-index: 220;
  background: rgb(0 0 0 / 35%);
}
.kind-vardlada {
  position: fixed;
  inset-block: 0;
  inset-inline-start: 0;
  z-index: 221;
  display: flex;
  flex-direction: column;
  width: min(20rem, 90vw);
  padding: var(--kind-space-4);
  gap: var(--kind-space-3);
  overflow-y: auto;
  background: var(--kind-color-surface);
  color: var(--kind-color-text);
  border-inline-end: 1px solid var(--kind-color-border);
}
.kind-vardlada[hidden],
.kind-vardlada__overlay[hidden] {
  display: none;
}
.kind-vardlada__huvud {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--kind-space-3);
}
.kind-vardlada__rubrik {
  margin: 0;
  font-size: var(--kind-font-h3, 1.125rem);
}
.kind-vardlada__stang {
  flex: none;
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  font: inherit;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--kind-color-text);
  background: none;
  border: 1px solid transparent;
  border-radius: var(--kind-radius);
  cursor: pointer;
}
.kind-vardlada__sokfalt {
  width: 100%;
  min-height: 44px;
  padding: var(--kind-space-2) var(--kind-space-3);
  font: inherit;
  color: var(--kind-color-text);
  background: var(--kind-color-bg);
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius);
}
.kind-vardlada__lista {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--kind-space-1);
}
.kind-vardlada__rad[hidden] {
  display: none;
}
.kind-vardlada__form {
  margin: 0;
}
.kind-vardlada__radinnehall {
  display: flex;
  align-items: center;
  gap: var(--kind-space-3);
  width: 100%;
  min-height: 44px;
  padding: var(--kind-space-2);
  border-radius: var(--kind-radius);
}
.kind-vardlada__byt {
  font: inherit;
  text-align: left;
  color: var(--kind-color-text);
  background: none;
  border: 1px solid transparent;
  cursor: pointer;
}
.kind-vardlada__byt:hover {
  background: var(--kind-color-accent-bg);
  border-color: var(--kind-color-accent);
}
/* Den aktiva raden är markerad och är med avsikt INGEN knapp -- ett tryck på
   den gör ingenting i gamla KIND, så den ligger inte i tabbordningen. */
.kind-vardlada__rad--aktiv > .kind-vardlada__radinnehall {
  background: var(--kind-color-accent-bg);
  border: 1px solid var(--kind-color-accent);
  font-weight: 600;
}
.kind-vardlada__logga,
.kind-vardlada__initial {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 2rem;
  height: 2rem;
  border-radius: var(--kind-radius-pill);
  object-fit: cover;
  background: var(--kind-color-accent-bg);
  color: var(--kind-color-accent);
  font-weight: 700;
  line-height: 1;
}
.kind-vardlada__namn {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* web#733: talet vid en ICKE-aktiv arbetsyta och pricken på kontrollen,
 * samma röst som vårdnavets bricka (.kind-vardnav__badge). */
.kind-vardlada__bricka {
  margin-inline-start: auto;
  min-width: 18px;
  height: 18px;
  padding-inline: 5px;
  border-radius: var(--kind-radius-pill);
  background: var(--kind-color-accent);
  color: var(--kind-color-bg);
  font-size: 0.8125rem;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}
.kind-workspace-switch--lada {
  position: relative;
}
.kind-workspace-switch__prick {
  position: absolute;
  top: 2px;
  inset-inline-start: 2px;
  width: 10px;
  height: 10px;
  border-radius: var(--kind-radius-pill);
  background: var(--kind-color-accent);
  box-shadow: 0 0 0 2px var(--kind-color-bg);
  pointer-events: none;
}
/* "Logga ut" till vänster och "Inställningar" till höger, längst ned i lådan
   (gamla KIND, fångst 09). `margin-block-start: auto` trycker foten till
   botten även i en kort lista. */
.kind-vardlada__fot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--kind-space-3);
  margin-block-start: auto;
  padding-block-start: var(--kind-space-3);
  border-block-start: 1px solid var(--kind-color-border);
}
.kind-vardlada__utloggning {
  margin: 0;
}
.kind-vardlada__fotknapp {
  min-height: 44px;
  padding: var(--kind-space-2) var(--kind-space-3);
  font: inherit;
  font-weight: 600;
  color: var(--kind-color-text);
  background: none;
  border: 1px solid var(--kind-color-border);
  border-radius: var(--kind-radius);
  cursor: pointer;
}
.kind-vardlada__fotlank {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: var(--kind-space-2) var(--kind-space-3);
  font-weight: 600;
  color: var(--kind-color-text);
}

/* web#734 skiva 2b: väntande inbjudan i lådan Workspaces + Join-dialogen. */
.kind-vardlada__inbjudan > summary {
  cursor: pointer;
  list-style: none;
}
.kind-vardlada__inbjudan > summary::-webkit-details-marker {
  display: none;
}
.kind-vardlada__aktivera {
  margin-inline-start: auto;
  font-size: 0.875rem;
  color: var(--kind-color-accent);
}
.kind-vardlada__joindialog {
  padding: 0.75rem;
  border: 1px solid var(--kind-color-accent);
  border-radius: 0.5rem;
  margin-block: 0.25rem 0.5rem;
}
.kind-vardlada__joindialog p {
  margin: 0 0 0.25rem;
}
