@innspel/react-native 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/index.cjs +41 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -7
- package/dist/index.d.ts +11 -7
- package/dist/index.js +41 -34
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/InnspelProvider.tsx","../src/skjermbilde.ts","../src/tema.ts","../src/generated/tokens.ts","../src/widget/Widget.tsx","../src/Ikon.tsx","../../../node_modules/ionicons/dist/svg/add-outline.svg","../../../node_modules/ionicons/dist/svg/arrow-back-outline.svg","../../../node_modules/ionicons/dist/svg/brush-outline.svg","../../../node_modules/ionicons/dist/svg/bug.svg","../../../node_modules/ionicons/dist/svg/bug-outline.svg","../../../node_modules/ionicons/dist/svg/bulb.svg","../../../node_modules/ionicons/dist/svg/calendar-outline.svg","../../../node_modules/ionicons/dist/svg/camera-outline.svg","../../../node_modules/ionicons/dist/svg/chatbox-outline.svg","../../../node_modules/ionicons/dist/svg/checkmark-circle-outline.svg","../../../node_modules/ionicons/dist/svg/checkmark-outline.svg","../../../node_modules/ionicons/dist/svg/chevron-down-outline.svg","../../../node_modules/ionicons/dist/svg/chevron-forward-outline.svg","../../../node_modules/ionicons/dist/svg/chevron-up-outline.svg","../../../node_modules/ionicons/dist/svg/close-circle-outline.svg","../../../node_modules/ionicons/dist/svg/close-outline.svg","../../../node_modules/ionicons/dist/svg/cloud-offline-outline.svg","../../../node_modules/ionicons/dist/svg/construct-outline.svg","../../../node_modules/ionicons/dist/svg/contrast-outline.svg","../../../node_modules/ionicons/dist/svg/ellipse-outline.svg","../../../node_modules/ionicons/dist/svg/exit-outline.svg","../../../node_modules/ionicons/dist/svg/flask-outline.svg","../../../node_modules/ionicons/dist/svg/grid-outline.svg","../../../node_modules/ionicons/dist/svg/hourglass-outline.svg","../../../node_modules/ionicons/dist/svg/image-outline.svg","../../../node_modules/ionicons/dist/svg/images-outline.svg","../../../node_modules/ionicons/dist/svg/list-outline.svg","../../../node_modules/ionicons/dist/svg/lock-closed-outline.svg","../../../node_modules/ionicons/dist/svg/git-merge-outline.svg","../../../node_modules/ionicons/dist/svg/open-outline.svg","../../../node_modules/ionicons/dist/svg/scan-outline.svg","../../../node_modules/ionicons/dist/svg/swap-vertical-outline.svg","../../../node_modules/ionicons/dist/svg/trash-outline.svg","../../../node_modules/ionicons/dist/svg/warning-outline.svg","../src/widget/Felt.tsx","../src/widget/primitiver.tsx","../src/widget/tekster.ts","../src/widget/Valg.tsx","../src/widget/KjenteFeil.tsx","../src/widget/Kvittering.tsx","../src/widget/Sporingslinje.tsx","../src/widget/status.ts","../src/widget/MineInnspill.tsx","../src/widget/nyttSvar.ts","../src/widget/Skjermbilde.tsx","../src/InnspelPrivate.tsx","../src/program/InnspelProgram.tsx","../src/program/periode.ts","../src/program/Aksept.tsx","../src/program/HvordanGikkDet.tsx","../src/program/Oppfolging.tsx","../src/program/Oppgaver.tsx","../src/program/ProgramSpor.tsx","../src/lagring.ts"],"sourcesContent":["import type { InnspelClient, OpenFeedbackOptions } from '@innspel/core';\nimport React, { createContext, useCallback, useContext, useMemo, useRef, useState } from 'react';\nimport { View } from 'react-native';\nimport { createPrivateRegistry, SkjermbildeContext, type ImageStepNote, type ScreenshotAdapter, type SkjermbildeKontekst, type ViewRef } from './skjermbilde.js';\nimport { byggTema, TemaProvider, type PartialTheme } from './tema.js';\nimport { Widget, type SubmittedInfo } from './widget/Widget.js';\n\ninterface InnspelKontekst {\n client: InnspelClient;\n /** Åpner widgeten. Samme som `client.openFeedback()`. */\n open: (options?: OpenFeedbackOptions) => Promise<void>;\n close: () => void;\n}\n\nconst Kontekst = createContext<InnspelKontekst | null>(null);\n\n/**\n * Pakk appen i denne, og widgeten finnes.\n *\n * Provideren gjør fire ting: den registrerer visningen hos kjernen (så\n * `client.openFeedback()` virker hvor som helst i appen, også utenfor React),\n * den holder temaet, den rendrer selve arket — og den pakker vertsappen i én\n * `View` med referanse, som er det skjermbildet tas av (K4). Modalen ligger\n * utenfor den viewen og kommer aldri med på bildet.\n *\n * @example\n * ```tsx\n * const innspel = init({ … });\n *\n * export default function App() {\n * return (\n * <InnspelProvider client={innspel} screenshot={createScreenshotAdapter(captureRef)}>\n * <MinApp />\n * </InnspelProvider>\n * );\n * }\n * ```\n */\nexport function InnspelProvider({\n client,\n children,\n theme,\n colorScheme = 'dark',\n tenantName,\n screenshot,\n imageStepNote,\n onSubmitted,\n}: {\n client: InnspelClient;\n children?: React.ReactNode;\n /** Vertens egne tokens. Alt som utelates faller tilbake på Innspels tema. */\n theme?: PartialTheme;\n colorScheme?: 'dark' | 'light';\n /** Navnet som står på svaret i «Mine innspill» — leietakerens, ikke Innspels. */\n tenantName?: string;\n /**\n * Fangst av skjermbilde, typisk `createScreenshotAdapter(captureRef)` fra\n * react-native-view-shot. Uten den finnes ikke skjermbilde-steget (DD-26) —\n * og det finnes uansett ikke når `screenshotsEnabled` er av (K18).\n */\n screenshot?: ScreenshotAdapter;\n /**\n * Leietakerens egen setning ved bildesteget, f.eks. «Legg ved et skjermbilde av feilen.\n * Ikke send bilder av andre personer.» Står ved knappene og i forhåndsvisningen. Én\n * streng gjelder begge spor; `{ feil, onske }` gir hvert spor sin. Leietakeren kjenner\n * brukerne sine; plattformen eier ikke den setningen.\n */\n imageStepNote?: ImageStepNote;\n /**\n * Kalles når et innspill er sendt — eller lagt i køen fordi nettet var borte (F26).\n * `type`, `queued`, og `id` når saken finnes hos tjeneren. Ingen identitet: saksnummeret\n * er sakens, og det innsenderen alt ser i kvitteringen. Bruk det til å hente tellingen\n * på «Mine innspill» på nytt, eller til å be om varsler i det riktige øyeblikket —\n * rett etter første innsending, ikke ved oppstart. Kalles ikke for «Ja, jeg også».\n */\n onSubmitted?: (info: SubmittedInfo) => void;\n}) {\n const [synlig, setSynlig] = useState(false);\n const [apneOpsjoner, setApneOpsjoner] = useState<OpenFeedbackOptions | undefined>();\n const registrert = useRef(false);\n const rootRef = useRef<ViewRef | null>(null);\n const privat = useMemo(createPrivateRegistry, []);\n\n const open = useCallback(\n async (options?: OpenFeedbackOptions) => {\n setApneOpsjoner(options);\n setSynlig(true);\n },\n [],\n );\n\n const close = useCallback(() => setSynlig(false), []);\n\n // Registreres én gang. Kjernen kaller `presenter.open()` fra\n // `client.openFeedback()`, som er veien inn for kode som ikke er en\n // React-komponent — en navigasjonshandler, en krasjlytter hos verten.\n if (!registrert.current) {\n client.registerPresenter({ open });\n registrert.current = true;\n }\n\n const tema = useMemo(() => byggTema(theme, colorScheme), [theme, colorScheme]);\n const verdi = useMemo<InnspelKontekst>(() => ({ client, open, close }), [client, open, close]);\n const skjermbilde = useMemo<SkjermbildeKontekst>(\n () => ({ adapter: screenshot ?? null, rootRef, privat }),\n [screenshot, privat],\n );\n\n return (\n <Kontekst.Provider value={verdi}>\n <SkjermbildeContext.Provider value={skjermbilde}>\n <TemaProvider value={tema}>\n <View ref={rootRef} collapsable={false} style={{ flex: 1 }} testID=\"innspel-rot\">\n {children}\n </View>\n <Widget\n client={client}\n synlig={synlig}\n {...(apneOpsjoner ? { apneOpsjoner } : {})}\n {...(tenantName ? { tenantName } : {})}\n {...(imageStepNote ? { imageStepNote } : {})}\n {...(onSubmitted ? { onSubmitted } : {})}\n onLukk={close}\n />\n </TemaProvider>\n </SkjermbildeContext.Provider>\n </Kontekst.Provider>\n );\n}\n\n/**\n * Klienten og `open` fra nærmeste {@link InnspelProvider}.\n *\n * Kaster utenfor provideren i stedet for å gi `null`: en knapp som stille ikke\n * gjør noe er verre enn en feil under utvikling (tech-decisions.md, «Feil bruk\n * feiler høyt og tidlig»).\n */\nexport function useInnspel(): InnspelKontekst {\n const k = useContext(Kontekst);\n if (!k) {\n throw new Error(\n '[innspel] useInnspel() ble kalt utenfor <InnspelProvider>. Pakk appen din i den — se README.md.',\n );\n }\n return k;\n}\n","import type { MaskRect } from '@innspel/core';\nimport { createContext, useContext, type ComponentRef, type RefObject } from 'react';\nimport { Image, type View } from 'react-native';\n\n/** Host-elementet bak en `View` — det som kan måles og fanges. RN 0.87: `View` er en funksjonskomponent, så typen hentes herfra. */\nexport type ViewRef = ComponentRef<typeof View>;\n\n/**\n * Fangst av skjermbilde er det ene stedet widgeten trenger noe React Native\n * ikke har innebygd. Pakken tar INGEN avhengighet på det (K19, samme mønster som\n * `createStorage`): verten sender inn `captureRef` fra `react-native-view-shot`,\n * og uten adapter finnes ikke skjermbilde-steget (DD-26) — ikke som en grå\n * knapp, det finnes ikke.\n *\n * Alt som rører plattformen går gjennom adapteren, også måling og fillesing, så\n * widgeten kan testes med en fake og maskeringen bevises uten native kode.\n */\n\nexport interface ScreenshotCapture {\n /** Fil-URI fra fangsten. Forlater aldri enheten før den er maskert og rekomponert. */\n uri: string;\n /** Bitmapens størrelse i piksler. */\n width: number;\n height: number;\n}\n\nexport interface CaptureOptions {\n format: 'jpg' | 'png';\n /** 0–1, kun JPEG. */\n quality: number;\n}\n\nexport interface ScreenshotAdapter {\n /** Fanger viewen bak referansen til en fil. Kalles ved «Legg ved skjermbilde» (K4), og igjen på forhåndsvisningen for å rekomponere. */\n capture(ref: RefObject<ViewRef | null>, options: CaptureOptions): Promise<ScreenshotCapture>;\n /**\n * Velger et bilde fra enhetens bildebibliotek — «Velg bilde». `null` når innsenderen\n * avbryter. Uten metoden finnes ikke valget. Bildet går gjennom samme forhåndsvisning\n * og maskering, og det som lastes opp er komposittet fra `capture`, aldri fila.\n */\n pick?(): Promise<ScreenshotCapture | null>;\n /**\n * `false` fjerner «Legg ved skjermbilde» og lar bare «Velg bilde» stå — når skjermen\n * widgeten åpnes fra sjelden er der feilen er. `capture` trengs likevel til å\n * rekomponere forhåndsvisningen. Standard er `true`.\n */\n captureScreen?: boolean;\n /** Viewens rektangel i vinduskoordinater, i punkter. Null når den ikke er montert. */\n measure(ref: RefObject<ViewRef | null>): Promise<MaskRect | null>;\n /** Leser en fangst som Blob for opplasting. */\n read(uri: string): Promise<Blob>;\n}\n\n/** Signaturen til `captureRef` i react-native-view-shot — det eneste verten trenger å sende inn. */\nexport type CaptureRefFn = (\n ref: RefObject<ViewRef | null> | ViewRef,\n options: { format: 'jpg' | 'png'; quality: number; result: 'tmpfile' },\n) => Promise<string>;\n\n/**\n * Vertens bildevelger. Resultatet trenger bare `uri`; mangler størrelsen, måles den.\n * Returner `null` når innsenderen avbryter.\n *\n * @example\n * ```ts\n * import * as ImagePicker from 'expo-image-picker';\n * const pickImage: PickImageFn = async () => {\n * const r = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ['images'], exif: false });\n * return r.canceled ? null : { uri: r.assets[0]!.uri, width: r.assets[0]!.width, height: r.assets[0]!.height };\n * };\n * ```\n */\nexport type PickImageFn = () => Promise<{ uri: string; width?: number; height?: number } | null>;\n\n/**\n * Leietakerens setning ved bildesteget: én for begge spor, eller én per spor.\n * Et spor uten setning viser ingen.\n */\nexport type ImageStepNote = string | { feil?: string; onske?: string };\n\nexport interface ScreenshotAdapterOptions {\n /** Gir «Velg bilde». Pakken tar ingen avhengighet på en velger (K19). */\n pickImage?: PickImageFn;\n /** `false` fjerner «Legg ved skjermbilde». Standard er `true`. */\n captureScreen?: boolean;\n}\n\nfunction storrelse(uri: string): Promise<{ width: number; height: number }> {\n return new Promise((resolve, reject) => Image.getSize(uri, (w, h) => resolve({ width: w, height: h }), reject));\n}\n\n/**\n * Lager adapteren av vertens `captureRef`. Dimensjonene hentes med `Image.getSize`,\n * målingen med `measureInWindow`, og fila leses med `fetch(uri).blob()` — alt fra\n * React Native selv.\n *\n * @example\n * ```tsx\n * import { captureRef } from 'react-native-view-shot';\n * <InnspelProvider client={innspel} screenshot={createScreenshotAdapter(captureRef)}>\n * // Med bildevelger, og uten fangst av skjermen widgeten åpnes fra:\n * <InnspelProvider client={innspel} screenshot={createScreenshotAdapter(captureRef, { pickImage, captureScreen: false })}>\n * ```\n */\nexport function createScreenshotAdapter(captureRef: CaptureRefFn, options: ScreenshotAdapterOptions = {}): ScreenshotAdapter {\n const { pickImage, captureScreen } = options;\n return {\n async capture(ref, opts) {\n const uri = await captureRef(ref, { format: opts.format, quality: opts.quality, result: 'tmpfile' });\n return { uri, ...(await storrelse(uri)) };\n },\n ...(pickImage\n ? {\n async pick() {\n const valgt = await pickImage();\n if (!valgt) return null;\n const { width, height } = valgt.width && valgt.height ? { width: valgt.width, height: valgt.height } : await storrelse(valgt.uri);\n return { uri: valgt.uri, width, height };\n },\n }\n : {}),\n ...(captureScreen === false ? { captureScreen: false } : {}),\n measure(ref) {\n return new Promise((resolve) => {\n const view = ref.current;\n if (!view) return resolve(null);\n view.measureInWindow((x, y, width, height) => resolve({ x, y, width, height }));\n });\n },\n async read(uri) {\n const res = await fetch(uri);\n return res.blob();\n },\n };\n}\n\n/**\n * Private views (DD-39): det verten har merket med `<InnspelPrivate>`. Registeret\n * lever i provideren; widgeten måler hver av dem i fangstøyeblikket og legger en\n * maske brukeren ikke kan fjerne.\n */\nexport interface PrivateRegistry {\n register(ref: RefObject<ViewRef | null>): () => void;\n refs(): ReadonlyArray<RefObject<ViewRef | null>>;\n}\n\nexport function createPrivateRegistry(): PrivateRegistry {\n const alle = new Set<RefObject<ViewRef | null>>();\n return {\n register(ref) {\n alle.add(ref);\n return () => {\n alle.delete(ref);\n };\n },\n refs: () => [...alle],\n };\n}\n\nexport interface SkjermbildeKontekst {\n adapter: ScreenshotAdapter | null;\n /** Vertsappen — det som fanges. Modalen ligger utenfor og kommer aldri med. */\n rootRef: RefObject<ViewRef | null>;\n privat: PrivateRegistry;\n}\n\nexport const SkjermbildeContext = createContext<SkjermbildeKontekst | null>(null);\n\nexport function useSkjermbilde(): SkjermbildeKontekst | null {\n return useContext(SkjermbildeContext);\n}\n","import { createContext, useContext } from 'react';\nimport { light, t, type InnspelColors, type InnspelTheme } from './generated/tokens.js';\n\n/**\n * Widgeten lever INNE i vertsappen (DD-21) og skal arve dens flate. Verten\n * sender et delvis tema; alt den ikke sender faller tilbake på Innspels eget\n * (M0.4), som er generert fra `theme/theme.ts` og målt mot WCAG AA.\n *\n * Ingen hex-verdi, px-verdi eller fontstørrelse skrives i en komponent — alt\n * hentes herfra (CLAUDE.md, «Styling»). `fontFamily` finnes ikke: systemfonten\n * er standard i React Native, og å sette den ville brutt med vertsappen.\n */\n\n/**\n * De genererte tokenene er `as const`, så `t.touch` har typen `48` og ikke\n * `number`. Det er riktig for KILDEN — den skal ikke kunne endres ved et uhell\n * — men gjør temaet umulig å overstyre: verten ville måttet sende nøyaktig 48.\n * Denne typen åpner verdiene uten å åpne nøkkelsettet: en vert kan bytte en\n * farge, men ikke finne på en ny.\n */\nexport type Tema = Omit<\n InnspelTheme,\n 'color' | 'space' | 'radius' | 'font' | 'lineHeight' | 'motion' | 'touch' | 'screenPadding' | 'hairline'\n> & {\n color: Record<keyof InnspelColors, string>;\n space: Record<keyof InnspelTheme['space'], number>;\n radius: Record<keyof InnspelTheme['radius'], number>;\n font: Record<keyof InnspelTheme['font'], number>;\n lineHeight: Record<keyof InnspelTheme['lineHeight'], number>;\n motion: Record<keyof InnspelTheme['motion'], number>;\n touch: number;\n screenPadding: number;\n hairline: number;\n};\n\nexport type PartialTheme = {\n color?: Partial<Tema['color']>;\n} & Partial<Omit<Tema, 'color'>>;\n\n/**\n * Fletter vertens tokens over Innspels egne.\n *\n * @param vertens Delvis tema fra `<InnspelProvider theme={…}>`.\n * @param palett `dark` er standard: widgeten åpnes oftest over en app i mørk\n * modus, og et lyst ark over en mørk app blender.\n */\nexport function byggTema(vertens?: PartialTheme, palett: 'dark' | 'light' = 'dark'): Tema {\n const bunn = (palett === 'light' ? light : t) as unknown as Tema;\n if (!vertens) return bunn;\n\n return {\n ...bunn,\n ...vertens,\n color: { ...bunn.color, ...vertens.color },\n };\n}\n\nconst TemaContext = createContext<Tema>(t as unknown as Tema);\n\nexport const TemaProvider = TemaContext.Provider;\n\n/** Tokenene som gjelder her. Bruk ALDRI en literal farge eller avstand i stedet. */\nexport function useTema(): Tema {\n return useContext(TemaContext);\n}\n","/**\n * tokens.ts — GENERERT fra theme/theme.ts (avtrykk c1045545046d).\n * Rediger aldri denne filen. Endre temaet i kilden og kjør\n * `node scripts/generate-tokens.ts`, som CI verifiserer med `--check`.\n *\n * Tokenene @innspel/react-native faller tilbake på når verten ikke sender egne.\n * Widgeten lever inne i vertsappen og skal arve dens flate (DD-21); dette er\n * bunnen, ikke fasiten.\n *\n * 77 kontrastpar er målt mot WCAG AA i begge paletter, og generatoren\n * nekter å skrive hvis ett faller under kravet. Farge bærer aldri mening alene\n * — hver status har ikon og tekstetikett (DD-08).\n *\n * fontFamily finnes ikke her med vilje: systemfonten er standard i React\n * Native, og å sette den ville brutt med vertsappen.\n */\n\n/** Mørk palett — fallback når verten ikke sender egne tokens. */\nexport const t = {\n color: {\n bg: \"#111417\",\n surface: \"#1A1E22\",\n surfaceRaised: \"#232830\",\n border: \"#2E343B\",\n borderStrong: \"#3D444D\",\n borderInteractive: \"#7C8894\",\n textPrimary: \"#F2F4F6\",\n textSecondary: \"#B4BCC5\",\n textMuted: \"#8D96A1\",\n textDisabled: \"#5A626B\",\n actionPrimary: \"#5AD3E2\",\n onActionPrimary: \"#04252A\",\n actionSecondaryBorder: \"#7C8894\",\n actionSecondaryText: \"#F2F4F6\",\n brand: \"#5AD3E2\",\n onBrand: \"#04252A\",\n brandFill: \"#0E7C8C\",\n onBrandFill: \"#FFFFFF\",\n brandBg: \"#0C2A30\",\n danger: \"#FF7A8C\",\n dangerFill: \"#C4001F\",\n onDangerFill: \"#FFFFFF\",\n dangerBg: \"#2C1116\",\n success: \"#3ED88A\",\n onSuccess: \"#062015\",\n successBg: \"#0E2A1E\",\n warning: \"#FFC24D\",\n onWarning: \"#2A1C02\",\n warningBg: \"#2C2107\",\n info: \"#5CC0FF\",\n onInfo: \"#04222F\",\n infoBg: \"#0E2531\",\n neutral: \"#A3ACB6\",\n onNeutral: \"#111417\",\n neutralBg: \"#242A31\",\n scrim: \"rgba(0, 0, 0, 0.72)\",\n },\n space: {\n xs: 4,\n sm: 8,\n md: 16,\n lg: 24,\n xl: 32,\n xxl: 48,\n },\n radius: {\n sm: 6,\n md: 8,\n lg: 12,\n pill: 999,\n },\n font: {\n display: 40,\n h1: 24,\n h2: 21,\n h3: 18,\n body: 16,\n small: 13,\n tiny: 11,\n },\n lineHeight: {\n display: 48,\n h1: 30,\n h2: 27,\n h3: 24,\n body: 24,\n small: 18,\n tiny: 16,\n },\n weight: {\n regular: \"400\",\n medium: \"500\",\n semibold: \"600\",\n bold: \"700\",\n },\n motion: {\n fast: 120,\n base: 200,\n slow: 320,\n },\n icon: { inline: 20, minste: 16 },\n touch: 48,\n screenPadding: 24,\n hairline: 1,\n} as const;\n\n/** Lys palett. */\nexport const light = {\n color: {\n bg: \"#F6F7F9\",\n surface: \"#FFFFFF\",\n surfaceRaised: \"#EDEFF3\",\n border: \"#D2D7DE\",\n borderStrong: \"#B9C0C9\",\n borderInteractive: \"#6F7883\",\n textPrimary: \"#14181D\",\n textSecondary: \"#454D57\",\n textMuted: \"#5C6470\",\n textDisabled: \"#9AA2AD\",\n actionPrimary: \"#0A6673\",\n onActionPrimary: \"#FFFFFF\",\n actionSecondaryBorder: \"#6F7883\",\n actionSecondaryText: \"#14181D\",\n brand: \"#0A6673\",\n onBrand: \"#FFFFFF\",\n brandFill: \"#0A6673\",\n onBrandFill: \"#FFFFFF\",\n brandBg: \"#E0F0F2\",\n danger: \"#B3001B\",\n dangerFill: \"#B3001B\",\n onDangerFill: \"#FFFFFF\",\n dangerBg: \"#FCE8EA\",\n success: \"#04693C\",\n onSuccess: \"#FFFFFF\",\n successBg: \"#E4F4EC\",\n warning: \"#7A5200\",\n onWarning: \"#FFFFFF\",\n warningBg: \"#FBF1DE\",\n info: \"#00588F\",\n onInfo: \"#FFFFFF\",\n infoBg: \"#E4F0F8\",\n neutral: \"#5C6470\",\n onNeutral: \"#FFFFFF\",\n neutralBg: \"#EEF0F3\",\n scrim: \"rgba(10, 14, 18, 0.45)\",\n },\n space: {\n xs: 4,\n sm: 8,\n md: 16,\n lg: 24,\n xl: 32,\n xxl: 48,\n },\n radius: {\n sm: 6,\n md: 8,\n lg: 12,\n pill: 999,\n },\n font: {\n display: 40,\n h1: 24,\n h2: 21,\n h3: 18,\n body: 16,\n small: 13,\n tiny: 11,\n },\n lineHeight: {\n display: 48,\n h1: 30,\n h2: 27,\n h3: 24,\n body: 24,\n small: 18,\n tiny: 16,\n },\n weight: {\n regular: \"400\",\n medium: \"500\",\n semibold: \"600\",\n bold: \"700\",\n },\n motion: {\n fast: 120,\n base: 200,\n slow: 320,\n },\n icon: { inline: 20, minste: 16 },\n touch: 48,\n screenPadding: 24,\n hairline: 1,\n} as const;\n\n/** Innspillets statuser. `fg`/`bg` er TOKENNAVN og slås opp i den aktive paletten. Nøklene er Submissions.SubmissionStatus i contracts/. */\nexport const submissionStatus = {\n ny: {\n statusType: \"reviewing\",\n ikon: \"ellipse-outline\",\n etikett: { feil: \"Mottatt\", onske: \"Mottatt\" },\n lofte: { feil: \"Vi har fått den. Du hører fra oss.\", onske: \"Vi har fått den. Du hører fra oss.\" },\n fg: \"textSecondary\",\n bg: \"neutralBg\",\n variant: \"outline\",\n },\n vurderes: {\n statusType: \"reviewing\",\n ikon: \"hourglass-outline\",\n etikett: { feil: \"Vurderes\", onske: \"Vurderes\" },\n lofte: { feil: \"Svar innen {frist} — også hvis det er nei.\", onske: \"Svar innen {frist} — også hvis det er nei.\" },\n fg: \"info\",\n bg: \"infoBg\",\n variant: \"outline\",\n },\n planlagt: {\n statusType: \"active\",\n ikon: \"calendar-outline\",\n etikett: { feil: \"Planlagt\", onske: \"Planlagt\" },\n lofte: { feil: \"Du får beskjed når den er rettet.\", onske: \"Du får beskjed når det er levert.\" },\n fg: \"brand\",\n bg: \"brandBg\",\n variant: \"outline\",\n },\n bygges: {\n statusType: \"active\",\n ikon: \"construct-outline\",\n etikett: { feil: \"Retter nå\", onske: \"Bygger\" },\n lofte: { feil: \"Du får beskjed når den er rettet.\", onske: \"Du får beskjed når det er levert.\" },\n fg: \"brand\",\n bg: \"brandBg\",\n variant: \"filled\",\n },\n kjent_feil: {\n statusType: \"active\",\n ikon: \"warning-outline\",\n etikett: { feil: \"Kjent feil\", onske: \"Kjent feil\" },\n lofte: { feil: \"Kjent feil. Du får beskjed når den er rettet.\", onske: \"Kjent feil. Du får beskjed når den er rettet.\" },\n fg: \"warning\",\n bg: \"warningBg\",\n variant: \"outline\",\n },\n levert: {\n statusType: \"complete\",\n ikon: \"checkmark-circle-outline\",\n etikett: { feil: \"Rettet\", onske: \"Levert\" },\n lofte: { feil: \"Ferdig. Ser du feilen igjen, send et nytt innspill.\", onske: \"Ferdig. Takk for ønsket.\" },\n fg: \"success\",\n bg: \"successBg\",\n variant: \"outline\",\n },\n avvist: {\n statusType: \"closed\",\n ikon: \"close-circle-outline\",\n etikett: { feil: \"Avvist\", onske: \"Avvist\" },\n lofte: { feil: \"Vi har svart på denne.\", onske: \"Vi har svart på denne.\" },\n fg: \"danger\",\n bg: \"dangerBg\",\n variant: \"outline\",\n },\n duplikat: {\n statusType: \"closed\",\n ikon: \"git-merge-outline\",\n etikett: { feil: \"Slått sammen\", onske: \"Slått sammen\" },\n lofte: { feil: \"Slått sammen med et innspill som ligner.\", onske: \"Slått sammen med et innspill som ligner.\" },\n fg: \"neutral\",\n bg: \"neutralBg\",\n variant: \"outline\",\n },\n} as const;\n\n/** Programmets statuser. Nøklene er Programs.ProgramStatus i contracts/. */\nexport const programStatus = {\n utkast: {\n ikon: \"create-outline\",\n etikett: \"Utkast\",\n fg: \"textSecondary\",\n bg: \"neutralBg\",\n variant: \"dashed\",\n },\n aapen: {\n ikon: \"ellipse-outline\",\n etikett: \"Åpen\",\n fg: \"info\",\n bg: \"infoBg\",\n variant: \"outline\",\n },\n aktiv: {\n ikon: \"checkmark-circle-outline\",\n etikett: \"Aktiv\",\n fg: \"success\",\n bg: \"successBg\",\n variant: \"outline\",\n },\n avsluttes: {\n ikon: \"time-outline\",\n etikett: \"Avsluttes\",\n fg: \"warning\",\n bg: \"warningBg\",\n variant: \"outline\",\n },\n avsluttet: {\n ikon: \"checkmark-circle-outline\",\n etikett: \"Avsluttet\",\n fg: \"neutral\",\n bg: \"neutralBg\",\n variant: \"outline\",\n },\n avbrutt: {\n ikon: \"close-circle\",\n etikett: \"Avbrutt\",\n fg: \"dangerFill\",\n bg: \"onDangerFill\",\n variant: \"filled\",\n },\n} as const;\n\n/** Kjent feil-statusene (M2.4). Nøklene er KnownIssues.KnownIssueStatus i contracts/; «fikset» heter «Rettet» (DD-22). */\nexport const knownIssueStatus = {\n aktiv: {\n ikon: \"warning-outline\",\n etikett: \"Aktiv\",\n fg: \"warning\",\n bg: \"warningBg\",\n variant: \"outline\",\n },\n fikset: {\n ikon: \"checkmark-circle-outline\",\n etikett: \"Rettet\",\n fg: \"success\",\n bg: \"successBg\",\n variant: \"dashed\",\n },\n} as const;\n\n/** Løftet for `vurderes` uten frist: svaret loves, tidspunktet ikke (DD-07, DD-28). */\nexport const lofteUtenFrist = \"Du får svar — også hvis det er nei.\";\n\n/** Skjermbilde-maskering. Faste signalfarger, uavhengig av palett (DD-39, DD-40). Vedlegg er M1.3. */\nexport const screenRules = {\n brushFill: \"#E5007D\",\n autoMaskFill: \"#101114\",\n autoMaskStroke: \"#E5007D\",\n autoMaskText: \"#FFFFFF\",\n previewBackdrop: \"#000000\",\n qrBackdrop: \"#FFFFFF\",\n brushWidth: 28,\n textBlurRadius: 24,\n} as const;\n\n/** Formen widgeten tar imot. Verten sender et delvis tema; resten faller tilbake hit. */\nexport type InnspelTheme = typeof t;\nexport type InnspelColors = InnspelTheme['color'];\n","import {\n InnspelApiError,\n InnspelQueueFullError,\n type AttachmentInput,\n type InnspelClient,\n type KnownIssueCard,\n type MaskRect,\n type MySubmission,\n type OpenFeedbackOptions,\n type PatternFinding,\n} from '@innspel/core';\nimport React, { useCallback, useContext, useEffect, useRef, useState } from 'react';\nimport { KeyboardAvoidingView, Modal, Pressable, View } from 'react-native';\nimport { initialWindowMetrics, SafeAreaInsetsContext } from 'react-native-safe-area-context';\nimport { Ikon } from '../Ikon.js';\nimport { useSkjermbilde, type ImageStepNote, type ScreenshotCapture, type ViewRef } from '../skjermbilde.js';\nimport { useTema } from '../tema.js';\nimport { Felt } from './Felt.js';\nimport { Valg } from './Valg.js';\nimport { KjenteFeil } from './KjenteFeil.js';\nimport { Kvittering, type KvitteringArt } from './Kvittering.js';\nimport { MineInnspill, type MineInnspillHandtak } from './MineInnspill.js';\nimport { Skjermbilde } from './Skjermbilde.js';\nimport { Banner, Btn } from './primitiver.js';\nimport { tekst } from './tekster.js';\n\nexport type Steg = 'valg' | 'kjenteFeil' | 'felt' | 'skjermbilde' | 'kvittering' | 'mine';\n\n/**\n * Det verten får vite når et innspill er sendt (F26). Sakens nummer, aldri innsenderens\n * identitet — nummeret er det hun alt ser i kvitteringen. `queued` når nettet var borte\n * og innspillet ligger i køen: hun trykket Send, og det teller. «Ja, jeg også» på en kjent\n * feil gir ikke dette kallet — det er Reach, ikke en ny sak.\n */\nexport interface SubmittedInfo {\n type: 'feil' | 'onske';\n queued: boolean;\n /** Finnes når saken er opprettet hos tjeneren; mangler i køen. */\n id?: string;\n}\n\n/** JPEG med denne kvaliteten holder et 3×-skjermbilde godt under 5 MB (K9) og gjør uskarphet irreversibel i praksis. */\nconst FANGST = { format: 'jpg', quality: 0.85 } as const;\n\n/**\n * Widgeten. Ett ark over vertsappen — aldri en flytende knapp over innhold\n * (DD-21).\n *\n * **DD-47, og hvorfor det står her og ikke i en TODO:** arket er en dialog og\n * oppfører seg som en. `<Modal>` gir fokusfellen; `onRequestClose` er\n * Android-tilbake og ESC på tastatur; `accessibilityViewIsModal` skjuler\n * vertsappen for skjermlesere på iOS; kvitteringen er en live-region. Sentrys\n * crash-modal mangler alle fire (issue #23288, #9291) — den er leverandøren som\n * dokumenterer både løsningen og mangelen.\n *\n * **Flyten er ikke symmetrisk.** Feilsporet møter kjente feil FØR feltet: den\n * som står i en feil skal slippe å skrive noe hvis svaret allerede finnes.\n * Ønskesporet møter dem ETTER: et ønske må formuleres før det kan sammenlignes.\n *\n * **Skjermbildet (2f, K4):** tas først når innsenderen trykker, aldri ved åpning.\n * Steget finnes bare når leietakeren har skjermbilde på OG verten har gitt en\n * adapter (DD-26). Private views måles i fangstøyeblikket (DD-39). Det som\n * lastes opp er komposittet av forhåndsvisningen med maskene — rå-URI-en går\n * aldri videre. Teksten sendes først; bildet kan feile alene (DD-42).\n */\nexport function Widget({\n client,\n synlig,\n apneOpsjoner,\n onLukk,\n tenantName,\n imageStepNote,\n onSubmitted,\n}: {\n client: InnspelClient;\n synlig: boolean;\n apneOpsjoner?: OpenFeedbackOptions;\n onLukk: () => void;\n tenantName?: string;\n imageStepNote?: ImageStepNote;\n /** F26: kalles etter en innsending — sendt eller køet. Aldri for «ja, jeg også». */\n onSubmitted?: (info: SubmittedInfo) => void;\n}) {\n const tema = useTema();\n // Edge-to-edge (Android 15+, Expo SDK 53+): Modal tegner under status- og\n // navigasjonslinja uansett props. Insets fra vertens SafeAreaProvider, ellers\n // vinduets fra oppstart; useSafeAreaInsets ville kastet uten provider.\n const insets = useContext(SafeAreaInsetsContext) ?? initialWindowMetrics?.insets ?? { top: 0, bottom: 0, left: 0, right: 0 };\n const skjermbilde = useSkjermbilde();\n const previewRef = useRef<ViewRef | null>(null);\n\n const [steg, setSteg] = useState<Steg>('valg');\n const [spor, setSpor] = useState<'feil' | 'onske'>('feil');\n const [verdi, setVerdi] = useState('');\n const [kort, setKort] = useState<KnownIssueCard[]>([]);\n const [lasterKort, setLasterKort] = useState(false);\n const [lenketTil, setLenketTil] = useState<KnownIssueCard | undefined>();\n const [funn, setFunn] = useState<PatternFinding[]>([]);\n const [fjernede, setFjernede] = useState<string[]>([]);\n const [sender, setSender] = useState(false);\n const online = useNettstatus(client);\n const [feil, setFeil] = useState<string | undefined>();\n const [kvittering, setKvittering] = useState<{ art: KvitteringArt; nr?: string; vedlegg?: 'feilet' | 'forkastet'; frist?: string; sak?: MySubmission }>();\n const [mine, setMine] = useState<MySubmission[]>([]);\n const [lasterMine, setLasterMine] = useState(false);\n\n // Skjermbildet: rå fangst til forhåndsvisning, private views i rotens punkter,\n // og det ferdige, maskerte vedlegget som sendes med teksten.\n const [bilde, setBilde] = useState<ScreenshotCapture | undefined>();\n const [automasker, setAutomasker] = useState<MaskRect[]>([]);\n const [rotStorrelse, setRotStorrelse] = useState({ width: 1, height: 1 });\n const [komponerer, setKomponerer] = useState(false);\n const [kilde, setKilde] = useState<'skjerm' | 'galleri'>('skjerm');\n const [vedlegg, setVedlegg] = useState<AttachmentInput | undefined>();\n\n // Leietakerens grenser: startverdiene fra init(), oppdatert fra plattformen ved åpning (M2.5).\n const [innstillinger, setInnstillinger] = useState({ ...client.settings });\n\n // DD-26: steget finnes ikke uten begge. Aldri en deaktivert knapp.\n const skjermbildeMulig = innstillinger.screenshotsEnabled && skjermbilde?.adapter != null;\n const fangstMulig = skjermbildeMulig && skjermbilde?.adapter?.captureScreen !== false;\n const galleriMulig = skjermbildeMulig && typeof skjermbilde?.adapter?.pick === 'function';\n // Vertens setning for sporet innsenderen står i.\n const bildeNotat = typeof imageStepNote === 'string' ? imageStepNote : imageStepNote?.[spor];\n\n const nullstill = useCallback(() => {\n setSteg('valg');\n setSpor('feil');\n setVerdi('');\n setKort([]);\n setLenketTil(undefined);\n setFunn([]);\n setFjernede([]);\n setFeil(undefined);\n setKvittering(undefined);\n setBilde(undefined);\n setAutomasker([]);\n setVedlegg(undefined);\n setKomponerer(false);\n }, []);\n\n // «Mine innspill» åpnet av verten (`view: 'mine'`) er en visning OVER det innsenderen\n // holdt på, ikke et steg i skjemaet (F3). `stegForMine` er steget under — det lukking\n // og «Tilbake» fører tilbake til, så et utkast i feltet står der ved neste åpning.\n const [mineDirekte, setMineDirekte] = useState(false);\n const [stegForMine, setStegForMine] = useState<Steg>('valg');\n const stegRef = useRef(steg);\n stegRef.current = steg;\n\n /** Noe innsenderen har laget og ikke sendt. Det vinner over vertens `track` (F1). */\n const harUtkast = verdi.trim().length > 0 || vedlegg !== undefined;\n\n /**\n * Lukking beholder spor, steg og tekst (F1, samme modell som `@innspel/web`). Fram til\n * 2026-09-15 nullstilte den, og Android-tilbake kastet teksten på ett trykk.\n */\n const lukk = useCallback(() => {\n onLukk();\n if (stegRef.current === 'mine' && mineDirekte) {\n setSteg(stegForMine);\n setMineDirekte(false);\n }\n }, [onLukk, mineDirekte, stegForMine]);\n\n /** Kvitteringen er det ene stedet som nullstiller — der er innspillet sendt. */\n const lukkOgNullstill = useCallback(() => {\n onLukk();\n nullstill();\n setMineDirekte(false);\n setStegForMine('valg');\n }, [onLukk, nullstill]);\n\n // Køen tømmes når widgeten ÅPNES — aldri ved oppstart (DD-41). Resultatet\n // vises ikke: en flush som lykkes er ikke en hendelse innsenderen ba om.\n useEffect(() => {\n if (!synlig) return;\n client.track({ name: 'widget_opened' });\n void client.queue.flush().catch(() => undefined);\n // Konfigurasjonen er et tilbud: svarer den, oppdateres grensene; ellers står de.\n void client.loadSettings().then((s) => setInnstillinger({ ...s })).catch(() => undefined);\n\n // «Mine innspill» (DD-62): tellingen på knappen hentes ved åpning, stille — feiler\n // kallet, står knappen uten tall. Anonym modus har ingen liste og kalles aldri.\n if (!client.isAnonymous) {\n void client.subjects\n .submissions()\n .then(setMine)\n .catch(() => undefined);\n }\n\n // Et utkast vinner over vertens `track`: å bytte spor under en skrevet tekst ville\n // sendt en feil som ønske. «Mine innspill» legges over utkastet og tar det ikke bort.\n if (apneOpsjoner?.view === 'mine' && !client.isAnonymous) void visMine(true);\n else if (apneOpsjoner?.track && !harUtkast) void velgSpor(apneOpsjoner.track);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [synlig]);\n\n const hentKort = useCallback(async () => {\n setLasterKort(true);\n try {\n const q = apneOpsjoner?.screen ? { screen: apneOpsjoner.screen } : {};\n setKort(await client.knownIssues.for(q));\n } finally {\n setLasterKort(false);\n }\n }, [client, apneOpsjoner?.screen]);\n\n const velgSpor = useCallback(\n async (valgt: 'feil' | 'onske') => {\n setSpor(valgt);\n client.track({ name: 'track_selected', type: valgt });\n\n if (valgt === 'onske') {\n // Ønskesporet skriver først; sammenligningen kommer etterpå.\n setSteg('felt');\n return;\n }\n\n setSteg('kjenteFeil');\n await hentKort();\n },\n [client, hentKort],\n );\n\n // Treffene er et tilbud, aldri en sperre (wireframe 2c): er lista tom når\n // oppslaget er ferdig, hoppes skjermen over — rett til feltet, ingen melding.\n useEffect(() => {\n if (steg === 'kjenteFeil' && !lasterKort && kort.length === 0) setSteg('felt');\n }, [steg, lasterKort, kort.length]);\n\n const endreTekst = useCallback(\n (v: string) => {\n setVerdi(v);\n setFunn(client.scanText(v));\n },\n [client],\n );\n\n /**\n * «Legg ved skjermbilde» (K4): fangsten skjer HER, ved trykket, av vertsappen\n * bak arket. Private views måles i samme øyeblikk (DD-39) og regnes om til\n * rotens punkter. Feiler fangsten, kan innsenderen sende uten.\n */\n const taSkjermbilde = useCallback(async () => {\n if (!skjermbilde?.adapter) return;\n const { adapter, rootRef, privat } = skjermbilde;\n setFeil(undefined);\n try {\n const fangst = await adapter.capture(rootRef, FANGST);\n const rot = await adapter.measure(rootRef);\n const private_ = await Promise.all(privat.refs().map((r) => adapter.measure(r)));\n if (rot) {\n setRotStorrelse({ width: rot.width, height: rot.height });\n setAutomasker(\n private_\n .filter((r): r is MaskRect => r !== null)\n .map((r) => ({ x: r.x - rot.x, y: r.y - rot.y, width: r.width, height: r.height })),\n );\n } else {\n setRotStorrelse({ width: fangst.width, height: fangst.height });\n setAutomasker([]);\n }\n setBilde(fangst);\n setKilde('skjerm');\n setSteg('skjermbilde');\n } catch {\n setFeil(tekst.skjermbildeFeilet);\n }\n }, [skjermbilde]);\n\n /**\n * «Velg bilde»: vertens velger, ved trykket. Ingen private views — de hører til\n * skjermen bak arket, ikke til et bilde fra et annet sted — og rot-viewen fanges\n * aldri. Avbryter innsenderen, skjer ingenting.\n */\n const velgBilde = useCallback(async () => {\n const pick = skjermbilde?.adapter?.pick;\n if (!pick) return;\n setFeil(undefined);\n try {\n const valgt = await pick.call(skjermbilde.adapter);\n if (!valgt) return;\n setRotStorrelse({ width: valgt.width, height: valgt.height });\n setAutomasker([]);\n setBilde(valgt);\n setKilde('galleri');\n setSteg('skjermbilde');\n } catch {\n setFeil(tekst.bildeFeilet);\n }\n }, [skjermbilde]);\n\n /**\n * «Legg ved og fortsett»: forhåndsvisningen MED maskene fanges på nytt, og det\n * er komposittet som blir vedlegget. Rå-URI-en brukes aldri etter dette.\n */\n const leggVedBilde = useCallback(async () => {\n if (!skjermbilde?.adapter) return;\n setKomponerer(true);\n try {\n const komposit = await skjermbilde.adapter.capture(previewRef, FANGST);\n const body = await skjermbilde.adapter.read(komposit.uri);\n setVedlegg({ mime: 'image/jpeg', body, width: komposit.width, height: komposit.height });\n setBilde(undefined);\n setSteg('felt');\n } catch {\n setFeil(tekst.skjermbildeFeilet);\n setSteg('felt');\n } finally {\n setKomponerer(false);\n }\n }, [skjermbilde]);\n\n const fjernBilde = useCallback(() => {\n setBilde(undefined);\n setAutomasker([]);\n setVedlegg(undefined);\n setSteg('felt');\n }, []);\n\n /**\n * Ett steg tilbake, ALDRI en nullstilling (UX-gjennomgangen C1). Fra feltet er\n * forrige steg kjente feil i feilsporet når det fantes treff — ellers valget.\n * Fram til 2026-09-14 kalte «Tilbake» `nullstill`, og 120 tegn forsvant på ett\n * trykk.\n */\n // F33: et åpent tillegg-felt i «Mine innspill» lukkes FØR arket, og teksten beholdes —\n // samme regel som F1 ga skjemaet. Utkastene per sak bor her, så de overlever lista.\n const mineRef = useRef<MineInnspillHandtak>(null);\n const tilleggUtkast = useRef(new Map<string, string>());\n\n const gaaTilbake = useCallback(() => {\n setFeil(undefined);\n // F3: åpnet verten lista direkte, finnes det ikke noe forrige steg i widgeten.\n if (steg === 'mine') {\n if (mineRef.current?.lukkFelt()) return;\n if (mineDirekte) lukk();\n else setSteg('valg');\n return;\n }\n if (steg === 'skjermbilde') {\n setBilde(undefined);\n setAutomasker([]);\n setSteg('felt');\n return;\n }\n if (steg === 'felt' && spor === 'feil' && kort.length > 0) {\n setSteg('kjenteFeil');\n return;\n }\n setSteg('valg');\n }, [steg, spor, kort.length, mineDirekte, lukk]);\n\n /**\n * Android-tilbake og ESC (`onRequestClose`). Er det et forrige steg, er det «Tilbake»;\n * på første steg lukker den; på kvitteringen er innspillet sendt, og den nullstiller.\n */\n const androidTilbake = useCallback(() => {\n if (steg === 'valg') lukk();\n else if (steg === 'kvittering') lukkOgNullstill();\n else gaaTilbake();\n }, [steg, lukk, lukkOgNullstill, gaaTilbake]);\n\n const send = useCallback(async () => {\n // Ønskesporet sendes rett fra feltet: kontrakten har ingen ønskekort, og steget\n // «Har noen ønsket dette?» kommer tilbake når den har det (DD-03, presisert\n // 2026-09-14 — fram til da gikk Send i ring uten treff).\n setSender(true);\n setFeil(undefined);\n try {\n const res = await client.capture({\n type: spor,\n text: verdi,\n ...(vedlegg ? { attachment: vedlegg } : {}),\n ...(spor === 'feil' && lenketTil ? { relatedKnownIssueId: lenketTil.id } : {}),\n context: fjernetKontekst(client, fjernede, apneOpsjoner?.screen),\n } as never);\n\n if (res.status === 'queued') {\n setKvittering({ art: 'kø', ...(res.attachment ? { vedlegg: 'forkastet' as const } : {}) });\n } else {\n setKvittering({\n art: spor,\n nr: res.submission.id,\n // Kortet får HELE saken: sporingslinjen leser `status`, `createdAt` og\n // `statusChangedAt` derfra — ingen nye felter, ingen ny kontrakt (DD-28).\n sak: res.submission,\n // Tidsløftet i kvitteringen er DATOEN fra svaret, aldri «innen 90 dager» (DD-07, DD-28).\n ...(res.submission.deadlineAt ? { frist: res.submission.deadlineAt } : {}),\n ...(res.attachment?.status === 'failed' ? { vedlegg: 'feilet' as const } : {}),\n });\n }\n setSteg('kvittering');\n // F26: verten får vite at det skjedde — etter kvitteringen, så et kast i vertens\n // kode aldri kan holde innsenderen fra å se at innspillet gikk.\n onSubmitted?.(res.status === 'queued' ? { type: spor, queued: true } : { type: spor, queued: false, id: res.submission.id });\n } catch (e) {\n // Teksten mistes ALDRI: den står i feltet, og årsaken er i klartekst.\n if (e instanceof InnspelQueueFullError) setFeil(e.userMessage);\n else if (e instanceof InnspelApiError) setFeil(e.message);\n else setFeil('tjeneren svarte ikke.');\n } finally {\n setSender(false);\n }\n }, [client, spor, verdi, vedlegg, lenketTil, fjernede, apneOpsjoner?.screen, onSubmitted]);\n\n const jaOgsa = useCallback(\n async (k: KnownIssueCard) => {\n setSender(true);\n try {\n const res = await client.knownIssues.confirm(k.id);\n setKvittering({ art: 'jaOgsa', nr: res.id, sak: res });\n setSteg('kvittering');\n } catch (e) {\n setFeil(e instanceof InnspelApiError ? e.message : 'tjeneren svarte ikke.');\n } finally {\n setSender(false);\n }\n },\n [client],\n );\n\n /** `direkte`: verten åpnet lista (`view: 'mine'`). Ellers kom innsenderen via knappen på valget. */\n const visMine = useCallback(async (direkte = false) => {\n if (direkte) {\n if (stegRef.current !== 'mine') setStegForMine(stegRef.current);\n } else {\n setStegForMine('valg');\n }\n setMineDirekte(direkte);\n setSteg('mine');\n setLasterMine(true);\n try {\n setMine(await client.subjects.submissions());\n } catch {\n setMine([]);\n } finally {\n setLasterMine(false);\n }\n }, [client]);\n\n /** «Send nytt innspill» i lista: til utkastet om det finnes, ellers et nytt skjema. */\n const nyttFraMine = useCallback(() => {\n setMineDirekte(false);\n if (harUtkast) setSteg(stegForMine);\n else nullstill();\n }, [harUtkast, stegForMine, nullstill]);\n\n return (\n <Modal\n visible={synlig}\n transparent\n animationType=\"slide\"\n // Android-tilbake og ESC. Uten den er dialogen en felle (DD-47); med `lukk` direkte\n // kastet den teksten (F1). Den er «Tilbake» så lenge det finnes et forrige steg.\n onRequestClose={androidTilbake}\n accessibilityViewIsModal\n >\n {/* Vinduet krymper ikke lenger for tastaturet på edge-to-edge, så arket løftes\n her. Offseten trekker fra navigasjonslinja: arket har den alt som padding,\n og tastaturet dekker den. */}\n <KeyboardAvoidingView\n behavior=\"padding\"\n keyboardVerticalOffset={-insets.bottom}\n style={{ flex: 1, backgroundColor: tema.color.scrim, justifyContent: 'flex-end', paddingTop: insets.top }}\n >\n <View\n testID=\"innspel-widget\"\n accessibilityViewIsModal\n accessibilityRole=\"none\"\n style={{\n backgroundColor: tema.color.bg,\n borderTopLeftRadius: tema.radius.lg * 2,\n borderTopRightRadius: tema.radius.lg * 2,\n padding: tema.screenPadding,\n paddingBottom: tema.screenPadding + insets.bottom,\n paddingLeft: tema.screenPadding + insets.left,\n paddingRight: tema.screenPadding + insets.right,\n gap: tema.space.md,\n maxHeight: '92%',\n minHeight: '60%',\n // Bildesteget får fast høyde: forhåndsvisningen tilpasses plassen som er igjen, og\n // uten en kjent høyde har den ingen øvre grense (se Skjermbilde.tsx).\n ...(steg === 'skjermbilde' ? { height: '92%' as const } : {}),\n }}\n >\n <View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>\n {steg !== 'valg' && steg !== 'kvittering' ? (\n <Btn variant=\"ghost\" testID=\"tilbake\" ikon=\"arrow-back-outline\" label={tekst.tilbake} onPress={gaaTilbake} />\n ) : (\n <View />\n )}\n <Pressable\n testID=\"lukk\"\n accessibilityRole=\"button\"\n accessibilityLabel={tekst.lukk}\n onPress={steg === 'kvittering' ? lukkOgNullstill : lukk}\n style={{ minWidth: tema.touch, minHeight: tema.touch, alignItems: 'center', justifyContent: 'center' }}\n >\n <Ikon navn=\"close-outline\" farge={tema.color.textSecondary} />\n </Pressable>\n </View>\n\n {feil ? <Banner live ikon=\"warning-outline\" tone=\"danger\" children={tekst.sendefeilBanner(feil)} /> : null}\n {/* `cloud-offline-outline` er samme ikon portalens offline-banner bruker. */}\n {!online && steg !== 'kvittering' && steg !== 'mine' ? (\n <Banner ikon=\"cloud-offline-outline\" tone=\"info\" testID=\"offline-banner\" children={tekst.offlineBanner} />\n ) : null}\n\n {steg === 'valg' ? (\n <>\n <Valg onVelg={velgSpor} anonym={client.isAnonymous} />\n {/* DD-62: med innspill fra før er dette en inngang i foten med tellingen —\n flate, ikke ghost. Anonym: ingen liste, ingen knapp (DD-02). */}\n {!client.isAnonymous ? (\n <View style={{ flex: 1, justifyContent: 'flex-end' }}>\n <Btn\n variant=\"secondary\"\n testID=\"mine-innspill\"\n ikon=\"list-outline\"\n label={mine.length > 0 ? tekst.mineMedAntall(mine.length) : tekst.mineTittel}\n accessibilityLabel={mine.length > 0 ? tekst.mineEtikett(mine.length) : tekst.mineTittel}\n onPress={() => void visMine()}\n />\n </View>\n ) : null}\n </>\n ) : null}\n\n {steg === 'kjenteFeil' ? (\n <KjenteFeil\n kort={kort}\n spor={spor}\n laster={lasterKort}\n sender={sender}\n onJaOgsa={jaOgsa}\n onLigner={(k) => {\n setLenketTil(k);\n setSteg('felt');\n }}\n onNei={() => setSteg('felt')}\n />\n ) : null}\n\n {steg === 'felt' ? (\n <Felt\n spor={spor}\n verdi={verdi}\n onEndre={endreTekst}\n minTextLength={innstillinger.minTextLength}\n textMaxLength={innstillinger.textMaxLength}\n // Åpningsskjermen står i lista innsenderen ser, ikke bare i det som sendes:\n // det hun ikke ser, kan hun ikke fjerne (DD-05, K5). Web-widgeten gjør det\n // samme — RN sendte den ikke i det hele tatt før F23.\n kontekst={{ ...client.context, ...(apneOpsjoner?.screen ? { screen: apneOpsjoner.screen } : {}) }}\n fjernedeFelter={fjernede}\n onFjernKontekst={(f) => setFjernede((x) => [...x, f])}\n {...(lenketTil ? { lenketTil, onFjernLenke: () => setLenketTil(undefined) } : {})}\n funn={funn}\n onSend={send}\n sender={sender}\n harFeil={feil !== undefined}\n offline={!online}\n {...(fangstMulig ? { onSkjermbilde: taSkjermbilde } : {})}\n {...(galleriMulig ? { onVelgBilde: velgBilde } : {})}\n {...(bildeNotat ? { bildeNotat } : {})}\n harVedlegg={vedlegg !== undefined}\n onFjernVedlegg={fjernBilde}\n />\n ) : null}\n\n {steg === 'skjermbilde' && bilde ? (\n <Skjermbilde\n bilde={bilde}\n automaskerRot={automasker}\n rotStorrelse={rotStorrelse}\n previewRef={previewRef}\n komponerer={komponerer}\n kilde={kilde}\n {...(bildeNotat ? { notat: bildeNotat } : {})}\n onFjern={fjernBilde}\n onLeggVed={leggVedBilde}\n />\n ) : null}\n\n {steg === 'kvittering' && kvittering ? (\n <Kvittering\n art={kvittering.art}\n {...(kvittering.nr ? { saksnummer: kvittering.nr } : {})}\n {...(kvittering.vedlegg ? { vedlegg: kvittering.vedlegg } : {})}\n {...(kvittering.frist ? { frist: kvittering.frist } : {})}\n {...(kvittering.sak && kvittering.sak.pending !== true ? { sak: kvittering.sak } : {})}\n {...(tenantName ? { tenantName } : {})}\n anonym={client.isAnonymous}\n onLukk={lukkOgNullstill}\n />\n ) : null}\n\n {steg === 'mine' ? (\n <MineInnspill\n ref={mineRef}\n utkastLager={tilleggUtkast.current}\n storage={client.storage}\n rader={mine}\n laster={lasterMine}\n {...(tenantName ? { tenantName } : {})}\n onNytt={nyttFraMine}\n // DD-69: «Legg til mer» går gjennom kjernen; svaret er den oppdaterte saken,\n // som byttes inn i lista — ingen ny henting.\n leggTil={(id, text) => client.subjects.addAddendum(id, text)}\n onOppdatert={(sak) => setMine((liste) => liste.map((r) => (r.pending !== true && r.id === sak.id ? sak : r)))}\n minTextLength={innstillinger.minTextLength}\n textMaxLength={innstillinger.textMaxLength}\n />\n ) : null}\n </View>\n </KeyboardAvoidingView>\n </Modal>\n );\n}\n\n/**\n * Konteksten uten linjene innsenderen har fjernet (DD-05). Et fjernet felt\n * settes til `undefined` — det er slik kjernen (0.2.1) skiller «fjern» fra\n * «behold fra init»; å bare utelate nøkkelen ville fylt feltet igjen. Feltene\n * er en lukket hviteliste, så det som ikke står i `client.context` finnes ikke\n * å fjerne.\n */\n/**\n * Nettstatus fra verten (`init({ connectivity })`). Uten den er svaret alltid «på nett»:\n * widgeten vet da om nettet først når et kall feiler, og køen tar over (DD-41).\n */\nfunction useNettstatus(client: InnspelClient): boolean {\n const c = client.connectivity;\n const [online, setOnline] = useState(() => c?.isOnline() ?? true);\n useEffect(() => {\n if (!c) return undefined;\n setOnline(c.isOnline());\n return c.subscribe?.((v) => setOnline(v));\n }, [c]);\n return online;\n}\n\n/**\n * Konteksten som sendes med innsendingen: skjermen verten åpnet med, minus det innsenderen\n * har fjernet. Samme form som web-widgeten (F23) — skjermen lå bare i kjente feil-oppslaget\n * her, så panelet fikk «Skjerm —» på hver sak fra appen.\n *\n * `screen` står FØR fjern-logikken med vilje: en fjernet skjermlinje skal bli borte selv om\n * verten åpnet med et skjermnavn (DD-05). Åpningsskjermen er ikke et smutthull.\n */\nfunction fjernetKontekst(client: InnspelClient, fjernede: string[], skjerm: string | undefined) {\n const ut: Record<string, unknown> = {};\n if (skjerm) ut['screen'] = skjerm;\n for (const k of [...Object.keys(client.context), 'screen']) {\n if (k !== 'sdkVersion' && fjernede.includes(k)) ut[k] = undefined;\n }\n return ut;\n}\n","import React from 'react';\nimport { SvgXml } from 'react-native-svg';\nimport { useTema } from './tema.js';\n\nimport addOutline from '../../../node_modules/ionicons/dist/svg/add-outline.svg';\nimport arrowBackOutline from '../../../node_modules/ionicons/dist/svg/arrow-back-outline.svg';\nimport brushOutline from '../../../node_modules/ionicons/dist/svg/brush-outline.svg';\nimport bug from '../../../node_modules/ionicons/dist/svg/bug.svg';\nimport bugOutline from '../../../node_modules/ionicons/dist/svg/bug-outline.svg';\nimport bulb from '../../../node_modules/ionicons/dist/svg/bulb.svg';\nimport calendarOutline from '../../../node_modules/ionicons/dist/svg/calendar-outline.svg';\nimport cameraOutline from '../../../node_modules/ionicons/dist/svg/camera-outline.svg';\nimport chatboxOutline from '../../../node_modules/ionicons/dist/svg/chatbox-outline.svg';\nimport checkmarkCircleOutline from '../../../node_modules/ionicons/dist/svg/checkmark-circle-outline.svg';\nimport checkmarkOutline from '../../../node_modules/ionicons/dist/svg/checkmark-outline.svg';\nimport chevronDownOutline from '../../../node_modules/ionicons/dist/svg/chevron-down-outline.svg';\nimport chevronForwardOutline from '../../../node_modules/ionicons/dist/svg/chevron-forward-outline.svg';\nimport chevronUpOutline from '../../../node_modules/ionicons/dist/svg/chevron-up-outline.svg';\nimport closeCircleOutline from '../../../node_modules/ionicons/dist/svg/close-circle-outline.svg';\nimport closeOutline from '../../../node_modules/ionicons/dist/svg/close-outline.svg';\nimport cloudOfflineOutline from '../../../node_modules/ionicons/dist/svg/cloud-offline-outline.svg';\nimport constructOutline from '../../../node_modules/ionicons/dist/svg/construct-outline.svg';\nimport contrastOutline from '../../../node_modules/ionicons/dist/svg/contrast-outline.svg';\nimport ellipseOutline from '../../../node_modules/ionicons/dist/svg/ellipse-outline.svg';\nimport exitOutline from '../../../node_modules/ionicons/dist/svg/exit-outline.svg';\nimport flaskOutline from '../../../node_modules/ionicons/dist/svg/flask-outline.svg';\nimport gridOutline from '../../../node_modules/ionicons/dist/svg/grid-outline.svg';\nimport hourglassOutline from '../../../node_modules/ionicons/dist/svg/hourglass-outline.svg';\nimport imageOutline from '../../../node_modules/ionicons/dist/svg/image-outline.svg';\nimport imagesOutline from '../../../node_modules/ionicons/dist/svg/images-outline.svg';\nimport listOutline from '../../../node_modules/ionicons/dist/svg/list-outline.svg';\nimport lockClosedOutline from '../../../node_modules/ionicons/dist/svg/lock-closed-outline.svg';\nimport mergeOutline from '../../../node_modules/ionicons/dist/svg/git-merge-outline.svg';\nimport openOutline from '../../../node_modules/ionicons/dist/svg/open-outline.svg';\nimport scanOutline from '../../../node_modules/ionicons/dist/svg/scan-outline.svg';\nimport swapVerticalOutline from '../../../node_modules/ionicons/dist/svg/swap-vertical-outline.svg';\nimport trashOutline from '../../../node_modules/ionicons/dist/svg/trash-outline.svg';\nimport warningOutline from '../../../node_modules/ionicons/dist/svg/warning-outline.svg';\n\n/**\n * Ionicons som inline SVG i React Native. «Emoji brukes aldri i\n * implementasjonen» (brand-ui-guidelines): en emoji tegnes av operativsystemet\n * i sine egne faste farger — den følger verken vertens palett eller temaets\n * ikonmål, den ser ulik ut på iOS og Android, og 🐞 leses opp som «marihøne».\n *\n * Navnene er de SAMME som i `submissionStatus`/`knownIssueStatus` i\n * `theme/theme.ts` (gjennom `src/generated/tokens.ts`), i ikonkartene i\n * `design/wireframes/innsending-widget.jsx` og `betaprogram-tester.jsx`, og i\n * `portal/src/lib/Ikon.tsx` og `panel/src/status/Ikon.tsx` — ett ikonkart for\n * hele produktet, tre rendrere.\n *\n * Stiene går via `node_modules` fordi ioniconss `exports` ikke eksponerer\n * SVG-filene. Strengene INLINES ved bygg av esbuild-lasteren `.svg: text` i\n * `tsup.config.ts`, så pakken får ingen runtime-avhengighet av `ionicons` —\n * bare av `react-native-svg`, som er en peer.\n *\n * **Importen er statisk og uten `try`.** Mangler verten `react-native-svg`,\n * feiler Metro ved bygg med navnet på pakken. Det er riktig sted: et manglende\n * peer skal stoppe bygget, ikke bli til et usynlig ikon i en widget som er i\n * drift. Se «`react-native-svg` som peer i @innspel/react-native» i\n * `docs/tech-decisions.md`.\n */\n\n/**\n * En `<title>` i en SVG leses opp — «Bug» foran teksten — og ikonet er\n * dekorativt: teksten ved siden av bærer meningen (DD-08). Samme stripping som\n * `portal/src/lib/Ikon.tsx` og `panel/src/status/Ikon.tsx`.\n *\n * Ionicons 8.1.0 leverer ingen titler (målt: 0 av 1357 filer), så steget er\n * forebyggende — det finnes fordi en oppgradering som legger dem tilbake ellers\n * ville endret opplesningsrekkefølgen i widgeten uten at noe ble rødt.\n * Eksportert for at testen skal kunne bevise at det faktisk fjerner noe.\n */\nexport const utenTittel = (svg: string) => svg.replace(/<title>[\\s\\S]*?<\\/title>/g, '');\n\nconst IKONER: Record<string, string> = Object.fromEntries(\n Object.entries({\n 'add-outline': addOutline,\n 'arrow-back-outline': arrowBackOutline,\n 'brush-outline': brushOutline,\n // Fylte varianter: bare på sporvalgets to kort (DD-63), der ikonet bærer stemningen.\n bug,\n bulb,\n 'bug-outline': bugOutline,\n 'calendar-outline': calendarOutline,\n 'camera-outline': cameraOutline,\n // «Send» og «Send nytt innspill» — ikonkartet i wireframen (R8.3).\n 'chatbox-outline': chatboxOutline,\n 'checkmark-circle-outline': checkmarkCircleOutline,\n // Haken ALENE: sporingslinjens passerte ledd er allerede en sirkel (R8.3).\n 'checkmark-outline': checkmarkOutline,\n 'chevron-down-outline': chevronDownOutline,\n // Sporvalgets rader peker videre (R8.3, DD-63) — dekorativ, etiketten bærer meningen.\n 'chevron-forward-outline': chevronForwardOutline,\n 'chevron-up-outline': chevronUpOutline,\n 'close-circle-outline': closeCircleOutline,\n 'close-outline': closeOutline,\n 'cloud-offline-outline': cloudOfflineOutline,\n 'construct-outline': constructOutline,\n 'contrast-outline': contrastOutline,\n 'ellipse-outline': ellipseOutline,\n 'exit-outline': exitOutline,\n 'flask-outline': flaskOutline,\n 'git-merge-outline': mergeOutline,\n 'grid-outline': gridOutline,\n 'hourglass-outline': hourglassOutline,\n 'image-outline': imageOutline,\n 'images-outline': imagesOutline,\n 'list-outline': listOutline,\n 'lock-closed-outline': lockClosedOutline,\n 'open-outline': openOutline,\n 'scan-outline': scanOutline,\n 'swap-vertical-outline': swapVerticalOutline,\n 'trash-outline': trashOutline,\n 'warning-outline': warningOutline,\n }).map(([navn, svg]) => [navn, utenTittel(svg)]),\n);\n\n/** Navnene `Ikon` kjenner. Et navn som ikke står her kaster ved rendring, aldri stille. */\nexport const IKONNAVN: readonly string[] = Object.keys(IKONER);\n\n/**\n * Dekorativt ikon — alltid ved siden av tekst, aldri alene. Farge og form\n * bærer ikke mening alene (DD-08), så ikonet er skjult for skjermlesere og\n * teksten sier alt.\n *\n * Målet kommer fra `icon` i temaet, aldri fra et tall her: Ionicons tegner med\n * 6,25 % av boksen, så strektykkelsen følger målet, og `minste` (16) er gulvet\n * der streken treffer 1,00 px. Fargen settes som `color`, som er det\n * `currentColor` i SVG-en løses mot.\n */\nexport function Ikon({\n navn,\n storrelse = 'inline',\n farge,\n}: {\n navn: string;\n /**\n * `minste` i piller, hint og chips · `inline` ved siden av brødtekst · `stor`\n * de to stedene ikonet står ALENE og bærer stemningen: sporvalgets flater og\n * kvitteringen. `stor` er et MULTIPLUM av tokenet, ikke et nytt tall — samme\n * regel som `.innspel-flate-ikon` og `.innspel-kvittering-ikon` på web.\n */\n storrelse?: 'stor' | 'inline' | 'minste';\n /** En farge fra temaet. Uten: `textPrimary`. Aldri en literal. */\n farge?: string;\n}) {\n const tema = useTema();\n const svg = IKONER[navn];\n if (!svg) throw new Error(`[innspel] Ikonet «${navn}» er ikke tatt med i Ikon.tsx.`);\n\n const maal =\n storrelse === 'minste' ? tema.icon.minste : storrelse === 'stor' ? 2 * tema.icon.inline : tema.icon.inline;\n return (\n <SvgXml\n // `testID` er navnet: en test kan da slå fast HVILKET ikon en flate tegner,\n // ikke bare at den tegner ett. @testing-library/react-native v14 har ingen\n // spørring på komponenttype lenger, så uten den ville ikonet vært usynlig i test.\n testID={`ikon-${navn}`}\n xml={svg}\n width={maal}\n height={maal}\n color={farge ?? tema.color.textPrimary}\n // Konturikonene har `fill=\"none\"` og `stroke=\"currentColor\"` selv. De fylte (DD-63)\n // har ingen fill på stiene, og react-native-svg tegner dem da svarte — fargen arves\n // fra rota her, og rører ikke en sti som alt sier «none».\n fill={farge ?? tema.color.textPrimary}\n accessibilityElementsHidden\n importantForAccessibility=\"no\"\n />\n );\n}\n","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M256 112v288M400 256H112\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M244 400 100 256l144-144M120 256h292\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"48px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M452.37 59.63a40.49 40.49 0 0 0-57.26 0L184 294.74c23.08 4.7 46.12 27.29 49.26 49.26l219.11-227.11a40.49 40.49 0 0 0 0-57.26M138 336c-29.88 0-54 24.5-54 54.86 0 23.95-20.88 36.57-36 36.57C64.56 449.74 92.82 464 120 464c39.78 0 72-32.73 72-73.14 0-30.36-24.12-54.86-54-54.86\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M463.55 272.13H400v-48.2q0-4.32-.27-8.47c29.57-27.88 32.25-64.63 32.27-103 0-8.61-6.64-16-15.25-16.41A16 16 0 0 0 400 112c0 28-1.86 48.15-9.9 63.84-19.22-41.15-65.78-63.91-134.1-63.91-39.8 0-74.19 9.13-99.43 26.39-14.9 10.19-26.2 22.91-33.7 37.72C114 160.65 112 141 112 112.46c0-8.61-6.6-16-15.2-16.44A16 16 0 0 0 80 112c0 37.63 2.61 73.73 32.44 101.63q-.43 5.06-.44 10.3v48.2H48.45c-8.61 0-16 6.62-16.43 15.23a16 16 0 0 0 16 16.77h64V320a143.3 143.3 0 0 0 10.39 53.69C96.74 396.64 80.18 422 80 463.34c0 8.74 6.62 16.3 15.36 16.65A16 16 0 0 0 112 464c0-27.66 9.1-44.71 26.17-61.32A144.37 144.37 0 0 0 220 459.42a16 16 0 0 0 20-15.49V192.45c0-8.61 6.62-16 15.23-16.43A16 16 0 0 1 272 192v251.93a16 16 0 0 0 20 15.49 144.4 144.4 0 0 0 81.82-56.74c17 16.54 26.09 33.52 26.17 60.95a16.27 16.27 0 0 0 15.1 16.37A16 16 0 0 0 432 464c0-41.68-16.6-67.23-42.39-90.31A143.3 143.3 0 0 0 400 320v-15.87h64a16 16 0 0 0 16-16.77c-.42-8.61-7.84-15.23-16.45-15.23\"/><path d=\"m321.39 104 .32.09c13.57 3.8 25.07-10.55 18.2-22.85A95.86 95.86 0 0 0 256.21 32h-.42a95.87 95.87 0 0 0-84.19 50.13c-6.84 12.58 5.14 27 18.84 22.86 19.71-6 41.79-9.06 65.56-9.06 24.09 0 46.09 2.72 65.39 8.07\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M370 378c28.89 23.52 46 46.07 46 86M142 378c-28.89 23.52-46 46.06-46 86M384 208c28.89-23.52 32-56.07 32-96M128 206c-28.89-23.52-32-54.06-32-94M464 288.13h-80M128 288.13H48M256 192v256\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><path d=\"M256 448c-70.4 0-128-57.6-128-128v-96.07c0-65.07 57.6-96 128-96h0c70.4 0 128 25.6 128 96V320c0 70.4-57.6 128-128 128\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><path d=\"M179.43 143.52a49.1 49.1 0 0 1-3.43-15.73A80 80 0 0 1 255.79 48h.42A80 80 0 0 1 336 127.79a41.9 41.9 0 0 1-3.12 14.3\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M288 464h-64a16 16 0 0 0 0 32h64a16 16 0 0 0 0-32M304 416h-96a16 16 0 0 0 0 32h96a16 16 0 0 0 0-32M369.42 62.69C339.35 32.58 299.07 16 256 16A159.62 159.62 0 0 0 96 176c0 46.62 17.87 90.23 49 119.64l4.36 4.09C167.37 316.57 192 339.64 192 360v24a16 16 0 0 0 16 16h24a8 8 0 0 0 8-8V274.82a8 8 0 0 0-5.13-7.47A130.7 130.7 0 0 1 208.71 253a16 16 0 1 1 18.58-26c7.4 5.24 21.65 13 28.71 13s21.31-7.78 28.73-13a16 16 0 0 1 18.56 26 130.7 130.7 0 0 1-26.16 14.32 8 8 0 0 0-5.13 7.47V392a8 8 0 0 0 8 8h24a16 16 0 0 0 16-16v-24c0-19.88 24.36-42.93 42.15-59.77l4.91-4.66C399.08 265 416 223.61 416 176a159.16 159.16 0 0 0-46.58-113.31\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><rect width=\"416\" height=\"384\" x=\"48\" y=\"80\" fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"32\" rx=\"48\"/><circle cx=\"296\" cy=\"232\" r=\"24\"/><circle cx=\"376\" cy=\"232\" r=\"24\"/><circle cx=\"296\" cy=\"312\" r=\"24\"/><circle cx=\"376\" cy=\"312\" r=\"24\"/><circle cx=\"136\" cy=\"312\" r=\"24\"/><circle cx=\"216\" cy=\"312\" r=\"24\"/><circle cx=\"136\" cy=\"392\" r=\"24\"/><circle cx=\"216\" cy=\"392\" r=\"24\"/><circle cx=\"296\" cy=\"392\" r=\"24\"/><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M128 48v32M384 48v32\"/><path fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M464 160H48\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"m350.54 148.68-26.62-42.06C318.31 100.08 310.62 96 302 96h-92c-8.62 0-16.31 4.08-21.92 10.62l-26.62 42.06C155.85 155.23 148.62 160 140 160H80a32 32 0 0 0-32 32v192a32 32 0 0 0 32 32h352a32 32 0 0 0 32-32V192a32 32 0 0 0-32-32h-59c-8.65 0-16.85-4.77-22.46-11.32\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><circle cx=\"256\" cy=\"272\" r=\"80\" fill=\"none\" stroke=\"currentColor\" stroke-miterlimit=\"10\" stroke-width=\"32px\"/><path d=\"M124 158v-22h-24v22\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M408 64H104a56.16 56.16 0 0 0-56 56v192a56.16 56.16 0 0 0 56 56h40v80l93.72-78.14a8 8 0 0 1 5.13-1.86H408a56.16 56.16 0 0 0 56-56V120a56.16 56.16 0 0 0-56-56Z\" fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M448 256c0-106-86-192-192-192S64 150 64 256s86 192 192 192 192-86 192-192Z\" fill=\"none\" stroke=\"currentColor\" stroke-miterlimit=\"10\" stroke-width=\"32px\"/><path d=\"M352 176 217.6 336 160 272\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M416 128 192 384l-96-96\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"m112 184 144 144 144-144\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"48px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"m184 112 144 144-144 144\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"48px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"m112 328 144-144 144 144\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"48px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M448 256c0-106-86-192-192-192S64 150 64 256s86 192 192 192 192-86 192-192Z\" fill=\"none\" stroke=\"currentColor\" stroke-miterlimit=\"10\" stroke-width=\"32px\"/><path d=\"M320 320 192 192M192 320l128-128\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M368 368 144 144M368 144 144 368\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M93.72 183.25C49.49 198.05 16 233.1 16 288c0 66 54 112 120 112h184.37M467.82 377.74C485.24 363.3 496 341.61 496 312c0-59.82-53-85.76-96-88-8.89-89.54-71-144-144-144-26.16 0-48.79 6.93-67.6 18.14\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><path d=\"M448 448 64 64\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-miterlimit=\"10\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M436.67 184.11a27.17 27.17 0 0 1-38.3 0l-22.48-22.49a27.15 27.15 0 0 1 0-38.29l50.89-50.89a.85.85 0 0 0-.26-1.38C393.68 57 351.09 64.15 324.05 91c-25.88 25.69-27.35 64.27-17.87 98a27 27 0 0 1-7.67 27.14l-173 160.76a40.76 40.76 0 1 0 57.57 57.54l162.15-173.3a27 27 0 0 1 26.77-7.7c33.46 8.94 71.49 7.26 97.07-17.94 27.49-27.08 33.42-74.94 20.1-102.33a.85.85 0 0 0-1.36-.22Z\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-miterlimit=\"10\" stroke-width=\"32px\"/><path d=\"M224 284c-17.48-17-25.49-24.91-31-30.29a18.24 18.24 0 0 1-3.33-21.35 20.8 20.8 0 0 1 3.5-4.62l15.68-15.29a18.7 18.7 0 0 1 5.63-3.87 18.11 18.11 0 0 1 20 3.62c5.45 5.29 15.43 15 33.41 32.52M317.07 291.3c40.95 38.1 90.62 83.27 110 99.41a13.46 13.46 0 0 1 .94 19.92L394.63 444a14 14 0 0 1-20.29-.76c-16.53-19.18-61.09-67.11-99.27-107\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><path d=\"m17.34 193.5 29.41-28.74a4.7 4.7 0 0 1 3.41-1.35 4.85 4.85 0 0 1 3.41 1.35h0a9.86 9.86 0 0 0 8.19 2.77c3.83-.42 7.92-1.6 10.57-4.12 6-5.8-.94-17.23 4.34-24.54a207 207 0 0 1 19.78-22.6c6-5.88 29.84-28.32 69.9-44.45A107.3 107.3 0 0 1 206.67 64c22.59 0 40 10 46.26 15.67a89.5 89.5 0 0 1 10.28 11.64 79 79 0 0 0-9.21-2.77 68.8 68.8 0 0 0-20-1.26c-13.33 1.09-29.41 7.26-38 14-13.9 11-19.87 25.72-20.81 44.71-.68 14.12 2.72 22.1 36.1 55.49a6.6 6.6 0 0 1-.34 9.16l-18.22 18a6.88 6.88 0 0 1-9.54.09c-21.94-21.94-36.65-33.09-45-38.16s-15.07-6.5-18.3-6.85a30.85 30.85 0 0 0-18.27 3.87 11.4 11.4 0 0 0-2.64 2 14.14 14.14 0 0 0 .42 20.08l1.71 1.6a4.63 4.63 0 0 1 0 6.64L71.73 246.6a4.7 4.7 0 0 1-3.41 1.4 4.86 4.86 0 0 1-3.41-1.35l-47.57-46.43a4.88 4.88 0 0 1 0-6.72\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><circle cx=\"256\" cy=\"256\" r=\"208\" fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><path d=\"M256 464c-114.88 0-208-93.12-208-208S141.12 48 256 48Z\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><circle cx=\"256\" cy=\"256\" r=\"192\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M320 176v-40a40 40 0 0 0-40-40H88a40 40 0 0 0-40 40v240a40 40 0 0 0 40 40h192a40 40 0 0 0 40-40v-40M384 176l80 80-80 80M191 256h273\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M176 48h160M118 304h276M208 48v93.48a64.1 64.1 0 0 1-9.88 34.18L73.21 373.49C48.4 412.78 76.63 464 123.08 464h265.84c46.45 0 74.68-51.22 49.87-90.51L313.87 175.66a64.1 64.1 0 0 1-9.87-34.18V48\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-miterlimit=\"10\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><rect width=\"176\" height=\"176\" x=\"48\" y=\"48\" rx=\"20\" ry=\"20\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><rect width=\"176\" height=\"176\" x=\"288\" y=\"48\" rx=\"20\" ry=\"20\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><rect width=\"176\" height=\"176\" x=\"48\" y=\"288\" rx=\"20\" ry=\"20\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><rect width=\"176\" height=\"176\" x=\"288\" y=\"288\" rx=\"20\" ry=\"20\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M145.61 464h220.78c19.8 0 35.55-16.29 33.42-35.06C386.06 308 304 310 304 256s83.11-51 95.8-172.94c2-18.78-13.61-35.06-33.41-35.06H145.61c-19.8 0-35.37 16.28-33.41 35.06C124.89 205 208 201 208 256s-82.06 52-95.8 172.94c-2.14 18.77 13.61 35.06 33.41 35.06\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><path d=\"M343.3 432H169.13c-15.6 0-20-18-9.06-29.16C186.55 376 240 356.78 240 326V224c0-19.85-38-35-61.51-67.2-3.88-5.31-3.49-12.8 6.37-12.8h142.73c8.41 0 10.23 7.43 6.4 12.75C310.82 189 272 204.05 272 224v102c0 30.53 55.71 47 80.4 76.87 9.95 12.04 6.47 29.13-9.1 29.13\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><rect width=\"416\" height=\"352\" x=\"48\" y=\"80\" rx=\"48\" ry=\"48\" fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><circle cx=\"336\" cy=\"176\" r=\"32\" fill=\"none\" stroke=\"currentColor\" stroke-miterlimit=\"10\" stroke-width=\"32px\"/><path d=\"m304 335.79-90.66-90.49a32 32 0 0 0-43.87-1.3L48 352M224 432l123.34-123.34a32 32 0 0 1 43.11-2L464 368\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M432 112V96a48.14 48.14 0 0 0-48-48H64a48.14 48.14 0 0 0-48 48v256a48.14 48.14 0 0 0 48 48h16\" fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><rect width=\"400\" height=\"336\" x=\"96\" y=\"128\" rx=\"45.99\" ry=\"45.99\" fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><ellipse cx=\"372.92\" cy=\"219.64\" rx=\"30.77\" ry=\"30.55\" fill=\"none\" stroke=\"currentColor\" stroke-miterlimit=\"10\" stroke-width=\"32px\"/><path d=\"M342.15 372.17 255 285.78a30.93 30.93 0 0 0-42.18-1.21L96 387.64M265.23 464l118.59-117.73a31 31 0 0 1 41.46-1.87L496 402.91\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M160 144h288M160 256h288M160 368h288\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><circle cx=\"80\" cy=\"144\" r=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><circle cx=\"80\" cy=\"256\" r=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><circle cx=\"80\" cy=\"368\" r=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M336 208v-95a80 80 0 0 0-160 0v95\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><rect width=\"320\" height=\"272\" x=\"96\" y=\"208\" rx=\"48\" ry=\"48\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><circle cx=\"129\" cy=\"96\" r=\"48\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><circle cx=\"129\" cy=\"416\" r=\"48\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><path d=\"M129 144v224\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><circle cx=\"385\" cy=\"288\" r=\"48\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><path d=\"M129 144c0 96 112 144 208 144\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M384 224v184a40 40 0 0 1-40 40H104a40 40 0 0 1-40-40V168a40 40 0 0 1 40-40h167.48M336 64h112v112M224 288 440 72\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M336 448h56a56 56 0 0 0 56-56v-56M448 176v-56a56 56 0 0 0-56-56h-56M176 448h-56a56 56 0 0 1-56-56v-56M64 176v-56a56 56 0 0 1 56-56h56\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M464 208 352 96 240 208M352 113.13V416M48 304l112 112 112-112M160 398V96\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"m112 112 20 320c.95 18.49 14.4 32 32 32h184c17.67 0 30.87-13.51 32-32l20-320\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><path d=\"M80 112h352\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-miterlimit=\"10\" stroke-width=\"32px\"/><path d=\"M192 112V72h0a23.93 23.93 0 0 1 24-24h80a23.93 23.93 0 0 1 24 24h0v40M256 176v224M184 176l8 224M328 176l-8 224\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M85.57 446.25h340.86a32 32 0 0 0 28.17-47.17L284.18 82.58c-12.09-22.44-44.27-22.44-56.36 0L57.4 399.08a32 32 0 0 0 28.17 47.17\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><path d=\"m250.26 195.39 5.74 122 5.73-121.95a5.74 5.74 0 0 0-5.79-6h0a5.74 5.74 0 0 0-5.68 5.95\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><path fill=\"currentColor\" d=\"M256 397.25a20 20 0 1 1 20-20 20 20 0 0 1-20 20\"/></svg>","import type { ContextInput, KnownIssueCard, PatternFinding } from '@innspel/core';\nimport React, { useMemo, useState } from 'react';\nimport { Pressable, ScrollView, Text, TextInput, View } from 'react-native';\nimport { Ikon } from '../Ikon.js';\nimport { useTema } from '../tema.js';\nimport { Btn, H, Hint, Meta, Tekstknapp } from './primitiver.js';\nimport { kontekstVerdi, tekst } from './tekster.js';\n\n/**\n * 2d + 2e — feltet og kontekstlinja. Ett felt, ingenting annet.\n *\n * DD-44: send er inaktiv under `minTextLength` (standard 10), og det er det\n * ENESTE kravet. Ingen kategori, ingen alvorlighet, ingen reproduksjonsfelt.\n * 2h i wireframen er ikke en skjerm — den er fraværet av felter her.\n *\n * DD-45: placeholderen stiller to spørsmål i feilsporet.\n *\n * DD-46: mønstervarselet vises FØR sending og fjerner aldri noe selv.\n * «Fjern» og «Behold» er innsenderens valg; teksten endres bare ved «Fjern».\n *\n * DD-05: konteksten er synlig og kan fjernes linje for linje. Den er en lukket\n * hviteliste (K5) — det som ikke står der, finnes ikke å fjerne.\n */\nexport function Felt({\n spor,\n verdi,\n onEndre,\n minTextLength,\n textMaxLength,\n kontekst,\n fjernedeFelter,\n onFjernKontekst,\n lenketTil,\n onFjernLenke,\n funn,\n onSend,\n sender,\n harFeil,\n offline,\n onSkjermbilde,\n onVelgBilde,\n bildeNotat,\n harVedlegg,\n onFjernVedlegg,\n}: {\n spor: 'feil' | 'onske';\n verdi: string;\n onEndre: (v: string) => void;\n minTextLength: number;\n textMaxLength: number;\n kontekst: ContextInput & { sdkVersion: string };\n fjernedeFelter: string[];\n onFjernKontekst: (felt: string) => void;\n lenketTil?: KnownIssueCard;\n onFjernLenke?: () => void;\n funn: PatternFinding[];\n onSend: () => void;\n sender?: boolean;\n /** Forrige sending feilet: knappen heter «Prøv igjen» til neste forsøk (C7). */\n harFeil?: boolean;\n /** Verten har meldt at nettet er nede (`init({ connectivity })`): knappen heter «Lagre — sendes når du er på nett». */\n offline?: boolean;\n /**\n * «Legg ved skjermbilde» (2f, K4). Utelatt = steget finnes ikke (DD-26): leietakeren\n * har skjermbilde av, eller verten ga ingen adapter. Aldri en deaktivert knapp.\n */\n onSkjermbilde?: () => void;\n /** «Velg bilde» fra galleriet. Utelatt = valget finnes ikke; samme regel som over. */\n onVelgBilde?: () => void;\n /** Vertens setning ved bildesteget (`imageStepNote`). Leietakeren eier den, ikke plattformen. */\n bildeNotat?: string;\n /** Et maskert skjermbilde ligger klart og sendes etter teksten (DD-42). */\n harVedlegg?: boolean;\n onFjernVedlegg?: () => void;\n}) {\n const tema = useTema();\n const [apen, setApen] = useState(false);\n const [beholdt, setBeholdt] = useState<string[]>([]);\n\n const brukt = verdi.length;\n const forKort = brukt < minTextLength;\n const full = brukt >= textMaxLength;\n // Telleren dukker opp ved 80 % — ikke før. En teller fra første tegn gjør\n // lengden til oppgaven i stedet for innholdet.\n const visTeller = brukt >= textMaxLength * 0.8;\n\n const uavklart = funn.find((f) => !beholdt.includes(f.match));\n\n // Lista er LUKKET (K5): det som ikke står her, finnes ikke å sende. Etikettene er\n // portalens — samme felt, samme ord i begge flater — og verdiene er ORD, ikke koder\n // (DD-50, presisert 2026-09-20). Verdien som SENDES er uendret.\n const linjer = useMemo(\n () =>\n Object.entries(tekst.kontekstEtiketter)\n .map(([felt, etikett]) => {\n const rå = (kontekst as unknown as Record<string, string | undefined>)[felt];\n return rå && !fjernedeFelter.includes(felt) ? { felt, etikett, verdi: kontekstVerdi(felt, rå) } : null;\n })\n .filter((x): x is { felt: string; etikett: string; verdi: string } => x !== null),\n [kontekst, fjernedeFelter],\n );\n\n // Kroppen scroller og Send står fast under den. Arket har bare maxHeight, så\n // uten scrollflate tegnet et høyt skjema (utvidet kontekst) forbi bunnpaddingen\n // og Send havnet under navigasjonslinja. Roten er flexGrow/flexShrink, ikke\n // flex: 1 — den gir flexBasis 0, og arket ville aldri vokst forbi minHeight.\n return (\n <View testID=\"skjema\" style={{ flexGrow: 1, flexShrink: 1, gap: tema.space.md }}>\n <ScrollView\n testID=\"skjema-kropp\"\n style={{ flexGrow: 0, flexShrink: 1 }}\n contentContainerStyle={{ gap: tema.space.md }}\n keyboardShouldPersistTaps=\"handled\"\n >\n {lenketTil ? (\n <View\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n gap: tema.space.sm,\n minHeight: tema.touch,\n borderWidth: tema.hairline,\n borderColor: tema.color.borderInteractive,\n borderRadius: tema.radius.pill,\n paddingLeft: tema.space.md,\n paddingRight: tema.space.xs,\n }}\n >\n <Text style={{ flex: 1, color: tema.color.textPrimary, fontSize: tema.font.small }}>\n {tekst.lenketTil(lenketTil.title)}\n </Text>\n <Pressable\n testID=\"fjern-lenke\"\n accessibilityRole=\"button\"\n accessibilityLabel={tekst.fjernLenke}\n onPress={onFjernLenke}\n style={{ minWidth: tema.touch, minHeight: tema.touch, alignItems: 'center', justifyContent: 'center' }}\n >\n <Ikon navn=\"close-outline\" farge={tema.color.textSecondary} />\n </Pressable>\n </View>\n ) : null}\n\n {uavklart ? (\n <View\n style={{\n gap: tema.space.sm,\n backgroundColor: tema.color.warningBg,\n borderRadius: tema.radius.md,\n padding: tema.space.md,\n }}\n >\n <Text\n accessibilityRole=\"alert\"\n accessibilityLiveRegion=\"polite\"\n style={{\n color: tema.color.warning,\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n fontWeight: tema.weight.medium,\n }}\n >\n {tekst.monsterSpm[uavklart.kind]}\n </Text>\n <View style={{ flexDirection: 'row', gap: tema.space.sm }}>\n <Btn\n grow\n variant=\"secondary\"\n testID=\"monster-fjern\"\n label={tekst.monsterFjern}\n onPress={() => onEndre(verdi.slice(0, uavklart.start) + verdi.slice(uavklart.end))}\n />\n <Btn\n grow\n variant=\"ghost\"\n testID=\"monster-behold\"\n label={tekst.monsterBehold}\n onPress={() => setBeholdt((b) => [...b, uavklart.match])}\n />\n </View>\n <Hint>{tekst.monsterForklaring}</Hint>\n </View>\n ) : null}\n\n <H>{spor === 'onske' ? tekst.feltLabelOnske : tekst.feltLabelFeil}</H>\n\n <TextInput\n testID=\"innspill-tekst\"\n accessibilityLabel={spor === 'onske' ? tekst.feltLabelOnske : tekst.feltLabelFeil}\n value={verdi}\n onChangeText={onEndre}\n maxLength={textMaxLength}\n multiline\n numberOfLines={4}\n placeholder={spor === 'onske' ? tekst.placeholderOnske : tekst.placeholderFeil}\n placeholderTextColor={tema.color.textMuted}\n style={{\n backgroundColor: tema.color.surfaceRaised,\n borderWidth: tema.hairline,\n borderColor: full ? tema.color.warning : tema.color.borderStrong,\n borderRadius: tema.radius.md,\n padding: tema.space.md,\n color: tema.color.textPrimary,\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n minHeight: tema.touch * 2,\n textAlignVertical: 'top',\n }}\n />\n\n {visTeller ? (\n <Text\n testID=\"teller\"\n accessibilityLiveRegion={full ? 'assertive' : 'polite'}\n style={{\n alignSelf: 'flex-end',\n color: full ? tema.color.warning : tema.color.textMuted,\n fontSize: tema.font.small,\n }}\n >\n {brukt} / {textMaxLength}\n {full ? tekst.tellerFull : ''}\n </Text>\n ) : null}\n\n {/* 2f — opt-in per innsending. Bildet tas først ved trykk (K4). */}\n {harVedlegg ? (\n <View\n testID=\"vedlegg-chip\"\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n gap: tema.space.sm,\n minHeight: tema.touch,\n borderWidth: tema.hairline,\n borderColor: tema.color.borderInteractive,\n borderRadius: tema.radius.pill,\n paddingLeft: tema.space.md,\n paddingRight: tema.space.xs,\n }}\n >\n <Ikon navn=\"image-outline\" storrelse=\"minste\" farge={tema.color.textPrimary} />\n <Text style={{ flex: 1, color: tema.color.textPrimary, fontSize: tema.font.small }}>{tekst.bildeLagtVed}</Text>\n <Pressable\n testID=\"fjern-vedlegg\"\n accessibilityRole=\"button\"\n accessibilityLabel={tekst.fjernSkjermbilde}\n onPress={onFjernVedlegg}\n style={{ minWidth: tema.touch, minHeight: tema.touch, alignItems: 'center', justifyContent: 'center' }}\n >\n <Ikon navn=\"close-outline\" farge={tema.color.textSecondary} />\n </Pressable>\n </View>\n ) : onSkjermbilde || onVelgBilde ? (\n // F7 (brukerreisene 2026-09-15): knappene har ingen egen hjelpetekst. Web-widgeten\n // har aldri hatt det, og Følget sender sin egen setning som `imageStepNote` — med\n // pakkens hint i tillegg sto det tre tekster under to knapper. Løftet om at bildet\n // tas ved trykk og kan maskeres står i selve steget (Skjermbilde), der det gjelder.\n <View style={{ gap: tema.space.sm }}>\n {onSkjermbilde ? (\n <Btn\n variant=\"secondary\"\n testID=\"legg-ved-skjermbilde\"\n ikon=\"camera-outline\"\n label={tekst.leggVedSkjermbilde}\n onPress={onSkjermbilde}\n />\n ) : null}\n {onVelgBilde ? (\n <Btn\n variant=\"secondary\"\n testID=\"velg-bilde\"\n ikon=\"images-outline\"\n label={tekst.velgBilde}\n onPress={onVelgBilde}\n />\n ) : null}\n {bildeNotat ? (\n <View testID=\"bilde-notat\">\n <Hint>{bildeNotat}</Hint>\n </View>\n ) : null}\n </View>\n ) : null}\n\n {/*\n 2e — LUKKET i arket (DD-05 ordrett: «Én linje «Vis» under feltet ekspanderer»).\n Portalens «alltid åpen» er PORTALENS presisering av samme DD: arket er lavt,\n tastaturet tar halve skjermen, og seks rader på 48 px skyver feltet ut av syne.\n Lukket er linja en OPPSUMMERING — den navngir det innsenderen kjenner igjen, og\n lista er hele sannheten.\n */}\n <View style={{ borderTopWidth: tema.hairline, borderTopColor: tema.color.border, paddingTop: tema.space.xs }}>\n <Pressable\n testID=\"kontekst-bryter\"\n accessibilityRole=\"button\"\n accessibilityState={{ expanded: apen }}\n onPress={() => setApen((a) => !a)}\n style={{ minHeight: tema.touch, flexDirection: 'row', alignItems: 'center', gap: tema.space.sm }}\n >\n {/* Ikonet er et eget element, ikke et tegn i teksten: en SVG kan ikke\n ligge inne i en `Text` i React Native. */}\n <Ikon\n navn={apen ? 'chevron-up-outline' : 'chevron-down-outline'}\n storrelse=\"minste\"\n farge={tema.color.textSecondary}\n />\n <Text style={{ flex: 1, color: tema.color.textSecondary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }}>\n {apen ? tekst.kontekstLinjeApen : tekst.kontekstLinjeLukket}\n </Text>\n <Text style={{ color: tema.color.actionSecondaryText, fontSize: tema.font.body, fontWeight: tema.weight.semibold }}>\n {apen ? tekst.kontekstSkjul : tekst.kontekstVis}\n </Text>\n </Pressable>\n\n {apen ? (\n <View>\n {linjer.map((l) => (\n <View\n key={l.felt}\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n gap: tema.space.md,\n minHeight: tema.touch,\n borderTopWidth: tema.hairline,\n borderTopColor: tema.color.border,\n }}\n >\n {/* Etiketten er `small`; VERDIEN er `body` halvfet (DD-67). */}\n <Meta testID={`kontekst-etikett-${l.felt}`}>{l.etikett}</Meta>\n <View style={{ flex: 1, minWidth: 0 }}>\n <Text\n testID={`kontekst-verdi-${l.felt}`}\n style={{ color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body, fontWeight: tema.weight.semibold }}\n >\n {l.verdi}\n </Text>\n </View>\n {/* Hver linje er ETT hvitelistefelt og kan fjernes alene (DD-05, K5). */}\n <Tekstknapp\n testID={`fjern-${l.felt}`}\n ikon=\"close-outline\"\n label={tekst.kontekstFjern}\n accessibilityLabel={tekst.kontekstFjernA11y(l.etikett)}\n onPress={() => onFjernKontekst(l.felt)}\n />\n </View>\n ))}\n {/* K5 — skjermens ene hjelpesetning, og bare når lista står. */}\n <View style={{ paddingTop: tema.space.sm }}>\n <Hint>{tekst.kontekstAldri}</Hint>\n </View>\n </View>\n ) : null}\n </View>\n\n </ScrollView>\n\n <View testID=\"skjema-fot\" style={{ flexGrow: 1, flexShrink: 0, justifyContent: 'flex-end' }}>\n <Btn\n testID=\"send\"\n label={sender ? tekst.sender : harFeil ? tekst.provIgjen : offline ? tekst.offlineLagre : tekst.send}\n disabled={forKort || sender}\n busy={sender}\n hint={forKort ? tekst.forKort(minTextLength) : harVedlegg ? tekst.sendHintMedBilde : undefined}\n onPress={onSend}\n // F10: tastaturet er oppe når Send trykkes. En ScrollView i vertens tre over\n // provideren kan ta første trykk — det skal likevel sende.\n trykkForbiForelder\n />\n </View>\n </View>\n );\n}\n","import React, { useMemo, useRef } from 'react';\nimport { Pressable, Text, View, type GestureResponderEvent, type StyleProp, type ViewStyle } from 'react-native';\nimport { Ikon } from '../Ikon.js';\nimport { useTema } from '../tema.js';\n\n/**\n * Primitivene widgeten er bygget av. Alt visuelt kommer fra tema-tokens —\n * ingen hex, ingen px, ingen fontstørrelse skrives her (CLAUDE.md, «Styling»).\n *\n * Minste trykkflate er `skala.touch` (48). Den er ikke en anbefaling: den er\n * grønt-kriterium for widgeten, og en knapp under målet er en feil.\n *\n * `ikon` er alltid et IONICONS-NAVN, aldri en emoji (brand-ui-guidelines,\n * UX-gjennomgangen C3). Navnene står i `src/Ikon.tsx`, og et ukjent navn kaster.\n */\n\n/**\n * `tonet` er DD-63s par `brandBg`/`brand`: et valg som ikke er skjermens primærhandling, men\n * som sparer innsenderen for arbeid («Ja, jeg også», «Gjort» per oppgave). ALDRI\n * `actionPrimary` — da blir tre like spørsmål tre primærknapper (DD-58, F32).\n */\ntype Variant = 'primary' | 'secondary' | 'ghost' | 'danger' | 'tonet';\n\nexport function Btn({\n label,\n onPress,\n variant = 'primary',\n ikon,\n hint,\n disabled,\n accessibilityLabel,\n grow,\n testID,\n busy,\n trykkForbiForelder,\n}: {\n label: string;\n onPress?: () => void;\n variant?: Variant;\n ikon?: string;\n hint?: string;\n disabled?: boolean;\n accessibilityLabel?: string;\n grow?: boolean;\n testID?: string;\n /** Handlingen pågår: `busy` i tilstanden, så skjermleseren hører at knappen jobber, ikke bare at den er låst. */\n busy?: boolean;\n /**\n * Trykket teller selv om en FORELDER i vertens tre tok responderen (F10). Se\n * {@link useTrykkForbiForelder}. Brukes på Send, der et tapt trykk er et innspill som\n * ikke ble sendt.\n */\n trykkForbiForelder?: boolean;\n}) {\n const tema = useTema();\n const c = tema.color;\n const forbi = useTrykkForbiForelder(onPress, !!disabled, tema.touch / 2);\n\n const bakgrunn =\n variant === 'primary' ? c.actionPrimary : variant === 'tonet' ? c.brandBg : variant === 'secondary' ? c.surfaceRaised : 'transparent';\n const tekstfarge =\n variant === 'primary' ? c.onActionPrimary\n : variant === 'tonet' ? c.brand\n : variant === 'danger' ? c.danger\n : c.actionSecondaryText;\n const kant =\n variant === 'ghost' || variant === 'tonet' ? 'transparent' : variant === 'primary' ? c.actionPrimary : c.actionSecondaryBorder;\n\n return (\n <View style={grow ? { flex: 1 } : undefined}>\n <Pressable\n testID={testID}\n accessibilityRole=\"button\"\n // Hintet er synlig tekst OG del av etiketten: en skjermleserbruker skal\n // få vite hvorfor knappen er inaktiv uten å lete etter teksten under.\n accessibilityLabel={accessibilityLabel ?? (hint ? `${label}. ${hint}` : label)}\n accessibilityState={{ disabled: !!disabled, busy: !!busy }}\n disabled={disabled}\n onPress={onPress}\n {...(trykkForbiForelder ? forbi : {})}\n style={{\n minHeight: tema.touch,\n borderRadius: tema.radius.md,\n borderWidth: tema.hairline,\n borderColor: kant,\n backgroundColor: disabled ? c.surface : bakgrunn,\n paddingHorizontal: tema.space.md,\n alignItems: 'center',\n justifyContent: 'center',\n flexDirection: 'row',\n gap: tema.space.sm,\n opacity: disabled ? 0.6 : 1,\n }}\n >\n {ikon ? <Ikon navn={ikon} farge={disabled ? c.textDisabled : tekstfarge} /> : null}\n <Text\n style={{\n color: disabled ? c.textDisabled : tekstfarge,\n fontSize: tema.font.body,\n fontWeight: tema.weight.semibold,\n }}\n >\n {label}\n </Text>\n </Pressable>\n {hint ? <Hint>{hint}</Hint> : null}\n </View>\n );\n}\n\n/**\n * Et trykk som ender på knappen, teller — også når knappen aldri fikk responderen (F10).\n *\n * React Natives responder-system spør forfedrene i REACT-treet, ytterst først, i\n * capture-fasen (`traverseTwoPhase` over `fiber.return` i renderen). Modalen er et eget\n * vindu på Android, men i React-treet står den der verten plasserte provideren. Står den i\n * en `ScrollView` med `keyboardShouldPersistTaps` på `'never'` (standard), tar den\n * ScrollView-en trykket mens tastaturet er oppe og slipper det med `blurTextInput`\n * (`_handleStartShouldSetResponderCapture` i ScrollView.js). Pressable-en får aldri\n * `onResponderGrant`, og `onPress` kalles aldri: første trykk lukker bare tastaturet.\n *\n * Widgeten kan ikke vinne capture-fasen over en forelder. Men `onTouchStart`/`onTouchEnd`\n * sendes av `ReactNativeBridgeEventPlugin` til målet uavhengig av hvem som er responder.\n * Et trykk som endte innenfor `slingring` av der det startet, uten at `onPressIn` kom,\n * kalles derfor som `onPress` — etter at responder-hendelsene for samme trykk er\n * ferdige, så et vanlig trykk aldri teller to ganger. En låst knapp trykkes aldri.\n */\nfunction useTrykkForbiForelder(onPress: (() => void) | undefined, laast: boolean, slingring: number) {\n const start = useRef<{ x: number; y: number } | null>(null);\n const fikkResponder = useRef(false);\n // Siste verdier leses i timeouten, ikke verdiene fra renderen trykket startet i.\n const siste = useRef({ onPress, laast });\n siste.current = { onPress, laast };\n\n return useMemo(\n () => ({\n onPressIn: () => {\n fikkResponder.current = true;\n },\n onTouchStart: (e: GestureResponderEvent) => {\n start.current = { x: e.nativeEvent.pageX, y: e.nativeEvent.pageY };\n },\n onTouchEnd: (e: GestureResponderEvent) => {\n const s = start.current;\n start.current = null;\n const innenfor =\n s !== null &&\n Math.abs(e.nativeEvent.pageX - s.x) <= slingring &&\n Math.abs(e.nativeEvent.pageY - s.y) <= slingring;\n setTimeout(() => {\n const tatt = fikkResponder.current;\n fikkResponder.current = false;\n if (!tatt && innenfor && !siste.current.laast) siste.current.onPress?.();\n }, 0);\n },\n onTouchCancel: () => {\n start.current = null;\n fikkResponder.current = false;\n },\n }),\n [slingring],\n );\n}\n\n/**\n * Overskriften. `sub` er INGRESSEN og står i `body` (DD-67, presisert 2026-09-20) — ikke i\n * `small`: det er ikke en hjelpetekst, det er hva skjermen handler om. Trenger en flate en\n * meta-linje i `small` under overskriften, er det {@link Meta}, ikke `sub`.\n */\nexport function H({\n children,\n sub,\n meta,\n nivaa = 2,\n testID,\n}: {\n children: string;\n sub?: string;\n meta?: string;\n nivaa?: 2 | 3;\n testID?: string;\n}) {\n const tema = useTema();\n return (\n <View style={{ gap: tema.space.xs }}>\n <Text\n testID={testID}\n accessibilityRole=\"header\"\n style={{\n color: tema.color.textPrimary,\n fontSize: nivaa === 2 ? tema.font.h2 : tema.font.h3,\n lineHeight: nivaa === 2 ? tema.lineHeight.h2 : tema.lineHeight.h3,\n fontWeight: tema.weight.bold,\n }}\n >\n {children}\n </Text>\n {sub ? <Sek>{sub}</Sek> : null}\n {meta ? <Meta>{meta}</Meta> : null}\n </View>\n );\n}\n\n/** Brødtekst — standarden (DD-67). Alt innsenderen avgjør på er dette eller større. */\nexport function Brodtekst({ children, testID }: { children: React.ReactNode; testID?: string }) {\n const tema = useTema();\n return (\n <Text\n testID={testID}\n style={{ color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }}\n >\n {children}\n </Text>\n );\n}\n\n/** Brødtekst i sekundærfargen — ingressen, omveien, løftet. Fortsatt `body`. */\nexport function Sek({ children, testID }: { children: React.ReactNode; testID?: string }) {\n const tema = useTema();\n return (\n <Text\n testID={testID}\n style={{ color: tema.color.textSecondary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }}\n >\n {children}\n </Text>\n );\n}\n\n/**\n * Skjermens HELT: det ene tallet eller den ene setningen innsenderen kom for (DD-67).\n * `h1` er den største størrelsen widgeten bruker — `display` er panelets.\n */\nexport function Helt({\n children,\n testID,\n farge,\n live,\n}: {\n children: React.ReactNode;\n testID?: string;\n farge?: string;\n /** Kvitteringens helt leses opp alene, uten at hele kortet gjentas (DD-47). */\n live?: boolean;\n}) {\n const tema = useTema();\n return (\n <Text\n testID={testID}\n {...(live ? { accessibilityRole: 'alert' as const, accessibilityLiveRegion: 'polite' as const } : {})}\n style={{\n color: farge ?? tema.color.textPrimary,\n fontSize: tema.font.h1,\n lineHeight: tema.lineHeight.h1,\n fontWeight: tema.weight.bold,\n }}\n >\n {children}\n </Text>\n );\n}\n\n/** ÉN meta-linje per rad, i `small` — det er nettopp det `small` er til (DD-67). */\nexport function Meta({ children, testID, farge }: { children: React.ReactNode; testID?: string; farge?: string }) {\n const tema = useTema();\n return (\n <Text\n testID={testID}\n style={{ color: farge ?? tema.color.textMuted, fontSize: tema.font.small, lineHeight: tema.lineHeight.small }}\n >\n {children}\n </Text>\n );\n}\n\n/**\n * En handling uten flate. Trykkflaten er `touch` selv om teksten er lavere. `noytral` gir\n * tekstfargen, for «Gå ut av programmet» og andre handlinger som ikke er forslag — den røde\n * er dialogen (DD-53).\n */\nexport function Tekstknapp({\n label,\n ikon,\n onPress,\n noytral,\n disabled,\n testID,\n accessibilityLabel,\n}: {\n label: string;\n ikon?: string;\n onPress?: () => void;\n noytral?: boolean;\n disabled?: boolean;\n testID?: string;\n accessibilityLabel?: string;\n}) {\n const tema = useTema();\n const farge = disabled ? tema.color.textDisabled : noytral ? tema.color.textPrimary : tema.color.actionSecondaryText;\n return (\n <Pressable\n testID={testID}\n accessibilityRole=\"button\"\n accessibilityLabel={accessibilityLabel ?? label}\n accessibilityState={{ disabled: !!disabled }}\n disabled={disabled}\n onPress={onPress}\n style={{\n alignSelf: 'flex-start',\n minHeight: tema.touch,\n flexDirection: 'row',\n alignItems: 'center',\n gap: tema.space.sm,\n }}\n >\n {ikon ? <Ikon navn={ikon} storrelse=\"minste\" farge={farge} /> : null}\n <Text style={{ color: farge, fontSize: tema.font.body, fontWeight: tema.weight.semibold }}>{label}</Text>\n </Pressable>\n );\n}\n\n/**\n * Merkelappen «Nytt svar» (F14). `small`, ikke `tiny`: `tiny` finnes ikke i widgeten\n * (DD-67, presisert 2026-09-20).\n */\nexport function Pille({ children, testID }: { children: React.ReactNode; testID?: string }) {\n const tema = useTema();\n return (\n <Text\n testID={testID}\n style={{\n color: tema.color.info,\n backgroundColor: tema.color.infoBg,\n fontSize: tema.font.small,\n lineHeight: tema.lineHeight.small,\n fontWeight: tema.weight.semibold,\n borderRadius: tema.radius.pill,\n paddingHorizontal: tema.space.sm,\n overflow: 'hidden',\n }}\n >\n {children}\n </Text>\n );\n}\n\nexport function Hint({ children }: { children: React.ReactNode }) {\n const tema = useTema();\n return (\n <Text\n style={{\n color: tema.color.textMuted,\n fontSize: tema.font.small,\n lineHeight: tema.lineHeight.small,\n }}\n >\n {children}\n </Text>\n );\n}\n\nexport function Card({\n children,\n dashed,\n style,\n testID,\n accessibilityLabel,\n}: {\n children: React.ReactNode;\n dashed?: boolean;\n style?: StyleProp<ViewStyle>;\n testID?: string;\n accessibilityLabel?: string;\n}) {\n const tema = useTema();\n return (\n <View\n testID={testID}\n {...(accessibilityLabel ? { accessibilityLabel } : {})}\n style={[\n {\n backgroundColor: tema.color.surface,\n borderRadius: tema.radius.lg,\n borderWidth: tema.hairline,\n borderColor: tema.color.border,\n borderStyle: dashed ? 'dashed' : 'solid',\n padding: tema.space.md,\n gap: tema.space.sm,\n },\n style,\n ]}\n >\n {children}\n </View>\n );\n}\n\n/**\n * Status som ikon + etikett. Fargen er et TILLEGG, aldri bæreren: to av\n * palettens statusfarger er målt til under 1,5 i innbyrdes kontrast, så\n * etiketten er det som faktisk skiller dem (DD-08).\n */\nexport function StatusPill({\n ikon,\n etikett,\n fg,\n bg,\n testID,\n}: {\n ikon: string;\n etikett: string;\n fg: string;\n bg: string;\n testID?: string;\n}) {\n const tema = useTema();\n // `fg`/`bg` er TOKENNAVN fra theme.ts, ikke farger: samme mappe virker i begge\n // paletter og i vertens eget tema (DD-21).\n const farge = (navn: string, reserve: string) => (tema.color as Record<string, string>)[navn] ?? reserve;\n return (\n <View\n testID={testID}\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n gap: tema.space.xs,\n alignSelf: 'flex-start',\n paddingHorizontal: tema.space.sm,\n paddingVertical: tema.space.xs,\n borderRadius: tema.radius.pill,\n backgroundColor: farge(bg, tema.color.neutralBg),\n }}\n >\n <Ikon navn={ikon} storrelse=\"minste\" farge={farge(fg, tema.color.textSecondary)} />\n <Text style={{ color: farge(fg, tema.color.textSecondary), fontSize: tema.font.small, fontWeight: tema.weight.medium }}>\n {etikett}\n </Text>\n </View>\n );\n}\n\n/**\n * Varsel. Rollen ligger på `Text`, ikke på containeren: `accessible` på en\n * container sluker barna som egne fokusstopp (`tdd-contract-validation`).\n */\nexport function Banner({\n ikon,\n tone,\n children,\n live,\n testID,\n}: {\n ikon: string;\n tone: 'info' | 'warning' | 'danger' | 'success';\n children: string;\n live?: boolean;\n testID?: string;\n}) {\n const tema = useTema();\n return (\n <View\n testID={testID}\n style={{\n flexDirection: 'row',\n gap: tema.space.sm,\n backgroundColor: tema.color[`${tone}Bg` as keyof typeof tema.color],\n borderRadius: tema.radius.md,\n padding: tema.space.md,\n }}\n >\n <Ikon navn={ikon} farge={tema.color[tone]} />\n <Text\n accessibilityRole=\"alert\"\n accessibilityLiveRegion={live ? 'polite' : 'none'}\n style={{\n flex: 1,\n color: tema.color[tone],\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n }}\n >\n {children}\n </Text>\n </View>\n );\n}\n","import type { Platform } from '@innspel/core';\n\n/**\n * Hver streng innsenderen ser, ett sted.\n *\n * Ordlyden er ikke fri: den er tegnet i `design/wireframes/innsending-widget.jsx` og\n * `betaprogram-tester.jsx` — som er SPESIFIKASJONER, ikke forbilder (DD-71) — og bundet av\n * beslutninger. Utseendet er godkjent på konseptsiden\n * `docs/forslag/redesign/konsept/widget-konsept-v0.1-2026-09-20.html`.\n *\n * SETNINGEN innsenderen får for en status (DD-08) står IKKE her — den bor i\n * `submissionStatus` i `theme/theme.ts` og leses fra den genererte mappa (`status.ts`), så\n * appen, portalen og panelet ikke kan love tre ulike ting.\n *\n * Språket er innsenderens, ikke repoets (DD-50, presisert 2026-09-14 og 2026-09-20): aldri\n * «spor», «reproduksjon», «privat view» eller et kontraktfeltnavn — og aldri en\n * kontraktVERDI: `android` heter «Android», `nb-NO` heter «Norsk (bokmål)».\n *\n * Norsk bokmål. Ingen leietakernavn: strengen som nevner avsenderen tar navnet som\n * parameter, siden pakken skal kunne brukes av hvem som helst.\n */\n\n/**\n * «Sak f8dc» — de fire siste tegnene av id-en, som panelet viser (`#f8dc`, DD-63): innsender\n * og saksbehandler skal peke på samme nummer. Ekte id-er er UUIDv7 (36 tegn); før sto hele\n * strengen i lista. Et kort prefiks-format («sub_2041») beholder resten etter understreken.\n */\nexport function saksnr(id: string): string {\n const i = id.indexOf('_');\n const rest = i >= 0 ? id.slice(i + 1) : id;\n return rest.length > 8 ? rest.slice(-4) : rest;\n}\n\nconst stor = (s: string): string => (s ? s.charAt(0).toUpperCase() + s.slice(1) : s);\n\n/**\n * Kontraktens `platform`-verdi som et ord (DD-50, presisert 2026-09-20). Verdien som SENDES\n * er uendret; dette er bare det innsenderen leser. Samme ord som portalen bruker.\n */\nconst PLATTFORM_ORD: Record<string, string> = {\n android: 'Android',\n ios: 'iOS',\n web: 'Web',\n tvos: 'TV',\n};\n\n/**\n * Språktaggen som et ord (DD-50). Lista er lukket og norsk: `Intl.DisplayNames` finnes ikke\n * i alle Hermes-bygg, og et forsøk som feiler ville sluppet `nb-NO` ut på skjermen. Et ukjent\n * språk får hovedtaggen med stor forbokstav, aldri regionsuffikset.\n */\nconst SPRAAK_ORD: Record<string, string> = {\n nb: 'Norsk (bokmål)',\n nn: 'Norsk (nynorsk)',\n no: 'Norsk',\n se: 'Nordsamisk',\n en: 'Engelsk',\n sv: 'Svensk',\n da: 'Dansk',\n fi: 'Finsk',\n is: 'Islandsk',\n de: 'Tysk',\n nl: 'Nederlandsk',\n fr: 'Fransk',\n es: 'Spansk',\n it: 'Italiensk',\n pt: 'Portugisisk',\n pl: 'Polsk',\n lt: 'Litauisk',\n ru: 'Russisk',\n uk: 'Ukrainsk',\n ar: 'Arabisk',\n so: 'Somali',\n ti: 'Tigrinja',\n tr: 'Tyrkisk',\n ur: 'Urdu',\n fa: 'Persisk',\n th: 'Thai',\n vi: 'Vietnamesisk',\n zh: 'Kinesisk',\n ja: 'Japansk',\n ko: 'Koreansk',\n};\n\nexport function plattformOrd(verdi: string): string {\n return PLATTFORM_ORD[verdi.toLowerCase()] ?? stor(verdi);\n}\n\nexport function spraakOrd(verdi: string): string {\n const hoved = verdi.toLowerCase().split(/[-_]/)[0] ?? verdi;\n return SPRAAK_ORD[hoved] ?? stor(hoved);\n}\n\n/** «én», «to», «tre» — tall i en setning skrives med bokstaver opp til tre (DD-14, DD-32). */\nconst TALLORD = ['null', 'én', 'to', 'tre'] as const;\nconst tallord = (n: number): string => TALLORD[n] ?? String(n);\n\nexport const tekst = {\n // 2b — første valg\n valgTittel: 'Hva gjelder det?',\n sporFeil: 'Noe virker ikke',\n /** DD-67, produkteier 2026-09-20: dette er VALGETS tekst, ikke en hjelpetekst. */\n sporFeilUnder: 'Noe er galt eller virker rart',\n sporOnske: 'Jeg ønsker meg noe',\n sporOnskeUnder: 'Noe du savner eller vil ha annerledes',\n /**\n * Anonym modus (DD-62 (3)). Portalens ordlyd, med widgetens ord. ALDRI «du er ikke logget\n * inn»: anonym modus er leietakerens valg ved `init()`, og widgeten vet ikke om\n * innsenderen er logget inn i vertsappen.\n */\n sendAnonymtHint: 'Innspillet kobles ikke til deg, og du kan ikke følge det etterpå.',\n\n // 2c — kjente feil (DD-29, DD-30). Ingen undertittel: overskriften stiller spørsmålet.\n kjenteFeilTittelFeil: 'Er det dette du ser?',\n kjenteFeilTittelOnske: 'Har noen ønsket dette?',\n svarJa: 'Ja, jeg også',\n svarLigner: 'Ligner, men ikke helt',\n svarNei: 'Nei, det er noe annet',\n omvei: 'Omvei:',\n rettesI: (versjon: string) => `Rettes i ${versjon}`,\n rettetI: (versjon: string) => `Rettet i ${versjon}`,\n /** Hvert kort er ÉN gruppe med samlet navn; de tre svarene er knapper i den. */\n kjentFeilGruppe: (tittel: string, status: string, versjon?: string) =>\n versjon ? `Kjent feil: ${tittel}, ${status}, ${versjon}` : `Kjent feil: ${tittel}, ${status}`,\n\n // 2d + 2e — feltet og kontekstlinja\n /**\n * «Ditt innspill», ikke «Din feil» (DD-54). «Din» festet saken til personen, og «feil»\n * karakteriserte den før noen hadde lest den — innsenderen leste det som skyld.\n */\n feltLabelFeil: 'Ditt innspill',\n feltLabelOnske: 'Ditt ønske',\n /** DD-45: to spørsmål i feilsporet. Kilde: Sentry «What's the bug? What did you expect?» */\n placeholderFeil: 'Hva skjedde? Hva forventet du?',\n placeholderOnske: 'Hva ønsker du deg?',\n send: 'Send',\n sender: 'Sender …',\n /** DD-44: minimum tegn er det ENESTE kravet. */\n forKort: (min: number) => `Minst ${min} tegn. Ingenting annet er obligatorisk.`,\n tellerFull: ' — kort og konkret holder',\n /**\n * DD-05 ordrett: «Én linje «Vis» under feltet ekspanderer». Lukket er linja en\n * OPPSUMMERING — den navngir det innsenderen kjenner igjen; lista er hele sannheten.\n */\n kontekstLinjeLukket: 'Skjerm og enhet legges ved',\n kontekstLinjeApen: 'Dette legges ved',\n kontekstVis: 'Vis',\n kontekstSkjul: 'Skjul',\n kontekstFjern: 'Fjern',\n kontekstFjernA11y: (etikett: string) => `Fjern ${etikett.toLowerCase()} fra innsendingen`,\n /** K5 — skjermens ene hjelpesetning, og bare når lista står. */\n kontekstAldri: 'Aldri navn, e-post, telefon, posisjon eller det som står på skjermen.',\n /**\n * Etikettene er portalens: samme felt, samme ord i begge flater (DD-50, presisert\n * 2026-09-20). Fram til R8.3 sto det «Plattform» og «OS» her.\n */\n kontekstEtiketter: {\n screen: 'Skjerm',\n appVersion: 'Appversjon',\n platform: 'Enhet',\n os: 'System',\n build: 'Bygg',\n locale: 'Språk',\n } as Record<string, string>,\n lenketTil: (tittel: string) => `Lenket til: «${tittel}»`,\n fjernLenke: 'Fjern lenken til den kjente feilen',\n\n // 2f — skjermbilde (K4, DD-39, DD-40, DD-42)\n leggVedSkjermbilde: 'Legg ved skjermbilde',\n velgBilde: 'Velg bilde',\n skjermbildeUnderGalleri: 'Bildet er fra galleriet. Appen maskerer ingenting i det for deg — mal over det som ikke skal med.',\n bildeFeilet: 'kunne ikke hente bildet. Du kan sende uten.',\n skjermbildeTittel: 'Se over bildet',\n skjermbildeUnder: 'Bildet ble tatt da du trykket. Det du maskerer, ser vi aldri.',\n maskering: 'Maskering',\n maskerFelt: 'Masker felt',\n tegnOver: 'Tegn over',\n maskerAllTekst: 'Masker all tekst',\n maskertAvAppen: 'Maskert av appen',\n maskertAvAppenHint: 'Dette feltet er alltid dekket og kan ikke avdekkes.',\n dittStrok: 'Trykk på et dekket felt for å angre.',\n angreSiste: 'Angre siste',\n angreSisteA11y: 'Angre det siste feltet du dekket',\n allTekstHint: 'Hele bildet er gjort uskarpt så tekst ikke kan leses. Layouten er synlig.',\n fjernBildet: 'Fjern bildet',\n leggVed: 'Legg ved',\n bildeLagtVed: 'Bilde lagt ved',\n fjernSkjermbilde: 'Fjern bildet',\n sendHintMedBilde: 'Teksten sendes først; bildet lastes opp for seg.',\n skjermbildeFeilet: 'kunne ikke ta skjermbilde. Du kan sende uten.',\n skjermbildeA11y: (auto: number, egne: number, uskarpt: boolean) =>\n `Forhåndsvisning av skjermbildet. ${auto ? `${auto} felt maskert av appen og kan ikke avmaskeres. ` : ''}${egne ? `${egne} felt maskert av deg. ` : ''}${uskarpt ? 'All tekst er gjort uskarp. ' : ''}Trykk for å maskere et felt, dra for å tegne over.`,\n\n // DD-46 — mønstervarsel. Aldri stille redaksjon.\n monsterSpm: {\n email: 'Dette ser ut som en e-postadresse. Vil du fjerne den?',\n phone: 'Dette ser ut som et telefonnummer. Vil du fjerne det?',\n card: 'Dette ser ut som et kortnummer. Vil du fjerne det?',\n ip: 'Dette ser ut som en IP-adresse. Vil du fjerne den?',\n token: 'Dette ser ut som en tilgangsnøkkel. Vil du fjerne den?',\n },\n monsterFjern: 'Fjern',\n monsterBehold: 'Behold',\n monsterForklaring: 'Teksten endres bare hvis du trykker Fjern. Vi fjerner aldri noe stille.',\n\n /* 2g — kvitteringen som KORT (DD-07, P1 (a) 2026-09-20).\n Etiketten sier hva som skjedde; HELTEN er løftets setning. */\n kvitteringSendtDato: (dato: string) => `Sendt ${dato}`,\n kvitteringSendtAnonymtDato: (dato: string) => `Sendt anonymt ${dato}`,\n kvitteringRegistrertDato: (dato: string) => `Registrert ${dato}`,\n kvitteringLagretDato: (dato: string) => `Lagret ${dato}`,\n kvitteringFeil: 'Du får beskjed når den er rettet, eller hvis vi trenger mer.',\n kvitteringJaOgsa: 'Du får beskjed når den er rettet.',\n kvitteringUnder: 'Ligger under «Mine innspill» og oppdaterer seg selv.',\n saksnummer: (nr: string) => `Sak ${saksnr(nr)}`,\n tilbakeTilAppen: 'Tilbake til appen',\n /** DD-42: saken er sendt, bildet kom ikke med — aldri en blokkert innsending. */\n kvitteringVedleggFeilet: 'Sendt — skjermbildet kunne ikke legges ved',\n tekstenErLagret: 'Teksten din er lagret.',\n vedleggFeiletBanner: 'Bildet ble ikke lastet opp. Saken er sendt uten det — vil du, kan du sende et nytt innspill med bilde.',\n saksnummerUtenVedlegg: (nr: string) => `Sak ${saksnr(nr)} · uten vedlegg`,\n\n /* 2i — køet uten nett (DD-41, presisert 2026-09-20). Kortet lover ikke svar, og det er\n derfor ikke kvitteringen: kvitteringen kommer når køen tømmes. */\n koIngenNett: 'Ingen nett',\n koHelt: 'Sendes når du er på nett.',\n koUnder: 'Du ser den under «Mine innspill» til den er sendt.',\n offlineBanner: 'Ingen nett. Lagres og sendes automatisk.',\n offlineLagre: 'Lagre — sendes når du er på nett',\n /** DD-41: et skjermbilde køes aldri. */\n offlineUtenBilde: 'Skjermbilde kan ikke legges ved uten nett. Teksten sendes; bildet ble ikke lagret.',\n sendefeilBanner: (arsak: string) => `Kunne ikke sende: ${arsak} Teksten din er beholdt.`,\n provIgjen: 'Prøv igjen',\n\n // 2j — mine innspill\n mineTittel: 'Mine innspill',\n /** Knappen på første steg med innspill fra før (DD-62): tallet er det som gjør den til en inngang. */\n mineMedAntall: (n: number) => `Mine innspill · ${n}`,\n mineEtikett: (n: number) => `Mine innspill, ${n} innspill`,\n mineLaster: 'Henter innspillene dine',\n /** DD-19: tomheten er OVERSKRIFTEN, ikke en grå linje under tittelen. */\n mineTomTittel: 'Du har ikke sendt noe ennå',\n /** Ordrett portalens `mineTomHint` — én innsender, to flater, samme setning. */\n mineTomHint: (leietaker: string) => `Det første innspillet tar under et minutt. Feil eller ønske — ${leietaker} svarer på begge.`,\n mineTomHintGenerisk: 'Det første innspillet tar under et minutt. Feil eller ønske — du får svar på begge.',\n /** Køraden har ingen saksnummer å vise — hodet sier hva den er i stedet (DD-41). */\n mineIkkeSendtHode: (spor: string) => `${stor(spor)} · ikke sendt ennå`,\n mineFeil: 'Innspillene dine kunne ikke hentes nå.',\n /** «Feil · sak 2041» — sporet først, aldri rå id og aldri kontraktens type (DD-50). */\n sakHode: (spor: string, nr: string) => `${stor(spor)} · sak ${saksnr(nr)}`,\n /** F14: svaret kom siden forrige gang denne enheten viste lista. */\n nyttSvar: 'Nytt svar',\n // Leietakeren fjernet vedlegget. Bare AT — aldri hvorfor, av hvem eller når.\n bildeFjernet: 'Bildet er fjernet.',\n svarFra: (leietaker: string, dato: string) => `Svar fra ${leietaker} · ${dato}`,\n svarFraGenerisk: (dato: string) => `Svar · ${dato}`,\n // DD-69 — «Legg til mer»: innsenderens egne ord, ikke et svar på svaret.\n leggTilMer: 'Legg til mer',\n leggTilMerLabel: 'Legg til mer på denne saken',\n leggTilMerPlaceholder: 'Hva vil du legge til?',\n leggTilMerHint: 'Blir stående på saken din, under det du alt har skrevet. Ikke et svar på svaret — det blir ingen samtale her.',\n avbryt: 'Avbryt',\n duLaTil: (dato: string) => `Du la til · ${dato}`,\n lagtTil: 'Lagt til',\n tilleggTak: 'Du har lagt til tre ganger. Har du mer, send et nytt innspill.',\n tilleggLukket: 'Saken er avsluttet — send et nytt innspill.',\n /** F34: serverens egen setning (InnspelApiError) — aldri en rå feil. */\n tilleggFeil: (arsak: string) => `Kunne ikke legge til: ${arsak} Teksten din er beholdt.`,\n tilleggIngenNett: 'Ingen nett. Teksten din er beholdt — prøv igjen når du er på nett.',\n tilleggFeilGenerisk: 'Kunne ikke legge til. Teksten din er beholdt — prøv igjen.',\n sendNytt: 'Send nytt innspill',\n /** Tom tilstand: det finnes ikke noe «nytt» å sende når ingenting er sendt. */\n sendForste: 'Send innspill',\n\n /* Sporingslinjen (DD-08/DD-28 presisert 2026-09-20). Ordene er innsenderens, aldri\n kontraktens: ingen status-enum, ingen «deadline». Samme ord som portalen. */\n sporEtikett: 'Sakens gang',\n sporSvarInnen: 'Svar innen',\n /** Mottatt: fristen finnes ikke ennå, og vi lover ingen dato på en sak ingen har åpnet. */\n sporDatoenSettes: 'dato kommer',\n /** Planlagt/Bygges: kontrakten har ingen leveringsdato, og DD-28 forbyr en ETA. */\n sporIngenDato: 'ingen dato lovet',\n sporNaarTenantTarDen: (leietaker: string) => `når ${leietaker} tar den`,\n sporNaarDenTasOpp: 'når de tar den',\n /** P3 (a), produkteier 2026-09-20. Klientregel på `deadlineAt` — ingen ny status. */\n sporFristenErGatt: 'Fristen er gått',\n\n // 3a — invitasjonsbanneret (DD-12). Kontakttaket står IKKE her (DD-14).\n invitasjonRegion: 'Invitasjon til betaprogram',\n invitasjonHva: (navn: string) => `Vil du teste «${navn}»?`,\n /** Én meta-linje med det kontrakten har: antall oppgaver og perioden. */\n invitasjonMeta: (oppgaver: number, periode: string) => `${oppgaver} oppgaver · ${periode}`,\n lesMer: 'Les mer og bli med',\n avvisInvitasjon: 'Avvis invitasjonen',\n\n // 3b — aksepten (DD-13, DD-32, DD-37)\n /**\n * DD-32, presisert 2026-09-20: tallene skal være SANNE. Summen når anslagene er ulike —\n * et snitt av 5, 3 og 2 er ikke sant for noen av oppgavene.\n */\n akseptTallSum: (oppgaver: number, minutter: number, periode: string) =>\n `${oppgaver} oppgaver · ca. ${minutter} min i alt · ${periode}`,\n akseptTallHver: (oppgaver: number, minutter: number, periode: string) =>\n `${oppgaver} oppgaver · ca. ${minutter} min hver · ${periode}`,\n akseptOppgaver: 'Hva vi ber om',\n akseptOppgaveTid: (minutter: number) => `ca. ${minutter} min`,\n akseptKjenteFeil: 'Kjente feil vi vet om',\n akseptInnsamling: 'Hva som samles inn',\n /** Samme ord som kontekstlista (DD-50): «enhet», ikke «plattform». */\n akseptInnsamlingTekst: 'Skjerm, appversjon, enhet og det du svarer. Aldri navn, e-post, telefon eller posisjon.',\n akseptVilkar: 'Les vilkårene',\n /**\n * Skjermens ENE hjelpesetning: taket og utgangen i én (DD-67). «høyst N» — tallet er\n * `maxContacts`, et TAK som kan senkes og aldri heves, og antall oppfølginger er malene,\n * som kan være færre. «Vi spør tre ganger» lover noe som ikke er sant (DD-14).\n */\n akseptTakOgUtgang: (maks: number) =>\n `Vi spør høyst ${tallord(maks)} ${maks === 1 ? 'gang' : 'ganger'} underveis. Du kan gå ut når som helst — ingen vilkår, ingen avtale.`,\n akseptTakOgUtgangVilkar: (maks: number) =>\n `Vi spør høyst ${tallord(maks)} ${maks === 1 ? 'gang' : 'ganger'} underveis. Du kan gå ut når som helst.`,\n bliMed: 'Bli med',\n bliMedHint: 'Samtykket gjelder bare dette programmet.',\n /** DD-12: tokenet er engangs og kom i leietakerens egen kanal — plattformen sender aldri. */\n bliMedUtenToken: 'Åpne lenken vi sendte deg for å bli med.',\n akseptFeil: (arsak: string) => `Kunne ikke bli med: ${arsak}`,\n\n // 3c — deltakelsen og «Gå ut» (DD-36). Kontakttaket står IKKE her (DD-14).\n deltakelseRegion: 'Ditt betaprogram',\n gaaUt: 'Gå ut av programmet',\n gaaUtTittel: 'Gå ut av programmet?',\n gaaUtTekst: (navn: string) =>\n `Du tas ut av testgruppen med en gang. «${navn}» slås av for deg, og vi tar ikke kontakt igjen. Det du allerede har svart, beholdes.`,\n bliVaerende: 'Bli værende',\n gaaUtBekreft: 'Gå ut',\n\n /* Programmets sporingslinje (P1 (a), produkteier 2026-09-20): deltakelsen bæres av\n linjen, ikke av et kvitteringskort — merkefargen er for det som er SENDT (DD-41). */\n programSporEtikett: 'Programmets gang',\n programBleMed: 'Du ble med',\n programGjort: (gjort: number, av: number) => `${gjort} av ${av} gjort`,\n programOver: 'Programmet er over',\n /** Under nå-leddet, ÉN linje. Aldri «to igjen»: «1 av 3» sier alt tallet sier (DD-08). */\n programNaarDetPasser: 'når det passer',\n\n // 3c — oppgavene\n oppgaverTittel: 'Oppgavene',\n oppgaveGjort: 'Gjort',\n oppgaveGjortLabel: (tittel: string) => `Gjort: ${tittel}`,\n /** Oppgavens ENE meta-linje i `small` (DD-67). Setningen hennes står i `body` under. */\n oppgaveGjortMeta: (dato: string, utfall: string) => `Gjort ${dato} · ${utfall.toLowerCase()}`,\n oppgaveTid: (minutter: number, skjerm?: string) => `ca. ${minutter} min${skjerm ? ` · ${skjerm}` : ''}`,\n oppgaveUbekreftet: 'Svaret ble ikke bekreftet — merk den på nytt',\n oppgaveRadA11y: (nr: number, tittel: string, status: string) => `Oppgave ${nr}: ${tittel}, ${status}`,\n oppgaveIkkeGjort: 'ikke gjort',\n\n // 3e — «Hvordan gikk det?»: tre lukkede valg, aldri en skala (DD-15)\n hvordanGikkDet: 'Hvordan gikk det?',\n utfallFungerte: 'Fungerte',\n utfallDelvis: 'Fungerte delvis',\n utfallIkke: 'Fungerte ikke',\n setningLabel: 'Vil du si én setning om det?',\n setningValgfritt: 'Valgfritt',\n lagre: 'Lagre',\n /** Etter «Ikke»: feilsporet er vertens — plattformen navigerer aldri selv. */\n meldFeil: 'Meld det som feil',\n svarFeil: (arsak: string) => `Kunne ikke lagre svaret: ${arsak}`,\n\n // 3d — oppfølgingskortene (DD-34): arten avgjør knappene. Ingen kontaktnummer (DD-14).\n oppfolgingRegion: 'Oppfølging fra betaprogrammet',\n oppfolgingKost: 'Ett spørsmål · tar under ett minutt',\n senere: 'Senere',\n svarNaa: 'Svar nå',\n aapneOppgavene: 'Åpne oppgavene',\n\n // Felles\n tilbake: 'Tilbake',\n lukk: 'Lukk',\n venterPaaNett: 'Venter på nett',\n feil: 'feil',\n onske: 'ønske',\n} as const;\n\n/**\n * Løftene som IKKE hører til en innsendingsstatus. Statusenes løfter står i\n * `submissionStatus` i `theme/theme.ts` og leses gjennom `status.ts` — det var tre kopier av\n * dem før 2026-09-14 (UX-gjennomgangen C5).\n */\nexport const lofte = {\n venterNett: 'Sendes automatisk når du er på nett.',\n} as const;\n\n/** Kontekstens verdi slik innsenderen leser den (DD-50). Verdien som sendes er uendret. */\nexport function kontekstVerdi(felt: string, verdi: string): string {\n if (felt === 'platform') return plattformOrd(verdi as Platform);\n if (felt === 'locale') return spraakOrd(verdi);\n return verdi;\n}\n","import React from 'react';\nimport { Pressable, Text, View } from 'react-native';\nimport { Ikon } from '../Ikon.js';\nimport { useTema } from '../tema.js';\nimport { H, Hint } from './primitiver.js';\nimport { tekst } from './tekster.js';\n\n/**\n * 2b — første valg, og eneste steg som ikke har «Tilbake».\n *\n * DD-02: ALDRI et tredje valg, og aldri spørsmål om kategori eller alvorlighet. Valget her\n * styrer alt etterpå: feilsporet får kjente feil FØR feltet og kan bære koblingsnøkler,\n * ønskesporet får dem etter og kan ikke.\n *\n * **R8.3 (widget-konsept v0.1):** valgene er RADER, ikke to rammede kort side om side. Det\n * fylte ikonet i merkefargen på en rund flate bærer vekten (DD-63) — 40 px ikon\n * (`storrelse=\"stor\"`, 2 × `icon.inline`) på en flate som er `touch + sm`; raden er\n * `touch + lg`. Vekten står ETT sted, så raden trenger ingen ramme.\n *\n * Undertekstene er VALGETS TEKST, ikke hjelpetekst (produkteier 2026-09-20): de skiller\n * sporene, og de er det eneste som sier hva valget betyr. Skjermen har derfor ingen\n * hjelpesetning — spørsmålet er overskriften.\n *\n * **Anonym modus** (DD-62 (3), DD-02): uten feedback-token finnes ingen «Mine innspill».\n * Én setning sier hva anonymt betyr, så fraværet ikke leses som en feil. Setningen er\n * portalens, ALDRI «du er ikke logget inn»: anonym modus er leietakerens valg ved `init()`,\n * og widgeten vet ikke om innsenderen er logget inn i vertsappen.\n */\nexport function Valg({ onVelg, anonym }: { onVelg: (spor: 'feil' | 'onske') => void; anonym?: boolean }) {\n const tema = useTema();\n\n const rad = (spor: 'feil' | 'onske', ikon: string, label: string, under: string, forst: boolean) => (\n <Pressable\n testID={`spor-${spor}`}\n accessibilityRole=\"button\"\n accessibilityLabel={`${label}, ${under}`}\n onPress={() => onVelg(spor)}\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n gap: tema.space.md,\n minHeight: tema.touch + tema.space.lg,\n paddingVertical: tema.space.sm,\n borderTopWidth: forst ? 0 : tema.hairline,\n borderTopColor: tema.color.border,\n }}\n >\n <View\n testID={`spor-${spor}-ikonflate`}\n style={{\n width: tema.touch + tema.space.sm,\n height: tema.touch + tema.space.sm,\n borderRadius: tema.radius.pill,\n backgroundColor: tema.color.brandBg,\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <Ikon navn={ikon} storrelse=\"stor\" farge={tema.color.brand} />\n </View>\n <View style={{ flex: 1, minWidth: 0 }}>\n <Text style={{ color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body, fontWeight: tema.weight.semibold }}>\n {label}\n </Text>\n {/* Valgets tekst, ikke hjelpetekst — måleren får unntak for denne (DD-67). */}\n <Text style={{ color: tema.color.textMuted, fontSize: tema.font.small, lineHeight: tema.lineHeight.small }}>\n {under}\n </Text>\n </View>\n <Ikon navn=\"chevron-forward-outline\" storrelse=\"minste\" farge={tema.color.textMuted} />\n </Pressable>\n );\n\n return (\n <View style={{ gap: tema.space.lg }}>\n <H>{tekst.valgTittel}</H>\n <View>\n {rad('feil', 'bug', tekst.sporFeil, tekst.sporFeilUnder, true)}\n {rad('onske', 'bulb', tekst.sporOnske, tekst.sporOnskeUnder, false)}\n </View>\n {anonym ? <Hint>{tekst.sendAnonymtHint}</Hint> : null}\n </View>\n );\n}\n","import type { KnownIssueCard } from '@innspel/core';\nimport React from 'react';\nimport { ActivityIndicator, ScrollView, Text, View } from 'react-native';\nimport { knownIssueStatus } from '../generated/tokens.js';\nimport { Ikon } from '../Ikon.js';\nimport { useTema } from '../tema.js';\nimport { Btn, H, Sek, Tekstknapp } from './primitiver.js';\nimport { tekst } from './tekster.js';\n\n/** DD-03: maks tre kort. Grensen er klientens — registeret kan ha flere. */\nconst MAKS_KORT = 3;\n\n/**\n * 2c — kjente feil. Differensiatoren: vises FØR feltet i feilsporet, ETTER i ønskesporet.\n *\n * DD-29 gir kortet TRE svar, ikke to: «Ja, jeg også» (Reach +1, ingen ny sak) · «Ligner,\n * men ikke helt» (eget innspill med lenke, uten tvunget match) · «Nei, det er noe annet»\n * (vanlig innsending). Det midterste er hele poenget — uten det tvinger man et valg mellom\n * å bli talt feil og å ikke bli talt.\n *\n * **R8.3 (widget-konsept v0.1, DD-63 presisert 2026-09-20):** ingen av de tre er skjermens\n * primærhandling, og INGEN av dem står i aksjonsfargen — tre fylte knapper var tre\n * primærknapper. «Ja, jeg også» er `tonet` fordi det er valget som sparer innsenderen for å\n * skrive; «Ligner, men ikke helt» er en tekstknapp ved siden av; «Nei, det er noe annet»\n * står alene i foten. Kortene er RADER med skillelinje, ikke kort i kort: nullpunktet fant\n * 10 rammede elementer på denne skjermen.\n *\n * DD-30 gir raden tre deler: tittelen i `body` halvfet, OMVEIEN i `body` — det er den\n * innsenderen faktisk trenger — og status som ikon + ord i ÉN meta-linje, med versjonen som\n * et tillegg («Aktiv · rettes i 3.2»). «Rettet i 3.1» står som ETT ledd; ordet «Rettet»\n * skal aldri stå to ganger.\n *\n * Undertittelen «Kjenner du igjen en av disse?» er ute: overskriften stiller spørsmålet, og\n * en skjerm har høyst én hjelpesetning (DD-67).\n *\n * Tilgjengelighet: kortet er IKKE én knapp. Tre svar må være tre fokusstopp, og `accessible`\n * på radcontaineren ville slukt dem. I stedet bærer hver knapp kortets samlede navn i\n * etiketten, så en skjermleserbruker som lander på «Ja, jeg også» vet hvilken feil svaret\n * gjelder.\n *\n * Treffene er et tilbud, aldri en sperre: feiler oppslaget eller er lista tom, hoppes\n * skjermen over uten melding. Det håndteres i Widget, ikke her.\n */\nexport function KjenteFeil({\n kort,\n spor,\n laster,\n sender,\n onJaOgsa,\n onLigner,\n onNei,\n}: {\n kort: KnownIssueCard[];\n spor: 'feil' | 'onske';\n laster?: boolean;\n /** «Ja, jeg også» er underveis: alle svar låses, så ett trykk gir én bekreftelse (C7). */\n sender?: boolean;\n onJaOgsa: (k: KnownIssueCard) => void;\n onLigner: (k: KnownIssueCard) => void;\n onNei: () => void;\n}) {\n const tema = useTema();\n const tittel = spor === 'onske' ? tekst.kjenteFeilTittelOnske : tekst.kjenteFeilTittelFeil;\n\n if (laster) {\n return (\n <View style={{ flex: 1, gap: tema.space.md }}>\n <H>{tittel}</H>\n <ActivityIndicator accessibilityLabel=\"Sjekker kjente feil\" color={tema.color.textSecondary} />\n </View>\n );\n }\n\n // Samme form som skjemaet: radene scroller, «Nei, det er noe annet» står fast.\n return (\n <View testID=\"kjente-feil\" style={{ flexGrow: 1, flexShrink: 1, gap: tema.space.md }}>\n <H>{tittel}</H>\n\n <ScrollView\n testID=\"kjente-feil-liste\"\n style={{ flexGrow: 0, flexShrink: 1 }}\n keyboardShouldPersistTaps=\"handled\"\n >\n {kort.slice(0, MAKS_KORT).map((k, i) => {\n // Kortet har ALLTID en status (C5/C6): «Aktiv» eller «Rettet», fra\n // knownIssueStatus i temaet. Er feilen RETTET, bærer statusordet versjonen som\n // ETT ledd («Rettet i 3.1»); er den aktiv, står versjonen som et tillegg til\n // pillens ord («Aktiv · rettes i 3.2»). Ordet «Rettet» står aldri to ganger.\n const o = knownIssueStatus[k.status] ?? knownIssueStatus.aktiv;\n const rettet = k.status === 'fikset';\n const statusOrd = rettet && k.fixedIn ? tekst.rettetI(k.fixedIn) : o.etikett;\n const tillegg = !rettet && k.fixedIn ? `· ${tekst.rettesI(k.fixedIn).toLowerCase()}` : undefined;\n const gruppe = tekst.kjentFeilGruppe(k.title, statusOrd, tillegg?.replace('· ', ''));\n\n return (\n <View\n key={k.id}\n testID={`kjent-feil-${k.id}`}\n style={{\n gap: tema.space.sm,\n paddingVertical: tema.space.md,\n borderTopWidth: i === 0 ? 0 : tema.hairline,\n borderTopColor: tema.color.border,\n }}\n >\n <Text\n testID={`kjent-feil-tittel-${k.id}`}\n style={{\n color: tema.color.textPrimary,\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n fontWeight: tema.weight.semibold,\n }}\n >\n {k.title}\n </Text>\n\n {/* Omveien er `body` — det er den innsenderen faktisk trenger (DD-30, DD-67). */}\n {k.workaround ? (\n <Sek testID={`kjent-feil-omvei-${k.id}`}>\n {tekst.omvei} {k.workaround}\n </Sek>\n ) : null}\n\n {/* ÉN meta-linje i `small` — ikon og ord, aldri farge alene (DD-08). */}\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: tema.space.sm, flexWrap: 'wrap' }}>\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: tema.space.xs }}>\n <Ikon navn={o.ikon} storrelse=\"minste\" farge={tema.color[o.fg as keyof typeof tema.color]} />\n <Text\n style={{\n color: tema.color[o.fg as keyof typeof tema.color],\n fontSize: tema.font.small,\n lineHeight: tema.lineHeight.small,\n fontWeight: tema.weight.semibold,\n }}\n >\n {statusOrd}\n </Text>\n </View>\n {tillegg ? (\n <Text style={{ color: tema.color.textMuted, fontSize: tema.font.small, lineHeight: tema.lineHeight.small }}>\n {tillegg}\n </Text>\n ) : null}\n </View>\n\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: tema.space.md }}>\n <Btn\n variant=\"tonet\"\n testID={`ja-ogsa-${k.id}`}\n label={tekst.svarJa}\n accessibilityLabel={`${tekst.svarJa}. ${gruppe}`}\n disabled={sender}\n busy={sender}\n onPress={() => onJaOgsa(k)}\n />\n <Tekstknapp\n testID={`ligner-${k.id}`}\n label={tekst.svarLigner}\n accessibilityLabel={`${tekst.svarLigner}. ${gruppe}`}\n disabled={sender}\n onPress={() => onLigner(k)}\n />\n </View>\n </View>\n );\n })}\n </ScrollView>\n\n <View testID=\"kjente-feil-fot\" style={{ flexShrink: 0 }}>\n <Btn variant=\"secondary\" testID=\"nei-noe-annet\" label={tekst.svarNei} disabled={sender} onPress={onNei} />\n </View>\n </View>\n );\n}\n","import type { SubmissionStatusView } from '@innspel/core';\nimport React from 'react';\nimport { Text, View } from 'react-native';\nimport { Ikon } from '../Ikon.js';\nimport { useTema } from '../tema.js';\nimport { Banner, Btn, Helt } from './primitiver.js';\nimport { Sporingslinje, sporingsledd } from './Sporingslinje.js';\nimport { formaterFrist, statusVisning } from './status.js';\nimport { tekst } from './tekster.js';\n\nexport type KvitteringArt = 'feil' | 'onske' | 'jaOgsa' | 'kø';\n\n/**\n * 2g — kvitteringen. Den LOVER noe, per spor (DD-07), og saksnummeret er der så innsenderen\n * kan vise til det hos support. Ingen «vurder appen». Ingen oppfordring til å dele.\n * Innsenderen har nettopp gjort oss en tjeneste — å be om en til er å ta betalt for den.\n *\n * **R8.3 (widget-konsept v0.1, DD-07 presisert 2026-09-20, P1 (a)):** kvitteringen er et\n * KORT — det innsenderen tar vare på. Leietakerens navn og saksnummeret i hjørnet, «Sendt\n * <dato>» som etikett, og **løftets setning som skjermens helt**. R8.1s brief ba om datoen\n * som helt, men en ny sak står i Mottatt, og en Mottatt-sak har med vilje ingen frist\n * («Svarfristen starter ikke ved innsending»). Datoen finnes ikke ennå; den tar heltens\n * plass i «Mine innspill» den dagen saken er i Vurderes (DD-28). Sporingslinjen under sier\n * hva som skjer videre.\n *\n * **Kø-kortet (DD-41)** er samme form, men ALDRI i merkefargen: merkefargen er for det som\n * er sendt. Stiplet kant på `surface`, «Ingen nett» med ikon der saksnummeret ellers står,\n * ingen sporingslinje og intet saksnummer — det finnes ikke noe å spore før serveren har\n * saken. Kortet er derfor ikke kvitteringen; kvitteringen kommer når køen tømmes.\n *\n * DD-42: feilet vedlegget, er saken likevel sendt. DD-47: helten er live-regionen — den\n * leses opp alene, uten at hele kortet gjentas.\n */\nexport function Kvittering({\n art,\n saksnummer,\n vedlegg,\n frist,\n sak,\n anonym,\n tenantName,\n onLukk,\n}: {\n art: KvitteringArt;\n saksnummer?: string;\n /** `feilet`: teksten er lagret, bildet kom ikke med. `forkastet`: køet offline uten bilde. */\n vedlegg?: 'feilet' | 'forkastet';\n /** Svarfristen fra svaret (`deadlineAt`). Tidsløftet er DATOEN, aldri «innen 90 dager» (DD-07, DD-28). */\n frist?: string;\n /** Saken slik serveren svarte. Gir sporingslinjen leddene — ingen nye felter. */\n sak?: SubmissionStatusView;\n /** Anonym modus (DD-62): linja om «Mine innspill» finnes ikke, for lista gjør det ikke. */\n anonym?: boolean;\n /** Leietakerens navn på kortet — aldri Innspels. */\n tenantName?: string;\n onLukk: () => void;\n}) {\n const tema = useTema();\n const ko = art === 'kø';\n\n const helt = {\n feil: tekst.kvitteringFeil,\n // Løftet er NØYAKTIG det «Mine innspill» og panelet viser for «Vurderes»: det leses fra\n // temaet, så kvitteringen og statusen ikke kan si to ting.\n onske: statusVisning('vurderes', 'onske', frist).lofte,\n jaOgsa: tekst.kvitteringJaOgsa,\n kø: tekst.koHelt,\n }[art];\n\n const dato = formaterFrist(sak?.createdAt ?? new Date().toISOString());\n const etikett =\n vedlegg === 'feilet' ? tekst.kvitteringVedleggFeilet\n : ko ? tekst.kvitteringLagretDato(dato)\n : art === 'jaOgsa' ? tekst.kvitteringRegistrertDato(dato)\n : anonym ? tekst.kvitteringSendtAnonymtDato(dato)\n : tekst.kvitteringSendtDato(dato);\n\n // Køet: ingenting er sendt, så det finnes ingen gang å spore og ingen sak å følge.\n const ledd = sak && !ko ? sporingsledd(sak, tenantName) : [];\n // Anonym modus har ingen liste, så linja om «Mine innspill» ville løyet (DD-62).\n const under = anonym ? undefined : ko ? tekst.koUnder : saksnummer ? tekst.kvitteringUnder : undefined;\n\n return (\n <View testID=\"kvittering\" style={{ flex: 1, gap: tema.space.md }}>\n {vedlegg === 'feilet' ? <Banner ikon=\"warning-outline\" tone=\"warning\" children={tekst.vedleggFeiletBanner} /> : null}\n {vedlegg === 'forkastet' ? <Banner ikon=\"image-outline\" tone=\"info\" children={tekst.offlineUtenBilde} /> : null}\n\n <View\n testID=\"kvittering-kort\"\n style={{\n backgroundColor: ko ? tema.color.surface : tema.color.brandFill,\n borderRadius: tema.radius.lg,\n borderWidth: ko ? tema.hairline : 0,\n borderStyle: ko ? 'dashed' : 'solid',\n borderColor: tema.color.borderInteractive,\n padding: tema.space.md,\n gap: tema.space.md,\n }}\n >\n <View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', gap: tema.space.sm }}>\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: tema.space.sm, flexShrink: 1 }}>\n <Ikon\n navn={ko ? 'swap-vertical-outline' : 'checkmark-circle-outline'}\n farge={ko ? tema.color.textSecondary : tema.color.onBrandFill}\n />\n {tenantName ? (\n <Text\n style={{\n color: ko ? tema.color.textPrimary : tema.color.onBrandFill,\n fontSize: tema.font.body,\n fontWeight: tema.weight.bold,\n }}\n >\n {tenantName}\n </Text>\n ) : null}\n </View>\n {ko ? (\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: tema.space.xs }}>\n <Ikon navn=\"cloud-offline-outline\" storrelse=\"minste\" farge={tema.color.textMuted} />\n <Text style={{ color: tema.color.textMuted, fontSize: tema.font.small, fontWeight: tema.weight.semibold }}>\n {tekst.koIngenNett}\n </Text>\n </View>\n ) : saksnummer ? (\n <Text\n style={{ color: tema.color.onBrandFill, fontSize: tema.font.small, fontWeight: tema.weight.semibold }}\n >\n {vedlegg === 'feilet' ? tekst.saksnummerUtenVedlegg(saksnummer) : tekst.saksnummer(saksnummer)}\n </Text>\n ) : null}\n </View>\n\n <View style={{ gap: tema.space.xs }}>\n <Text\n style={{\n color: ko ? tema.color.textMuted : tema.color.onBrandFill,\n fontSize: tema.font.small,\n lineHeight: tema.lineHeight.small,\n }}\n >\n {etikett}\n </Text>\n {/* HELTEN: løftets setning, ikke et tall (P1 (a)). Live-region (DD-47). */}\n <Helt testID=\"kvittering-tekst\" live farge={ko ? tema.color.textPrimary : tema.color.onBrandFill}>\n {vedlegg === 'feilet' ? `${tekst.tekstenErLagret} ${helt}` : helt}\n </Helt>\n </View>\n\n {under ? (\n <>\n <View\n style={{\n borderTopWidth: tema.hairline,\n borderTopColor: ko ? tema.color.borderStrong : tema.color.onBrandFill,\n borderStyle: 'dashed',\n }}\n />\n <Text\n testID=\"kvittering-under\"\n style={{\n color: ko ? tema.color.textPrimary : tema.color.onBrandFill,\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n }}\n >\n {under}\n </Text>\n </>\n ) : null}\n </View>\n\n {ledd.length > 0 ? <Sporingslinje ledd={ledd} testID=\"kvittering-spor\" /> : null}\n\n {/* Foten ligger utenfor det som ruller — primærhandlingen i tommelsonen (DD-47).\n Egen padding over: sporingslinjens siste linje har lang underkant, og uten den\n klistret knappen seg til teksten på telefonen. */}\n <View style={{ flex: 1, justifyContent: 'flex-end', paddingTop: tema.space.sm }}>\n <Btn testID=\"tilbake-til-appen\" label={tekst.tilbakeTilAppen} onPress={onLukk} />\n </View>\n </View>\n );\n}\n","import type { MySubmission, SubmissionStatus, SubmissionType } from '@innspel/core';\nimport React from 'react';\nimport { Text, View } from 'react-native';\nimport { Ikon } from '../Ikon.js';\nimport { useTema } from '../tema.js';\nimport { Helt } from './primitiver.js';\nimport { formaterFrist, formaterKortFrist, statusVisning } from './status.js';\nimport { tekst } from './tekster.js';\n\n/**\n * Sakens gang, for innsenderen (R8.3, widget-konsept v0.1 · DD-08 og DD-28 presisert\n * 2026-09-20). Samme komponent og samme regler som portalens\n * `portal/src/lib/widget/Sporingslinje.tsx` — én innsender, to flater, samme form.\n *\n * Reglene, som wireframen spesifiserer dem:\n *\n * - Bare ÅPNE saker (`statusType` `reviewing`/`active`) har linje. En avsluttet sak får\n * pillen og én linje — det er ikke noe igjen å spore, og aldri begge former (DD-08).\n * {@link sporingsledd} gir tom liste for dem, og den som kaller viser pillen i stedet.\n * - Leddene utledes av `status`, og INGEN ny kontrakt: datoene som finnes er `createdAt`\n * (Mottatt), `statusChangedAt` (nå-leddet) og `deadlineAt` (Vurderes).\n * - **Et passert mellomledd har ingen dato.** Kontrakten bærer bare den SISTE\n * statusendringen, så «Vurderes 6. sep» på en Planlagt-sak finnes ikke som felt, og en\n * gjettet dato er verre enn ingen (DD-28, presisert etter R7.3).\n * - SISTE ledd har et TALL bare når kontrakten har datoen — `deadlineAt`, som finnes kun i\n * Vurderes. Da er tallet skjermens helt (DD-67). Ellers står leddet uten tall.\n * - Nå-leddet bærer statusens ikon OG etikett fra temaet (DD-08): linjen erstatter pillen,\n * den skjuler ikke statusen.\n * - **Fristen er gått** (P3 (a), produkteier 2026-09-20): er `deadlineAt` passert mens saken\n * står i Vurderes, står siste ledd i `warning` med ⚠ i noden — én gang, som de andre\n * leddenes ikon — «Fristen er gått» som etikett og datoen som tall, fortsatt tallet hun\n * ble lovet. Løftet under er uendret: det er det leietakeren sa. Aldri rødt (DD-53).\n * Regelen er en KLIENTREGEL på `deadlineAt`; det finnes ingen slik status i kontrakten, og\n * ingen ny skal lages.\n */\n\nexport type LeddTilstand = 'gjort' | 'naa' | 'kommer' | 'brutt';\n\nexport interface Ledd {\n nokkel: string;\n etikett: string;\n tilstand: LeddTilstand;\n /** Ionicons-navn fra temaet. Nå-leddet og det brutte har det; passerte har haken. */\n ikon?: string;\n /** Linja under etiketten: datoen som finnes, eller hva som skjer. Aldri en gjettet dato. */\n detalj?: string;\n /** Datoen som tall — skjermens helt. Finnes bare på siste ledd i Vurderes (`deadlineAt`). */\n tall?: string;\n}\n\n/** Hovedlinjen i tilstandsmaskinen, slik innsenderen ser den (domain-model.md). */\nconst HOVEDLINJE: SubmissionStatus[] = ['ny', 'vurderes', 'planlagt', 'bygges', 'levert'];\n\n/** Statusene som fortsatt er i bevegelse. Avsluttede (`complete`/`closed`) har ingen linje. */\nfunction erApen(rad: MySubmission): boolean {\n if (rad.pending === true) return false;\n return rad.statusType === 'reviewing' || rad.statusType === 'active';\n}\n\n/**\n * Leddene for en åpen sak. Tom liste = ingen linje (avsluttet sak, køet rad, eller en status\n * utenfor hovedlinjen som ikke har en gang å spore).\n *\n * @param naa Injiseres av testene; ellers klokka nå. Regelen om passert frist er klientens.\n */\nexport function sporingsledd(rad: MySubmission, tenantName?: string, naa: Date = new Date()): Ledd[] {\n if (rad.pending === true || !erApen(rad)) return [];\n\n const type: SubmissionType = rad.type;\n const navn = (status: SubmissionStatus) => statusVisning(status, type).etikett;\n const ikon = (status: SubmissionStatus) => statusVisning(status, type).ikon;\n const ledd: Ledd[] = [];\n\n // «Kjent feil» står utenfor hovedlinjen: saken er bekreftet mot en kjent feil, og det\n // eneste som gjenstår er at den rettes.\n if (rad.status === 'kjent_feil') {\n ledd.push({ nokkel: 'ny', etikett: navn('ny'), tilstand: 'gjort', detalj: formaterFrist(rad.createdAt) });\n ledd.push({ nokkel: 'kjent_feil', etikett: navn('kjent_feil'), tilstand: 'naa', ikon: ikon('kjent_feil'), detalj: formaterFrist(rad.statusChangedAt) });\n ledd.push({ nokkel: 'slutt', etikett: navn('levert'), tilstand: 'kommer', detalj: tekst.sporIngenDato });\n return ledd;\n }\n\n const naaIndeks = HOVEDLINJE.indexOf(rad.status);\n if (naaIndeks < 0) return [];\n\n for (let i = 0; i <= naaIndeks; i++) {\n const status = HOVEDLINJE[i]!;\n const erNaa = i === naaIndeks;\n ledd.push({\n nokkel: status,\n etikett: navn(status),\n tilstand: erNaa ? 'naa' : 'gjort',\n ...(erNaa ? { ikon: ikon(status) } : {}),\n // Mottatt har `createdAt`, nå-leddet har `statusChangedAt`. Et passert ledd mellom dem\n // har ingen dato i kontrakten, og får derfor ingen.\n ...(i === 0 ? { detalj: formaterFrist(rad.createdAt) } : erNaa ? { detalj: formaterFrist(rad.statusChangedAt) } : {}),\n });\n }\n\n // En sak i Mottatt får vise hva som kommer — det er det eneste stedet linjen peker forbi\n // nå-leddet, fordi «Vurderes» er handlingen innsenderen venter på.\n if (rad.status === 'ny') {\n ledd.push({\n nokkel: 'vurderes',\n etikett: navn('vurderes'),\n tilstand: 'kommer',\n detalj: tenantName ? tekst.sporNaarTenantTarDen(tenantName) : tekst.sporNaarDenTasOpp,\n });\n }\n\n // Siste ledd. `reviewing` venter på et SVAR (fristen er tidsløftet); `active` venter på at\n // det blir levert, og der finnes ingen dato i kontrakten.\n if (rad.statusType === 'reviewing') {\n const frist = rad.deadlineAt;\n const gatt = frist !== undefined && rad.status === 'vurderes' && new Date(frist).getTime() < naa.getTime();\n ledd.push(\n gatt\n ? { nokkel: 'slutt', etikett: tekst.sporFristenErGatt, tilstand: 'brutt', ikon: 'warning-outline', tall: formaterKortFrist(frist) }\n : {\n nokkel: 'slutt',\n etikett: tekst.sporSvarInnen,\n tilstand: 'kommer',\n ...(frist ? { tall: formaterKortFrist(frist) } : { detalj: tekst.sporDatoenSettes }),\n },\n );\n } else {\n ledd.push({ nokkel: 'slutt', etikett: navn('levert'), tilstand: 'kommer', detalj: tekst.sporIngenDato });\n }\n\n return ledd;\n}\n\n/**\n * Linjen. Ett ledd per steg, med noden, navnet og enten tallet (helten) eller detaljen.\n * Ikonet er dekorativt og står i NODEN, én gang — etiketten bærer meningen (DD-08).\n */\nexport function Sporingslinje({\n ledd,\n testID,\n etikett = tekst.sporEtikett,\n}: {\n ledd: Ledd[];\n testID?: string;\n etikett?: string;\n}) {\n const tema = useTema();\n if (ledd.length === 0) return null;\n\n const farge = (l: Ledd): string =>\n l.tilstand === 'brutt' ? tema.color.warning\n : l.tilstand === 'gjort' ? tema.color.success\n : l.tilstand === 'naa' ? tema.color.brand\n : tema.color.borderStrong;\n\n return (\n <View\n testID={testID}\n accessibilityRole=\"list\"\n accessibilityLabel={etikett}\n style={{ flexDirection: 'row', alignItems: 'flex-start', gap: tema.space.xs }}\n >\n {ledd.map((l, i) => {\n const siste = i === ledd.length - 1;\n const c = farge(l);\n return (\n <View\n key={l.nokkel}\n testID={testID ? `${testID}-ledd-${l.nokkel}` : undefined}\n style={siste ? { flexShrink: 0, gap: tema.space.xs } : { flex: 1, minWidth: 0, gap: tema.space.xs }}\n >\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: tema.space.xs }}>\n {/* Noden er 24; ikonet i den er 16 — `icon.minste` er gulvet. */}\n <View\n style={{\n width: tema.space.lg,\n height: tema.space.lg,\n borderRadius: tema.radius.pill,\n borderWidth: tema.hairline * 2,\n borderColor: c,\n borderStyle: l.tilstand === 'kommer' ? 'dashed' : 'solid',\n backgroundColor: l.tilstand === 'gjort' ? tema.color.success : 'transparent',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n {l.tilstand === 'gjort' ? (\n <Ikon navn=\"checkmark-outline\" storrelse=\"minste\" farge={tema.color.bg} />\n ) : l.ikon ? (\n <Ikon navn={l.ikon} storrelse=\"minste\" farge={c} />\n ) : null}\n </View>\n {!siste ? (\n <View\n style={{\n flex: 1,\n height: tema.hairline * 2,\n borderRadius: tema.radius.pill,\n backgroundColor: l.tilstand === 'gjort' ? tema.color.success : tema.color.borderStrong,\n }}\n />\n ) : null}\n </View>\n {/* Leddenes etiketter er `small` — det er nettopp det `small` er til (DD-67). */}\n <Text\n style={{\n color: l.tilstand === 'brutt' ? tema.color.warning : l.tilstand === 'kommer' ? tema.color.textMuted : tema.color.textPrimary,\n fontSize: tema.font.small,\n lineHeight: tema.lineHeight.small,\n fontWeight: l.tilstand === 'naa' || l.tilstand === 'brutt' ? tema.weight.semibold : tema.weight.regular,\n }}\n >\n {l.etikett}\n </Text>\n {l.tall !== undefined ? (\n <Helt testID={testID ? `${testID}-tall` : undefined} farge={l.tilstand === 'brutt' ? tema.color.warning : tema.color.textPrimary}>\n {l.tall}\n </Helt>\n ) : l.detalj !== undefined ? (\n <Text style={{ color: tema.color.textMuted, fontSize: tema.font.small, lineHeight: tema.lineHeight.small }}>\n {l.detalj}\n </Text>\n ) : null}\n </View>\n );\n })}\n </View>\n );\n}\n","import type { SubmissionStatus, SubmissionStatusView, SubmissionType } from '@innspel/core';\nimport { lofteUtenFrist, submissionStatus } from '../generated/tokens.js';\nimport { lofte, tekst } from './tekster.js';\n\n/**\n * Statusen slik innsenderen ser den. ALT kommer fra `submissionStatus` i\n * `theme/theme.ts`, gjennom den genererte mappa: navnet per spor (DD-22),\n * setningen innsenderen får (DD-08), IKONNAVNET og tokennavnene for farge.\n *\n * Navn, farge og løfte sto hardkodet her OG i `@innspel/web` OG i panelet før\n * 2026-09-14 og spriket (UX-gjennomgangen C5). Ikonet sto igjen som emoji til\n * 2026-09-15, fordi Ionicons i React Native krever en peer-avhengighet — se\n * «`react-native-svg` som peer i @innspel/react-native» i `tech-decisions.md`.\n *\n * DD-08 / «Styling» i CLAUDE.md: **farge bærer aldri mening alene.** `brand` og\n * `info`, og `brand` og `danger`, er målt til under 1,5 i innbyrdes kontrast av\n * tema-generatoren, så etiketten er det som faktisk bærer meningen.\n */\nexport interface StatusVisning {\n /** Ionicons-navn fra temaet — aldri en emoji (brand-ui-guidelines). */\n ikon: string;\n etikett: string;\n /** Tokennavn i den aktive paletten, ikke en farge. */\n fg: string;\n bg: string;\n lofte: string;\n}\n\n/** Norsk dato uten klokkeslett — fristen er en dato, ikke et tidspunkt (DD-28). */\nexport function formaterFrist(iso: string): string {\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return iso;\n return new Intl.DateTimeFormat('nb-NO', { day: 'numeric', month: 'long' }).format(d);\n}\n\nconst KORT_MANED = ['jan', 'feb', 'mar', 'apr', 'mai', 'jun', 'jul', 'aug', 'sep', 'okt', 'nov', 'des'] as const;\n\n/**\n * Datoen som TALL i sporingslinjen — «28. sep», ikke «28. september» (R8.3).\n *\n * Tallet er skjermens helt og står i `h1` i en av tre kolonner på en telefon. «28.\n * september» i 24 px er bredere enn en tredjedel av arket, og skjøv linjen ut av\n * spalten; konseptsiden og wireframene tegner den korte formen av nettopp den grunn.\n * Ingenting går tapt: løftet under linjen skriver datoen ut i sin helhet («Svar innen 3.\n * desember — også hvis det er nei.»), og det er løftet som er tidsløftet (DD-28).\n * Forkortelsene står her, ikke i `Intl`: `month: 'short'` gir «28. sep.» med punktum i\n * nb-NO, og punktumet leses som en forkortet setning.\n */\nexport function formaterKortFrist(iso: string): string {\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return iso;\n return `${d.getDate()}. ${KORT_MANED[d.getMonth()]}`;\n}\n\n/**\n * Oversetter en innsending til det innsenderen skal se.\n *\n * @param status Maskinens status fra kontrakten.\n * @param type Sporet — avgjør «Rettet» mot «Levert» (DD-22).\n * @param deadlineAt Svarfristen, satt kun i `vurderes`.\n */\nexport function statusVisning(status: SubmissionStatus, type: SubmissionType, deadlineAt?: string): StatusVisning {\n const o = submissionStatus[status];\n const spor: 'feil' | 'onske' = type === 'onske' ? 'onske' : 'feil';\n return {\n ikon: o.ikon,\n etikett: o.etikett[spor],\n fg: o.fg,\n bg: o.bg,\n lofte: settInnFrist(o.lofte[spor], deadlineAt),\n };\n}\n\n/**\n * `{frist}` byttes med datoen (DD-28). Uten frist finnes ikke tidsløftet, og da\n * står den fristløse setningen i stedet — aldri en tom plassholder på skjermen.\n */\nfunction settInnFrist(mal: string, deadlineAt: string | undefined): string {\n if (!mal.includes('{frist}')) return mal;\n return deadlineAt ? mal.replace('{frist}', formaterFrist(deadlineAt)) : lofteUtenFrist;\n}\n\n/** Raden som venter på nett (DD-41). Den har ingen saksnummer og intet løfte om svar. */\nexport const venterVisning: StatusVisning = {\n ikon: 'cloud-offline-outline',\n etikett: 'Venter på nett',\n fg: 'textSecondary',\n bg: 'neutralBg',\n lofte: lofte.venterNett,\n};\n\n/**\n * Etikett for en hel rad, brukt som skjermleserens sammendrag. Ikonet er\n * `aria-hidden` i UI-et, så etiketten må bære alt.\n */\nexport function radEtikett(rad: SubmissionStatusView): string {\n const v = statusVisning(rad.status, rad.type, rad.deadlineAt);\n const spor = rad.type === 'onske' ? tekst.onske : tekst.feil;\n return `${tekst.sakHode(spor, rad.id)}: ${rad.text}. Status ${v.etikett.toLowerCase()}. ${v.lofte}`;\n}\n","import { InnspelApiError, NettverksFeil, type InnspelStorage, type MySubmission, type SubmissionStatusView } from '@innspel/core';\nimport React, { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';\nimport { ActivityIndicator, Keyboard, ScrollView, Text, TextInput, View, type ScrollViewInstance } from 'react-native';\nimport { Ikon } from '../Ikon.js';\nimport { useTema } from '../tema.js';\nimport { Brodtekst, Btn, Card, H, Hint, Meta, Pille, Sek, StatusPill, Tekstknapp } from './primitiver.js';\nimport { markerSvarSett, merkNyeSvar } from './nyttSvar.js';\nimport { Sporingslinje, sporingsledd } from './Sporingslinje.js';\nimport { formaterFrist, statusVisning, venterVisning } from './status.js';\nimport { tekst } from './tekster.js';\n\n/**\n * 2j — «Mine innspill» (DD-27).\n *\n * Tre ting skjer her som ikke skjer noe annet sted:\n *\n * - **Offline-køen er synlig** (DD-41). Raden som venter på nett står der den hører hjemme,\n * uten saksnummer og uten sporingslinje — serveren har ingen sak å spore. Shake er den\n * eneste leverandøren som viser dette til brukeren; en usynlig kø er ikke til å skille fra\n * tapt tekst.\n * - **Svaret står OVER sporingslinjen**, ordrett som i panelet (F14, DD-27): det er det\n * ferskeste som har skjedd. Innsenderen skal ikke måtte lete etter svaret i en e-post som\n * aldri kom — plattformen sender ingen e-post (K14).\n * - **«Legg til mer»** (DD-69): en åpen sak får en tekstknapp, bare når serveren sier\n * `canAddAddendum`. Trykk åpner ett felt INNE i kortet. Tilleggene står under innsenderens\n * egen tekst, FØR svaret, med nøytral kant: det er innsenderens ord, ikke en tråd.\n *\n * **R8.3 (widget-konsept v0.1, DD-08 presisert 2026-09-20):** statusen har to former, aldri\n * begge. En ÅPEN sak (`statusType` `reviewing`/`active`) viser {@link Sporingslinje} med\n * løftet i `body` under; en AVSLUTTET (`complete`/`closed`) viser pillen med løftet ved\n * siden av. Avvist har samme vekt som Rettet. Rekkefølgen i kortet er sakshodet →\n * innsenderens tekst → tilleggene → svaret → linjen/pillen → løftet.\n *\n * **F32/F33 (Følget, bygg 30):** mens et tillegg skrives, tar «Send» og «Avbryt» fotens\n * plass, og «Send nytt innspill» er borte: én primærhandling om gangen (DD-69).\n * Android-tilbake lukker BARE feltet ({@link MineInnspillHandtak.lukkFelt}) og beholder\n * teksten per sak, som skjemaet gjør (F1).\n */\n\n/** Det verten (Widget) trenger for Android-tilbake: lukk feltet før arket (F33). */\nexport interface MineInnspillHandtak {\n /** Lukker et åpent tillegg-felt og beholder teksten. `true` når det var ett å lukke. */\n lukkFelt(): boolean;\n}\n\nexport const MineInnspill = forwardRef<MineInnspillHandtak, {\n rader: MySubmission[];\n laster?: boolean;\n tenantName?: string;\n onNytt: () => void;\n /** Vertens lagring — «nytt svar» er per enhet, aldri noe plattformen vet (F14). */\n storage: InnspelStorage;\n /** DD-69: kjernens `subjects.addAddendum`. Utelatt = knappen finnes ikke (DD-26). */\n leggTil?: (submissionId: string, text: string) => Promise<SubmissionStatusView>;\n /** Den oppdaterte saken fra serveren etter et tillegg — byttes inn i `rader` av verten. */\n onOppdatert?: (sak: SubmissionStatusView) => void;\n /** Leietakerens grenser, som ved innsending (DD-44). */\n minTextLength?: number;\n textMaxLength?: number;\n /** F33: utkast per sak som overlever at lista lukkes og åpnes igjen. Verten eier det. */\n utkastLager?: Map<string, string>;\n}>(function MineInnspill({\n rader,\n laster,\n tenantName,\n onNytt,\n storage,\n leggTil,\n onOppdatert,\n minTextLength,\n textMaxLength,\n utkastLager,\n}, ref) {\n const tema = useTema();\n const min = minTextLength ?? 10;\n const maks = textMaxLength ?? 280;\n\n // DD-69: ett felt om gangen, i kortet det gjelder. Teksten beholdes til den er sendt\n // eller innsenderen avbryter — aldri mistet av en feil.\n const [apen, setApen] = useState<string | null>(null);\n const [utkast, setUtkast] = useState('');\n const [sender, setSender] = useState(false);\n const [feil, setFeil] = useState<{ id: string; tekst: string } | undefined>();\n const [lagtTil, setLagtTil] = useState<string | undefined>();\n\n // F33: teksten per sak overlever at feltet lukkes med tilbake. «Avbryt» tømmer med vilje.\n const egetLager = useRef(new Map<string, string>());\n const lager = utkastLager ?? egetLager.current;\n\n // F32: feltet rulles fram når det åpnes, så det ikke ligger under tastaturet.\n const rulleRef = useRef<ScrollViewInstance>(null);\n const kortY = useRef(new Map<string, number>());\n\n const apneFelt = (id: string) => {\n setApen(id);\n setUtkast(lager.get(id) ?? '');\n setFeil(undefined);\n setLagtTil(undefined);\n const y = kortY.current.get(id);\n if (y !== undefined) rulleRef.current?.scrollTo({ y, animated: true });\n };\n\n const lukkFelt = (): boolean => {\n if (apen === null) return false;\n Keyboard.dismiss();\n if (utkast.trim()) lager.set(apen, utkast);\n else lager.delete(apen);\n setApen(null);\n setUtkast('');\n setFeil(undefined);\n return true;\n };\n\n const avbryt = () => {\n if (apen !== null) lager.delete(apen);\n setApen(null);\n setUtkast('');\n setFeil(undefined);\n };\n\n useImperativeHandle(ref, () => ({ lukkFelt }));\n\n const send = async (id: string) => {\n if (!leggTil) return;\n setSender(true);\n setFeil(undefined);\n try {\n const sak = await leggTil(id, utkast.trim());\n onOppdatert?.(sak);\n lager.delete(id);\n setApen(null);\n setUtkast('');\n setLagtTil(id);\n } catch (e) {\n // 409 er ikke en feil i innsenderens tekst, men regelen sagt av serveren (race):\n // samme setning som når knappen er borte. Serverens egen setning ellers. Nettet borte\n // er kjernens `NettverksFeil` (F34) — aldri rå i UI-et: «Ingen nett …», og teksten står.\n const kode = e instanceof InnspelApiError ? e.code : undefined;\n const tekstFeil =\n kode === 'addendum_limit_reached' ? tekst.tilleggTak\n : kode === 'submission_closed' ? tekst.tilleggLukket\n : e instanceof InnspelApiError && e.message ? tekst.tilleggFeil(e.message)\n : e instanceof NettverksFeil ? tekst.tilleggIngenNett\n : tekst.tilleggFeilGenerisk;\n setFeil({ id, tekst: tekstFeil });\n } finally {\n setSender(false);\n }\n };\n\n // F14: nye svar først, og merket. «Nytt» er «kommet siden forrige gang denne enheten\n // viste lista» — kjernen eier både definisjonen og lagringen, så widget og portal kan\n // ikke drive fra hverandre. Feiler lagringen, vises lista umerket i serverens rekkefølge.\n const [visning, setVisning] = useState<{ rad: MySubmission; nytt: boolean }[]>(() => rader.map((rad) => ({ rad, nytt: false })));\n useEffect(() => {\n let gjelder = true;\n void merkNyeSvar(rader, storage)\n .then((m) => {\n if (gjelder) setVisning(m);\n })\n .catch(() => {\n if (gjelder) setVisning(rader.map((rad) => ({ rad, nytt: false })));\n });\n return () => {\n gjelder = false;\n };\n }, [storage, rader]);\n\n // Lista er vist. Ved neste åpning er disse svarene ikke nye lenger.\n useEffect(() => {\n if (!laster && rader.length) void markerSvarSett(storage).catch(() => undefined);\n }, [storage, laster, rader]);\n\n const tom = !laster && rader.length === 0;\n\n return (\n <View style={{ flex: 1, gap: tema.space.md }}>\n {/* DD-19: tomheten er OVERSKRIFTEN, ikke en grå linje under «Mine innspill». */}\n {tom ? (\n <H sub={tenantName ? tekst.mineTomHint(tenantName) : tekst.mineTomHintGenerisk}>{tekst.mineTomTittel}</H>\n ) : (\n <H>{tekst.mineTittel}</H>\n )}\n\n {laster ? (\n <ActivityIndicator accessibilityLabel={tekst.mineLaster} color={tema.color.textSecondary} />\n ) : tom ? null : (\n <ScrollView ref={rulleRef} style={{ flex: 1 }} contentContainerStyle={{ gap: tema.space.md }} keyboardShouldPersistTaps=\"handled\">\n {visning.map(({ rad, nytt }) => {\n const venter = rad.pending === true;\n const v = venter ? venterVisning : statusVisning(rad.status, rad.type, rad.deadlineAt);\n const nokkel = venter ? rad.clientRef : rad.id;\n const sakId = venter ? undefined : rad.id;\n const svar = venter ? undefined : rad.reply;\n const tillegg = venter ? [] : (rad.addenda ?? []);\n const kanLeggeTil = !venter && !!leggTil && rad.canAddAddendum === true;\n const taketNådd = !venter && rad.canAddAddendum === false && tillegg.length >= 3;\n const feltApent = sakId !== undefined && apen === sakId;\n const brukt = utkast.length;\n const full = brukt >= maks;\n const visTeller = brukt >= maks * 0.8;\n // DD-08: én status, én form. Åpen sak har linjen, avsluttet har pillen.\n const ledd = venter ? [] : sporingsledd(rad, tenantName);\n\n return (\n <View\n key={nokkel}\n onLayout={(e) => {\n if (sakId !== undefined) kortY.current.set(sakId, e.nativeEvent.layout.y);\n }}\n >\n <Card dashed={venter} testID={`sakskort-${nokkel}`}>\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: tema.space.sm, flexWrap: 'wrap' }}>\n <Ikon\n navn={rad.type === 'onske' ? 'bulb' : 'bug'}\n storrelse=\"minste\"\n farge={tema.color.brand}\n />\n <Meta>\n {venter\n ? tekst.mineIkkeSendtHode(rad.type === 'onske' ? tekst.onske : tekst.feil)\n : tekst.sakHode(rad.type === 'onske' ? tekst.onske : tekst.feil, rad.id)}\n </Meta>\n {nytt ? <Pille testID=\"nytt-svar\">{tekst.nyttSvar}</Pille> : null}\n </View>\n\n {/* Innsenderens egne ord — `body`, alltid (DD-67). */}\n <Brodtekst testID={`sakstekst-${nokkel}`}>{rad.text}</Brodtekst>\n\n {tillegg.length > 0 ? (\n <View testID={`tillegg-${sakId}`} style={{ gap: tema.space.sm }}>\n {tillegg.map((a) => (\n <View\n key={a.id}\n style={{\n borderLeftWidth: tema.hairline * 2,\n borderLeftColor: tema.color.border,\n paddingLeft: tema.space.md,\n gap: tema.space.xs,\n }}\n >\n <Meta>{tekst.duLaTil(formaterFrist(a.createdAt))}</Meta>\n <Brodtekst testID={`tillegg-tekst-${a.id}`}>{a.text}</Brodtekst>\n </View>\n ))}\n </View>\n ) : null}\n\n {/* Svaret OVER linjen (F14) — og i `body`, det er beslutningsgrunnlaget. */}\n {svar ? (\n <View\n testID={`svar-${sakId}`}\n style={{\n borderLeftWidth: tema.hairline * 2,\n borderLeftColor: tema.color.brand,\n paddingLeft: tema.space.md,\n gap: tema.space.xs,\n }}\n >\n <Meta>\n {tenantName ? tekst.svarFra(tenantName, formaterFrist(svar.at)) : tekst.svarFraGenerisk(formaterFrist(svar.at))}\n </Meta>\n <Brodtekst testID={`svar-tekst-${sakId}`}>{svar.text}</Brodtekst>\n </View>\n ) : null}\n\n {ledd.length > 0 ? (\n <Sporingslinje ledd={ledd} testID={`spor-${sakId}`} />\n ) : (\n <StatusPill testID={`status-pille-${nokkel}`} ikon={v.ikon} etikett={v.etikett} fg={v.fg} bg={v.bg} />\n )}\n <Sek testID={`lofte-${nokkel}`}>{v.lofte}</Sek>\n\n {!venter && rad.attachmentRemoved ? (\n <View testID={`bilde-fjernet-${rad.id}`} style={{ flexDirection: 'row', gap: tema.space.xs, alignItems: 'center' }}>\n <Ikon navn=\"trash-outline\" storrelse=\"minste\" farge={tema.color.textMuted} />\n <Hint>{tekst.bildeFjernet}</Hint>\n </View>\n ) : null}\n\n {sakId !== undefined && lagtTil === sakId ? (\n <Text accessibilityLiveRegion=\"polite\" testID={`lagt-til-${sakId}`} style={{ color: tema.color.success, fontSize: tema.font.small }}>\n {tekst.lagtTil}\n </Text>\n ) : null}\n\n {feltApent ? (\n <View testID={`tillegg-felt-${sakId}`} style={{ gap: tema.space.sm }}>\n <Meta>{tekst.leggTilMerLabel}</Meta>\n <TextInput\n testID=\"tillegg-tekst\"\n accessibilityLabel={tekst.leggTilMerLabel}\n value={utkast}\n onChangeText={setUtkast}\n maxLength={maks}\n multiline\n numberOfLines={3}\n autoFocus\n placeholder={tekst.leggTilMerPlaceholder}\n placeholderTextColor={tema.color.textMuted}\n style={{\n backgroundColor: tema.color.surfaceRaised,\n borderWidth: tema.hairline,\n borderColor: full ? tema.color.warning : tema.color.borderStrong,\n borderRadius: tema.radius.md,\n padding: tema.space.md,\n color: tema.color.textPrimary,\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n minHeight: tema.touch * 2,\n textAlignVertical: 'top',\n }}\n />\n {visTeller ? (\n <Text\n testID=\"tillegg-teller\"\n accessibilityLiveRegion={full ? 'assertive' : 'polite'}\n style={{ alignSelf: 'flex-end', color: full ? tema.color.warning : tema.color.textMuted, fontSize: tema.font.small }}\n >\n {brukt} / {maks}\n {full ? tekst.tellerFull : ''}\n </Text>\n ) : null}\n {feil?.id === sakId ? (\n <Text accessibilityLiveRegion=\"assertive\" testID={`tillegg-feil-${sakId}`} style={{ color: tema.color.danger, fontSize: tema.font.small, lineHeight: tema.lineHeight.small }}>\n {feil.tekst}\n </Text>\n ) : null}\n {/* F32: «Send» og «Avbryt» står i foten, utenfor det som ruller — ikke her. */}\n </View>\n ) : kanLeggeTil ? (\n <Tekstknapp\n testID={`legg-til-mer-${sakId}`}\n ikon=\"add-outline\"\n label={tekst.leggTilMer}\n accessibilityLabel={tekst.leggTilMerLabel}\n onPress={() => sakId !== undefined && apneFelt(sakId)}\n />\n ) : taketNådd ? (\n <Hint>{tekst.tilleggTak}</Hint>\n ) : null}\n </Card>\n </View>\n );\n })}\n </ScrollView>\n )}\n\n {apen !== null ? (\n // F32: fotens plass — én primærhandling om gangen. «Send nytt innspill» er borte til\n // tillegget er sendt eller avbrutt, så første trykk aldri treffer feil knapp.\n <View testID=\"tillegg-fot\" style={{ gap: tema.space.sm }}>\n <View style={{ flexDirection: 'row', gap: tema.space.sm }}>\n <Btn\n testID=\"tillegg-send\"\n label={sender ? tekst.sender : tekst.send}\n disabled={utkast.length < min || sender}\n busy={sender}\n {...(utkast.length < min ? { hint: tekst.forKort(min) } : {})}\n onPress={() => void send(apen)}\n grow\n />\n <Btn testID=\"tillegg-avbryt\" label={tekst.avbryt} variant=\"secondary\" onPress={avbryt} grow />\n </View>\n <Hint>{tekst.leggTilMerHint}</Hint>\n </View>\n ) : (\n <Btn testID=\"send-nytt\" ikon=\"chatbox-outline\" label={tom ? tekst.sendForste : tekst.sendNytt} onPress={onNytt} />\n )}\n </View>\n );\n});\n","import type { InnspelStorage, MySubmission } from '@innspel/core';\n\n/**\n * F14 (brukerreisene 2026-09-15) — «Saken med nytt svar ligger ikke øverst og er ikke\n * merket.» Produkteier svarte i panelet; i appen sto feilen nummer to, under et ønske uten\n * nytt svar, og ingenting sa at det var kommet noe.\n *\n * Løftet er at alle får svar. Et svar innsenderen ikke oppdager, er et brutt løfte — og\n * lista er sortert på når saken ble SENDT (serveren: `OrderByDescending(CreatedAt)`), som\n * ikke sier noe om når det skjedde noe med den.\n *\n * **Hva «nytt» betyr her.** Plattformen eier aldri sluttbrukere, og skal ikke vite hva hun\n * har lest. «Nytt» er derfor «kommet siden forrige gang DENNE enheten viste lista»: ett\n * tidspunkt i lagringen verten allerede injiserer, ingen serverstate, ingen pseudonym, og\n * ingenting som forlater enheten. Bytter hun telefon, ser hun svarene som nye én gang til\n * — en ærlig pris for ikke å spore mennesker.\n *\n * **Hvorfor her og ikke i `@innspel/core`.** Kjernen har et hardt tak på 10 kB gzip\n * (CLAUDE.md), og modulen dyttet den til 10273 B. En visningsregel er ikke verdt kjernens\n * budsjett. Skal `@innspel/web` ha det samme, kopieres de femten linjene dit — billigere\n * enn å bryte taket eller å presse koden til den blir uleselig.\n *\n * Forkastet: sortering på svartidspunkt alene, uten merke — da ville et svar fra i fjor\n * ligget øverst for alltid. Forkastet: å la serveren avgjøre — den måtte lagret «sett» per\n * pseudonym, altså nettopp det plattformen ikke skal vite.\n */\n\nconst NØKKEL = 'innspel:svar-sett';\n\n/** En rad med om svaret på den er kommet siden sist enheten viste lista. */\nexport interface MedNyhet {\n rad: MySubmission;\n nytt: boolean;\n}\n\n/**\n * Radene med nye svar først, hver merket. Rekkefølgen ellers er serverens — nyest sendt\n * først, som fortsatt er riktig for alt uten nytt svar. Køede rader har intet svar og er\n * aldri nye. En ødelagt eller uleselig lagring gir «alt er nytt»: heller vise at det finnes\n * svar enn å gjemme dem.\n */\nexport async function merkNyeSvar(rader: readonly MySubmission[], storage: InnspelStorage): Promise<MedNyhet[]> {\n let grense = 0;\n try {\n grense = Number.parseInt((await storage.get(NØKKEL)) ?? '', 10) || 0;\n } catch {\n grense = 0;\n }\n const tid = (r: MySubmission) => (r.pending === true ? NaN : Date.parse(r.reply?.at ?? ''));\n const merket = rader.map((rad) => ({ rad, nytt: tid(rad) > grense }));\n return [...merket.filter((m) => m.nytt), ...merket.filter((m) => !m.nytt)];\n}\n\n/**\n * Setter «sist sett» til nå. Kalles når innsenderen HAR sett lista — ikke når den hentes i\n * bakgrunnen for tellingen på knappen (DD-62), for da har hun ikke sett noe. Feiler\n * lagringen, vises merket én gang for mye; det er ikke verdt å avbryte visningen for.\n */\nexport async function markerSvarSett(storage: InnspelStorage, nå: number = Date.now()): Promise<void> {\n try {\n await storage.set(NØKKEL, String(nå));\n } catch {\n /* vertens lagring — ikke vår å redde */\n }\n}\n","import { skaler, strokTilRekter, treffer, trykkTilRekt, type MaskPoint, type MaskRect } from '@innspel/core';\nimport React, { useCallback, useMemo, useRef, useState, type RefObject } from 'react';\nimport { Image, Pressable, StyleSheet, Text, View, type GestureResponderEvent, type LayoutChangeEvent } from 'react-native';\nimport { screenRules } from '../generated/tokens.js';\nimport { Ikon } from '../Ikon.js';\nimport type { ScreenshotCapture, ViewRef } from '../skjermbilde.js';\nimport { useTema } from '../tema.js';\nimport { Btn, H, Hint } from './primitiver.js';\nimport { tekst } from './tekster.js';\n\nexport type MaskVerktoy = 'felt' | 'pensel';\n\n/**\n * 2f — skjermbildet, tatt ved trykk og forhåndsvist (K4). Tre likestilte\n * maskeringsveier (DD-40): «Masker felt» (ett trykk legger en boks), «Tegn over»\n * (fingerstrøk) og «Masker all tekst» (heldekkende uskarphet — se DD-40,\n * presisert for RN). Private views (DD-39) ligger der FØR innsenderen ser bildet,\n * merket «Maskert av appen», og kan ikke fjernes. Egne masker fjernes med ett\n * trykk på dem.\n *\n * Maskeringen skjer i bitmapen ved komposisjon: bildet vises med maskeringslagene\n * over, og «Legg ved og fortsett» fanger denne viewen på nytt. Det er komposittet\n * som lastes opp — rå-URI-en forlater aldri widgeten.\n *\n * Fargene her er `screenRules`: det ene stedet temaet ikke gjelder, fordi\n * maskene må være synlige uansett hva skjermbildet selv inneholder.\n */\nexport function Skjermbilde({\n bilde,\n automaskerRot,\n rotStorrelse,\n previewRef,\n komponerer,\n kilde = 'skjerm',\n notat,\n onFjern,\n onLeggVed,\n}: {\n bilde: ScreenshotCapture;\n /** Private views i vertsappens punkter (relativt til rot-viewen). */\n automaskerRot: MaskRect[];\n rotStorrelse: { width: number; height: number };\n previewRef: RefObject<ViewRef | null>;\n komponerer: boolean;\n /** Fra galleriet: private views kan ikke gjelde, og forhåndsvisningen sier det. */\n kilde?: 'skjerm' | 'galleri';\n /** Vertens setning ved bildesteget. */\n notat?: string;\n onFjern: () => void;\n onLeggVed: () => void;\n}) {\n const tema = useTema();\n const [verktoy, setVerktoy] = useState<MaskVerktoy>('pensel');\n const [allTekst, setAllTekst] = useState(false);\n const [egne, setEgne] = useState<MaskRect[]>([]);\n const [ramme, setRamme] = useState<{ width: number; height: number } | null>(null);\n const strok = useRef<MaskPoint[]>([]);\n\n // Bildet tilpasses rammen med bevart sideforhold; alt annet regnes i visningens punkter.\n const visning = useMemo(() => {\n if (!ramme) return null;\n const s = Math.min(ramme.width / bilde.width, ramme.height / bilde.height);\n return { width: Math.floor(bilde.width * s), height: Math.floor(bilde.height * s) };\n }, [ramme, bilde.width, bilde.height]);\n\n const automasker = useMemo(\n () => (visning ? automaskerRot.map((r) => skaler(r, rotStorrelse, visning)) : []),\n [automaskerRot, rotStorrelse, visning],\n );\n\n const onLayout = useCallback((e: LayoutChangeEvent) => {\n const { width, height } = e.nativeEvent.layout;\n setRamme({ width, height });\n }, []);\n\n const punkt = (e: GestureResponderEvent): MaskPoint => ({ x: e.nativeEvent.locationX, y: e.nativeEvent.locationY });\n\n const onGrant = (e: GestureResponderEvent) => {\n if (!visning) return;\n const p = punkt(e);\n // Ett trykk på en egen maske angrer den (wireframe 2f). Private views rører den aldri.\n const treff = egne.findIndex((r) => treffer(p, r));\n if (treff >= 0) {\n setEgne((x) => x.filter((_, i) => i !== treff));\n return;\n }\n if (verktoy === 'felt') {\n const r = trykkTilRekt(p, { width: tema.touch * 4, height: tema.touch }, visning);\n if (r) setEgne((x) => [...x, r]);\n return;\n }\n strok.current = [p];\n };\n\n const onMove = (e: GestureResponderEvent) => {\n if (verktoy !== 'pensel' || strok.current.length === 0) return;\n strok.current.push(punkt(e));\n };\n\n const onRelease = () => {\n if (verktoy !== 'pensel' || !visning || strok.current.length === 0) return;\n const rekter = strokTilRekter(strok.current, screenRules.brushWidth, visning);\n strok.current = [];\n if (rekter.length) setEgne((x) => [...x, ...rekter]);\n };\n\n const knapp = (id: MaskVerktoy | 'allTekst', ikon: string, label: string) => {\n const valgt = id === 'allTekst' ? allTekst : verktoy === id && !allTekst;\n return (\n <Pressable\n key={id}\n testID={`verktoy-${id}`}\n accessibilityRole=\"button\"\n accessibilityLabel={label}\n accessibilityState={{ selected: valgt }}\n onPress={() => (id === 'allTekst' ? setAllTekst((a) => !a) : setVerktoy(id))}\n style={{\n flex: 1,\n minHeight: tema.touch,\n alignItems: 'center',\n justifyContent: 'center',\n gap: tema.space.xs,\n padding: tema.space.xs,\n borderRadius: tema.radius.md,\n borderWidth: tema.hairline,\n borderColor: tema.color.actionSecondaryBorder,\n borderBottomWidth: valgt ? tema.hairline * 2 : tema.hairline,\n borderBottomColor: valgt ? tema.color.textPrimary : tema.color.actionSecondaryBorder,\n backgroundColor: valgt ? tema.color.surfaceRaised : 'transparent',\n }}\n >\n <Ikon navn={ikon} farge={tema.color.textPrimary} />\n <Text\n style={{\n color: tema.color.textPrimary,\n fontSize: tema.font.small,\n fontWeight: valgt ? tema.weight.semibold : tema.weight.regular,\n }}\n >\n {label}\n </Text>\n </Pressable>\n );\n };\n\n const a11y = tekst.skjermbildeA11y(automasker.length, egne.length, allTekst);\n\n // Høyden kommer ovenfra: arket har fast høyde i dette steget (Widget.tsx), rammen får det\n // som er igjen etter overskrift, verktøylinje og fot, og forhåndsvisningen ligger OVER rammen\n // i stedet for i flyten. Før vokste rammen med visningen, onLayout ga ny ramme, og et 9:20-\n // bilde endte begrenset av bredden alene — knappene havnet under navigasjonslinja. Ingen\n // scroll: berøring på forhåndsvisningen er maskering.\n return (\n <View testID=\"skjermbilde-steg\" style={{ flexGrow: 1, flexShrink: 1, gap: tema.space.md }}>\n <H sub={kilde === 'galleri' ? tekst.skjermbildeUnderGalleri : tekst.skjermbildeUnder}>{tekst.skjermbildeTittel}</H>\n {notat ? (\n <View testID=\"bilde-notat\">\n <Hint>{notat}</Hint>\n </View>\n ) : null}\n\n <View accessibilityRole=\"toolbar\" accessibilityLabel={tekst.maskering} style={{ flexDirection: 'row', gap: tema.space.sm }}>\n {knapp('felt', 'scan-outline', tekst.maskerFelt)}\n {knapp('pensel', 'brush-outline', tekst.tegnOver)}\n {knapp('allTekst', 'grid-outline', tekst.maskerAllTekst)}\n </View>\n\n <View\n testID=\"skjermbilde-ramme\"\n onLayout={onLayout}\n style={{\n flexGrow: 1,\n flexShrink: 1,\n flexBasis: 0,\n minHeight: tema.touch * 5,\n backgroundColor: screenRules.previewBackdrop,\n borderRadius: tema.radius.md,\n overflow: 'hidden',\n }}\n >\n <View testID=\"skjermbilde-flate\" pointerEvents=\"box-none\" style={[StyleSheet.absoluteFill, { alignItems: 'center', justifyContent: 'center' }]}>\n {visning ? (\n <View\n ref={previewRef}\n collapsable={false}\n testID=\"forhandsvisning\"\n accessibilityRole=\"image\"\n accessibilityLabel={a11y}\n onStartShouldSetResponder={() => !komponerer}\n onMoveShouldSetResponder={() => !komponerer}\n onResponderGrant={onGrant}\n onResponderMove={onMove}\n onResponderRelease={onRelease}\n onResponderTerminate={onRelease}\n style={{ width: visning.width, height: visning.height, backgroundColor: screenRules.previewBackdrop }}\n >\n <Image\n testID=\"skjermbilde-bilde\"\n source={{ uri: bilde.uri }}\n blurRadius={allTekst ? screenRules.textBlurRadius : 0}\n style={{ width: visning.width, height: visning.height }}\n accessibilityIgnoresInvertColors\n />\n\n {automasker.map((r, i) => (\n <View\n key={`auto-${i}`}\n testID={`automask-${i}`}\n pointerEvents=\"none\"\n style={{\n position: 'absolute',\n left: r.x,\n top: r.y,\n width: r.width,\n height: r.height,\n backgroundColor: screenRules.autoMaskFill,\n borderWidth: tema.hairline * 2,\n borderColor: screenRules.autoMaskStroke,\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n {!komponerer ? (\n // Etiketten står PÅ den maskerte flaten og måles mot NETTOPP den\n // (skjermKontrastpar i theme.ts). textSecondary var 2,2:1 (C11a).\n // Ikonet arver samme farge: det er unntaket i «Styling» — maskeringen\n // tegnes i faste signalfarger, ikke i palettens.\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: tema.space.xs }}>\n <Ikon navn=\"lock-closed-outline\" storrelse=\"minste\" farge={screenRules.autoMaskText} />\n <Text style={{ color: screenRules.autoMaskText, fontSize: tema.font.small }} numberOfLines={1}>\n {tekst.maskertAvAppen}\n </Text>\n </View>\n ) : null}\n </View>\n ))}\n\n {egne.map((r, i) => (\n <View\n key={`egen-${i}`}\n testID={`maske-${i}`}\n pointerEvents=\"none\"\n style={{ position: 'absolute', left: r.x, top: r.y, width: r.width, height: r.height, backgroundColor: screenRules.brushFill }}\n />\n ))}\n </View>\n ) : null}\n </View>\n </View>\n\n {automasker.length ? (\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: tema.space.xs }}>\n <Ikon navn=\"lock-closed-outline\" storrelse=\"minste\" farge={tema.color.textMuted} />\n <Hint>{tekst.maskertAvAppenHint}</Hint>\n </View>\n ) : null}\n {egne.length ? <Hint>{tekst.dittStrok}</Hint> : null}\n {allTekst ? <Hint>{tekst.allTekstHint}</Hint> : null}\n\n <View testID=\"skjermbilde-fot\" style={{ flexShrink: 0, gap: tema.space.sm }}>\n {/* «Angre siste» som KNAPP: å treffe en maske med fingeren er en motorisk\n oppgave, og angrefunksjonen kan ikke være den eneste veien tilbake — samme\n grunn som DD-40 gir både pensel og knapp (C11d). */}\n <Btn\n variant=\"secondary\"\n testID=\"angre-siste\"\n label={tekst.angreSiste}\n accessibilityLabel={tekst.angreSisteA11y}\n disabled={komponerer || egne.length === 0}\n onPress={() => setEgne((x) => x.slice(0, -1))}\n />\n <Btn\n variant=\"danger\"\n testID=\"fjern-bildet\"\n ikon=\"trash-outline\"\n label={tekst.fjernBildet}\n onPress={onFjern}\n disabled={komponerer}\n />\n <Btn testID=\"legg-ved\" label={tekst.leggVed} onPress={onLeggVed} disabled={komponerer || !visning} />\n </View>\n </View>\n );\n}\n","import React, { useEffect, useRef } from 'react';\nimport { View, type StyleProp, type ViewStyle } from 'react-native';\nimport { useSkjermbilde, type ViewRef } from './skjermbilde.js';\n\n/**\n * Merk det som aldri skal være med på et skjermbilde (DD-39): navn i en liste,\n * et kontonummer, en samtale. Pakk det inn, og widgeten maskerer det FØR\n * innsenderen ser forhåndsvisningen — som «Maskert av appen», og penselen kan\n * ikke oppheve det. Din kode er sannheten, ikke brukerens presisjon.\n *\n * Uten skjermbilde-adapter gjør komponenten ingenting utover å rendre barna.\n *\n * @example\n * ```tsx\n * <InnspelPrivate><Text>{bruker.navn}</Text></InnspelPrivate>\n * ```\n */\nexport function InnspelPrivate({ children, style }: { children?: React.ReactNode; style?: StyleProp<ViewStyle> }) {\n const ref = useRef<ViewRef | null>(null);\n const kontekst = useSkjermbilde();\n const registrer = kontekst?.privat.register;\n\n useEffect(() => {\n if (!registrer) return;\n return registrer(ref);\n }, [registrer]);\n\n // collapsable={false}: Android slår ellers sammen en View uten stil med\n // forelderen, og da finnes det ingenting å måle.\n return (\n <View ref={ref} collapsable={false} style={style} testID=\"innspel-privat\">\n {children}\n </View>\n );\n}\n","import {\n InnspelApiError,\n type FollowUpView,\n type MyPrograms,\n type ParticipationView,\n type ProgramTask,\n type ProgramView,\n type TaskOutcome,\n} from '@innspel/core';\nimport React, { useCallback, useEffect, useState } from 'react';\nimport { Modal, Pressable, View } from 'react-native';\nimport { Ikon } from '../Ikon.js';\nimport { useInnspel } from '../InnspelProvider.js';\nimport { useTema } from '../tema.js';\nimport { Banner, Brodtekst, Btn, Card, H, Tekstknapp } from '../widget/primitiver.js';\nimport { periode } from './periode.js';\nimport { tekst } from '../widget/tekster.js';\nimport { Aksept } from './Aksept.js';\nimport { HvordanGikkDet } from './HvordanGikkDet.js';\nimport { Oppfolging } from './Oppfolging.js';\nimport { Oppgaver } from './Oppgaver.js';\nimport { ProgramSpor, programErOver } from './ProgramSpor.js';\n\ntype Dialog = { type: 'oppgave'; task: ProgramTask } | { type: 'oppfolging'; oppfolging: FollowUpView };\n\n/**\n * Betaprogrammet i vertsappen: 3a banneret, 3b aksepten og deltakelsen med «Gå ut» (DD-36).\n * Sett den der vertsappen vil ha invitasjonen — typisk øverst på hjemskjermen. Uten\n * invitasjon og uten deltakelse rendrer den INGENTING.\n *\n * **Tokenet kommer fra verten** (DD-12). Plattformen sender aldri invitasjonen: leietakeren\n * får `program.invitation_created` med tokenet, løser pseudonymet til sin egen bruker og\n * sender lenken i sin egen kanal. Verten fanger tokenet fra dyplenken og gir det hit. Uten\n * det viser banneret fortsatt invitasjonen — men «Bli med» er inaktiv, med grunnen på\n * skjermen, i stedet for å feile ved trykk (DD-02).\n *\n * **R8.3 (widget-konsept v0.1, P1 (a)):** deltakelsen er et SAKSKORT med sporingslinje —\n * «Du ble med → N av M gjort → Programmet er over <dato>», der sluttdatoen er helten — og\n * oppgavene er en tett liste med «Gjort» tonet per rad. Merkefargen på en flate er for det\n * som er sendt (DD-41); et program pågår.\n *\n * **Kontakttaket står ingen steder i det testeren leser** (DD-14, presisert 2026-09-20):\n * ikke i banneret, ikke i deltakelsens meta-linje, ikke i oppfølgingskortet. `contactsSent`\n * og `maxContacts` finnes i kontrakten og leses av PANELET.\n *\n * @example\n * ```tsx\n * <InnspelProgram invitationToken={tokenFraDyplenke} />\n * ```\n */\nexport function InnspelProgram({\n invitationToken,\n onEndring,\n onMeldFeil,\n}: {\n /** Engangs-tokenet fra leietakerens egen kanal, typisk fanget fra en dyplenke. */\n invitationToken?: string;\n /** Kalles når testeren blir med eller går ut — for vertens egen navigasjon. */\n onEndring?: (deltakelse: ParticipationView | null) => void;\n /**\n * Kalles når testeren vil melde at en oppgave ikke gikk — verten åpner feilsporet med\n * oppgaven som kontekst. Utelatt = tilbudet vises ikke (DD-26).\n */\n onMeldFeil?: (task: ProgramTask) => void;\n}) {\n const { client } = useInnspel();\n const tema = useTema();\n\n const [mine, setMine] = useState<MyPrograms | undefined>();\n const [deltakelse, setDeltakelse] = useState<ParticipationView | undefined>();\n const [viserAksept, setViserAksept] = useState(false);\n const [viserGaaUt, setViserGaaUt] = useState(false);\n const [avvist, setAvvist] = useState(false);\n const [sender, setSender] = useState(false);\n const [feil, setFeil] = useState<string | undefined>();\n const [dialog, setDialog] = useState<Dialog | undefined>();\n const [svarFeil, setSvarFeil] = useState<string | undefined>();\n const [lagtBort, setLagtBort] = useState<ReadonlySet<string>>(new Set());\n\n const leggBort = useCallback((id: string) => setLagtBort((s) => new Set([...s, id])), []);\n\n /**\n * «Lagre» i «Hvordan gikk det?»: én dialog, to mål. Fullføringen legges på deltakelsen så\n * raden viser svaret straks; et svar på oppfølging tar kortet ut av lista.\n *\n * `meldEtterpaa`: «Meld det som feil» lagrer FØRST og gir så oppgaven til verten — svaret\n * skal ikke gå tapt fordi hun valgte den veien ut (DD-02).\n */\n const lagreSvar = useCallback(\n async (outcome: TaskOutcome, text: string | undefined, meldEtterpaa = false) => {\n if (!dialog || !deltakelse) return;\n setSender(true);\n setSvarFeil(undefined);\n try {\n if (dialog.type === 'oppgave') {\n const ny = await client.programs.completeTask(dialog.task.id, { outcome, ...(text ? { text } : {}) });\n setDeltakelse({ ...deltakelse, completions: [...deltakelse.completions, ny] });\n if (meldEtterpaa && onMeldFeil) onMeldFeil(dialog.task);\n } else {\n await client.programs.respond(dialog.oppfolging.id, { outcome, ...(text ? { text } : {}) });\n setMine((m) => (m ? { ...m, pendingFollowUps: m.pendingFollowUps.filter((f) => f.id !== dialog.oppfolging.id) } : m));\n }\n setDialog(undefined);\n } catch (e) {\n setSvarFeil(e instanceof InnspelApiError ? e.message : 'tjeneren svarte ikke.');\n } finally {\n setSender(false);\n }\n },\n [client, deltakelse, dialog, onMeldFeil],\n );\n\n // Anonym modus har ingen programmer, og skal ikke spørre: kallet ville blitt 401 uansett,\n // og et kall som alltid feiler er ikke en tilstand — det er støy.\n useEffect(() => {\n if (client.isAnonymous) return;\n let levende = true;\n void client.programs\n .list()\n .then((svar) => {\n if (!levende) return;\n setMine(svar);\n // Aktiv deltakelse er det som vises; trukket kommer aldri tilbake fra listen.\n setDeltakelse(svar.participations.find((p) => p.status !== 'trukket'));\n })\n // Programmet er et tilbud, aldri en sperre: svarer ikke kallet, finnes banneret ikke.\n .catch(() => undefined);\n return () => {\n levende = false;\n };\n }, [client]);\n\n const bliMed = useCallback(async () => {\n if (!invitationToken) return;\n setSender(true);\n setFeil(undefined);\n try {\n const ny = await client.programs.accept(invitationToken);\n setDeltakelse(ny);\n setViserAksept(false);\n onEndring?.(ny);\n } catch (e) {\n setFeil(e instanceof InnspelApiError ? e.message : 'tjeneren svarte ikke.');\n } finally {\n setSender(false);\n }\n }, [client, invitationToken, onEndring]);\n\n const gaaUt = useCallback(async () => {\n if (!deltakelse) return;\n setSender(true);\n try {\n await client.programs.withdraw(deltakelse.id);\n setDeltakelse(undefined);\n setViserGaaUt(false);\n onEndring?.(null);\n } catch (e) {\n setFeil(e instanceof InnspelApiError ? e.message : 'tjeneren svarte ikke.');\n } finally {\n setSender(false);\n }\n }, [client, deltakelse, onEndring]);\n\n // Deltakelsen vinner over invitasjonen: har man sagt ja, er banneret ferdig.\n const invitasjon = deltakelse ? undefined : mine?.invitations[0];\n const program: ProgramView | undefined = deltakelse?.program ?? invitasjon?.program;\n\n if (!program) return null;\n\n if (deltakelse) {\n // 3d: kortene for DETTE programmet, i den rekkefølgen kontaktene kom. Et kort testeren\n // har lagt bort i denne økten vises ikke igjen før neste oppstart.\n const kort = (mine?.pendingFollowUps ?? [])\n .filter((f) => f.programId === program.id && !lagtBort.has(f.id))\n .sort((a, b) => a.emittedAt.localeCompare(b.emittedAt));\n const over = programErOver(deltakelse, program);\n\n return (\n <View testID=\"program-deltakelse\" accessibilityLabel={tekst.deltakelseRegion} style={{ gap: tema.space.md }}>\n {/* Oppfølgingskortet ligger OVER deltakelseskortet, ikke i det: det er en annen\n avsender-handling, og deltakelsen står som den står. */}\n {kort.map((f) => (\n <Oppfolging\n key={f.id}\n oppfolging={f}\n onSenere={() => leggBort(f.id)}\n onSvar={() => {\n setSvarFeil(undefined);\n setDialog({ type: 'oppfolging', oppfolging: f });\n }}\n onAapneOppgavene={() => leggBort(f.id)}\n onGaaUt={() => setViserGaaUt(true)}\n />\n ))}\n\n <Card style={{ gap: tema.space.md }}>\n <H>{program.name}</H>\n <ProgramSpor deltakelse={deltakelse} program={program} />\n {feil ? <Banner live ikon=\"warning-outline\" tone=\"warning\" children={feil} /> : null}\n <Oppgaver\n tasks={program.tasks}\n completions={deltakelse.completions}\n over={over}\n onGjort={(task) => {\n setSvarFeil(undefined);\n setDialog({ type: 'oppgave', task });\n }}\n />\n {/* DD-36: «Gå ut» er ALLTID synlig — og i TEKSTFARGEN. Den røde er dialogen (DD-53). */}\n <Tekstknapp noytral testID=\"gaa-ut\" ikon=\"exit-outline\" label={tekst.gaaUt} onPress={() => setViserGaaUt(true)} />\n </Card>\n\n {dialog ? (\n <HvordanGikkDet\n {...(dialog.type === 'oppgave' ? { under: dialog.task.title } : { spoersmaal: dialog.oppfolging.question })}\n sender={sender}\n {...(svarFeil ? { feil: svarFeil } : {})}\n {...(dialog.type === 'oppgave' && onMeldFeil\n ? { onMeldFeil: (outcome: TaskOutcome, text: string | undefined) => void lagreSvar(outcome, text, true) }\n : {})}\n onLagre={(outcome, text) => void lagreSvar(outcome, text)}\n onLukk={() => setDialog(undefined)}\n />\n ) : null}\n\n {viserGaaUt ? (\n <Modal visible transparent animationType=\"fade\" onRequestClose={() => setViserGaaUt(false)} accessibilityViewIsModal>\n <View style={{ flex: 1, backgroundColor: tema.color.scrim, justifyContent: 'flex-end', padding: tema.space.md }}>\n <View\n testID=\"gaa-ut-dialog\"\n accessibilityViewIsModal\n style={{\n backgroundColor: tema.color.surface,\n borderRadius: tema.radius.lg,\n borderWidth: tema.hairline,\n borderColor: tema.color.borderStrong,\n padding: tema.space.md,\n gap: tema.space.md,\n }}\n >\n <H nivaa={3}>{tekst.gaaUtTittel}</H>\n <Brodtekst>{tekst.gaaUtTekst(program.name)}</Brodtekst>\n <View style={{ flexDirection: 'row', gap: tema.space.sm }}>\n {/* «Bli værende» står først: utgangen er et valg, ikke en felle med angreknapp. */}\n <Btn grow variant=\"secondary\" testID=\"bli-vaerende\" label={tekst.bliVaerende} onPress={() => setViserGaaUt(false)} />\n <Btn\n grow\n variant=\"danger\"\n testID=\"bekreft-gaa-ut\"\n ikon=\"exit-outline\"\n label={tekst.gaaUtBekreft}\n disabled={sender}\n onPress={() => void gaaUt()}\n />\n </View>\n </View>\n </View>\n </Modal>\n ) : null}\n </View>\n );\n }\n\n if (!invitasjon || avvist) return null;\n\n return (\n <>\n {/* 3a — invitasjonsbanneret. Flaten er `brandBg` UTEN ramme: flaten er nok. */}\n <View\n testID=\"program-banner\"\n accessibilityLabel={tekst.invitasjonRegion}\n style={{\n backgroundColor: tema.color.brandBg,\n borderRadius: tema.radius.lg,\n padding: tema.space.md,\n gap: tema.space.md,\n }}\n >\n <View style={{ flexDirection: 'row', gap: tema.space.sm, alignItems: 'flex-start' }}>\n <View style={{ paddingTop: tema.space.xs }}>\n <Ikon navn=\"flask-outline\" farge={tema.color.brand} />\n </View>\n <View style={{ flex: 1, minWidth: 0 }}>\n {/* Spørsmålet er kortets HELT, og ÉN meta-linje bærer det kontrakten har:\n antall oppgaver og perioden. Kontakttaket står ikke her (DD-14). */}\n <H nivaa={3} meta={tekst.invitasjonMeta(program.tasks.length, periode(program.opensAt, program.closesAt))}>\n {tekst.invitasjonHva(program.name)}\n </H>\n </View>\n {/* Avvisbart: invitasjonen er et tilbud. Den kommer tilbake ved neste oppstart. */}\n <Pressable\n testID=\"avvis-invitasjon\"\n accessibilityRole=\"button\"\n accessibilityLabel={tekst.avvisInvitasjon}\n onPress={() => setAvvist(true)}\n style={{ minWidth: tema.touch, minHeight: tema.touch, alignItems: 'center', justifyContent: 'center' }}\n >\n <Ikon navn=\"close-outline\" farge={tema.color.textSecondary} />\n </Pressable>\n </View>\n {feil && !viserAksept ? <Banner live ikon=\"warning-outline\" tone=\"danger\" children={tekst.akseptFeil(feil)} /> : null}\n {/* Kortets ENE handling, fylt. */}\n <Btn testID=\"les-mer\" label={tekst.lesMer} onPress={() => setViserAksept(true)} />\n </View>\n\n {viserAksept ? (\n <Aksept\n program={program}\n harToken={!!invitationToken}\n sender={sender}\n {...(feil ? { feil } : {})}\n onBliMed={() => void bliMed()}\n onLukk={() => setViserAksept(false)}\n />\n ) : null}\n </>\n );\n}\n","/**\n * Datoene testeren ser i aksepten (DD-32): «10.–24. oktober», eller med begge\n * måneder når perioden krysser et månedsskifte. Norsk bokmål, ingen klokkeslett —\n * et program varer i dager, og et tidspunkt ville lovet en presisjon som ikke finnes.\n */\nconst MANEDER = [\n 'januar',\n 'februar',\n 'mars',\n 'april',\n 'mai',\n 'juni',\n 'juli',\n 'august',\n 'september',\n 'oktober',\n 'november',\n 'desember',\n] as const;\n\nexport function periode(opensAt: string, closesAt: string): string {\n const fra = new Date(opensAt);\n const til = new Date(closesAt);\n if (Number.isNaN(fra.getTime()) || Number.isNaN(til.getTime())) return '';\n\n const sammeManed = fra.getMonth() === til.getMonth() && fra.getFullYear() === til.getFullYear();\n return sammeManed\n ? `${fra.getDate()}.–${til.getDate()}. ${MANEDER[til.getMonth()]}`\n : `${fra.getDate()}. ${MANEDER[fra.getMonth()]} – ${til.getDate()}. ${MANEDER[til.getMonth()]}`;\n}\n\n/**\n * Tiden aksepten skriver øverst (DD-32, presisert 2026-09-20): **tallet skal være SANT.**\n *\n * Fram til R8.3 sto her `minutterPerOppgave()`, som rundet av GJENNOMSNITTET: anslagene\n * 5, 3 og 2 minutter ble «ca. 3 min hver», som ikke er sant for noen av de tre — mens\n * radene under sa 5, 3 og 2. Regelen nå: `like` bare når alle oppgavene har samme anslag,\n * og da er tallet det anslaget («ca. M min hver»); ellers er tallet SUMMEN («ca. M min i\n * alt»). Anslaget er obligatorisk ved opprettelse, så lista er aldri tom i praksis.\n */\nexport function minutterLinje(tasks: ReadonlyArray<{ estimatedMinutes: number }>): { minutter: number; like: boolean } {\n if (tasks.length === 0) return { minutter: 0, like: true };\n const forste = tasks[0]!.estimatedMinutes;\n const like = tasks.every((t) => t.estimatedMinutes === forste);\n return like ? { minutter: forste, like: true } : { minutter: tasks.reduce((sum, t) => sum + t.estimatedMinutes, 0), like: false };\n}\n","import type { ProgramView } from '@innspel/core';\nimport React from 'react';\nimport { Linking, Modal, Pressable, ScrollView, Text, View } from 'react-native';\nimport { knownIssueStatus } from '../generated/tokens.js';\nimport { Ikon } from '../Ikon.js';\nimport { useTema } from '../tema.js';\nimport { Banner, Btn, H, Hint, Meta, Sek } from '../widget/primitiver.js';\nimport { tekst } from '../widget/tekster.js';\nimport { minutterLinje, periode } from './periode.js';\n\n/**\n * 3b — aksepten: forventningsavklaringen, i DD-13s rekkefølge — hva testes · hvor lenge ·\n * hva vi ber om · kjente feil (hele lista) · hva som samles inn · at det kommer høyst N\n * spørsmål og at hun kan gå ut.\n *\n * Fordi «hva testes» står først, er PROGRAMNAVNET skjermens helt og hypotesen ingressen\n * (DD-13, presisert 2026-09-20) — det er ikke et valg, det følger av rekkefølgen.\n *\n * **Tallene øverst (DD-32, presisert 2026-09-20)** skal være SANNE: hver oppgave bærer sitt\n * eget `estimatedMinutes` på raden, og linja øverst bærer SUMMEN når anslagene er ulike.\n * «ca. M min hver» står bare når alle er like. Se {@link minutterLinje}.\n *\n * **Kontakttaket som tall står ikke her** (DD-14, presisert 2026-09-20). Det testeren får\n * vite, er at det kommer HØYST N spørsmål — N er `maxContacts`, et tak som kan senkes og\n * aldri heves, og antall oppfølginger er malene, som kan være færre. «Vi tar kontakt maks 3\n * ganger» lovet noe som ikke er sant.\n *\n * Seksjonene er overskrift + innhold, ikke fire rammede kort. Vilkår er en LENKE, aldri en\n * avkryssing (DD-37); ved forpliktelsesfri form (tvunget når leietakeren har mindreårige\n * brukere, K37) finnes ingen vilkår ut over at man kan gå ut når som helst.\n *\n * «Bli med» krever tokenet leietakeren sendte i sin egen kanal (DD-12). Uten det verten har\n * fanget fra dyplenken er knappen inaktiv, med grunnen på skjermen — forklart lås, aldri en\n * 4xx som første møte med regelen (DD-02).\n */\nfunction Seksjon({ tittel, children }: { tittel: string; children: React.ReactNode }) {\n const tema = useTema();\n return (\n <View style={{ gap: tema.space.sm }}>\n <Text\n accessibilityRole=\"header\"\n style={{ color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body, fontWeight: tema.weight.bold }}\n >\n {tittel}\n </Text>\n {children}\n </View>\n );\n}\n\nexport function Aksept({\n program,\n harToken,\n sender,\n feil,\n onBliMed,\n onLukk,\n}: {\n program: ProgramView;\n harToken: boolean;\n sender: boolean;\n feil?: string;\n onBliMed: () => void;\n onLukk: () => void;\n}) {\n const tema = useTema();\n const { minutter, like } = minutterLinje(program.tasks);\n const tall = (like ? tekst.akseptTallHver : tekst.akseptTallSum)(\n program.tasks.length,\n minutter,\n periode(program.opensAt, program.closesAt),\n );\n const medVilkar = !!program.termsUrl && !program.commitmentFree;\n\n return (\n <Modal visible transparent animationType=\"slide\" onRequestClose={onLukk} accessibilityViewIsModal>\n <View style={{ flex: 1, backgroundColor: tema.color.scrim, justifyContent: 'flex-end' }}>\n <View\n testID=\"program-aksept\"\n accessibilityViewIsModal\n style={{\n backgroundColor: tema.color.bg,\n borderTopLeftRadius: tema.radius.lg * 2,\n borderTopRightRadius: tema.radius.lg * 2,\n padding: tema.screenPadding,\n gap: tema.space.md,\n maxHeight: '92%',\n minHeight: '60%',\n }}\n >\n <View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>\n <Btn variant=\"ghost\" testID=\"aksept-tilbake\" ikon=\"arrow-back-outline\" label={tekst.tilbake} onPress={onLukk} />\n <View />\n </View>\n\n {feil ? <Banner live ikon=\"warning-outline\" tone=\"danger\" children={tekst.akseptFeil(feil)} /> : null}\n\n <ScrollView contentContainerStyle={{ gap: tema.space.lg }}>\n {/* DD-13: «hva testes» først — programnavnet er helten, hypotesen ingressen. */}\n <H testID=\"aksept-tittel\" sub={program.hypothesis}>\n {program.name}\n </H>\n\n {/* DD-32: tallene på én linje, FØR forklaringen. Summen, når anslagene er ulike. */}\n <Text\n testID=\"aksept-tall\"\n style={{\n color: tema.color.textPrimary,\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n fontWeight: tema.weight.semibold,\n }}\n >\n {tall}\n </Text>\n\n <Seksjon tittel={tekst.akseptOppgaver}>\n <View>\n {program.tasks.map((o, i) => (\n <View\n key={o.id}\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n gap: tema.space.sm,\n minHeight: tema.touch + tema.space.sm,\n paddingVertical: tema.space.sm,\n borderTopWidth: i === 0 ? 0 : tema.hairline,\n borderTopColor: tema.color.border,\n }}\n >\n <View\n style={{\n width: tema.space.lg,\n height: tema.space.lg,\n borderRadius: tema.radius.pill,\n borderWidth: tema.hairline * 2,\n borderStyle: 'dashed',\n borderColor: tema.color.borderStrong,\n }}\n />\n <View style={{ flex: 1, minWidth: 0 }}>\n <Text\n style={{ color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body, fontWeight: tema.weight.semibold }}\n >\n {o.title}\n </Text>\n {/* Oppgavens ENE meta-linje i `small` (DD-67), med sitt EGET anslag. */}\n <Meta>{tekst.oppgaveTid(o.estimatedMinutes, o.screenHint)}</Meta>\n </View>\n </View>\n ))}\n </View>\n </Seksjon>\n\n {program.knownIssues.length > 0 ? (\n <Seksjon tittel={tekst.akseptKjenteFeil}>\n <View>\n {program.knownIssues.map((k, i) => {\n // Samme rad som widgetens kjente feil-steg (DD-30s tre deler), uten\n // svarknappene: aksepten forteller, den spør ikke.\n const o = knownIssueStatus[k.status] ?? knownIssueStatus.aktiv;\n const rettet = k.status === 'fikset';\n const statusOrd = rettet && k.fixedIn ? tekst.rettetI(k.fixedIn) : o.etikett;\n const tillegg = !rettet && k.fixedIn ? `· ${tekst.rettesI(k.fixedIn).toLowerCase()}` : undefined;\n return (\n <View\n key={k.id}\n style={{\n gap: tema.space.xs,\n paddingVertical: tema.space.sm,\n borderTopWidth: i === 0 ? 0 : tema.hairline,\n borderTopColor: tema.color.border,\n }}\n >\n <Text\n style={{ color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body, fontWeight: tema.weight.semibold }}\n >\n {k.title}\n </Text>\n {k.workaround ? (\n <Sek>\n {tekst.omvei} {k.workaround}\n </Sek>\n ) : null}\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: tema.space.sm, flexWrap: 'wrap' }}>\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: tema.space.xs }}>\n <Ikon navn={o.ikon} storrelse=\"minste\" farge={tema.color[o.fg as keyof typeof tema.color]} />\n <Text\n style={{\n color: tema.color[o.fg as keyof typeof tema.color],\n fontSize: tema.font.small,\n lineHeight: tema.lineHeight.small,\n fontWeight: tema.weight.semibold,\n }}\n >\n {statusOrd}\n </Text>\n </View>\n {tillegg ? <Meta>{tillegg}</Meta> : null}\n </View>\n </View>\n );\n })}\n </View>\n </Seksjon>\n ) : null}\n\n <Seksjon tittel={tekst.akseptInnsamling}>\n {/* Samme ord som kontekstlista i feltet: «enhet», ikke «plattform» (DD-50). */}\n <Sek>{tekst.akseptInnsamlingTekst}</Sek>\n {/* DD-37: lenke, aldri avkryssing — og ingen vilkår i forpliktelsesfri form. */}\n {medVilkar ? (\n <Pressable\n testID=\"vilkar-lenke\"\n accessibilityRole=\"link\"\n accessibilityLabel={tekst.akseptVilkar}\n onPress={() => void Linking.openURL(String(program.termsUrl))}\n style={{ minHeight: tema.touch, flexDirection: 'row', alignItems: 'center', gap: tema.space.sm }}\n >\n <Ikon navn=\"open-outline\" storrelse=\"minste\" farge={tema.color.actionSecondaryText} />\n <Text style={{ color: tema.color.actionSecondaryText, fontSize: tema.font.body, fontWeight: tema.weight.semibold }}>\n {tekst.akseptVilkar}\n </Text>\n </Pressable>\n ) : null}\n {/* Skjermens ENE hjelpesetning: taket og utgangen i én (DD-67). */}\n <Hint>\n {medVilkar ? tekst.akseptTakOgUtgangVilkar(program.maxContacts) : tekst.akseptTakOgUtgang(program.maxContacts)}\n </Hint>\n </Seksjon>\n </ScrollView>\n\n <Btn\n testID=\"bli-med\"\n label={tekst.bliMed}\n disabled={!harToken || sender}\n hint={harToken ? tekst.bliMedHint : tekst.bliMedUtenToken}\n onPress={onBliMed}\n />\n </View>\n </View>\n </Modal>\n );\n}\n","import type { TaskOutcome } from '@innspel/core';\nimport React, { useState } from 'react';\nimport { Modal, Pressable, Text, TextInput, View } from 'react-native';\nimport { Ikon } from '../Ikon.js';\nimport { useTema } from '../tema.js';\nimport { Banner, Btn, H, Meta, Tekstknapp } from '../widget/primitiver.js';\nimport { tekst } from '../widget/tekster.js';\n\n/** Ionicons-navn fra ikonkartet i `design/wireframes/betaprogram-tester.jsx`, aldri en emoji. */\nexport const UTFALL: ReadonlyArray<{ verdi: TaskOutcome; ikon: string; etikett: string }> = [\n { verdi: 'fungerte', ikon: 'checkmark-circle-outline', etikett: tekst.utfallFungerte },\n { verdi: 'delvis', ikon: 'contrast-outline', etikett: tekst.utfallDelvis },\n { verdi: 'ikke', ikon: 'close-circle-outline', etikett: tekst.utfallIkke },\n];\n\nexport const SETNING_MAKS = 140;\n\nexport function utfallEtikett(verdi: TaskOutcome): string {\n return UTFALL.find((u) => u.verdi === verdi)?.etikett ?? verdi;\n}\n\n/**\n * 3e — «Hvordan gikk det?». TRE lukkede valg og ETT åpent, sist — aldri en skala, og aldri\n * en gradering av appen: det er OPPGAVEN som evalueres, ikke produktet (DD-15). Samme ark\n * for «Gjort» på en oppgave og for «Svar nå» på en oppfølging (3d): det er det samme\n * spørsmålet, og testeren skal kjenne det igjen.\n *\n * **R8.3 (widget-konsept v0.1):** spørsmålet er HELTEN, og oppgaven står i `small` over som\n * det spørsmålet gjelder. Valgene er radiorader i `body` med ikon, LIKE I VEKT og uten\n * farge: «Fungerte ikke» er like nyttig for leietakeren som «Fungerte». Det valgte har fylt\n * sirkel med hake OG halvfet tekst — form og vekt, ikke bare farge (DD-08).\n *\n * Den valgfrie setningen har INGEN eksempelsetning som plassholder: etiketten stiller\n * spørsmålet, og et eksempel i et fritekstfelt ber om etterligning. (Dagens\n * `setningPlaceholder` var dessuten en setning fra en annen leietakers domene — den hører\n * ikke i en plattformpakke, `CLAUDE.md`.)\n *\n * «Lagre» er den ENESTE fylte knappen, i foten, i tommelsonen. «Lagre» er slutten, og\n * hintet «Ferdig — ingen flere spørsmål nå.» er tatt ut: knappen sier det selv.\n *\n * Etter «Fungerte ikke» tilbys «Meld det som feil» som en TEKSTKNAPP, aldri en andre\n * primærknapp. Den lagrer svaret og gir oppgaven videre til verten, som åpner feilsporet —\n * plattformen navigerer aldri selv, og svaret skal ikke gå tapt på veien.\n */\nexport function HvordanGikkDet({\n under,\n spoersmaal,\n sender,\n feil,\n onLagre,\n onMeldFeil,\n onLukk,\n}: {\n /** Hva spørsmålet gjelder — oppgavens tittel. Utelatt når arket kom fra en oppfølging. */\n under?: string;\n /** Oppfølgingens eget spørsmål. Utelatt: «Hvordan gikk det?». */\n spoersmaal?: string;\n sender: boolean;\n feil?: string;\n onLagre: (outcome: TaskOutcome, text: string | undefined) => void;\n /** Utelatt = tilbudet finnes ikke (DD-26): verten har ikke sagt hvor feilsporet er. */\n onMeldFeil?: (outcome: TaskOutcome, text: string | undefined) => void;\n onLukk: () => void;\n}) {\n const tema = useTema();\n const [valgt, setValgt] = useState<TaskOutcome | undefined>();\n const [setning, setSetning] = useState('');\n\n const tekstVerdi = () => {\n const trimmet = setning.trim();\n return trimmet.length > 0 ? trimmet : undefined;\n };\n\n return (\n <Modal visible transparent animationType=\"slide\" onRequestClose={onLukk} accessibilityViewIsModal>\n <View style={{ flex: 1, backgroundColor: tema.color.scrim, justifyContent: 'flex-end' }}>\n <View\n testID=\"hvordan-gikk-det\"\n accessibilityViewIsModal\n style={{\n backgroundColor: tema.color.bg,\n borderTopLeftRadius: tema.radius.lg * 2,\n borderTopRightRadius: tema.radius.lg * 2,\n padding: tema.screenPadding,\n gap: tema.space.md,\n maxHeight: '92%',\n }}\n >\n <View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>\n <Btn variant=\"ghost\" testID=\"hvordan-tilbake\" ikon=\"arrow-back-outline\" label={tekst.tilbake} onPress={onLukk} />\n <View />\n </View>\n\n <View style={{ gap: tema.space.xs }}>\n {under ? <Meta>{under}</Meta> : null}\n <H>{spoersmaal ?? tekst.hvordanGikkDet}</H>\n </View>\n\n <View\n testID=\"utfall-gruppe\"\n accessibilityRole=\"radiogroup\"\n accessibilityLabel={spoersmaal ?? tekst.hvordanGikkDet}\n >\n {UTFALL.map((u, i) => {\n const aktiv = valgt === u.verdi;\n return (\n <Pressable\n key={u.verdi}\n testID={`utfall-${u.verdi}`}\n accessibilityRole=\"radio\"\n accessibilityLabel={u.etikett}\n accessibilityState={{ checked: aktiv }}\n onPress={() => setValgt(u.verdi)}\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n gap: tema.space.md,\n minHeight: tema.touch + tema.space.sm,\n borderTopWidth: i === 0 ? 0 : tema.hairline,\n borderTopColor: tema.color.border,\n }}\n >\n {/* Form OG vekt, ikke bare farge (DD-08). */}\n <View\n testID={aktiv ? `utfall-merke-${u.verdi}` : undefined}\n style={{\n width: tema.space.lg,\n height: tema.space.lg,\n borderRadius: tema.radius.pill,\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: aktiv ? tema.color.brand : 'transparent',\n borderWidth: tema.hairline * 2,\n borderColor: aktiv ? tema.color.brand : tema.color.borderInteractive,\n }}\n >\n {aktiv ? <Ikon navn=\"checkmark-outline\" storrelse=\"minste\" farge={tema.color.onBrand} /> : null}\n </View>\n <Ikon navn={u.ikon} farge={tema.color.textSecondary} />\n <Text\n testID={`utfall-etikett-${u.verdi}`}\n style={{\n flex: 1,\n color: tema.color.textPrimary,\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n fontWeight: aktiv ? tema.weight.semibold : tema.weight.regular,\n }}\n >\n {u.etikett}\n </Text>\n </Pressable>\n );\n })}\n </View>\n\n <View style={{ gap: tema.space.sm }}>\n <Text style={{ color: tema.color.textSecondary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }}>\n {tekst.setningLabel} <Text style={{ color: tema.color.textMuted }}>{tekst.setningValgfritt}</Text>\n </Text>\n <TextInput\n testID=\"hvordan-setning\"\n accessibilityLabel={tekst.setningLabel}\n value={setning}\n onChangeText={setSetning}\n maxLength={SETNING_MAKS}\n multiline\n numberOfLines={2}\n style={{\n backgroundColor: tema.color.surfaceRaised,\n borderWidth: tema.hairline,\n borderColor: tema.color.borderStrong,\n borderRadius: tema.radius.md,\n padding: tema.space.md,\n color: tema.color.textPrimary,\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n minHeight: tema.touch * 1.5,\n textAlignVertical: 'top',\n }}\n />\n </View>\n\n {/* Tilbudet er en tekstknapp, ikke en andre primærknapp (DD-58, DD-63). */}\n {valgt === 'ikke' && onMeldFeil ? (\n <Tekstknapp\n testID=\"meld-feil\"\n ikon=\"bug-outline\"\n label={tekst.meldFeil}\n disabled={sender}\n onPress={() => onMeldFeil('ikke', tekstVerdi())}\n />\n ) : null}\n\n {feil ? <Banner live ikon=\"warning-outline\" tone=\"danger\" children={tekst.svarFeil(feil)} /> : null}\n\n <Btn\n testID=\"hvordan-lagre\"\n label={tekst.lagre}\n disabled={valgt === undefined || sender}\n busy={sender}\n onPress={() => {\n if (valgt === undefined) return;\n onLagre(valgt, tekstVerdi());\n }}\n />\n </View>\n </View>\n </Modal>\n );\n}\n","import type { FollowUpView } from '@innspel/core';\nimport React from 'react';\nimport { View } from 'react-native';\nimport { Ikon } from '../Ikon.js';\nimport { useTema } from '../tema.js';\nimport { Btn, H } from '../widget/primitiver.js';\nimport { tekst } from '../widget/tekster.js';\n\n/** Kontakter med spørsmål tar svar; de andre er handlinger (tech-decisions «M3.2 (forts.)»). */\nexport function tarSvar(kind: FollowUpView['kind']): boolean {\n return kind === 'hvordan_gikk_det' || kind === 'sjekkpunkt';\n}\n\n/**\n * 3d — oppfølgingskortene i appen (DD-34). Ett spørsmål per kort, som kortets HELT, og ÉN\n * linje som sier hva det koster: ett spørsmål, under ett minutt.\n *\n * Arten avgjør knappene: et spørsmål får «Svar nå» (åpner «Hvordan gikk det?» med spørsmålet\n * som helt), en påminnelse «Åpne oppgavene» — og navngir fristen i selve spørsmålet, som\n * produkteier skrev det — og tilbudet om utgang «Bli værende» / «Gå ut», invertert fra press:\n * utgangen er svaret som tilbys. «Senere» legger kortet bort i denne økten; det kommer\n * tilbake ved neste oppstart, aldri som push — plattformen holder ingen push-tokens.\n *\n * **«Kontakt 1 av 3» er ute** (DD-14, presisert 2026-09-20): tellingen er en regel mellom\n * Innspel og leietakeren, ikke noe testeren kan gjøre noe med. `contactsSent` finnes i\n * kontrakten og leses av PANELET.\n *\n * Flaten er `brandBg` UTEN ramme, som invitasjonen — det er samme avsender, og flaten er nok.\n */\nexport function Oppfolging({\n oppfolging,\n onSenere,\n onSvar,\n onAapneOppgavene,\n onGaaUt,\n}: {\n oppfolging: FollowUpView;\n onSenere: () => void;\n onSvar: () => void;\n onAapneOppgavene: () => void;\n onGaaUt: () => void;\n}) {\n const tema = useTema();\n const art = tarSvar(oppfolging.kind) ? 'spoersmaal' : oppfolging.kind === 'tilbud_om_utgang' ? 'utgang' : 'paaminnelse';\n\n return (\n <View\n testID={`oppfolging-${oppfolging.id}`}\n accessibilityLabel={tekst.oppfolgingRegion}\n style={{\n backgroundColor: tema.color.brandBg,\n borderRadius: tema.radius.lg,\n padding: tema.space.md,\n gap: tema.space.md,\n }}\n >\n <View style={{ flexDirection: 'row', gap: tema.space.sm, alignItems: 'flex-start' }}>\n <View style={{ paddingTop: tema.space.xs }}>\n <Ikon navn=\"flask-outline\" farge={tema.color.brand} />\n </View>\n <View style={{ flex: 1, minWidth: 0 }}>\n <H nivaa={3} meta={tekst.oppfolgingKost}>\n {oppfolging.question}\n </H>\n </View>\n </View>\n <View style={{ flexDirection: 'row', gap: tema.space.sm }}>\n {art === 'utgang' ? (\n <>\n {/* «Bli værende» står først: utgangen er et valg, ikke en felle. */}\n <Btn grow variant=\"secondary\" testID={`bli-vaerende-${oppfolging.id}`} label={tekst.bliVaerende} onPress={onSenere} />\n <Btn grow variant=\"secondary\" testID={`gaa-ut-${oppfolging.id}`} ikon=\"exit-outline\" label={tekst.gaaUtBekreft} onPress={onGaaUt} />\n </>\n ) : (\n <>\n <Btn grow variant=\"secondary\" testID={`senere-${oppfolging.id}`} label={tekst.senere} onPress={onSenere} />\n {art === 'spoersmaal' ? (\n <Btn grow testID={`svar-naa-${oppfolging.id}`} label={tekst.svarNaa} onPress={onSvar} />\n ) : (\n <Btn grow testID={`aapne-oppgavene-${oppfolging.id}`} label={tekst.aapneOppgavene} onPress={onAapneOppgavene} />\n )}\n </>\n )}\n </View>\n </View>\n );\n}\n","import type { ParticipationView, ProgramTask, TaskCompletionView } from '@innspel/core';\nimport React from 'react';\nimport { Text, View } from 'react-native';\nimport { Ikon } from '../Ikon.js';\nimport { useTema } from '../tema.js';\nimport { Btn, Meta, Sek } from '../widget/primitiver.js';\nimport { formaterFrist } from '../widget/status.js';\nimport { tekst } from '../widget/tekster.js';\nimport { utfallEtikett } from './HvordanGikkDet.js';\n\n/**\n * 3c — oppgavelista i deltakelseskortet. En TETT LISTE, ikke kort i kort.\n *\n * **R8.3 (widget-konsept v0.1, P1 (a)):** den gjorte raden har fylt sirkel med hake, ÉN\n * meta-linje i `small` med dato og utfall («Gjort 17. september · fungerte delvis»), og\n * TESTERENS EGEN SETNING i `body` under — det er hennes ord, og de er beslutningsgrunnlag\n * (DD-67). Dagens `oppgaveGjortMed` («Prøvd · <utfall>») ble denne linja.\n *\n * De som gjenstår har «Gjort» TONET i merkefargen på raden: to like valg, ingen av dem i\n * aksjonsfargen, fordi oppgavene kan gjøres i den rekkefølgen som passer (DD-63). Ingen\n * «Ferdig» i en fot — kortet ligger i vertens skjerm og har ingen egen fot, og en\n * «Ferdig»-knapp for tre oppgaver måtte valgt en oppgave for henne.\n *\n * «Ikke begynt» som etikett er ute: en åpen sirkel sier det (DD-08 — ikon og form, ikke et\n * ord i tillegg). Er programmet over, er «Gjort» borte: det er ingenting mer å gjøre.\n */\nexport function Oppgaver({\n tasks,\n completions,\n over,\n onGjort,\n}: {\n tasks: ProgramTask[];\n completions: ParticipationView['completions'];\n /** `closesAt` er passert eller deltakelsen er fullført: ingen flere «Gjort». */\n over?: boolean;\n onGjort: (task: ProgramTask) => void;\n}) {\n const tema = useTema();\n const ferdig = new Map<string, TaskCompletionView>(completions.map((c) => [c.taskId, c]));\n\n return (\n <View testID=\"oppgaver\" accessibilityLabel={tekst.oppgaverTittel}>\n {[...tasks]\n .sort((a, b) => a.order - b.order)\n .map((o, i) => {\n const c = ferdig.get(o.id);\n const meta = c ? tekst.oppgaveGjortMeta(formaterFrist(c.at), utfallEtikett(c.outcome)) : tekst.oppgaveTid(o.estimatedMinutes, o.screenHint);\n return (\n <View\n key={o.id}\n testID={`oppgave-${o.id}`}\n accessibilityLabel={tekst.oppgaveRadA11y(i + 1, o.title, c ? meta : tekst.oppgaveIkkeGjort)}\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n gap: tema.space.sm,\n minHeight: tema.touch + tema.space.sm,\n paddingVertical: tema.space.sm,\n borderTopWidth: i === 0 ? 0 : tema.hairline,\n borderTopColor: tema.color.border,\n }}\n >\n <View\n style={{\n width: tema.space.lg,\n height: tema.space.lg,\n borderRadius: tema.radius.pill,\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: c ? tema.color.success : 'transparent',\n borderWidth: c ? 0 : tema.hairline * 2,\n borderStyle: 'dashed',\n borderColor: tema.color.borderStrong,\n }}\n >\n {c ? <Ikon navn=\"checkmark-outline\" storrelse=\"minste\" farge={tema.color.bg} /> : null}\n </View>\n\n <View style={{ flex: 1, minWidth: 0 }}>\n <Text\n testID={`oppgave-tittel-${o.id}`}\n style={{ color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body, fontWeight: tema.weight.semibold }}\n >\n {o.title}\n </Text>\n <Meta testID={`oppgave-meta-${o.id}`}>{meta}</Meta>\n {/* Testerens egne ord i `body` — ikke i meta-linja (DD-67). */}\n {c?.text ? <Sek testID={`oppgave-setning-${o.id}`}>{c.text}</Sek> : null}\n </View>\n\n {!c && !over ? (\n <Btn\n variant=\"tonet\"\n testID={`gjort-${o.id}`}\n label={tekst.oppgaveGjort}\n accessibilityLabel={tekst.oppgaveGjortLabel(o.title)}\n onPress={() => onGjort(o)}\n />\n ) : null}\n </View>\n );\n })}\n </View>\n );\n}\n","import type { ParticipationView, ProgramView } from '@innspel/core';\nimport React from 'react';\nimport { Sporingslinje, type Ledd } from '../widget/Sporingslinje.js';\nimport { formaterFrist, formaterKortFrist } from '../widget/status.js';\nimport { tekst } from '../widget/tekster.js';\n\n/**\n * Programmets gang — samme komponent og samme regler som sakens (DD-08).\n *\n * **P1 (a), produkteier 2026-09-20:** deltakelsen bæres av SPORINGSLINJEN, ikke av et\n * kvitteringskort. Merkefargen på en flate er for det som er SENDT (kvitteringen, DD-41);\n * et program pågår, og deltakelseskortet er derfor sakskortets form — `surface` med ramme.\n * Identisk med portalens programskjerm.\n *\n * Tre ledd: «Du ble med» (`joinedAt`, passert), «N av M gjort» (nå-leddet, med\n * programikonet) og «Programmet er over» med `closesAt` som TALL — kortets HELT. Det er det\n * eneste som roper.\n *\n * Under nå-leddet står ÉN linje i `small` om når oppgavene kan gjøres. Aldri «to igjen»:\n * «1 av 3» sier alt tallet sier (DD-08, F8 — samme opplysning ikke to steder).\n *\n * Er programmet over (`fullfoert`, eller `closesAt` passert), er siste ledd PASSERT og\n * datoen står som dato — ikke som helt. Da er det ingenting mer å gjøre.\n */\nexport function programErOver(deltakelse: ParticipationView, program: ProgramView, naa: Date = new Date()): boolean {\n return deltakelse.status === 'fullfoert' || new Date(program.closesAt).getTime() < naa.getTime();\n}\n\nexport function programledd(deltakelse: ParticipationView, program: ProgramView, naa: Date = new Date()): Ledd[] {\n const over = programErOver(deltakelse, program, naa);\n const gjort = deltakelse.completions.length;\n const av = program.tasks.length;\n const alt = av > 0 && gjort >= av;\n\n return [\n { nokkel: 'ble-med', etikett: tekst.programBleMed, tilstand: 'gjort', detalj: formaterFrist(deltakelse.joinedAt) },\n {\n nokkel: 'gjort',\n etikett: tekst.programGjort(gjort, av),\n ...(over || alt\n ? { tilstand: 'gjort' as const }\n : { tilstand: 'naa' as const, ikon: 'flask-outline', detalj: tekst.programNaarDetPasser }),\n },\n over\n ? { nokkel: 'over', etikett: tekst.programOver, tilstand: 'gjort', detalj: formaterFrist(program.closesAt) }\n // Kort form: tallet står i én av tre kolonner på en telefon (se `formaterKortFrist`).\n : { nokkel: 'over', etikett: tekst.programOver, tilstand: 'kommer', tall: formaterKortFrist(program.closesAt) },\n ];\n}\n\nexport function ProgramSpor({ deltakelse, program }: { deltakelse: ParticipationView; program: ProgramView }) {\n return <Sporingslinje ledd={programledd(deltakelse, program)} testID=\"program-spor\" etikett={tekst.programSporEtikett} />;\n}\n","import type { InnspelStorage } from '@innspel/core';\n\n/**\n * Formen på lagringspakkene i React Native-økosystemet: AsyncStorage, MMKV med\n * async-fasade, expo-secure-store. Alle tre har disse tre metodene.\n */\nexport interface AsyncStorageLike {\n getItem(key: string): Promise<string | null>;\n setItem(key: string, value: string): Promise<void>;\n removeItem(key: string): Promise<void>;\n}\n\n/**\n * Lager en {@link InnspelStorage} av vertens egen lagringspakke.\n *\n * Pakken tar ingen avhengighet på AsyncStorage eller MMKV med vilje: verten har\n * som regel én av dem allerede, og to kopier av samme lagring i én app er verre\n * enn litt oppsett. Send inn den du bruker:\n *\n * @example\n * ```ts\n * import AsyncStorage from '@react-native-async-storage/async-storage';\n * const storage = createStorage(AsyncStorage);\n * ```\n *\n * Det eneste som lagres er offline-køen (DD-41) — aldri feedback-tokenet, aldri\n * en install- eller enhets-ID (K20). Lagringen trenger derfor ikke være kryptert.\n */\nexport function createStorage(pakke: AsyncStorageLike): InnspelStorage {\n return {\n get: (key) => pakke.getItem(key),\n set: (key, value) => pakke.setItem(key, value),\n remove: (key) => pakke.removeItem(key),\n };\n}\n\n/**\n * Lagring i minne. Køen overlever da ikke at appen lukkes, så den er til\n * utvikling og test — ikke til produksjon. `InnspelProvider` sier fra i\n * konsollen hvis den brukes uten at det er sagt eksplisitt.\n */\nexport function createMemoryStorage(): InnspelStorage {\n const rader = new Map<string, string>();\n return {\n get: async (key) => rader.get(key) ?? null,\n set: async (key, value) => {\n rader.set(key, value);\n },\n remove: async (key) => {\n rader.delete(key);\n },\n };\n}\n"],"mappings":"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","names":["createContext","useCallback","useContext","useMemo","useRef","useState","View","createContext","useContext","createContext","useContext","InnspelApiError","useCallback","useContext","useEffect","useRef","useState","Pressable","View","storrelse","useMemo","Pressable","Text","View","jsx","periode","jsx","jsxs","useMemo","View","Text","Pressable","Pressable","Text","View","jsx","jsxs","Pressable","View","Text","ScrollView","Text","View","jsx","jsxs","View","ScrollView","Text","Text","View","Text","View","jsx","jsxs","View","Text","jsx","jsxs","View","Text","useRef","useState","ActivityIndicator","ScrollView","Text","TextInput","View","jsx","jsxs","MineInnspill","useState","useRef","View","ActivityIndicator","ScrollView","Text","TextInput","useMemo","useRef","useState","Image","Pressable","Text","View","jsx","jsxs","useState","useRef","useMemo","Pressable","Text","View","Image","Fragment","jsx","jsxs","useContext","useRef","useState","useCallback","useEffect","InnspelApiError","View","Pressable","jsx","jsxs","createContext","useState","useRef","useMemo","useCallback","View","useContext","useEffect","useRef","View","jsx","useRef","useEffect","View","InnspelApiError","useCallback","useEffect","useState","Modal","Pressable","View","t","Modal","Pressable","ScrollView","Text","View","jsx","jsxs","View","Text","Modal","ScrollView","Pressable","useState","Modal","Pressable","Text","TextInput","View","jsx","jsxs","useState","Modal","View","Pressable","Text","TextInput","View","Fragment","jsx","jsxs","View","Text","View","jsx","jsxs","View","Text","jsx","Fragment","jsx","jsxs","useState","useCallback","InnspelApiError","useEffect","View","Modal","Pressable"]}
|
|
1
|
+
{"version":3,"sources":["../src/InnspelProvider.tsx","../src/skjermbilde.ts","../src/tema.ts","../src/generated/tokens.ts","../src/widget/Widget.tsx","../src/Ikon.tsx","../../../node_modules/ionicons/dist/svg/add-outline.svg","../../../node_modules/ionicons/dist/svg/arrow-back-outline.svg","../../../node_modules/ionicons/dist/svg/brush-outline.svg","../../../node_modules/ionicons/dist/svg/bug.svg","../../../node_modules/ionicons/dist/svg/bug-outline.svg","../../../node_modules/ionicons/dist/svg/bulb.svg","../../../node_modules/ionicons/dist/svg/calendar-outline.svg","../../../node_modules/ionicons/dist/svg/camera-outline.svg","../../../node_modules/ionicons/dist/svg/chatbox-outline.svg","../../../node_modules/ionicons/dist/svg/checkmark-circle-outline.svg","../../../node_modules/ionicons/dist/svg/checkmark-outline.svg","../../../node_modules/ionicons/dist/svg/chevron-down-outline.svg","../../../node_modules/ionicons/dist/svg/chevron-forward-outline.svg","../../../node_modules/ionicons/dist/svg/chevron-up-outline.svg","../../../node_modules/ionicons/dist/svg/close-circle-outline.svg","../../../node_modules/ionicons/dist/svg/close-outline.svg","../../../node_modules/ionicons/dist/svg/cloud-offline-outline.svg","../../../node_modules/ionicons/dist/svg/construct-outline.svg","../../../node_modules/ionicons/dist/svg/contrast-outline.svg","../../../node_modules/ionicons/dist/svg/ellipse-outline.svg","../../../node_modules/ionicons/dist/svg/exit-outline.svg","../../../node_modules/ionicons/dist/svg/flask-outline.svg","../../../node_modules/ionicons/dist/svg/grid-outline.svg","../../../node_modules/ionicons/dist/svg/hourglass-outline.svg","../../../node_modules/ionicons/dist/svg/image-outline.svg","../../../node_modules/ionicons/dist/svg/images-outline.svg","../../../node_modules/ionicons/dist/svg/list-outline.svg","../../../node_modules/ionicons/dist/svg/lock-closed-outline.svg","../../../node_modules/ionicons/dist/svg/git-merge-outline.svg","../../../node_modules/ionicons/dist/svg/open-outline.svg","../../../node_modules/ionicons/dist/svg/scan-outline.svg","../../../node_modules/ionicons/dist/svg/swap-vertical-outline.svg","../../../node_modules/ionicons/dist/svg/trash-outline.svg","../../../node_modules/ionicons/dist/svg/warning-outline.svg","../src/widget/Felt.tsx","../src/widget/primitiver.tsx","../src/widget/tekster.ts","../src/widget/Valg.tsx","../src/widget/KjenteFeil.tsx","../src/widget/Kvittering.tsx","../src/widget/Sporingslinje.tsx","../src/widget/status.ts","../src/widget/MineInnspill.tsx","../src/widget/nyttSvar.ts","../src/widget/Skjermbilde.tsx","../src/InnspelPrivate.tsx","../src/program/InnspelProgram.tsx","../src/program/periode.ts","../src/program/Aksept.tsx","../src/program/HvordanGikkDet.tsx","../src/program/Oppfolging.tsx","../src/program/Oppgaver.tsx","../src/program/ProgramSpor.tsx","../src/lagring.ts"],"sourcesContent":["import type { InnspelClient, OpenFeedbackOptions } from '@innspel/core';\nimport React, { createContext, useCallback, useContext, useMemo, useRef, useState } from 'react';\nimport { View } from 'react-native';\nimport { createPrivateRegistry, SkjermbildeContext, type ImageStepNote, type ScreenshotAdapter, type SkjermbildeKontekst, type ViewRef } from './skjermbilde.js';\nimport { byggTema, TemaProvider, type PartialTheme } from './tema.js';\nimport { Widget, type SubmittedInfo } from './widget/Widget.js';\n\ninterface InnspelKontekst {\n client: InnspelClient;\n /** Åpner widgeten. Samme som `client.openFeedback()`. */\n open: (options?: OpenFeedbackOptions) => Promise<void>;\n close: () => void;\n}\n\nconst Kontekst = createContext<InnspelKontekst | null>(null);\n\n/**\n * Pakk appen i denne, og widgeten finnes.\n *\n * Provideren gjør fire ting: den registrerer visningen hos kjernen (så\n * `client.openFeedback()` virker hvor som helst i appen, også utenfor React),\n * den holder temaet, den rendrer selve arket — og den pakker vertsappen i én\n * `View` med referanse, som er det skjermbildet tas av (K4). Modalen ligger\n * utenfor den viewen og kommer aldri med på bildet.\n *\n * @example\n * ```tsx\n * const innspel = init({ … });\n *\n * export default function App() {\n * return (\n * <InnspelProvider client={innspel} screenshot={createScreenshotAdapter(captureRef)}>\n * <MinApp />\n * </InnspelProvider>\n * );\n * }\n * ```\n */\nexport function InnspelProvider({\n client,\n children,\n theme,\n colorScheme = 'dark',\n tenantName,\n screenshot,\n imageStepNote,\n onSubmitted,\n}: {\n client: InnspelClient;\n children?: React.ReactNode;\n /** Vertens egne tokens. Alt som utelates faller tilbake på Innspels tema. */\n theme?: PartialTheme;\n colorScheme?: 'dark' | 'light';\n /** Navnet som står på svaret i «Mine innspill» — leietakerens, ikke Innspels. */\n tenantName?: string;\n /**\n * Fangst av skjermbilde, typisk `createScreenshotAdapter(captureRef)` fra\n * react-native-view-shot. Uten den finnes ikke skjermbilde-steget (DD-26) —\n * og det finnes uansett ikke når `screenshotsEnabled` er av (K18).\n */\n screenshot?: ScreenshotAdapter;\n /**\n * Leietakerens egen setning ved bildesteget, f.eks. «Legg ved et skjermbilde av feilen.\n * Ikke send bilder av andre personer.» Står ved knappene og i forhåndsvisningen. Én\n * streng gjelder begge spor; `{ feil, onske }` gir hvert spor sin. Leietakeren kjenner\n * brukerne sine; plattformen eier ikke den setningen.\n */\n imageStepNote?: ImageStepNote;\n /**\n * Kalles når et innspill er sendt — eller lagt i køen fordi nettet var borte (F26).\n * `type`, `queued`, og `id` og `number` når saken finnes hos tjeneren. Ingen identitet:\n * `number` er saksnummeret innsenderen alt ser i kvitteringen («Sak 10042»). Bruk det til å hente tellingen\n * på «Mine innspill» på nytt, eller til å be om varsler i det riktige øyeblikket —\n * rett etter første innsending, ikke ved oppstart. Kalles ikke for «Ja, jeg også».\n */\n onSubmitted?: (info: SubmittedInfo) => void;\n}) {\n const [synlig, setSynlig] = useState(false);\n const [apneOpsjoner, setApneOpsjoner] = useState<OpenFeedbackOptions | undefined>();\n const registrert = useRef(false);\n const rootRef = useRef<ViewRef | null>(null);\n const privat = useMemo(createPrivateRegistry, []);\n\n const open = useCallback(\n async (options?: OpenFeedbackOptions) => {\n setApneOpsjoner(options);\n setSynlig(true);\n },\n [],\n );\n\n const close = useCallback(() => setSynlig(false), []);\n\n // Registreres én gang. Kjernen kaller `presenter.open()` fra\n // `client.openFeedback()`, som er veien inn for kode som ikke er en\n // React-komponent — en navigasjonshandler, en krasjlytter hos verten.\n if (!registrert.current) {\n client.registerPresenter({ open });\n registrert.current = true;\n }\n\n const tema = useMemo(() => byggTema(theme, colorScheme), [theme, colorScheme]);\n const verdi = useMemo<InnspelKontekst>(() => ({ client, open, close }), [client, open, close]);\n const skjermbilde = useMemo<SkjermbildeKontekst>(\n () => ({ adapter: screenshot ?? null, rootRef, privat }),\n [screenshot, privat],\n );\n\n return (\n <Kontekst.Provider value={verdi}>\n <SkjermbildeContext.Provider value={skjermbilde}>\n <TemaProvider value={tema}>\n <View ref={rootRef} collapsable={false} style={{ flex: 1 }} testID=\"innspel-rot\">\n {children}\n </View>\n <Widget\n client={client}\n synlig={synlig}\n {...(apneOpsjoner ? { apneOpsjoner } : {})}\n {...(tenantName ? { tenantName } : {})}\n {...(imageStepNote ? { imageStepNote } : {})}\n {...(onSubmitted ? { onSubmitted } : {})}\n onLukk={close}\n />\n </TemaProvider>\n </SkjermbildeContext.Provider>\n </Kontekst.Provider>\n );\n}\n\n/**\n * Klienten og `open` fra nærmeste {@link InnspelProvider}.\n *\n * Kaster utenfor provideren i stedet for å gi `null`: en knapp som stille ikke\n * gjør noe er verre enn en feil under utvikling (tech-decisions.md, «Feil bruk\n * feiler høyt og tidlig»).\n */\nexport function useInnspel(): InnspelKontekst {\n const k = useContext(Kontekst);\n if (!k) {\n throw new Error(\n '[innspel] useInnspel() ble kalt utenfor <InnspelProvider>. Pakk appen din i den — se README.md.',\n );\n }\n return k;\n}\n","import type { MaskRect } from '@innspel/core';\nimport { createContext, useContext, type ComponentRef, type RefObject } from 'react';\nimport { Image, type View } from 'react-native';\n\n/** Host-elementet bak en `View` — det som kan måles og fanges. RN 0.87: `View` er en funksjonskomponent, så typen hentes herfra. */\nexport type ViewRef = ComponentRef<typeof View>;\n\n/**\n * Fangst av skjermbilde er det ene stedet widgeten trenger noe React Native\n * ikke har innebygd. Pakken tar INGEN avhengighet på det (K19, samme mønster som\n * `createStorage`): verten sender inn `captureRef` fra `react-native-view-shot`,\n * og uten adapter finnes ikke skjermbilde-steget (DD-26) — ikke som en grå\n * knapp, det finnes ikke.\n *\n * Alt som rører plattformen går gjennom adapteren, også måling og fillesing, så\n * widgeten kan testes med en fake og maskeringen bevises uten native kode.\n */\n\nexport interface ScreenshotCapture {\n /** Fil-URI fra fangsten. Forlater aldri enheten før den er maskert og rekomponert. */\n uri: string;\n /** Bitmapens størrelse i piksler. */\n width: number;\n height: number;\n}\n\nexport interface CaptureOptions {\n format: 'jpg' | 'png';\n /** 0–1, kun JPEG. */\n quality: number;\n}\n\nexport interface ScreenshotAdapter {\n /** Fanger viewen bak referansen til en fil. Kalles ved «Legg ved skjermbilde» (K4), og igjen på forhåndsvisningen for å rekomponere. */\n capture(ref: RefObject<ViewRef | null>, options: CaptureOptions): Promise<ScreenshotCapture>;\n /**\n * Velger et bilde fra enhetens bildebibliotek — «Velg bilde». `null` når innsenderen\n * avbryter. Uten metoden finnes ikke valget. Bildet går gjennom samme forhåndsvisning\n * og maskering, og det som lastes opp er komposittet fra `capture`, aldri fila.\n */\n pick?(): Promise<ScreenshotCapture | null>;\n /**\n * `false` fjerner «Legg ved skjermbilde» og lar bare «Velg bilde» stå — når skjermen\n * widgeten åpnes fra sjelden er der feilen er. `capture` trengs likevel til å\n * rekomponere forhåndsvisningen. Standard er `true`.\n */\n captureScreen?: boolean;\n /** Viewens rektangel i vinduskoordinater, i punkter. Null når den ikke er montert. */\n measure(ref: RefObject<ViewRef | null>): Promise<MaskRect | null>;\n /** Leser en fangst som Blob for opplasting. */\n read(uri: string): Promise<Blob>;\n}\n\n/** Signaturen til `captureRef` i react-native-view-shot — det eneste verten trenger å sende inn. */\nexport type CaptureRefFn = (\n ref: RefObject<ViewRef | null> | ViewRef,\n options: { format: 'jpg' | 'png'; quality: number; result: 'tmpfile' },\n) => Promise<string>;\n\n/**\n * Vertens bildevelger. Resultatet trenger bare `uri`; mangler størrelsen, måles den.\n * Returner `null` når innsenderen avbryter.\n *\n * @example\n * ```ts\n * import * as ImagePicker from 'expo-image-picker';\n * const pickImage: PickImageFn = async () => {\n * const r = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ['images'], exif: false });\n * return r.canceled ? null : { uri: r.assets[0]!.uri, width: r.assets[0]!.width, height: r.assets[0]!.height };\n * };\n * ```\n */\nexport type PickImageFn = () => Promise<{ uri: string; width?: number; height?: number } | null>;\n\n/**\n * Leietakerens setning ved bildesteget: én for begge spor, eller én per spor.\n * Et spor uten setning viser ingen.\n */\nexport type ImageStepNote = string | { feil?: string; onske?: string };\n\nexport interface ScreenshotAdapterOptions {\n /** Gir «Velg bilde». Pakken tar ingen avhengighet på en velger (K19). */\n pickImage?: PickImageFn;\n /** `false` fjerner «Legg ved skjermbilde». Standard er `true`. */\n captureScreen?: boolean;\n}\n\nfunction storrelse(uri: string): Promise<{ width: number; height: number }> {\n return new Promise((resolve, reject) => Image.getSize(uri, (w, h) => resolve({ width: w, height: h }), reject));\n}\n\n/**\n * Lager adapteren av vertens `captureRef`. Dimensjonene hentes med `Image.getSize`,\n * målingen med `measureInWindow`, og fila leses med `fetch(uri).blob()` — alt fra\n * React Native selv.\n *\n * @example\n * ```tsx\n * import { captureRef } from 'react-native-view-shot';\n * <InnspelProvider client={innspel} screenshot={createScreenshotAdapter(captureRef)}>\n * // Med bildevelger, og uten fangst av skjermen widgeten åpnes fra:\n * <InnspelProvider client={innspel} screenshot={createScreenshotAdapter(captureRef, { pickImage, captureScreen: false })}>\n * ```\n */\nexport function createScreenshotAdapter(captureRef: CaptureRefFn, options: ScreenshotAdapterOptions = {}): ScreenshotAdapter {\n const { pickImage, captureScreen } = options;\n return {\n async capture(ref, opts) {\n const uri = await captureRef(ref, { format: opts.format, quality: opts.quality, result: 'tmpfile' });\n return { uri, ...(await storrelse(uri)) };\n },\n ...(pickImage\n ? {\n async pick() {\n const valgt = await pickImage();\n if (!valgt) return null;\n const { width, height } = valgt.width && valgt.height ? { width: valgt.width, height: valgt.height } : await storrelse(valgt.uri);\n return { uri: valgt.uri, width, height };\n },\n }\n : {}),\n ...(captureScreen === false ? { captureScreen: false } : {}),\n measure(ref) {\n return new Promise((resolve) => {\n const view = ref.current;\n if (!view) return resolve(null);\n view.measureInWindow((x, y, width, height) => resolve({ x, y, width, height }));\n });\n },\n async read(uri) {\n const res = await fetch(uri);\n return res.blob();\n },\n };\n}\n\n/**\n * Private views (DD-39): det verten har merket med `<InnspelPrivate>`. Registeret\n * lever i provideren; widgeten måler hver av dem i fangstøyeblikket og legger en\n * maske brukeren ikke kan fjerne.\n */\nexport interface PrivateRegistry {\n register(ref: RefObject<ViewRef | null>): () => void;\n refs(): ReadonlyArray<RefObject<ViewRef | null>>;\n}\n\nexport function createPrivateRegistry(): PrivateRegistry {\n const alle = new Set<RefObject<ViewRef | null>>();\n return {\n register(ref) {\n alle.add(ref);\n return () => {\n alle.delete(ref);\n };\n },\n refs: () => [...alle],\n };\n}\n\nexport interface SkjermbildeKontekst {\n adapter: ScreenshotAdapter | null;\n /** Vertsappen — det som fanges. Modalen ligger utenfor og kommer aldri med. */\n rootRef: RefObject<ViewRef | null>;\n privat: PrivateRegistry;\n}\n\nexport const SkjermbildeContext = createContext<SkjermbildeKontekst | null>(null);\n\nexport function useSkjermbilde(): SkjermbildeKontekst | null {\n return useContext(SkjermbildeContext);\n}\n","import { createContext, useContext } from 'react';\nimport { light, t, type InnspelColors, type InnspelTheme } from './generated/tokens.js';\n\n/**\n * Widgeten lever INNE i vertsappen (DD-21) og skal arve dens flate. Verten\n * sender et delvis tema; alt den ikke sender faller tilbake på Innspels eget\n * (M0.4), som er generert fra `theme/theme.ts` og målt mot WCAG AA.\n *\n * Ingen hex-verdi, px-verdi eller fontstørrelse skrives i en komponent — alt\n * hentes herfra (CLAUDE.md, «Styling»). `fontFamily` finnes ikke: systemfonten\n * er standard i React Native, og å sette den ville brutt med vertsappen.\n */\n\n/**\n * De genererte tokenene er `as const`, så `t.touch` har typen `48` og ikke\n * `number`. Det er riktig for KILDEN — den skal ikke kunne endres ved et uhell\n * — men gjør temaet umulig å overstyre: verten ville måttet sende nøyaktig 48.\n * Denne typen åpner verdiene uten å åpne nøkkelsettet: en vert kan bytte en\n * farge, men ikke finne på en ny.\n */\nexport type Tema = Omit<\n InnspelTheme,\n 'color' | 'space' | 'radius' | 'font' | 'lineHeight' | 'motion' | 'touch' | 'screenPadding' | 'hairline'\n> & {\n color: Record<keyof InnspelColors, string>;\n space: Record<keyof InnspelTheme['space'], number>;\n radius: Record<keyof InnspelTheme['radius'], number>;\n font: Record<keyof InnspelTheme['font'], number>;\n lineHeight: Record<keyof InnspelTheme['lineHeight'], number>;\n motion: Record<keyof InnspelTheme['motion'], number>;\n touch: number;\n screenPadding: number;\n hairline: number;\n};\n\nexport type PartialTheme = {\n color?: Partial<Tema['color']>;\n} & Partial<Omit<Tema, 'color'>>;\n\n/**\n * Fletter vertens tokens over Innspels egne.\n *\n * @param vertens Delvis tema fra `<InnspelProvider theme={…}>`.\n * @param palett `dark` er standard: widgeten åpnes oftest over en app i mørk\n * modus, og et lyst ark over en mørk app blender.\n */\nexport function byggTema(vertens?: PartialTheme, palett: 'dark' | 'light' = 'dark'): Tema {\n const bunn = (palett === 'light' ? light : t) as unknown as Tema;\n if (!vertens) return bunn;\n\n return {\n ...bunn,\n ...vertens,\n color: { ...bunn.color, ...vertens.color },\n };\n}\n\nconst TemaContext = createContext<Tema>(t as unknown as Tema);\n\nexport const TemaProvider = TemaContext.Provider;\n\n/** Tokenene som gjelder her. Bruk ALDRI en literal farge eller avstand i stedet. */\nexport function useTema(): Tema {\n return useContext(TemaContext);\n}\n","/**\n * tokens.ts — GENERERT fra theme/theme.ts (avtrykk 8d9d03227be9).\n * Rediger aldri denne filen. Endre temaet i kilden og kjør\n * `node scripts/generate-tokens.ts`, som CI verifiserer med `--check`.\n *\n * Tokenene @innspel/react-native faller tilbake på når verten ikke sender egne.\n * Widgeten lever inne i vertsappen og skal arve dens flate (DD-21); dette er\n * bunnen, ikke fasiten.\n *\n * 83 kontrastpar er målt mot WCAG AA i begge paletter, og generatoren\n * nekter å skrive hvis ett faller under kravet. Farge bærer aldri mening alene\n * — hver status har ikon og tekstetikett (DD-08).\n *\n * fontFamily finnes ikke her med vilje: systemfonten er standard i React\n * Native, og å sette den ville brutt med vertsappen.\n */\n\n/** Mørk palett — fallback når verten ikke sender egne tokens. */\nexport const t = {\n color: {\n bg: \"#111417\",\n surface: \"#1A1E22\",\n surfaceRaised: \"#232830\",\n border: \"#2E343B\",\n borderStrong: \"#3D444D\",\n borderInteractive: \"#7C8894\",\n textPrimary: \"#F2F4F6\",\n textSecondary: \"#B4BCC5\",\n textMuted: \"#8D96A1\",\n textDisabled: \"#5A626B\",\n actionPrimary: \"#5AD3E2\",\n onActionPrimary: \"#04252A\",\n actionSecondaryBorder: \"#7C8894\",\n actionSecondaryText: \"#F2F4F6\",\n actionText: \"#5AD3E2\",\n brand: \"#5AD3E2\",\n onBrand: \"#04252A\",\n brandFill: \"#0E7C8C\",\n onBrandFill: \"#FFFFFF\",\n brandBg: \"#0C2A30\",\n danger: \"#FF7A8C\",\n dangerFill: \"#C4001F\",\n onDangerFill: \"#FFFFFF\",\n dangerBg: \"#2C1116\",\n success: \"#3ED88A\",\n onSuccess: \"#062015\",\n successBg: \"#0E2A1E\",\n warning: \"#FFC24D\",\n onWarning: \"#2A1C02\",\n warningBg: \"#2C2107\",\n info: \"#5CC0FF\",\n onInfo: \"#04222F\",\n infoBg: \"#0E2531\",\n neutral: \"#A3ACB6\",\n onNeutral: \"#111417\",\n neutralBg: \"#242A31\",\n scrim: \"rgba(0, 0, 0, 0.72)\",\n },\n space: {\n xs: 4,\n sm: 8,\n md: 16,\n lg: 24,\n xl: 32,\n xxl: 48,\n },\n radius: {\n sm: 6,\n md: 8,\n lg: 12,\n pill: 999,\n },\n font: {\n display: 40,\n h1: 24,\n h2: 21,\n h3: 18,\n body: 16,\n small: 13,\n tiny: 11,\n },\n lineHeight: {\n display: 48,\n h1: 30,\n h2: 27,\n h3: 24,\n body: 24,\n small: 18,\n tiny: 16,\n },\n weight: {\n regular: \"400\",\n medium: \"500\",\n semibold: \"600\",\n bold: \"700\",\n },\n motion: {\n fast: 120,\n base: 200,\n slow: 320,\n },\n icon: { inline: 20, minste: 16 },\n touch: 48,\n screenPadding: 24,\n hairline: 1,\n} as const;\n\n/** Lys palett. */\nexport const light = {\n color: {\n bg: \"#F6F7F9\",\n surface: \"#FFFFFF\",\n surfaceRaised: \"#EDEFF3\",\n border: \"#D2D7DE\",\n borderStrong: \"#B9C0C9\",\n borderInteractive: \"#6F7883\",\n textPrimary: \"#14181D\",\n textSecondary: \"#454D57\",\n textMuted: \"#5C6470\",\n textDisabled: \"#9AA2AD\",\n actionPrimary: \"#0A6673\",\n onActionPrimary: \"#FFFFFF\",\n actionSecondaryBorder: \"#6F7883\",\n actionSecondaryText: \"#14181D\",\n actionText: \"#0A6673\",\n brand: \"#0A6673\",\n onBrand: \"#FFFFFF\",\n brandFill: \"#0A6673\",\n onBrandFill: \"#FFFFFF\",\n brandBg: \"#E0F0F2\",\n danger: \"#B3001B\",\n dangerFill: \"#B3001B\",\n onDangerFill: \"#FFFFFF\",\n dangerBg: \"#FCE8EA\",\n success: \"#04693C\",\n onSuccess: \"#FFFFFF\",\n successBg: \"#E4F4EC\",\n warning: \"#7A5200\",\n onWarning: \"#FFFFFF\",\n warningBg: \"#FBF1DE\",\n info: \"#00588F\",\n onInfo: \"#FFFFFF\",\n infoBg: \"#E4F0F8\",\n neutral: \"#5C6470\",\n onNeutral: \"#FFFFFF\",\n neutralBg: \"#EEF0F3\",\n scrim: \"rgba(10, 14, 18, 0.45)\",\n },\n space: {\n xs: 4,\n sm: 8,\n md: 16,\n lg: 24,\n xl: 32,\n xxl: 48,\n },\n radius: {\n sm: 6,\n md: 8,\n lg: 12,\n pill: 999,\n },\n font: {\n display: 40,\n h1: 24,\n h2: 21,\n h3: 18,\n body: 16,\n small: 13,\n tiny: 11,\n },\n lineHeight: {\n display: 48,\n h1: 30,\n h2: 27,\n h3: 24,\n body: 24,\n small: 18,\n tiny: 16,\n },\n weight: {\n regular: \"400\",\n medium: \"500\",\n semibold: \"600\",\n bold: \"700\",\n },\n motion: {\n fast: 120,\n base: 200,\n slow: 320,\n },\n icon: { inline: 20, minste: 16 },\n touch: 48,\n screenPadding: 24,\n hairline: 1,\n} as const;\n\n/** Innspillets statuser. `fg`/`bg` er TOKENNAVN og slås opp i den aktive paletten. Nøklene er Submissions.SubmissionStatus i contracts/. */\nexport const submissionStatus = {\n ny: {\n statusType: \"reviewing\",\n ikon: \"ellipse-outline\",\n etikett: { feil: \"Mottatt\", onske: \"Mottatt\" },\n lofte: { feil: \"Vi har fått den. Du hører fra oss.\", onske: \"Vi har fått den. Du hører fra oss.\" },\n fg: \"textSecondary\",\n bg: \"neutralBg\",\n variant: \"outline\",\n },\n vurderes: {\n statusType: \"reviewing\",\n ikon: \"hourglass-outline\",\n etikett: { feil: \"Vurderes\", onske: \"Vurderes\" },\n lofte: { feil: \"Svar innen {frist} — også hvis det er nei.\", onske: \"Svar innen {frist} — også hvis det er nei.\" },\n fg: \"info\",\n bg: \"infoBg\",\n variant: \"outline\",\n },\n planlagt: {\n statusType: \"active\",\n ikon: \"calendar-outline\",\n etikett: { feil: \"Planlagt\", onske: \"Planlagt\" },\n lofte: { feil: \"Du får beskjed når den er rettet.\", onske: \"Du får beskjed når det er levert.\" },\n fg: \"brand\",\n bg: \"brandBg\",\n variant: \"outline\",\n },\n bygges: {\n statusType: \"active\",\n ikon: \"construct-outline\",\n etikett: { feil: \"Retter nå\", onske: \"Bygger\" },\n lofte: { feil: \"Du får beskjed når den er rettet.\", onske: \"Du får beskjed når det er levert.\" },\n fg: \"brand\",\n bg: \"brandBg\",\n variant: \"filled\",\n },\n kjent_feil: {\n statusType: \"active\",\n ikon: \"warning-outline\",\n etikett: { feil: \"Kjent feil\", onske: \"Kjent feil\" },\n lofte: { feil: \"Kjent feil. Du får beskjed når den er rettet.\", onske: \"Kjent feil. Du får beskjed når den er rettet.\" },\n fg: \"warning\",\n bg: \"warningBg\",\n variant: \"outline\",\n },\n levert: {\n statusType: \"complete\",\n ikon: \"checkmark-circle-outline\",\n etikett: { feil: \"Rettet\", onske: \"Levert\" },\n lofte: { feil: \"Ferdig. Ser du feilen igjen, send et nytt innspill.\", onske: \"Ferdig. Takk for ønsket.\" },\n fg: \"success\",\n bg: \"successBg\",\n variant: \"outline\",\n },\n avvist: {\n statusType: \"closed\",\n ikon: \"close-circle-outline\",\n etikett: { feil: \"Avvist\", onske: \"Avvist\" },\n lofte: { feil: \"Vi har svart på denne.\", onske: \"Vi har svart på denne.\" },\n fg: \"danger\",\n bg: \"dangerBg\",\n variant: \"outline\",\n },\n duplikat: {\n statusType: \"closed\",\n ikon: \"git-merge-outline\",\n etikett: { feil: \"Slått sammen\", onske: \"Slått sammen\" },\n lofte: { feil: \"Slått sammen med et innspill som ligner.\", onske: \"Slått sammen med et innspill som ligner.\" },\n fg: \"neutral\",\n bg: \"neutralBg\",\n variant: \"outline\",\n },\n} as const;\n\n/** Programmets statuser. Nøklene er Programs.ProgramStatus i contracts/. */\nexport const programStatus = {\n utkast: {\n ikon: \"create-outline\",\n etikett: \"Utkast\",\n fg: \"textSecondary\",\n bg: \"neutralBg\",\n variant: \"dashed\",\n },\n aapen: {\n ikon: \"ellipse-outline\",\n etikett: \"Åpen\",\n fg: \"info\",\n bg: \"infoBg\",\n variant: \"outline\",\n },\n aktiv: {\n ikon: \"checkmark-circle-outline\",\n etikett: \"Aktiv\",\n fg: \"success\",\n bg: \"successBg\",\n variant: \"outline\",\n },\n avsluttes: {\n ikon: \"time-outline\",\n etikett: \"Avsluttes\",\n fg: \"warning\",\n bg: \"warningBg\",\n variant: \"outline\",\n },\n avsluttet: {\n ikon: \"checkmark-circle-outline\",\n etikett: \"Avsluttet\",\n fg: \"neutral\",\n bg: \"neutralBg\",\n variant: \"outline\",\n },\n avbrutt: {\n ikon: \"close-circle\",\n etikett: \"Avbrutt\",\n fg: \"dangerFill\",\n bg: \"onDangerFill\",\n variant: \"filled\",\n },\n} as const;\n\n/** Kjent feil-statusene (M2.4). Nøklene er KnownIssues.KnownIssueStatus i contracts/; «fikset» heter «Rettet» (DD-22). */\nexport const knownIssueStatus = {\n aktiv: {\n ikon: \"warning-outline\",\n etikett: \"Aktiv\",\n fg: \"warning\",\n bg: \"warningBg\",\n variant: \"outline\",\n },\n fikset: {\n ikon: \"checkmark-circle-outline\",\n etikett: \"Rettet\",\n fg: \"success\",\n bg: \"successBg\",\n variant: \"dashed\",\n },\n} as const;\n\n/** Løftet for `vurderes` uten frist: svaret loves, tidspunktet ikke (DD-07, DD-28). */\nexport const lofteUtenFrist = \"Du får svar — også hvis det er nei.\";\n\n/** Skjermbilde-maskering. Faste signalfarger, uavhengig av palett (DD-39, DD-40). Vedlegg er M1.3. */\nexport const screenRules = {\n brushFill: \"#E5007D\",\n autoMaskFill: \"#101114\",\n autoMaskStroke: \"#E5007D\",\n autoMaskText: \"#FFFFFF\",\n previewBackdrop: \"#000000\",\n qrBackdrop: \"#FFFFFF\",\n brushWidth: 28,\n textBlurRadius: 24,\n} as const;\n\n/** Formen widgeten tar imot. Verten sender et delvis tema; resten faller tilbake hit. */\nexport type InnspelTheme = typeof t;\nexport type InnspelColors = InnspelTheme['color'];\n","import {\n InnspelApiError,\n InnspelQueueFullError,\n type AttachmentInput,\n type InnspelClient,\n type KnownIssueCard,\n type MaskRect,\n type MySubmission,\n type OpenFeedbackOptions,\n type PatternFinding,\n} from '@innspel/core';\nimport React, { useCallback, useContext, useEffect, useRef, useState } from 'react';\nimport { KeyboardAvoidingView, Modal, Pressable, View } from 'react-native';\nimport { initialWindowMetrics, SafeAreaInsetsContext } from 'react-native-safe-area-context';\nimport { Ikon } from '../Ikon.js';\nimport { useSkjermbilde, type ImageStepNote, type ScreenshotCapture, type ViewRef } from '../skjermbilde.js';\nimport { useTema } from '../tema.js';\nimport { Felt } from './Felt.js';\nimport { Valg } from './Valg.js';\nimport { KjenteFeil } from './KjenteFeil.js';\nimport { Kvittering, type KvitteringArt } from './Kvittering.js';\nimport { MineInnspill, type MineInnspillHandtak } from './MineInnspill.js';\nimport { Skjermbilde } from './Skjermbilde.js';\nimport { Banner, Btn } from './primitiver.js';\nimport { tekst } from './tekster.js';\n\nexport type Steg = 'valg' | 'kjenteFeil' | 'felt' | 'skjermbilde' | 'kvittering' | 'mine';\n\n/**\n * Det verten får vite når et innspill er sendt (F26). Sakens nummer, aldri innsenderens\n * identitet — nummeret er det hun alt ser i kvitteringen. `queued` når nettet var borte\n * og innspillet ligger i køen: hun trykket Send, og det teller. «Ja, jeg også» på en kjent\n * feil gir ikke dette kallet — det er Reach, ikke en ny sak.\n */\nexport interface SubmittedInfo {\n type: 'feil' | 'onske';\n queued: boolean;\n /** Finnes når saken er opprettet hos tjeneren; mangler i køen. */\n id?: string;\n /** Saksnummeret innsenderen ser i kvitteringen («Sak 10042»). Følger `id`: mangler i køen. */\n number?: number;\n}\n\n/** JPEG med denne kvaliteten holder et 3×-skjermbilde godt under 5 MB (K9) og gjør uskarphet irreversibel i praksis. */\nconst FANGST = { format: 'jpg', quality: 0.85 } as const;\n\n/**\n * Widgeten. Ett ark over vertsappen — aldri en flytende knapp over innhold\n * (DD-21).\n *\n * **DD-47, og hvorfor det står her og ikke i en TODO:** arket er en dialog og\n * oppfører seg som en. `<Modal>` gir fokusfellen; `onRequestClose` er\n * Android-tilbake og ESC på tastatur; `accessibilityViewIsModal` skjuler\n * vertsappen for skjermlesere på iOS; kvitteringen er en live-region. Sentrys\n * crash-modal mangler alle fire (issue #23288, #9291) — den er leverandøren som\n * dokumenterer både løsningen og mangelen.\n *\n * **Flyten er ikke symmetrisk.** Feilsporet møter kjente feil FØR feltet: den\n * som står i en feil skal slippe å skrive noe hvis svaret allerede finnes.\n * Ønskesporet møter dem ETTER: et ønske må formuleres før det kan sammenlignes.\n *\n * **Skjermbildet (2f, K4):** tas først når innsenderen trykker, aldri ved åpning.\n * Steget finnes bare når leietakeren har skjermbilde på OG verten har gitt en\n * adapter (DD-26). Private views måles i fangstøyeblikket (DD-39). Det som\n * lastes opp er komposittet av forhåndsvisningen med maskene — rå-URI-en går\n * aldri videre. Teksten sendes først; bildet kan feile alene (DD-42).\n */\nexport function Widget({\n client,\n synlig,\n apneOpsjoner,\n onLukk,\n tenantName,\n imageStepNote,\n onSubmitted,\n}: {\n client: InnspelClient;\n synlig: boolean;\n apneOpsjoner?: OpenFeedbackOptions;\n onLukk: () => void;\n tenantName?: string;\n imageStepNote?: ImageStepNote;\n /** F26: kalles etter en innsending — sendt eller køet. Aldri for «ja, jeg også». */\n onSubmitted?: (info: SubmittedInfo) => void;\n}) {\n const tema = useTema();\n // Edge-to-edge (Android 15+, Expo SDK 53+): Modal tegner under status- og\n // navigasjonslinja uansett props. Insets fra vertens SafeAreaProvider, ellers\n // vinduets fra oppstart; useSafeAreaInsets ville kastet uten provider.\n const insets = useContext(SafeAreaInsetsContext) ?? initialWindowMetrics?.insets ?? { top: 0, bottom: 0, left: 0, right: 0 };\n const skjermbilde = useSkjermbilde();\n const previewRef = useRef<ViewRef | null>(null);\n\n const [steg, setSteg] = useState<Steg>('valg');\n const [spor, setSpor] = useState<'feil' | 'onske'>('feil');\n const [verdi, setVerdi] = useState('');\n const [kort, setKort] = useState<KnownIssueCard[]>([]);\n const [lasterKort, setLasterKort] = useState(false);\n const [lenketTil, setLenketTil] = useState<KnownIssueCard | undefined>();\n const [funn, setFunn] = useState<PatternFinding[]>([]);\n const [fjernede, setFjernede] = useState<string[]>([]);\n const [sender, setSender] = useState(false);\n const online = useNettstatus(client);\n const [feil, setFeil] = useState<string | undefined>();\n const [kvittering, setKvittering] = useState<{ art: KvitteringArt; nr?: number; vedlegg?: 'feilet' | 'forkastet'; frist?: string; sak?: MySubmission }>();\n const [mine, setMine] = useState<MySubmission[]>([]);\n const [lasterMine, setLasterMine] = useState(false);\n\n // Skjermbildet: rå fangst til forhåndsvisning, private views i rotens punkter,\n // og det ferdige, maskerte vedlegget som sendes med teksten.\n const [bilde, setBilde] = useState<ScreenshotCapture | undefined>();\n const [automasker, setAutomasker] = useState<MaskRect[]>([]);\n const [rotStorrelse, setRotStorrelse] = useState({ width: 1, height: 1 });\n const [komponerer, setKomponerer] = useState(false);\n const [kilde, setKilde] = useState<'skjerm' | 'galleri'>('skjerm');\n const [vedlegg, setVedlegg] = useState<AttachmentInput | undefined>();\n\n // Leietakerens grenser: startverdiene fra init(), oppdatert fra plattformen ved åpning (M2.5).\n const [innstillinger, setInnstillinger] = useState({ ...client.settings });\n\n // DD-26: steget finnes ikke uten begge. Aldri en deaktivert knapp.\n const skjermbildeMulig = innstillinger.screenshotsEnabled && skjermbilde?.adapter != null;\n const fangstMulig = skjermbildeMulig && skjermbilde?.adapter?.captureScreen !== false;\n const galleriMulig = skjermbildeMulig && typeof skjermbilde?.adapter?.pick === 'function';\n // Vertens setning for sporet innsenderen står i.\n const bildeNotat = typeof imageStepNote === 'string' ? imageStepNote : imageStepNote?.[spor];\n\n const nullstill = useCallback(() => {\n setSteg('valg');\n setSpor('feil');\n setVerdi('');\n setKort([]);\n setLenketTil(undefined);\n setFunn([]);\n setFjernede([]);\n setFeil(undefined);\n setKvittering(undefined);\n setBilde(undefined);\n setAutomasker([]);\n setVedlegg(undefined);\n setKomponerer(false);\n }, []);\n\n // «Mine innspill» åpnet av verten (`view: 'mine'`) er en visning OVER det innsenderen\n // holdt på, ikke et steg i skjemaet (F3). `stegForMine` er steget under — det lukking\n // og «Tilbake» fører tilbake til, så et utkast i feltet står der ved neste åpning.\n const [mineDirekte, setMineDirekte] = useState(false);\n const [stegForMine, setStegForMine] = useState<Steg>('valg');\n const stegRef = useRef(steg);\n stegRef.current = steg;\n\n /** Noe innsenderen har laget og ikke sendt. Det vinner over vertens `track` (F1). */\n const harUtkast = verdi.trim().length > 0 || vedlegg !== undefined;\n\n /**\n * Lukking beholder spor, steg og tekst (F1, samme modell som `@innspel/web`). Fram til\n * 2026-09-15 nullstilte den, og Android-tilbake kastet teksten på ett trykk.\n */\n const lukk = useCallback(() => {\n onLukk();\n if (stegRef.current === 'mine' && mineDirekte) {\n setSteg(stegForMine);\n setMineDirekte(false);\n }\n }, [onLukk, mineDirekte, stegForMine]);\n\n /** Kvitteringen er det ene stedet som nullstiller — der er innspillet sendt. */\n const lukkOgNullstill = useCallback(() => {\n onLukk();\n nullstill();\n setMineDirekte(false);\n setStegForMine('valg');\n }, [onLukk, nullstill]);\n\n // Køen tømmes når widgeten ÅPNES — aldri ved oppstart (DD-41). Resultatet\n // vises ikke: en flush som lykkes er ikke en hendelse innsenderen ba om.\n useEffect(() => {\n if (!synlig) return;\n client.track({ name: 'widget_opened' });\n void client.queue.flush().catch(() => undefined);\n // Konfigurasjonen er et tilbud: svarer den, oppdateres grensene; ellers står de.\n void client.loadSettings().then((s) => setInnstillinger({ ...s })).catch(() => undefined);\n\n // «Mine innspill» (DD-62): tellingen på knappen hentes ved åpning, stille — feiler\n // kallet, står knappen uten tall. Anonym modus har ingen liste og kalles aldri.\n if (!client.isAnonymous) {\n void client.subjects\n .submissions()\n .then(setMine)\n .catch(() => undefined);\n }\n\n // Et utkast vinner over vertens `track`: å bytte spor under en skrevet tekst ville\n // sendt en feil som ønske. «Mine innspill» legges over utkastet og tar det ikke bort.\n if (apneOpsjoner?.view === 'mine' && !client.isAnonymous) void visMine(true);\n else if (apneOpsjoner?.track && !harUtkast) void velgSpor(apneOpsjoner.track);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [synlig]);\n\n const hentKort = useCallback(async () => {\n setLasterKort(true);\n try {\n const q = apneOpsjoner?.screen ? { screen: apneOpsjoner.screen } : {};\n setKort(await client.knownIssues.for(q));\n } finally {\n setLasterKort(false);\n }\n }, [client, apneOpsjoner?.screen]);\n\n const velgSpor = useCallback(\n async (valgt: 'feil' | 'onske') => {\n setSpor(valgt);\n client.track({ name: 'track_selected', type: valgt });\n\n if (valgt === 'onske') {\n // Ønskesporet skriver først; sammenligningen kommer etterpå.\n setSteg('felt');\n return;\n }\n\n setSteg('kjenteFeil');\n await hentKort();\n },\n [client, hentKort],\n );\n\n // Treffene er et tilbud, aldri en sperre (wireframe 2c): er lista tom når\n // oppslaget er ferdig, hoppes skjermen over — rett til feltet, ingen melding.\n useEffect(() => {\n if (steg === 'kjenteFeil' && !lasterKort && kort.length === 0) setSteg('felt');\n }, [steg, lasterKort, kort.length]);\n\n const endreTekst = useCallback(\n (v: string) => {\n setVerdi(v);\n setFunn(client.scanText(v));\n },\n [client],\n );\n\n /**\n * «Legg ved skjermbilde» (K4): fangsten skjer HER, ved trykket, av vertsappen\n * bak arket. Private views måles i samme øyeblikk (DD-39) og regnes om til\n * rotens punkter. Feiler fangsten, kan innsenderen sende uten.\n */\n const taSkjermbilde = useCallback(async () => {\n if (!skjermbilde?.adapter) return;\n const { adapter, rootRef, privat } = skjermbilde;\n setFeil(undefined);\n try {\n const fangst = await adapter.capture(rootRef, FANGST);\n const rot = await adapter.measure(rootRef);\n const private_ = await Promise.all(privat.refs().map((r) => adapter.measure(r)));\n if (rot) {\n setRotStorrelse({ width: rot.width, height: rot.height });\n setAutomasker(\n private_\n .filter((r): r is MaskRect => r !== null)\n .map((r) => ({ x: r.x - rot.x, y: r.y - rot.y, width: r.width, height: r.height })),\n );\n } else {\n setRotStorrelse({ width: fangst.width, height: fangst.height });\n setAutomasker([]);\n }\n setBilde(fangst);\n setKilde('skjerm');\n setSteg('skjermbilde');\n } catch {\n setFeil(tekst.skjermbildeFeilet);\n }\n }, [skjermbilde]);\n\n /**\n * «Velg bilde»: vertens velger, ved trykket. Ingen private views — de hører til\n * skjermen bak arket, ikke til et bilde fra et annet sted — og rot-viewen fanges\n * aldri. Avbryter innsenderen, skjer ingenting.\n */\n const velgBilde = useCallback(async () => {\n const pick = skjermbilde?.adapter?.pick;\n if (!pick) return;\n setFeil(undefined);\n try {\n const valgt = await pick.call(skjermbilde.adapter);\n if (!valgt) return;\n setRotStorrelse({ width: valgt.width, height: valgt.height });\n setAutomasker([]);\n setBilde(valgt);\n setKilde('galleri');\n setSteg('skjermbilde');\n } catch {\n setFeil(tekst.bildeFeilet);\n }\n }, [skjermbilde]);\n\n /**\n * «Legg ved og fortsett»: forhåndsvisningen MED maskene fanges på nytt, og det\n * er komposittet som blir vedlegget. Rå-URI-en brukes aldri etter dette.\n */\n const leggVedBilde = useCallback(async () => {\n if (!skjermbilde?.adapter) return;\n setKomponerer(true);\n try {\n const komposit = await skjermbilde.adapter.capture(previewRef, FANGST);\n const body = await skjermbilde.adapter.read(komposit.uri);\n setVedlegg({ mime: 'image/jpeg', body, width: komposit.width, height: komposit.height });\n setBilde(undefined);\n setSteg('felt');\n } catch {\n setFeil(tekst.skjermbildeFeilet);\n setSteg('felt');\n } finally {\n setKomponerer(false);\n }\n }, [skjermbilde]);\n\n const fjernBilde = useCallback(() => {\n setBilde(undefined);\n setAutomasker([]);\n setVedlegg(undefined);\n setSteg('felt');\n }, []);\n\n /**\n * Ett steg tilbake, ALDRI en nullstilling (UX-gjennomgangen C1). Fra feltet er\n * forrige steg kjente feil i feilsporet når det fantes treff — ellers valget.\n * Fram til 2026-09-14 kalte «Tilbake» `nullstill`, og 120 tegn forsvant på ett\n * trykk.\n */\n // F33: et åpent tillegg-felt i «Mine innspill» lukkes FØR arket, og teksten beholdes —\n // samme regel som F1 ga skjemaet. Utkastene per sak bor her, så de overlever lista.\n const mineRef = useRef<MineInnspillHandtak>(null);\n const tilleggUtkast = useRef(new Map<string, string>());\n\n const gaaTilbake = useCallback(() => {\n setFeil(undefined);\n // F3: åpnet verten lista direkte, finnes det ikke noe forrige steg i widgeten.\n if (steg === 'mine') {\n if (mineRef.current?.lukkFelt()) return;\n if (mineDirekte) lukk();\n else setSteg('valg');\n return;\n }\n if (steg === 'skjermbilde') {\n setBilde(undefined);\n setAutomasker([]);\n setSteg('felt');\n return;\n }\n if (steg === 'felt' && spor === 'feil' && kort.length > 0) {\n setSteg('kjenteFeil');\n return;\n }\n setSteg('valg');\n }, [steg, spor, kort.length, mineDirekte, lukk]);\n\n /**\n * Android-tilbake og ESC (`onRequestClose`). Er det et forrige steg, er det «Tilbake»;\n * på første steg lukker den; på kvitteringen er innspillet sendt, og den nullstiller.\n */\n const androidTilbake = useCallback(() => {\n if (steg === 'valg') lukk();\n else if (steg === 'kvittering') lukkOgNullstill();\n else gaaTilbake();\n }, [steg, lukk, lukkOgNullstill, gaaTilbake]);\n\n const send = useCallback(async () => {\n // Ønskesporet sendes rett fra feltet: kontrakten har ingen ønskekort, og steget\n // «Har noen ønsket dette?» kommer tilbake når den har det (DD-03, presisert\n // 2026-09-14 — fram til da gikk Send i ring uten treff).\n setSender(true);\n setFeil(undefined);\n try {\n const res = await client.capture({\n type: spor,\n text: verdi,\n ...(vedlegg ? { attachment: vedlegg } : {}),\n ...(spor === 'feil' && lenketTil ? { relatedKnownIssueId: lenketTil.id } : {}),\n context: fjernetKontekst(client, fjernede, apneOpsjoner?.screen),\n } as never);\n\n if (res.status === 'queued') {\n setKvittering({ art: 'kø', ...(res.attachment ? { vedlegg: 'forkastet' as const } : {}) });\n } else {\n setKvittering({\n art: spor,\n nr: res.submission.number,\n // Kortet får HELE saken: sporingslinjen leser `status`, `createdAt` og\n // `statusChangedAt` derfra — ingen nye felter, ingen ny kontrakt (DD-28).\n sak: res.submission,\n // Tidsløftet i kvitteringen er DATOEN fra svaret, aldri «innen 90 dager» (DD-07, DD-28).\n ...(res.submission.deadlineAt ? { frist: res.submission.deadlineAt } : {}),\n ...(res.attachment?.status === 'failed' ? { vedlegg: 'feilet' as const } : {}),\n });\n }\n setSteg('kvittering');\n // F26: verten får vite at det skjedde — etter kvitteringen, så et kast i vertens\n // kode aldri kan holde innsenderen fra å se at innspillet gikk.\n onSubmitted?.(res.status === 'queued' ? { type: spor, queued: true } : { type: spor, queued: false, id: res.submission.id, number: res.submission.number });\n } catch (e) {\n // Teksten mistes ALDRI: den står i feltet, og årsaken er i klartekst.\n if (e instanceof InnspelQueueFullError) setFeil(e.userMessage);\n else if (e instanceof InnspelApiError) setFeil(e.message);\n else setFeil('tjeneren svarte ikke.');\n } finally {\n setSender(false);\n }\n }, [client, spor, verdi, vedlegg, lenketTil, fjernede, apneOpsjoner?.screen, onSubmitted]);\n\n const jaOgsa = useCallback(\n async (k: KnownIssueCard) => {\n setSender(true);\n try {\n const res = await client.knownIssues.confirm(k.id);\n setKvittering({ art: 'jaOgsa', nr: res.number, sak: res });\n setSteg('kvittering');\n } catch (e) {\n setFeil(e instanceof InnspelApiError ? e.message : 'tjeneren svarte ikke.');\n } finally {\n setSender(false);\n }\n },\n [client],\n );\n\n /** `direkte`: verten åpnet lista (`view: 'mine'`). Ellers kom innsenderen via knappen på valget. */\n const visMine = useCallback(async (direkte = false) => {\n if (direkte) {\n if (stegRef.current !== 'mine') setStegForMine(stegRef.current);\n } else {\n setStegForMine('valg');\n }\n setMineDirekte(direkte);\n setSteg('mine');\n setLasterMine(true);\n try {\n setMine(await client.subjects.submissions());\n } catch {\n setMine([]);\n } finally {\n setLasterMine(false);\n }\n }, [client]);\n\n /** «Send nytt innspill» i lista: til utkastet om det finnes, ellers et nytt skjema. */\n const nyttFraMine = useCallback(() => {\n setMineDirekte(false);\n if (harUtkast) setSteg(stegForMine);\n else nullstill();\n }, [harUtkast, stegForMine, nullstill]);\n\n return (\n <Modal\n visible={synlig}\n transparent\n animationType=\"slide\"\n // Android-tilbake og ESC. Uten den er dialogen en felle (DD-47); med `lukk` direkte\n // kastet den teksten (F1). Den er «Tilbake» så lenge det finnes et forrige steg.\n onRequestClose={androidTilbake}\n accessibilityViewIsModal\n >\n {/* Vinduet krymper ikke lenger for tastaturet på edge-to-edge, så arket løftes\n her. Offseten trekker fra navigasjonslinja: arket har den alt som padding,\n og tastaturet dekker den. */}\n <KeyboardAvoidingView\n behavior=\"padding\"\n keyboardVerticalOffset={-insets.bottom}\n style={{ flex: 1, backgroundColor: tema.color.scrim, justifyContent: 'flex-end', paddingTop: insets.top }}\n >\n <View\n testID=\"innspel-widget\"\n accessibilityViewIsModal\n accessibilityRole=\"none\"\n style={{\n backgroundColor: tema.color.bg,\n borderTopLeftRadius: tema.radius.lg * 2,\n borderTopRightRadius: tema.radius.lg * 2,\n padding: tema.screenPadding,\n paddingBottom: tema.screenPadding + insets.bottom,\n paddingLeft: tema.screenPadding + insets.left,\n paddingRight: tema.screenPadding + insets.right,\n gap: tema.space.md,\n maxHeight: '92%',\n minHeight: '60%',\n // Bildesteget får fast høyde: forhåndsvisningen tilpasses plassen som er igjen, og\n // uten en kjent høyde har den ingen øvre grense (se Skjermbilde.tsx).\n ...(steg === 'skjermbilde' ? { height: '92%' as const } : {}),\n }}\n >\n <View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>\n {steg !== 'valg' && steg !== 'kvittering' ? (\n <Btn variant=\"ghost\" testID=\"tilbake\" ikon=\"arrow-back-outline\" label={tekst.tilbake} onPress={gaaTilbake} />\n ) : (\n <View />\n )}\n <Pressable\n testID=\"lukk\"\n accessibilityRole=\"button\"\n accessibilityLabel={tekst.lukk}\n onPress={steg === 'kvittering' ? lukkOgNullstill : lukk}\n style={{ minWidth: tema.touch, minHeight: tema.touch, alignItems: 'center', justifyContent: 'center' }}\n >\n <Ikon navn=\"close-outline\" farge={tema.color.textSecondary} />\n </Pressable>\n </View>\n\n {feil ? <Banner live ikon=\"warning-outline\" tone=\"danger\" children={tekst.sendefeilBanner(feil)} /> : null}\n {/* `cloud-offline-outline` er samme ikon portalens offline-banner bruker. */}\n {!online && steg !== 'kvittering' && steg !== 'mine' ? (\n <Banner ikon=\"cloud-offline-outline\" tone=\"info\" testID=\"offline-banner\" children={tekst.offlineBanner} />\n ) : null}\n\n {steg === 'valg' ? (\n <>\n <Valg onVelg={velgSpor} anonym={client.isAnonymous} />\n {/* DD-62: med innspill fra før er dette en inngang i foten med tellingen —\n flate, ikke ghost. Anonym: ingen liste, ingen knapp (DD-02). */}\n {!client.isAnonymous ? (\n <View style={{ flex: 1, justifyContent: 'flex-end' }}>\n <Btn\n variant=\"secondary\"\n testID=\"mine-innspill\"\n ikon=\"list-outline\"\n label={mine.length > 0 ? tekst.mineMedAntall(mine.length) : tekst.mineTittel}\n accessibilityLabel={mine.length > 0 ? tekst.mineEtikett(mine.length) : tekst.mineTittel}\n onPress={() => void visMine()}\n />\n </View>\n ) : null}\n </>\n ) : null}\n\n {steg === 'kjenteFeil' ? (\n <KjenteFeil\n kort={kort}\n spor={spor}\n laster={lasterKort}\n sender={sender}\n onJaOgsa={jaOgsa}\n onLigner={(k) => {\n setLenketTil(k);\n setSteg('felt');\n }}\n onNei={() => setSteg('felt')}\n />\n ) : null}\n\n {steg === 'felt' ? (\n <Felt\n spor={spor}\n verdi={verdi}\n onEndre={endreTekst}\n minTextLength={innstillinger.minTextLength}\n textMaxLength={innstillinger.textMaxLength}\n // Åpningsskjermen står i lista innsenderen ser, ikke bare i det som sendes:\n // det hun ikke ser, kan hun ikke fjerne (DD-05, K5). Web-widgeten gjør det\n // samme — RN sendte den ikke i det hele tatt før F23.\n kontekst={{ ...client.context, ...(apneOpsjoner?.screen ? { screen: apneOpsjoner.screen } : {}) }}\n fjernedeFelter={fjernede}\n onFjernKontekst={(f) => setFjernede((x) => [...x, f])}\n {...(lenketTil ? { lenketTil, onFjernLenke: () => setLenketTil(undefined) } : {})}\n funn={funn}\n onSend={send}\n sender={sender}\n harFeil={feil !== undefined}\n offline={!online}\n {...(fangstMulig ? { onSkjermbilde: taSkjermbilde } : {})}\n {...(galleriMulig ? { onVelgBilde: velgBilde } : {})}\n {...(bildeNotat ? { bildeNotat } : {})}\n harVedlegg={vedlegg !== undefined}\n onFjernVedlegg={fjernBilde}\n />\n ) : null}\n\n {steg === 'skjermbilde' && bilde ? (\n <Skjermbilde\n bilde={bilde}\n automaskerRot={automasker}\n rotStorrelse={rotStorrelse}\n previewRef={previewRef}\n komponerer={komponerer}\n kilde={kilde}\n {...(bildeNotat ? { notat: bildeNotat } : {})}\n onFjern={fjernBilde}\n onLeggVed={leggVedBilde}\n />\n ) : null}\n\n {steg === 'kvittering' && kvittering ? (\n <Kvittering\n art={kvittering.art}\n {...(kvittering.nr ? { saksnummer: kvittering.nr } : {})}\n {...(kvittering.vedlegg ? { vedlegg: kvittering.vedlegg } : {})}\n {...(kvittering.frist ? { frist: kvittering.frist } : {})}\n {...(kvittering.sak && kvittering.sak.pending !== true ? { sak: kvittering.sak } : {})}\n {...(tenantName ? { tenantName } : {})}\n anonym={client.isAnonymous}\n onLukk={lukkOgNullstill}\n />\n ) : null}\n\n {steg === 'mine' ? (\n <MineInnspill\n ref={mineRef}\n utkastLager={tilleggUtkast.current}\n storage={client.storage}\n rader={mine}\n laster={lasterMine}\n {...(tenantName ? { tenantName } : {})}\n onNytt={nyttFraMine}\n // DD-69: «Legg til mer» går gjennom kjernen; svaret er den oppdaterte saken,\n // som byttes inn i lista — ingen ny henting.\n leggTil={(id, text) => client.subjects.addAddendum(id, text)}\n onOppdatert={(sak) => setMine((liste) => liste.map((r) => (r.pending !== true && r.id === sak.id ? sak : r)))}\n minTextLength={innstillinger.minTextLength}\n textMaxLength={innstillinger.textMaxLength}\n />\n ) : null}\n </View>\n </KeyboardAvoidingView>\n </Modal>\n );\n}\n\n/**\n * Konteksten uten linjene innsenderen har fjernet (DD-05). Et fjernet felt\n * settes til `undefined` — det er slik kjernen (0.2.1) skiller «fjern» fra\n * «behold fra init»; å bare utelate nøkkelen ville fylt feltet igjen. Feltene\n * er en lukket hviteliste, så det som ikke står i `client.context` finnes ikke\n * å fjerne.\n */\n/**\n * Nettstatus fra verten (`init({ connectivity })`). Uten den er svaret alltid «på nett»:\n * widgeten vet da om nettet først når et kall feiler, og køen tar over (DD-41).\n */\nfunction useNettstatus(client: InnspelClient): boolean {\n const c = client.connectivity;\n const [online, setOnline] = useState(() => c?.isOnline() ?? true);\n useEffect(() => {\n if (!c) return undefined;\n setOnline(c.isOnline());\n return c.subscribe?.((v) => setOnline(v));\n }, [c]);\n return online;\n}\n\n/**\n * Konteksten som sendes med innsendingen: skjermen verten åpnet med, minus det innsenderen\n * har fjernet. Samme form som web-widgeten (F23) — skjermen lå bare i kjente feil-oppslaget\n * her, så panelet fikk «Skjerm —» på hver sak fra appen.\n *\n * `screen` står FØR fjern-logikken med vilje: en fjernet skjermlinje skal bli borte selv om\n * verten åpnet med et skjermnavn (DD-05). Åpningsskjermen er ikke et smutthull.\n */\nfunction fjernetKontekst(client: InnspelClient, fjernede: string[], skjerm: string | undefined) {\n const ut: Record<string, unknown> = {};\n if (skjerm) ut['screen'] = skjerm;\n for (const k of [...Object.keys(client.context), 'screen']) {\n if (k !== 'sdkVersion' && fjernede.includes(k)) ut[k] = undefined;\n }\n return ut;\n}\n","import React from 'react';\nimport { SvgXml } from 'react-native-svg';\nimport { useTema } from './tema.js';\n\nimport addOutline from '../../../node_modules/ionicons/dist/svg/add-outline.svg';\nimport arrowBackOutline from '../../../node_modules/ionicons/dist/svg/arrow-back-outline.svg';\nimport brushOutline from '../../../node_modules/ionicons/dist/svg/brush-outline.svg';\nimport bug from '../../../node_modules/ionicons/dist/svg/bug.svg';\nimport bugOutline from '../../../node_modules/ionicons/dist/svg/bug-outline.svg';\nimport bulb from '../../../node_modules/ionicons/dist/svg/bulb.svg';\nimport calendarOutline from '../../../node_modules/ionicons/dist/svg/calendar-outline.svg';\nimport cameraOutline from '../../../node_modules/ionicons/dist/svg/camera-outline.svg';\nimport chatboxOutline from '../../../node_modules/ionicons/dist/svg/chatbox-outline.svg';\nimport checkmarkCircleOutline from '../../../node_modules/ionicons/dist/svg/checkmark-circle-outline.svg';\nimport checkmarkOutline from '../../../node_modules/ionicons/dist/svg/checkmark-outline.svg';\nimport chevronDownOutline from '../../../node_modules/ionicons/dist/svg/chevron-down-outline.svg';\nimport chevronForwardOutline from '../../../node_modules/ionicons/dist/svg/chevron-forward-outline.svg';\nimport chevronUpOutline from '../../../node_modules/ionicons/dist/svg/chevron-up-outline.svg';\nimport closeCircleOutline from '../../../node_modules/ionicons/dist/svg/close-circle-outline.svg';\nimport closeOutline from '../../../node_modules/ionicons/dist/svg/close-outline.svg';\nimport cloudOfflineOutline from '../../../node_modules/ionicons/dist/svg/cloud-offline-outline.svg';\nimport constructOutline from '../../../node_modules/ionicons/dist/svg/construct-outline.svg';\nimport contrastOutline from '../../../node_modules/ionicons/dist/svg/contrast-outline.svg';\nimport ellipseOutline from '../../../node_modules/ionicons/dist/svg/ellipse-outline.svg';\nimport exitOutline from '../../../node_modules/ionicons/dist/svg/exit-outline.svg';\nimport flaskOutline from '../../../node_modules/ionicons/dist/svg/flask-outline.svg';\nimport gridOutline from '../../../node_modules/ionicons/dist/svg/grid-outline.svg';\nimport hourglassOutline from '../../../node_modules/ionicons/dist/svg/hourglass-outline.svg';\nimport imageOutline from '../../../node_modules/ionicons/dist/svg/image-outline.svg';\nimport imagesOutline from '../../../node_modules/ionicons/dist/svg/images-outline.svg';\nimport listOutline from '../../../node_modules/ionicons/dist/svg/list-outline.svg';\nimport lockClosedOutline from '../../../node_modules/ionicons/dist/svg/lock-closed-outline.svg';\nimport mergeOutline from '../../../node_modules/ionicons/dist/svg/git-merge-outline.svg';\nimport openOutline from '../../../node_modules/ionicons/dist/svg/open-outline.svg';\nimport scanOutline from '../../../node_modules/ionicons/dist/svg/scan-outline.svg';\nimport swapVerticalOutline from '../../../node_modules/ionicons/dist/svg/swap-vertical-outline.svg';\nimport trashOutline from '../../../node_modules/ionicons/dist/svg/trash-outline.svg';\nimport warningOutline from '../../../node_modules/ionicons/dist/svg/warning-outline.svg';\n\n/**\n * Ionicons som inline SVG i React Native. «Emoji brukes aldri i\n * implementasjonen» (brand-ui-guidelines): en emoji tegnes av operativsystemet\n * i sine egne faste farger — den følger verken vertens palett eller temaets\n * ikonmål, den ser ulik ut på iOS og Android, og 🐞 leses opp som «marihøne».\n *\n * Navnene er de SAMME som i `submissionStatus`/`knownIssueStatus` i\n * `theme/theme.ts` (gjennom `src/generated/tokens.ts`), i ikonkartene i\n * `design/wireframes/innsending-widget.jsx` og `betaprogram-tester.jsx`, og i\n * `portal/src/lib/Ikon.tsx` og `panel/src/status/Ikon.tsx` — ett ikonkart for\n * hele produktet, tre rendrere.\n *\n * Stiene går via `node_modules` fordi ioniconss `exports` ikke eksponerer\n * SVG-filene. Strengene INLINES ved bygg av esbuild-lasteren `.svg: text` i\n * `tsup.config.ts`, så pakken får ingen runtime-avhengighet av `ionicons` —\n * bare av `react-native-svg`, som er en peer.\n *\n * **Importen er statisk og uten `try`.** Mangler verten `react-native-svg`,\n * feiler Metro ved bygg med navnet på pakken. Det er riktig sted: et manglende\n * peer skal stoppe bygget, ikke bli til et usynlig ikon i en widget som er i\n * drift. Se «`react-native-svg` som peer i @innspel/react-native» i\n * `docs/tech-decisions.md`.\n */\n\n/**\n * En `<title>` i en SVG leses opp — «Bug» foran teksten — og ikonet er\n * dekorativt: teksten ved siden av bærer meningen (DD-08). Samme stripping som\n * `portal/src/lib/Ikon.tsx` og `panel/src/status/Ikon.tsx`.\n *\n * Ionicons 8.1.0 leverer ingen titler (målt: 0 av 1357 filer), så steget er\n * forebyggende — det finnes fordi en oppgradering som legger dem tilbake ellers\n * ville endret opplesningsrekkefølgen i widgeten uten at noe ble rødt.\n * Eksportert for at testen skal kunne bevise at det faktisk fjerner noe.\n */\nexport const utenTittel = (svg: string) => svg.replace(/<title>[\\s\\S]*?<\\/title>/g, '');\n\nconst IKONER: Record<string, string> = Object.fromEntries(\n Object.entries({\n 'add-outline': addOutline,\n 'arrow-back-outline': arrowBackOutline,\n 'brush-outline': brushOutline,\n // Fylte varianter: bare på sporvalgets to kort (DD-63), der ikonet bærer stemningen.\n bug,\n bulb,\n 'bug-outline': bugOutline,\n 'calendar-outline': calendarOutline,\n 'camera-outline': cameraOutline,\n // «Send» og «Send nytt innspill» — ikonkartet i wireframen (R8.3).\n 'chatbox-outline': chatboxOutline,\n 'checkmark-circle-outline': checkmarkCircleOutline,\n // Haken ALENE: sporingslinjens passerte ledd er allerede en sirkel (R8.3).\n 'checkmark-outline': checkmarkOutline,\n 'chevron-down-outline': chevronDownOutline,\n // Sporvalgets rader peker videre (R8.3, DD-63) — dekorativ, etiketten bærer meningen.\n 'chevron-forward-outline': chevronForwardOutline,\n 'chevron-up-outline': chevronUpOutline,\n 'close-circle-outline': closeCircleOutline,\n 'close-outline': closeOutline,\n 'cloud-offline-outline': cloudOfflineOutline,\n 'construct-outline': constructOutline,\n 'contrast-outline': contrastOutline,\n 'ellipse-outline': ellipseOutline,\n 'exit-outline': exitOutline,\n 'flask-outline': flaskOutline,\n 'git-merge-outline': mergeOutline,\n 'grid-outline': gridOutline,\n 'hourglass-outline': hourglassOutline,\n 'image-outline': imageOutline,\n 'images-outline': imagesOutline,\n 'list-outline': listOutline,\n 'lock-closed-outline': lockClosedOutline,\n 'open-outline': openOutline,\n 'scan-outline': scanOutline,\n 'swap-vertical-outline': swapVerticalOutline,\n 'trash-outline': trashOutline,\n 'warning-outline': warningOutline,\n }).map(([navn, svg]) => [navn, utenTittel(svg)]),\n);\n\n/** Navnene `Ikon` kjenner. Et navn som ikke står her kaster ved rendring, aldri stille. */\nexport const IKONNAVN: readonly string[] = Object.keys(IKONER);\n\n/**\n * Dekorativt ikon — alltid ved siden av tekst, aldri alene. Farge og form\n * bærer ikke mening alene (DD-08), så ikonet er skjult for skjermlesere og\n * teksten sier alt.\n *\n * Målet kommer fra `icon` i temaet, aldri fra et tall her: Ionicons tegner med\n * 6,25 % av boksen, så strektykkelsen følger målet, og `minste` (16) er gulvet\n * der streken treffer 1,00 px. Fargen settes som `color`, som er det\n * `currentColor` i SVG-en løses mot.\n */\nexport function Ikon({\n navn,\n storrelse = 'inline',\n farge,\n}: {\n navn: string;\n /**\n * `minste` i piller, hint og chips · `inline` ved siden av brødtekst · `stor`\n * de to stedene ikonet står ALENE og bærer stemningen: sporvalgets flater og\n * kvitteringen. `stor` er et MULTIPLUM av tokenet, ikke et nytt tall — samme\n * regel som `.innspel-flate-ikon` og `.innspel-kvittering-ikon` på web.\n */\n storrelse?: 'stor' | 'inline' | 'minste';\n /** En farge fra temaet. Uten: `textPrimary`. Aldri en literal. */\n farge?: string;\n}) {\n const tema = useTema();\n const svg = IKONER[navn];\n if (!svg) throw new Error(`[innspel] Ikonet «${navn}» er ikke tatt med i Ikon.tsx.`);\n\n const maal =\n storrelse === 'minste' ? tema.icon.minste : storrelse === 'stor' ? 2 * tema.icon.inline : tema.icon.inline;\n return (\n <SvgXml\n // `testID` er navnet: en test kan da slå fast HVILKET ikon en flate tegner,\n // ikke bare at den tegner ett. @testing-library/react-native v14 har ingen\n // spørring på komponenttype lenger, så uten den ville ikonet vært usynlig i test.\n testID={`ikon-${navn}`}\n xml={svg}\n width={maal}\n height={maal}\n color={farge ?? tema.color.textPrimary}\n // Konturikonene har `fill=\"none\"` og `stroke=\"currentColor\"` selv. De fylte (DD-63)\n // har ingen fill på stiene, og react-native-svg tegner dem da svarte — fargen arves\n // fra rota her, og rører ikke en sti som alt sier «none».\n fill={farge ?? tema.color.textPrimary}\n accessibilityElementsHidden\n importantForAccessibility=\"no\"\n />\n );\n}\n","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M256 112v288M400 256H112\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M244 400 100 256l144-144M120 256h292\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"48px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M452.37 59.63a40.49 40.49 0 0 0-57.26 0L184 294.74c23.08 4.7 46.12 27.29 49.26 49.26l219.11-227.11a40.49 40.49 0 0 0 0-57.26M138 336c-29.88 0-54 24.5-54 54.86 0 23.95-20.88 36.57-36 36.57C64.56 449.74 92.82 464 120 464c39.78 0 72-32.73 72-73.14 0-30.36-24.12-54.86-54-54.86\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M463.55 272.13H400v-48.2q0-4.32-.27-8.47c29.57-27.88 32.25-64.63 32.27-103 0-8.61-6.64-16-15.25-16.41A16 16 0 0 0 400 112c0 28-1.86 48.15-9.9 63.84-19.22-41.15-65.78-63.91-134.1-63.91-39.8 0-74.19 9.13-99.43 26.39-14.9 10.19-26.2 22.91-33.7 37.72C114 160.65 112 141 112 112.46c0-8.61-6.6-16-15.2-16.44A16 16 0 0 0 80 112c0 37.63 2.61 73.73 32.44 101.63q-.43 5.06-.44 10.3v48.2H48.45c-8.61 0-16 6.62-16.43 15.23a16 16 0 0 0 16 16.77h64V320a143.3 143.3 0 0 0 10.39 53.69C96.74 396.64 80.18 422 80 463.34c0 8.74 6.62 16.3 15.36 16.65A16 16 0 0 0 112 464c0-27.66 9.1-44.71 26.17-61.32A144.37 144.37 0 0 0 220 459.42a16 16 0 0 0 20-15.49V192.45c0-8.61 6.62-16 15.23-16.43A16 16 0 0 1 272 192v251.93a16 16 0 0 0 20 15.49 144.4 144.4 0 0 0 81.82-56.74c17 16.54 26.09 33.52 26.17 60.95a16.27 16.27 0 0 0 15.1 16.37A16 16 0 0 0 432 464c0-41.68-16.6-67.23-42.39-90.31A143.3 143.3 0 0 0 400 320v-15.87h64a16 16 0 0 0 16-16.77c-.42-8.61-7.84-15.23-16.45-15.23\"/><path d=\"m321.39 104 .32.09c13.57 3.8 25.07-10.55 18.2-22.85A95.86 95.86 0 0 0 256.21 32h-.42a95.87 95.87 0 0 0-84.19 50.13c-6.84 12.58 5.14 27 18.84 22.86 19.71-6 41.79-9.06 65.56-9.06 24.09 0 46.09 2.72 65.39 8.07\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M370 378c28.89 23.52 46 46.07 46 86M142 378c-28.89 23.52-46 46.06-46 86M384 208c28.89-23.52 32-56.07 32-96M128 206c-28.89-23.52-32-54.06-32-94M464 288.13h-80M128 288.13H48M256 192v256\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><path d=\"M256 448c-70.4 0-128-57.6-128-128v-96.07c0-65.07 57.6-96 128-96h0c70.4 0 128 25.6 128 96V320c0 70.4-57.6 128-128 128\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><path d=\"M179.43 143.52a49.1 49.1 0 0 1-3.43-15.73A80 80 0 0 1 255.79 48h.42A80 80 0 0 1 336 127.79a41.9 41.9 0 0 1-3.12 14.3\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M288 464h-64a16 16 0 0 0 0 32h64a16 16 0 0 0 0-32M304 416h-96a16 16 0 0 0 0 32h96a16 16 0 0 0 0-32M369.42 62.69C339.35 32.58 299.07 16 256 16A159.62 159.62 0 0 0 96 176c0 46.62 17.87 90.23 49 119.64l4.36 4.09C167.37 316.57 192 339.64 192 360v24a16 16 0 0 0 16 16h24a8 8 0 0 0 8-8V274.82a8 8 0 0 0-5.13-7.47A130.7 130.7 0 0 1 208.71 253a16 16 0 1 1 18.58-26c7.4 5.24 21.65 13 28.71 13s21.31-7.78 28.73-13a16 16 0 0 1 18.56 26 130.7 130.7 0 0 1-26.16 14.32 8 8 0 0 0-5.13 7.47V392a8 8 0 0 0 8 8h24a16 16 0 0 0 16-16v-24c0-19.88 24.36-42.93 42.15-59.77l4.91-4.66C399.08 265 416 223.61 416 176a159.16 159.16 0 0 0-46.58-113.31\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><rect width=\"416\" height=\"384\" x=\"48\" y=\"80\" fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"32\" rx=\"48\"/><circle cx=\"296\" cy=\"232\" r=\"24\"/><circle cx=\"376\" cy=\"232\" r=\"24\"/><circle cx=\"296\" cy=\"312\" r=\"24\"/><circle cx=\"376\" cy=\"312\" r=\"24\"/><circle cx=\"136\" cy=\"312\" r=\"24\"/><circle cx=\"216\" cy=\"312\" r=\"24\"/><circle cx=\"136\" cy=\"392\" r=\"24\"/><circle cx=\"216\" cy=\"392\" r=\"24\"/><circle cx=\"296\" cy=\"392\" r=\"24\"/><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M128 48v32M384 48v32\"/><path fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"32\" d=\"M464 160H48\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"m350.54 148.68-26.62-42.06C318.31 100.08 310.62 96 302 96h-92c-8.62 0-16.31 4.08-21.92 10.62l-26.62 42.06C155.85 155.23 148.62 160 140 160H80a32 32 0 0 0-32 32v192a32 32 0 0 0 32 32h352a32 32 0 0 0 32-32V192a32 32 0 0 0-32-32h-59c-8.65 0-16.85-4.77-22.46-11.32\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><circle cx=\"256\" cy=\"272\" r=\"80\" fill=\"none\" stroke=\"currentColor\" stroke-miterlimit=\"10\" stroke-width=\"32px\"/><path d=\"M124 158v-22h-24v22\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M408 64H104a56.16 56.16 0 0 0-56 56v192a56.16 56.16 0 0 0 56 56h40v80l93.72-78.14a8 8 0 0 1 5.13-1.86H408a56.16 56.16 0 0 0 56-56V120a56.16 56.16 0 0 0-56-56Z\" fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M448 256c0-106-86-192-192-192S64 150 64 256s86 192 192 192 192-86 192-192Z\" fill=\"none\" stroke=\"currentColor\" stroke-miterlimit=\"10\" stroke-width=\"32px\"/><path d=\"M352 176 217.6 336 160 272\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M416 128 192 384l-96-96\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"m112 184 144 144 144-144\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"48px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"m184 112 144 144-144 144\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"48px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"m112 328 144-144 144 144\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"48px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M448 256c0-106-86-192-192-192S64 150 64 256s86 192 192 192 192-86 192-192Z\" fill=\"none\" stroke=\"currentColor\" stroke-miterlimit=\"10\" stroke-width=\"32px\"/><path d=\"M320 320 192 192M192 320l128-128\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M368 368 144 144M368 144 144 368\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M93.72 183.25C49.49 198.05 16 233.1 16 288c0 66 54 112 120 112h184.37M467.82 377.74C485.24 363.3 496 341.61 496 312c0-59.82-53-85.76-96-88-8.89-89.54-71-144-144-144-26.16 0-48.79 6.93-67.6 18.14\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><path d=\"M448 448 64 64\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-miterlimit=\"10\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M436.67 184.11a27.17 27.17 0 0 1-38.3 0l-22.48-22.49a27.15 27.15 0 0 1 0-38.29l50.89-50.89a.85.85 0 0 0-.26-1.38C393.68 57 351.09 64.15 324.05 91c-25.88 25.69-27.35 64.27-17.87 98a27 27 0 0 1-7.67 27.14l-173 160.76a40.76 40.76 0 1 0 57.57 57.54l162.15-173.3a27 27 0 0 1 26.77-7.7c33.46 8.94 71.49 7.26 97.07-17.94 27.49-27.08 33.42-74.94 20.1-102.33a.85.85 0 0 0-1.36-.22Z\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-miterlimit=\"10\" stroke-width=\"32px\"/><path d=\"M224 284c-17.48-17-25.49-24.91-31-30.29a18.24 18.24 0 0 1-3.33-21.35 20.8 20.8 0 0 1 3.5-4.62l15.68-15.29a18.7 18.7 0 0 1 5.63-3.87 18.11 18.11 0 0 1 20 3.62c5.45 5.29 15.43 15 33.41 32.52M317.07 291.3c40.95 38.1 90.62 83.27 110 99.41a13.46 13.46 0 0 1 .94 19.92L394.63 444a14 14 0 0 1-20.29-.76c-16.53-19.18-61.09-67.11-99.27-107\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><path d=\"m17.34 193.5 29.41-28.74a4.7 4.7 0 0 1 3.41-1.35 4.85 4.85 0 0 1 3.41 1.35h0a9.86 9.86 0 0 0 8.19 2.77c3.83-.42 7.92-1.6 10.57-4.12 6-5.8-.94-17.23 4.34-24.54a207 207 0 0 1 19.78-22.6c6-5.88 29.84-28.32 69.9-44.45A107.3 107.3 0 0 1 206.67 64c22.59 0 40 10 46.26 15.67a89.5 89.5 0 0 1 10.28 11.64 79 79 0 0 0-9.21-2.77 68.8 68.8 0 0 0-20-1.26c-13.33 1.09-29.41 7.26-38 14-13.9 11-19.87 25.72-20.81 44.71-.68 14.12 2.72 22.1 36.1 55.49a6.6 6.6 0 0 1-.34 9.16l-18.22 18a6.88 6.88 0 0 1-9.54.09c-21.94-21.94-36.65-33.09-45-38.16s-15.07-6.5-18.3-6.85a30.85 30.85 0 0 0-18.27 3.87 11.4 11.4 0 0 0-2.64 2 14.14 14.14 0 0 0 .42 20.08l1.71 1.6a4.63 4.63 0 0 1 0 6.64L71.73 246.6a4.7 4.7 0 0 1-3.41 1.4 4.86 4.86 0 0 1-3.41-1.35l-47.57-46.43a4.88 4.88 0 0 1 0-6.72\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><circle cx=\"256\" cy=\"256\" r=\"208\" fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><path d=\"M256 464c-114.88 0-208-93.12-208-208S141.12 48 256 48Z\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><circle cx=\"256\" cy=\"256\" r=\"192\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M320 176v-40a40 40 0 0 0-40-40H88a40 40 0 0 0-40 40v240a40 40 0 0 0 40 40h192a40 40 0 0 0 40-40v-40M384 176l80 80-80 80M191 256h273\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M176 48h160M118 304h276M208 48v93.48a64.1 64.1 0 0 1-9.88 34.18L73.21 373.49C48.4 412.78 76.63 464 123.08 464h265.84c46.45 0 74.68-51.22 49.87-90.51L313.87 175.66a64.1 64.1 0 0 1-9.87-34.18V48\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-miterlimit=\"10\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><rect width=\"176\" height=\"176\" x=\"48\" y=\"48\" rx=\"20\" ry=\"20\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><rect width=\"176\" height=\"176\" x=\"288\" y=\"48\" rx=\"20\" ry=\"20\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><rect width=\"176\" height=\"176\" x=\"48\" y=\"288\" rx=\"20\" ry=\"20\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><rect width=\"176\" height=\"176\" x=\"288\" y=\"288\" rx=\"20\" ry=\"20\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M145.61 464h220.78c19.8 0 35.55-16.29 33.42-35.06C386.06 308 304 310 304 256s83.11-51 95.8-172.94c2-18.78-13.61-35.06-33.41-35.06H145.61c-19.8 0-35.37 16.28-33.41 35.06C124.89 205 208 201 208 256s-82.06 52-95.8 172.94c-2.14 18.77 13.61 35.06 33.41 35.06\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><path d=\"M343.3 432H169.13c-15.6 0-20-18-9.06-29.16C186.55 376 240 356.78 240 326V224c0-19.85-38-35-61.51-67.2-3.88-5.31-3.49-12.8 6.37-12.8h142.73c8.41 0 10.23 7.43 6.4 12.75C310.82 189 272 204.05 272 224v102c0 30.53 55.71 47 80.4 76.87 9.95 12.04 6.47 29.13-9.1 29.13\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><rect width=\"416\" height=\"352\" x=\"48\" y=\"80\" rx=\"48\" ry=\"48\" fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><circle cx=\"336\" cy=\"176\" r=\"32\" fill=\"none\" stroke=\"currentColor\" stroke-miterlimit=\"10\" stroke-width=\"32px\"/><path d=\"m304 335.79-90.66-90.49a32 32 0 0 0-43.87-1.3L48 352M224 432l123.34-123.34a32 32 0 0 1 43.11-2L464 368\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M432 112V96a48.14 48.14 0 0 0-48-48H64a48.14 48.14 0 0 0-48 48v256a48.14 48.14 0 0 0 48 48h16\" fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><rect width=\"400\" height=\"336\" x=\"96\" y=\"128\" rx=\"45.99\" ry=\"45.99\" fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><ellipse cx=\"372.92\" cy=\"219.64\" rx=\"30.77\" ry=\"30.55\" fill=\"none\" stroke=\"currentColor\" stroke-miterlimit=\"10\" stroke-width=\"32px\"/><path d=\"M342.15 372.17 255 285.78a30.93 30.93 0 0 0-42.18-1.21L96 387.64M265.23 464l118.59-117.73a31 31 0 0 1 41.46-1.87L496 402.91\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M160 144h288M160 256h288M160 368h288\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><circle cx=\"80\" cy=\"144\" r=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><circle cx=\"80\" cy=\"256\" r=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><circle cx=\"80\" cy=\"368\" r=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M336 208v-95a80 80 0 0 0-160 0v95\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><rect width=\"320\" height=\"272\" x=\"96\" y=\"208\" rx=\"48\" ry=\"48\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><circle cx=\"129\" cy=\"96\" r=\"48\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><circle cx=\"129\" cy=\"416\" r=\"48\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><path d=\"M129 144v224\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><circle cx=\"385\" cy=\"288\" r=\"48\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><path d=\"M129 144c0 96 112 144 208 144\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M384 224v184a40 40 0 0 1-40 40H104a40 40 0 0 1-40-40V168a40 40 0 0 1 40-40h167.48M336 64h112v112M224 288 440 72\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M336 448h56a56 56 0 0 0 56-56v-56M448 176v-56a56 56 0 0 0-56-56h-56M176 448h-56a56 56 0 0 1-56-56v-56M64 176v-56a56 56 0 0 1 56-56h56\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M464 208 352 96 240 208M352 113.13V416M48 304l112 112 112-112M160 398V96\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"m112 112 20 320c.95 18.49 14.4 32 32 32h184c17.67 0 30.87-13.51 32-32l20-320\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><path d=\"M80 112h352\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-miterlimit=\"10\" stroke-width=\"32px\"/><path d=\"M192 112V72h0a23.93 23.93 0 0 1 24-24h80a23.93 23.93 0 0 1 24 24h0v40M256 176v224M184 176l8 224M328 176l-8 224\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/></svg>","<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M85.57 446.25h340.86a32 32 0 0 0 28.17-47.17L284.18 82.58c-12.09-22.44-44.27-22.44-56.36 0L57.4 399.08a32 32 0 0 0 28.17 47.17\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><path d=\"m250.26 195.39 5.74 122 5.73-121.95a5.74 5.74 0 0 0-5.79-6h0a5.74 5.74 0 0 0-5.68 5.95\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"32px\"/><path fill=\"currentColor\" d=\"M256 397.25a20 20 0 1 1 20-20 20 20 0 0 1-20 20\"/></svg>","import type { ContextInput, KnownIssueCard, PatternFinding } from '@innspel/core';\nimport React, { useMemo, useState } from 'react';\nimport { Pressable, ScrollView, Text, TextInput, View } from 'react-native';\nimport { Ikon } from '../Ikon.js';\nimport { useTema } from '../tema.js';\nimport { Btn, H, Hint, Meta, Tekstknapp } from './primitiver.js';\nimport { kontekstVerdi, tekst } from './tekster.js';\n\n/**\n * 2d + 2e — feltet og kontekstlinja. Ett felt, ingenting annet.\n *\n * DD-44: send er inaktiv under `minTextLength` (standard 10), og det er det\n * ENESTE kravet. Ingen kategori, ingen alvorlighet, ingen reproduksjonsfelt.\n * 2h i wireframen er ikke en skjerm — den er fraværet av felter her.\n *\n * DD-45: placeholderen stiller to spørsmål i feilsporet.\n *\n * DD-46: mønstervarselet vises FØR sending og fjerner aldri noe selv.\n * «Fjern» og «Behold» er innsenderens valg; teksten endres bare ved «Fjern».\n *\n * DD-05: konteksten er synlig og kan fjernes linje for linje. Den er en lukket\n * hviteliste (K5) — det som ikke står der, finnes ikke å fjerne.\n */\nexport function Felt({\n spor,\n verdi,\n onEndre,\n minTextLength,\n textMaxLength,\n kontekst,\n fjernedeFelter,\n onFjernKontekst,\n lenketTil,\n onFjernLenke,\n funn,\n onSend,\n sender,\n harFeil,\n offline,\n onSkjermbilde,\n onVelgBilde,\n bildeNotat,\n harVedlegg,\n onFjernVedlegg,\n}: {\n spor: 'feil' | 'onske';\n verdi: string;\n onEndre: (v: string) => void;\n minTextLength: number;\n textMaxLength: number;\n kontekst: ContextInput & { sdkVersion: string };\n fjernedeFelter: string[];\n onFjernKontekst: (felt: string) => void;\n lenketTil?: KnownIssueCard;\n onFjernLenke?: () => void;\n funn: PatternFinding[];\n onSend: () => void;\n sender?: boolean;\n /** Forrige sending feilet: knappen heter «Prøv igjen» til neste forsøk (C7). */\n harFeil?: boolean;\n /** Verten har meldt at nettet er nede (`init({ connectivity })`): knappen heter «Lagre — sendes når du er på nett». */\n offline?: boolean;\n /**\n * «Legg ved skjermbilde» (2f, K4). Utelatt = steget finnes ikke (DD-26): leietakeren\n * har skjermbilde av, eller verten ga ingen adapter. Aldri en deaktivert knapp.\n */\n onSkjermbilde?: () => void;\n /** «Velg bilde» fra galleriet. Utelatt = valget finnes ikke; samme regel som over. */\n onVelgBilde?: () => void;\n /** Vertens setning ved bildesteget (`imageStepNote`). Leietakeren eier den, ikke plattformen. */\n bildeNotat?: string;\n /** Et maskert skjermbilde ligger klart og sendes etter teksten (DD-42). */\n harVedlegg?: boolean;\n onFjernVedlegg?: () => void;\n}) {\n const tema = useTema();\n const [apen, setApen] = useState(false);\n const [beholdt, setBeholdt] = useState<string[]>([]);\n\n const brukt = verdi.length;\n const forKort = brukt < minTextLength;\n const full = brukt >= textMaxLength;\n // Telleren dukker opp ved 80 % — ikke før. En teller fra første tegn gjør\n // lengden til oppgaven i stedet for innholdet.\n const visTeller = brukt >= textMaxLength * 0.8;\n\n const uavklart = funn.find((f) => !beholdt.includes(f.match));\n\n // Lista er LUKKET (K5): det som ikke står her, finnes ikke å sende. Etikettene er\n // portalens — samme felt, samme ord i begge flater — og verdiene er ORD, ikke koder\n // (DD-50, presisert 2026-09-20). Verdien som SENDES er uendret.\n const linjer = useMemo(\n () =>\n Object.entries(tekst.kontekstEtiketter)\n .map(([felt, etikett]) => {\n const rå = (kontekst as unknown as Record<string, string | undefined>)[felt];\n return rå && !fjernedeFelter.includes(felt) ? { felt, etikett, verdi: kontekstVerdi(felt, rå) } : null;\n })\n .filter((x): x is { felt: string; etikett: string; verdi: string } => x !== null),\n [kontekst, fjernedeFelter],\n );\n\n // Kroppen scroller og Send står fast under den. Arket har bare maxHeight, så\n // uten scrollflate tegnet et høyt skjema (utvidet kontekst) forbi bunnpaddingen\n // og Send havnet under navigasjonslinja. Roten er flexGrow/flexShrink, ikke\n // flex: 1 — den gir flexBasis 0, og arket ville aldri vokst forbi minHeight.\n return (\n <View testID=\"skjema\" style={{ flexGrow: 1, flexShrink: 1, gap: tema.space.md }}>\n <ScrollView\n testID=\"skjema-kropp\"\n style={{ flexGrow: 0, flexShrink: 1 }}\n contentContainerStyle={{ gap: tema.space.md }}\n keyboardShouldPersistTaps=\"handled\"\n >\n {lenketTil ? (\n <View\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n gap: tema.space.sm,\n minHeight: tema.touch,\n borderWidth: tema.hairline,\n borderColor: tema.color.borderInteractive,\n borderRadius: tema.radius.pill,\n paddingLeft: tema.space.md,\n paddingRight: tema.space.xs,\n }}\n >\n <Text style={{ flex: 1, color: tema.color.textPrimary, fontSize: tema.font.small }}>\n {tekst.lenketTil(lenketTil.title)}\n </Text>\n <Pressable\n testID=\"fjern-lenke\"\n accessibilityRole=\"button\"\n accessibilityLabel={tekst.fjernLenke}\n onPress={onFjernLenke}\n style={{ minWidth: tema.touch, minHeight: tema.touch, alignItems: 'center', justifyContent: 'center' }}\n >\n <Ikon navn=\"close-outline\" farge={tema.color.textSecondary} />\n </Pressable>\n </View>\n ) : null}\n\n {uavklart ? (\n <View\n style={{\n gap: tema.space.sm,\n backgroundColor: tema.color.warningBg,\n borderRadius: tema.radius.md,\n padding: tema.space.md,\n }}\n >\n <Text\n accessibilityRole=\"alert\"\n accessibilityLiveRegion=\"polite\"\n style={{\n color: tema.color.warning,\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n fontWeight: tema.weight.medium,\n }}\n >\n {tekst.monsterSpm[uavklart.kind]}\n </Text>\n <View style={{ flexDirection: 'row', gap: tema.space.sm }}>\n <Btn\n grow\n variant=\"secondary\"\n testID=\"monster-fjern\"\n label={tekst.monsterFjern}\n onPress={() => onEndre(verdi.slice(0, uavklart.start) + verdi.slice(uavklart.end))}\n />\n <Btn\n grow\n variant=\"ghost\"\n testID=\"monster-behold\"\n label={tekst.monsterBehold}\n onPress={() => setBeholdt((b) => [...b, uavklart.match])}\n />\n </View>\n <Hint>{tekst.monsterForklaring}</Hint>\n </View>\n ) : null}\n\n <H>{spor === 'onske' ? tekst.feltLabelOnske : tekst.feltLabelFeil}</H>\n\n <TextInput\n testID=\"innspill-tekst\"\n accessibilityLabel={spor === 'onske' ? tekst.feltLabelOnske : tekst.feltLabelFeil}\n value={verdi}\n onChangeText={onEndre}\n maxLength={textMaxLength}\n multiline\n numberOfLines={4}\n placeholder={spor === 'onske' ? tekst.placeholderOnske : tekst.placeholderFeil}\n placeholderTextColor={tema.color.textMuted}\n style={{\n backgroundColor: tema.color.surfaceRaised,\n borderWidth: tema.hairline,\n borderColor: full ? tema.color.warning : tema.color.borderStrong,\n borderRadius: tema.radius.md,\n padding: tema.space.md,\n color: tema.color.textPrimary,\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n minHeight: tema.touch * 2,\n textAlignVertical: 'top',\n }}\n />\n\n {visTeller ? (\n <Text\n testID=\"teller\"\n accessibilityLiveRegion={full ? 'assertive' : 'polite'}\n style={{\n alignSelf: 'flex-end',\n color: full ? tema.color.warning : tema.color.textMuted,\n fontSize: tema.font.small,\n }}\n >\n {brukt} / {textMaxLength}\n {full ? tekst.tellerFull : ''}\n </Text>\n ) : null}\n\n {/* 2f — opt-in per innsending. Bildet tas først ved trykk (K4). */}\n {harVedlegg ? (\n <View\n testID=\"vedlegg-chip\"\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n gap: tema.space.sm,\n minHeight: tema.touch,\n borderWidth: tema.hairline,\n borderColor: tema.color.borderInteractive,\n borderRadius: tema.radius.pill,\n paddingLeft: tema.space.md,\n paddingRight: tema.space.xs,\n }}\n >\n <Ikon navn=\"image-outline\" storrelse=\"minste\" farge={tema.color.textPrimary} />\n <Text style={{ flex: 1, color: tema.color.textPrimary, fontSize: tema.font.small }}>{tekst.bildeLagtVed}</Text>\n <Pressable\n testID=\"fjern-vedlegg\"\n accessibilityRole=\"button\"\n accessibilityLabel={tekst.fjernSkjermbilde}\n onPress={onFjernVedlegg}\n style={{ minWidth: tema.touch, minHeight: tema.touch, alignItems: 'center', justifyContent: 'center' }}\n >\n <Ikon navn=\"close-outline\" farge={tema.color.textSecondary} />\n </Pressable>\n </View>\n ) : onSkjermbilde || onVelgBilde ? (\n // F7 (brukerreisene 2026-09-15): knappene har ingen egen hjelpetekst. Web-widgeten\n // har aldri hatt det, og Følget sender sin egen setning som `imageStepNote` — med\n // pakkens hint i tillegg sto det tre tekster under to knapper. Løftet om at bildet\n // tas ved trykk og kan maskeres står i selve steget (Skjermbilde), der det gjelder.\n <View style={{ gap: tema.space.sm }}>\n {onSkjermbilde ? (\n <Btn\n variant=\"secondary\"\n testID=\"legg-ved-skjermbilde\"\n ikon=\"camera-outline\"\n label={tekst.leggVedSkjermbilde}\n onPress={onSkjermbilde}\n />\n ) : null}\n {onVelgBilde ? (\n <Btn\n variant=\"secondary\"\n testID=\"velg-bilde\"\n ikon=\"images-outline\"\n label={tekst.velgBilde}\n onPress={onVelgBilde}\n />\n ) : null}\n {bildeNotat ? (\n <View testID=\"bilde-notat\">\n <Hint>{bildeNotat}</Hint>\n </View>\n ) : null}\n </View>\n ) : null}\n\n {/*\n 2e — LUKKET i arket (DD-05 ordrett: «Én linje «Vis» under feltet ekspanderer»).\n Portalens «alltid åpen» er PORTALENS presisering av samme DD: arket er lavt,\n tastaturet tar halve skjermen, og seks rader på 48 px skyver feltet ut av syne.\n Lukket er linja en OPPSUMMERING — den navngir det innsenderen kjenner igjen, og\n lista er hele sannheten.\n */}\n <View style={{ borderTopWidth: tema.hairline, borderTopColor: tema.color.border, paddingTop: tema.space.xs }}>\n <Pressable\n testID=\"kontekst-bryter\"\n accessibilityRole=\"button\"\n accessibilityState={{ expanded: apen }}\n onPress={() => setApen((a) => !a)}\n style={{ minHeight: tema.touch, flexDirection: 'row', alignItems: 'center', gap: tema.space.sm }}\n >\n {/* Ikonet er et eget element, ikke et tegn i teksten: en SVG kan ikke\n ligge inne i en `Text` i React Native. */}\n <Ikon\n navn={apen ? 'chevron-up-outline' : 'chevron-down-outline'}\n storrelse=\"minste\"\n farge={tema.color.textSecondary}\n />\n <Text style={{ flex: 1, color: tema.color.textSecondary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }}>\n {apen ? tekst.kontekstLinjeApen : tekst.kontekstLinjeLukket}\n </Text>\n {/* «Vis»/«Skjul» er handlingen i linja, ikke etiketten — merkefargen (R8.4). */}\n <Text style={{ color: tema.color.actionText, fontSize: tema.font.body, fontWeight: tema.weight.semibold }}>\n {apen ? tekst.kontekstSkjul : tekst.kontekstVis}\n </Text>\n </Pressable>\n\n {apen ? (\n <View>\n {linjer.map((l) => (\n <View\n key={l.felt}\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n gap: tema.space.md,\n minHeight: tema.touch,\n borderTopWidth: tema.hairline,\n borderTopColor: tema.color.border,\n }}\n >\n {/* Etiketten er `small`; VERDIEN er `body` halvfet (DD-67). */}\n <Meta testID={`kontekst-etikett-${l.felt}`}>{l.etikett}</Meta>\n <View style={{ flex: 1, minWidth: 0 }}>\n <Text\n testID={`kontekst-verdi-${l.felt}`}\n style={{ color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body, fontWeight: tema.weight.semibold }}\n >\n {l.verdi}\n </Text>\n </View>\n {/* Hver linje er ETT hvitelistefelt og kan fjernes alene (DD-05, K5). */}\n <Tekstknapp\n testID={`fjern-${l.felt}`}\n ikon=\"close-outline\"\n label={tekst.kontekstFjern}\n accessibilityLabel={tekst.kontekstFjernA11y(l.etikett)}\n onPress={() => onFjernKontekst(l.felt)}\n />\n </View>\n ))}\n {/* K5 — skjermens ene hjelpesetning, og bare når lista står. */}\n <View style={{ paddingTop: tema.space.sm }}>\n <Hint>{tekst.kontekstAldri}</Hint>\n </View>\n </View>\n ) : null}\n </View>\n\n </ScrollView>\n\n <View testID=\"skjema-fot\" style={{ flexGrow: 1, flexShrink: 0, justifyContent: 'flex-end' }}>\n <Btn\n testID=\"send\"\n label={sender ? tekst.sender : harFeil ? tekst.provIgjen : offline ? tekst.offlineLagre : tekst.send}\n disabled={forKort || sender}\n busy={sender}\n hint={forKort ? tekst.forKort(minTextLength) : harVedlegg ? tekst.sendHintMedBilde : undefined}\n onPress={onSend}\n // F10: tastaturet er oppe når Send trykkes. En ScrollView i vertens tre over\n // provideren kan ta første trykk — det skal likevel sende.\n trykkForbiForelder\n />\n </View>\n </View>\n );\n}\n","import React, { useMemo, useRef } from 'react';\nimport { Pressable, Text, View, type GestureResponderEvent, type StyleProp, type ViewStyle } from 'react-native';\nimport { Ikon } from '../Ikon.js';\nimport { useTema } from '../tema.js';\n\n/**\n * Primitivene widgeten er bygget av. Alt visuelt kommer fra tema-tokens —\n * ingen hex, ingen px, ingen fontstørrelse skrives her (CLAUDE.md, «Styling»).\n *\n * Minste trykkflate er `skala.touch` (48). Den er ikke en anbefaling: den er\n * grønt-kriterium for widgeten, og en knapp under målet er en feil.\n *\n * `ikon` er alltid et IONICONS-NAVN, aldri en emoji (brand-ui-guidelines,\n * UX-gjennomgangen C3). Navnene står i `src/Ikon.tsx`, og et ukjent navn kaster.\n */\n\n/**\n * `tonet` er DD-63s par `brandBg`/`brand`: et valg som ikke er skjermens primærhandling, men\n * som sparer innsenderen for arbeid («Ja, jeg også», «Gjort» per oppgave). ALDRI\n * `actionPrimary` — da blir tre like spørsmål tre primærknapper (DD-58, F32).\n */\ntype Variant = 'primary' | 'secondary' | 'ghost' | 'danger' | 'tonet';\n\nexport function Btn({\n label,\n onPress,\n variant = 'primary',\n ikon,\n hint,\n disabled,\n accessibilityLabel,\n grow,\n testID,\n busy,\n trykkForbiForelder,\n}: {\n label: string;\n onPress?: () => void;\n variant?: Variant;\n ikon?: string;\n hint?: string;\n disabled?: boolean;\n accessibilityLabel?: string;\n grow?: boolean;\n testID?: string;\n /** Handlingen pågår: `busy` i tilstanden, så skjermleseren hører at knappen jobber, ikke bare at den er låst. */\n busy?: boolean;\n /**\n * Trykket teller selv om en FORELDER i vertens tre tok responderen (F10). Se\n * {@link useTrykkForbiForelder}. Brukes på Send, der et tapt trykk er et innspill som\n * ikke ble sendt.\n */\n trykkForbiForelder?: boolean;\n}) {\n const tema = useTema();\n const c = tema.color;\n const forbi = useTrykkForbiForelder(onPress, !!disabled, tema.touch / 2);\n\n const bakgrunn =\n variant === 'primary' ? c.actionPrimary : variant === 'tonet' ? c.brandBg : variant === 'secondary' ? c.surfaceRaised : 'transparent';\n const tekstfarge =\n variant === 'primary' ? c.onActionPrimary\n : variant === 'tonet' ? c.brand\n : variant === 'danger' ? c.danger\n : c.actionSecondaryText;\n const kant =\n variant === 'ghost' || variant === 'tonet' ? 'transparent' : variant === 'primary' ? c.actionPrimary : c.actionSecondaryBorder;\n\n return (\n <View style={grow ? { flex: 1 } : undefined}>\n <Pressable\n testID={testID}\n accessibilityRole=\"button\"\n // Hintet er synlig tekst OG del av etiketten: en skjermleserbruker skal\n // få vite hvorfor knappen er inaktiv uten å lete etter teksten under.\n accessibilityLabel={accessibilityLabel ?? (hint ? `${label}. ${hint}` : label)}\n accessibilityState={{ disabled: !!disabled, busy: !!busy }}\n disabled={disabled}\n onPress={onPress}\n {...(trykkForbiForelder ? forbi : {})}\n style={{\n minHeight: tema.touch,\n borderRadius: tema.radius.md,\n borderWidth: tema.hairline,\n borderColor: kant,\n backgroundColor: disabled ? c.surface : bakgrunn,\n paddingHorizontal: tema.space.md,\n alignItems: 'center',\n justifyContent: 'center',\n flexDirection: 'row',\n gap: tema.space.sm,\n opacity: disabled ? 0.6 : 1,\n }}\n >\n {ikon ? <Ikon navn={ikon} farge={disabled ? c.textDisabled : tekstfarge} /> : null}\n <Text\n style={{\n color: disabled ? c.textDisabled : tekstfarge,\n fontSize: tema.font.body,\n fontWeight: tema.weight.semibold,\n }}\n >\n {label}\n </Text>\n </Pressable>\n {hint ? <Hint>{hint}</Hint> : null}\n </View>\n );\n}\n\n/**\n * Et trykk som ender på knappen, teller — også når knappen aldri fikk responderen (F10).\n *\n * React Natives responder-system spør forfedrene i REACT-treet, ytterst først, i\n * capture-fasen (`traverseTwoPhase` over `fiber.return` i renderen). Modalen er et eget\n * vindu på Android, men i React-treet står den der verten plasserte provideren. Står den i\n * en `ScrollView` med `keyboardShouldPersistTaps` på `'never'` (standard), tar den\n * ScrollView-en trykket mens tastaturet er oppe og slipper det med `blurTextInput`\n * (`_handleStartShouldSetResponderCapture` i ScrollView.js). Pressable-en får aldri\n * `onResponderGrant`, og `onPress` kalles aldri: første trykk lukker bare tastaturet.\n *\n * Widgeten kan ikke vinne capture-fasen over en forelder. Men `onTouchStart`/`onTouchEnd`\n * sendes av `ReactNativeBridgeEventPlugin` til målet uavhengig av hvem som er responder.\n * Et trykk som endte innenfor `slingring` av der det startet, uten at `onPressIn` kom,\n * kalles derfor som `onPress` — etter at responder-hendelsene for samme trykk er\n * ferdige, så et vanlig trykk aldri teller to ganger. En låst knapp trykkes aldri.\n */\nfunction useTrykkForbiForelder(onPress: (() => void) | undefined, laast: boolean, slingring: number) {\n const start = useRef<{ x: number; y: number } | null>(null);\n const fikkResponder = useRef(false);\n // Siste verdier leses i timeouten, ikke verdiene fra renderen trykket startet i.\n const siste = useRef({ onPress, laast });\n siste.current = { onPress, laast };\n\n return useMemo(\n () => ({\n onPressIn: () => {\n fikkResponder.current = true;\n },\n onTouchStart: (e: GestureResponderEvent) => {\n start.current = { x: e.nativeEvent.pageX, y: e.nativeEvent.pageY };\n },\n onTouchEnd: (e: GestureResponderEvent) => {\n const s = start.current;\n start.current = null;\n const innenfor =\n s !== null &&\n Math.abs(e.nativeEvent.pageX - s.x) <= slingring &&\n Math.abs(e.nativeEvent.pageY - s.y) <= slingring;\n setTimeout(() => {\n const tatt = fikkResponder.current;\n fikkResponder.current = false;\n if (!tatt && innenfor && !siste.current.laast) siste.current.onPress?.();\n }, 0);\n },\n onTouchCancel: () => {\n start.current = null;\n fikkResponder.current = false;\n },\n }),\n [slingring],\n );\n}\n\n/**\n * Overskriften. `sub` er INGRESSEN og står i `body` (DD-67, presisert 2026-09-20) — ikke i\n * `small`: det er ikke en hjelpetekst, det er hva skjermen handler om. Trenger en flate en\n * meta-linje i `small` under overskriften, er det {@link Meta}, ikke `sub`.\n */\nexport function H({\n children,\n sub,\n meta,\n nivaa = 2,\n testID,\n}: {\n children: string;\n sub?: string;\n meta?: string;\n nivaa?: 2 | 3;\n testID?: string;\n}) {\n const tema = useTema();\n return (\n /*\n * `ark-tittel` er ETT fast punkt i arket, likt i hvert steg (#304): iOS-flytene lukker\n * tastaturet med et trykk på tomt område fordi Maestros `hideKeyboard` ikke finnes der,\n * og det var settets eneste koordinatavhengige linje. Bare skjermens EGEN overskrift\n * (`nivaa` 2) får den — en overskrift inne i et kort eller en dialog er `nivaa` 3, og to\n * like testID-er på skjermen gjør flyten tvetydig. Den valgfrie `testID` står fortsatt\n * på teksten, så ingen eksisterende flyt eller test flytter seg.\n */\n <View testID={nivaa === 2 ? 'ark-tittel' : undefined} style={{ gap: tema.space.xs }}>\n <Text\n testID={testID}\n accessibilityRole=\"header\"\n style={{\n color: tema.color.textPrimary,\n fontSize: nivaa === 2 ? tema.font.h2 : tema.font.h3,\n lineHeight: nivaa === 2 ? tema.lineHeight.h2 : tema.lineHeight.h3,\n fontWeight: tema.weight.bold,\n }}\n >\n {children}\n </Text>\n {sub ? <Sek>{sub}</Sek> : null}\n {meta ? <Meta>{meta}</Meta> : null}\n </View>\n );\n}\n\n/** Brødtekst — standarden (DD-67). Alt innsenderen avgjør på er dette eller større. */\nexport function Brodtekst({ children, testID }: { children: React.ReactNode; testID?: string }) {\n const tema = useTema();\n return (\n <Text\n testID={testID}\n style={{ color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }}\n >\n {children}\n </Text>\n );\n}\n\n/** Brødtekst i sekundærfargen — ingressen, omveien, løftet. Fortsatt `body`. */\nexport function Sek({ children, testID }: { children: React.ReactNode; testID?: string }) {\n const tema = useTema();\n return (\n <Text\n testID={testID}\n style={{ color: tema.color.textSecondary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }}\n >\n {children}\n </Text>\n );\n}\n\n/**\n * Skjermens HELT: det ene tallet eller den ene setningen innsenderen kom for (DD-67).\n * `h1` er den største størrelsen widgeten bruker — `display` er panelets.\n */\nexport function Helt({\n children,\n testID,\n farge,\n live,\n}: {\n children: React.ReactNode;\n testID?: string;\n farge?: string;\n /** Kvitteringens helt leses opp alene, uten at hele kortet gjentas (DD-47). */\n live?: boolean;\n}) {\n const tema = useTema();\n return (\n <Text\n testID={testID}\n {...(live ? { accessibilityRole: 'alert' as const, accessibilityLiveRegion: 'polite' as const } : {})}\n style={{\n color: farge ?? tema.color.textPrimary,\n fontSize: tema.font.h1,\n lineHeight: tema.lineHeight.h1,\n fontWeight: tema.weight.bold,\n }}\n >\n {children}\n </Text>\n );\n}\n\n/** ÉN meta-linje per rad, i `small` — det er nettopp det `small` er til (DD-67). */\nexport function Meta({ children, testID, farge }: { children: React.ReactNode; testID?: string; farge?: string }) {\n const tema = useTema();\n return (\n <Text\n testID={testID}\n style={{ color: farge ?? tema.color.textMuted, fontSize: tema.font.small, lineHeight: tema.lineHeight.small }}\n >\n {children}\n </Text>\n );\n}\n\n/**\n * En handling uten flate. Trykkflaten er `touch` selv om teksten er lavere.\n *\n * Standardfargen er `actionText` — merkefargen (R8.4). Uten flate og uten ramme er fargen\n * ALT som skiller knappen fra teksten rundt, og fram til 2026-09-20 sto den i\n * `actionSecondaryText`, som i lys palett er identisk med `textPrimary`: «Ligner, men ikke\n * helt» leste da som brødtekst ved siden av den tonede «Ja, jeg også» (R8.3-noten punkt 4).\n *\n * `noytral` gir tekstfargen, for «Gå ut av programmet» og andre handlinger som ikke er\n * forslag — den røde er dialogen (DD-53).\n */\nexport function Tekstknapp({\n label,\n ikon,\n onPress,\n noytral,\n disabled,\n testID,\n accessibilityLabel,\n}: {\n label: string;\n ikon?: string;\n onPress?: () => void;\n noytral?: boolean;\n disabled?: boolean;\n testID?: string;\n accessibilityLabel?: string;\n}) {\n const tema = useTema();\n const farge = disabled ? tema.color.textDisabled : noytral ? tema.color.textPrimary : tema.color.actionText;\n return (\n <Pressable\n testID={testID}\n accessibilityRole=\"button\"\n accessibilityLabel={accessibilityLabel ?? label}\n accessibilityState={{ disabled: !!disabled }}\n disabled={disabled}\n onPress={onPress}\n style={{\n alignSelf: 'flex-start',\n minHeight: tema.touch,\n flexDirection: 'row',\n alignItems: 'center',\n gap: tema.space.sm,\n }}\n >\n {ikon ? <Ikon navn={ikon} storrelse=\"minste\" farge={farge} /> : null}\n <Text style={{ color: farge, fontSize: tema.font.body, fontWeight: tema.weight.semibold }}>{label}</Text>\n </Pressable>\n );\n}\n\n/**\n * Merkelappen «Nytt svar» (F14). `small`, ikke `tiny`: `tiny` finnes ikke i widgeten\n * (DD-67, presisert 2026-09-20).\n */\nexport function Pille({ children, testID }: { children: React.ReactNode; testID?: string }) {\n const tema = useTema();\n return (\n <Text\n testID={testID}\n style={{\n color: tema.color.info,\n backgroundColor: tema.color.infoBg,\n fontSize: tema.font.small,\n lineHeight: tema.lineHeight.small,\n fontWeight: tema.weight.semibold,\n borderRadius: tema.radius.pill,\n paddingHorizontal: tema.space.sm,\n overflow: 'hidden',\n }}\n >\n {children}\n </Text>\n );\n}\n\nexport function Hint({ children }: { children: React.ReactNode }) {\n const tema = useTema();\n return (\n <Text\n style={{\n color: tema.color.textMuted,\n fontSize: tema.font.small,\n lineHeight: tema.lineHeight.small,\n }}\n >\n {children}\n </Text>\n );\n}\n\nexport function Card({\n children,\n dashed,\n style,\n testID,\n accessibilityLabel,\n}: {\n children: React.ReactNode;\n dashed?: boolean;\n style?: StyleProp<ViewStyle>;\n testID?: string;\n accessibilityLabel?: string;\n}) {\n const tema = useTema();\n return (\n <View\n testID={testID}\n {...(accessibilityLabel ? { accessibilityLabel } : {})}\n style={[\n {\n backgroundColor: tema.color.surface,\n borderRadius: tema.radius.lg,\n borderWidth: tema.hairline,\n borderColor: tema.color.border,\n borderStyle: dashed ? 'dashed' : 'solid',\n padding: tema.space.md,\n gap: tema.space.sm,\n },\n style,\n ]}\n >\n {children}\n </View>\n );\n}\n\n/**\n * Status som ikon + etikett. Fargen er et TILLEGG, aldri bæreren: to av\n * palettens statusfarger er målt til under 1,5 i innbyrdes kontrast, så\n * etiketten er det som faktisk skiller dem (DD-08).\n */\nexport function StatusPill({\n ikon,\n etikett,\n fg,\n bg,\n testID,\n}: {\n ikon: string;\n etikett: string;\n fg: string;\n bg: string;\n testID?: string;\n}) {\n const tema = useTema();\n // `fg`/`bg` er TOKENNAVN fra theme.ts, ikke farger: samme mappe virker i begge\n // paletter og i vertens eget tema (DD-21).\n const farge = (navn: string, reserve: string) => (tema.color as Record<string, string>)[navn] ?? reserve;\n return (\n <View\n testID={testID}\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n gap: tema.space.xs,\n alignSelf: 'flex-start',\n paddingHorizontal: tema.space.sm,\n paddingVertical: tema.space.xs,\n borderRadius: tema.radius.pill,\n backgroundColor: farge(bg, tema.color.neutralBg),\n }}\n >\n <Ikon navn={ikon} storrelse=\"minste\" farge={farge(fg, tema.color.textSecondary)} />\n <Text style={{ color: farge(fg, tema.color.textSecondary), fontSize: tema.font.small, fontWeight: tema.weight.medium }}>\n {etikett}\n </Text>\n </View>\n );\n}\n\n/**\n * Varsel. Rollen ligger på `Text`, ikke på containeren: `accessible` på en\n * container sluker barna som egne fokusstopp (`tdd-contract-validation`).\n */\nexport function Banner({\n ikon,\n tone,\n children,\n live,\n testID,\n}: {\n ikon: string;\n tone: 'info' | 'warning' | 'danger' | 'success';\n children: string;\n live?: boolean;\n testID?: string;\n}) {\n const tema = useTema();\n return (\n <View\n testID={testID}\n style={{\n flexDirection: 'row',\n gap: tema.space.sm,\n backgroundColor: tema.color[`${tone}Bg` as keyof typeof tema.color],\n borderRadius: tema.radius.md,\n padding: tema.space.md,\n }}\n >\n <Ikon navn={ikon} farge={tema.color[tone]} />\n <Text\n accessibilityRole=\"alert\"\n accessibilityLiveRegion={live ? 'polite' : 'none'}\n style={{\n flex: 1,\n color: tema.color[tone],\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n }}\n >\n {children}\n </Text>\n </View>\n );\n}\n","import type { Platform } from '@innspel/core';\n\n/**\n * Hver streng innsenderen ser, ett sted.\n *\n * Ordlyden er ikke fri: den er tegnet i `design/wireframes/innsending-widget.jsx` og\n * `betaprogram-tester.jsx` — som er SPESIFIKASJONER, ikke forbilder (DD-71) — og bundet av\n * beslutninger. Utseendet er godkjent på konseptsiden\n * `docs/forslag/redesign/konsept/widget-konsept-v0.1-2026-09-20.html`.\n *\n * SETNINGEN innsenderen får for en status (DD-08) står IKKE her — den bor i\n * `submissionStatus` i `theme/theme.ts` og leses fra den genererte mappa (`status.ts`), så\n * appen, portalen og panelet ikke kan love tre ulike ting.\n *\n * Språket er innsenderens, ikke repoets (DD-50, presisert 2026-09-14 og 2026-09-20): aldri\n * «spor», «reproduksjon», «privat view» eller et kontraktfeltnavn — og aldri en\n * kontraktVERDI: `android` heter «Android», `nb-NO` heter «Norsk (bokmål)».\n *\n * Norsk bokmål. Ingen leietakernavn: strengen som nevner avsenderen tar navnet som\n * parameter, siden pakken skal kunne brukes av hvem som helst.\n */\n\n/*\n * Saksnummeret er sakens løpenummer hos leietakeren, fra 10001 (`number` i svaret, DD-63\n * presisert 2026-09-26): «Sak 10042» her, «#10042» i panelet — innsender og saksbehandler\n * peker på samme tall. Uten tusenskille: det er et navn, ikke en mengde.\n */\n\nconst stor = (s: string): string => (s ? s.charAt(0).toUpperCase() + s.slice(1) : s);\n\n/**\n * Kontraktens `platform`-verdi som et ord (DD-50, presisert 2026-09-20). Verdien som SENDES\n * er uendret; dette er bare det innsenderen leser. Samme ord som portalen bruker.\n */\nconst PLATTFORM_ORD: Record<string, string> = {\n android: 'Android',\n ios: 'iOS',\n web: 'Web',\n tvos: 'TV',\n};\n\n/**\n * Språktaggen som et ord (DD-50). Lista er lukket og norsk: `Intl.DisplayNames` finnes ikke\n * i alle Hermes-bygg, og et forsøk som feiler ville sluppet `nb-NO` ut på skjermen. Et ukjent\n * språk får hovedtaggen med stor forbokstav, aldri regionsuffikset.\n */\nconst SPRAAK_ORD: Record<string, string> = {\n nb: 'Norsk (bokmål)',\n nn: 'Norsk (nynorsk)',\n no: 'Norsk',\n se: 'Nordsamisk',\n en: 'Engelsk',\n sv: 'Svensk',\n da: 'Dansk',\n fi: 'Finsk',\n is: 'Islandsk',\n de: 'Tysk',\n nl: 'Nederlandsk',\n fr: 'Fransk',\n es: 'Spansk',\n it: 'Italiensk',\n pt: 'Portugisisk',\n pl: 'Polsk',\n lt: 'Litauisk',\n ru: 'Russisk',\n uk: 'Ukrainsk',\n ar: 'Arabisk',\n so: 'Somali',\n ti: 'Tigrinja',\n tr: 'Tyrkisk',\n ur: 'Urdu',\n fa: 'Persisk',\n th: 'Thai',\n vi: 'Vietnamesisk',\n zh: 'Kinesisk',\n ja: 'Japansk',\n ko: 'Koreansk',\n};\n\nexport function plattformOrd(verdi: string): string {\n return PLATTFORM_ORD[verdi.toLowerCase()] ?? stor(verdi);\n}\n\nexport function spraakOrd(verdi: string): string {\n const hoved = verdi.toLowerCase().split(/[-_]/)[0] ?? verdi;\n return SPRAAK_ORD[hoved] ?? stor(hoved);\n}\n\n/** «én», «to», «tre» — tall i en setning skrives med bokstaver opp til tre (DD-14, DD-32). */\nconst TALLORD = ['null', 'én', 'to', 'tre'] as const;\nconst tallord = (n: number): string => TALLORD[n] ?? String(n);\n\nexport const tekst = {\n // 2b — første valg\n valgTittel: 'Hva gjelder det?',\n sporFeil: 'Noe virker ikke',\n /** DD-67, produkteier 2026-09-20: dette er VALGETS tekst, ikke en hjelpetekst. */\n sporFeilUnder: 'Noe er galt eller virker rart',\n sporOnske: 'Jeg ønsker meg noe',\n sporOnskeUnder: 'Noe du savner eller vil ha annerledes',\n /**\n * Anonym modus (DD-62 (3)). Portalens ordlyd, med widgetens ord. ALDRI «du er ikke logget\n * inn»: anonym modus er leietakerens valg ved `init()`, og widgeten vet ikke om\n * innsenderen er logget inn i vertsappen.\n */\n sendAnonymtHint: 'Innspillet kobles ikke til deg, og du kan ikke følge det etterpå.',\n\n // 2c — kjente feil (DD-29, DD-30). Ingen undertittel: overskriften stiller spørsmålet.\n kjenteFeilTittelFeil: 'Er det dette du ser?',\n kjenteFeilTittelOnske: 'Har noen ønsket dette?',\n svarJa: 'Ja, jeg også',\n svarLigner: 'Ligner, men ikke helt',\n svarNei: 'Nei, det er noe annet',\n omvei: 'Omvei:',\n rettesI: (versjon: string) => `Rettes i ${versjon}`,\n rettetI: (versjon: string) => `Rettet i ${versjon}`,\n /** Hvert kort er ÉN gruppe med samlet navn; de tre svarene er knapper i den. */\n kjentFeilGruppe: (tittel: string, status: string, versjon?: string) =>\n versjon ? `Kjent feil: ${tittel}, ${status}, ${versjon}` : `Kjent feil: ${tittel}, ${status}`,\n\n // 2d + 2e — feltet og kontekstlinja\n /**\n * «Ditt innspill», ikke «Din feil» (DD-54). «Din» festet saken til personen, og «feil»\n * karakteriserte den før noen hadde lest den — innsenderen leste det som skyld.\n */\n feltLabelFeil: 'Ditt innspill',\n feltLabelOnske: 'Ditt ønske',\n /** DD-45: to spørsmål i feilsporet. Kilde: Sentry «What's the bug? What did you expect?» */\n placeholderFeil: 'Hva skjedde? Hva forventet du?',\n placeholderOnske: 'Hva ønsker du deg?',\n send: 'Send',\n sender: 'Sender …',\n /** DD-44: minimum tegn er det ENESTE kravet. */\n forKort: (min: number) => `Minst ${min} tegn. Ingenting annet er obligatorisk.`,\n tellerFull: ' — kort og konkret holder',\n /**\n * DD-05 ordrett: «Én linje «Vis» under feltet ekspanderer». Lukket er linja en\n * OPPSUMMERING — den navngir det innsenderen kjenner igjen; lista er hele sannheten.\n */\n kontekstLinjeLukket: 'Skjerm og enhet legges ved',\n kontekstLinjeApen: 'Dette legges ved',\n kontekstVis: 'Vis',\n kontekstSkjul: 'Skjul',\n kontekstFjern: 'Fjern',\n kontekstFjernA11y: (etikett: string) => `Fjern ${etikett.toLowerCase()} fra innsendingen`,\n /** K5 — skjermens ene hjelpesetning, og bare når lista står. */\n kontekstAldri: 'Aldri navn, e-post, telefon, posisjon eller det som står på skjermen.',\n /**\n * Etikettene er portalens: samme felt, samme ord i begge flater (DD-50, presisert\n * 2026-09-20). Fram til R8.3 sto det «Plattform» og «OS» her.\n */\n kontekstEtiketter: {\n screen: 'Skjerm',\n appVersion: 'Appversjon',\n platform: 'Enhet',\n os: 'System',\n build: 'Bygg',\n locale: 'Språk',\n } as Record<string, string>,\n lenketTil: (tittel: string) => `Lenket til: «${tittel}»`,\n fjernLenke: 'Fjern lenken til den kjente feilen',\n\n // 2f — skjermbilde (K4, DD-39, DD-40, DD-42)\n leggVedSkjermbilde: 'Legg ved skjermbilde',\n velgBilde: 'Velg bilde',\n skjermbildeUnderGalleri: 'Bildet er fra galleriet. Appen maskerer ingenting i det for deg — mal over det som ikke skal med.',\n bildeFeilet: 'kunne ikke hente bildet. Du kan sende uten.',\n skjermbildeTittel: 'Se over bildet',\n skjermbildeUnder: 'Bildet ble tatt da du trykket. Det du maskerer, ser vi aldri.',\n maskering: 'Maskering',\n maskerFelt: 'Masker felt',\n tegnOver: 'Tegn over',\n maskerAllTekst: 'Masker all tekst',\n maskertAvAppen: 'Maskert av appen',\n maskertAvAppenHint: 'Dette feltet er alltid dekket og kan ikke avdekkes.',\n dittStrok: 'Trykk på et dekket felt for å angre.',\n angreSiste: 'Angre siste',\n angreSisteA11y: 'Angre det siste feltet du dekket',\n allTekstHint: 'Hele bildet er gjort uskarpt så tekst ikke kan leses. Layouten er synlig.',\n fjernBildet: 'Fjern bildet',\n leggVed: 'Legg ved',\n bildeLagtVed: 'Bilde lagt ved',\n fjernSkjermbilde: 'Fjern bildet',\n sendHintMedBilde: 'Teksten sendes først; bildet lastes opp for seg.',\n skjermbildeFeilet: 'kunne ikke ta skjermbilde. Du kan sende uten.',\n skjermbildeA11y: (auto: number, egne: number, uskarpt: boolean) =>\n `Forhåndsvisning av skjermbildet. ${auto ? `${auto} felt maskert av appen og kan ikke avmaskeres. ` : ''}${egne ? `${egne} felt maskert av deg. ` : ''}${uskarpt ? 'All tekst er gjort uskarp. ' : ''}Trykk for å maskere et felt, dra for å tegne over.`,\n\n // DD-46 — mønstervarsel. Aldri stille redaksjon.\n monsterSpm: {\n email: 'Dette ser ut som en e-postadresse. Vil du fjerne den?',\n phone: 'Dette ser ut som et telefonnummer. Vil du fjerne det?',\n card: 'Dette ser ut som et kortnummer. Vil du fjerne det?',\n ip: 'Dette ser ut som en IP-adresse. Vil du fjerne den?',\n token: 'Dette ser ut som en tilgangsnøkkel. Vil du fjerne den?',\n },\n monsterFjern: 'Fjern',\n monsterBehold: 'Behold',\n monsterForklaring: 'Teksten endres bare hvis du trykker Fjern. Vi fjerner aldri noe stille.',\n\n /* 2g — kvitteringen som KORT (DD-07, P1 (a) 2026-09-20).\n Etiketten sier hva som skjedde; HELTEN er løftets setning. */\n kvitteringSendtDato: (dato: string) => `Sendt ${dato}`,\n kvitteringSendtAnonymtDato: (dato: string) => `Sendt anonymt ${dato}`,\n kvitteringRegistrertDato: (dato: string) => `Registrert ${dato}`,\n kvitteringLagretDato: (dato: string) => `Lagret ${dato}`,\n kvitteringFeil: 'Du får beskjed når den er rettet, eller hvis vi trenger mer.',\n kvitteringJaOgsa: 'Du får beskjed når den er rettet.',\n kvitteringUnder: 'Ligger under «Mine innspill» og oppdaterer seg selv.',\n saksnummer: (nr: number) => `Sak ${nr}`,\n tilbakeTilAppen: 'Tilbake til appen',\n /** DD-42: saken er sendt, bildet kom ikke med — aldri en blokkert innsending. */\n kvitteringVedleggFeilet: 'Sendt — skjermbildet kunne ikke legges ved',\n tekstenErLagret: 'Teksten din er lagret.',\n vedleggFeiletBanner: 'Bildet ble ikke lastet opp. Saken er sendt uten det — vil du, kan du sende et nytt innspill med bilde.',\n saksnummerUtenVedlegg: (nr: number) => `Sak ${nr} · uten vedlegg`,\n\n /* 2i — køet uten nett (DD-41, presisert 2026-09-20). Kortet lover ikke svar, og det er\n derfor ikke kvitteringen: kvitteringen kommer når køen tømmes. */\n koIngenNett: 'Ingen nett',\n koHelt: 'Sendes når du er på nett.',\n koUnder: 'Du ser den under «Mine innspill» til den er sendt.',\n offlineBanner: 'Ingen nett. Lagres og sendes automatisk.',\n offlineLagre: 'Lagre — sendes når du er på nett',\n /** DD-41: et skjermbilde køes aldri. */\n offlineUtenBilde: 'Skjermbilde kan ikke legges ved uten nett. Teksten sendes; bildet ble ikke lagret.',\n sendefeilBanner: (arsak: string) => `Kunne ikke sende: ${arsak} Teksten din er beholdt.`,\n provIgjen: 'Prøv igjen',\n\n // 2j — mine innspill\n mineTittel: 'Mine innspill',\n /** Knappen på første steg med innspill fra før (DD-62): tallet er det som gjør den til en inngang. */\n mineMedAntall: (n: number) => `Mine innspill · ${n}`,\n mineEtikett: (n: number) => `Mine innspill, ${n} innspill`,\n mineLaster: 'Henter innspillene dine',\n /** DD-19: tomheten er OVERSKRIFTEN, ikke en grå linje under tittelen. */\n mineTomTittel: 'Du har ikke sendt noe ennå',\n /** Ordrett portalens `mineTomHint` — én innsender, to flater, samme setning. */\n mineTomHint: (leietaker: string) => `Det første innspillet tar under et minutt. Feil eller ønske — ${leietaker} svarer på begge.`,\n mineTomHintGenerisk: 'Det første innspillet tar under et minutt. Feil eller ønske — du får svar på begge.',\n /** Køraden har ingen saksnummer å vise — hodet sier hva den er i stedet (DD-41). */\n mineIkkeSendtHode: (spor: string) => `${stor(spor)} · ikke sendt ennå`,\n mineFeil: 'Innspillene dine kunne ikke hentes nå.',\n /** «Feil · sak 2041» — sporet først, aldri rå id og aldri kontraktens type (DD-50). */\n sakHode: (spor: string, nr: number) => `${stor(spor)} · sak ${nr}`,\n /** F14: svaret kom siden forrige gang denne enheten viste lista. */\n nyttSvar: 'Nytt svar',\n // Leietakeren fjernet vedlegget. Bare AT — aldri hvorfor, av hvem eller når.\n bildeFjernet: 'Bildet er fjernet.',\n svarFra: (leietaker: string, dato: string) => `Svar fra ${leietaker} · ${dato}`,\n svarFraGenerisk: (dato: string) => `Svar · ${dato}`,\n // DD-69 — «Legg til mer»: innsenderens egne ord, ikke et svar på svaret.\n leggTilMer: 'Legg til mer',\n leggTilMerLabel: 'Legg til mer på denne saken',\n leggTilMerPlaceholder: 'Hva vil du legge til?',\n leggTilMerHint: 'Blir stående på saken din, under det du alt har skrevet. Ikke et svar på svaret — det blir ingen samtale her.',\n avbryt: 'Avbryt',\n duLaTil: (dato: string) => `Du la til · ${dato}`,\n lagtTil: 'Lagt til',\n tilleggTak: 'Du har lagt til tre ganger. Har du mer, send et nytt innspill.',\n tilleggLukket: 'Saken er avsluttet — send et nytt innspill.',\n /** F34: serverens egen setning (InnspelApiError) — aldri en rå feil. */\n tilleggFeil: (arsak: string) => `Kunne ikke legge til: ${arsak} Teksten din er beholdt.`,\n tilleggIngenNett: 'Ingen nett. Teksten din er beholdt — prøv igjen når du er på nett.',\n tilleggFeilGenerisk: 'Kunne ikke legge til. Teksten din er beholdt — prøv igjen.',\n sendNytt: 'Send nytt innspill',\n /** Tom tilstand: det finnes ikke noe «nytt» å sende når ingenting er sendt. */\n sendForste: 'Send innspill',\n\n /* Sporingslinjen (DD-08/DD-28 presisert 2026-09-20). Ordene er innsenderens, aldri\n kontraktens: ingen status-enum, ingen «deadline». Samme ord som portalen. */\n sporEtikett: 'Sakens gang',\n sporSvarInnen: 'Svar innen',\n /** Mottatt: fristen finnes ikke ennå, og vi lover ingen dato på en sak ingen har åpnet. */\n sporDatoenSettes: 'dato kommer',\n /** Planlagt/Bygges: kontrakten har ingen leveringsdato, og DD-28 forbyr en ETA. */\n sporIngenDato: 'ingen dato lovet',\n sporNaarTenantTarDen: (leietaker: string) => `når ${leietaker} tar den`,\n sporNaarDenTasOpp: 'når de tar den',\n /** P3 (a), produkteier 2026-09-20. Klientregel på `deadlineAt` — ingen ny status. */\n sporFristenErGatt: 'Fristen er gått',\n\n // 3a — invitasjonsbanneret (DD-12). Kontakttaket står IKKE her (DD-14).\n invitasjonRegion: 'Invitasjon til betaprogram',\n invitasjonHva: (navn: string) => `Vil du teste «${navn}»?`,\n /** Én meta-linje med det kontrakten har: antall oppgaver og perioden. */\n invitasjonMeta: (oppgaver: number, periode: string) => `${oppgaver} oppgaver · ${periode}`,\n lesMer: 'Les mer og bli med',\n avvisInvitasjon: 'Avvis invitasjonen',\n\n // 3b — aksepten (DD-13, DD-32, DD-37)\n /**\n * DD-32, presisert 2026-09-20: tallene skal være SANNE. Summen når anslagene er ulike —\n * et snitt av 5, 3 og 2 er ikke sant for noen av oppgavene.\n */\n akseptTallSum: (oppgaver: number, minutter: number, periode: string) =>\n `${oppgaver} oppgaver · ca. ${minutter} min i alt · ${periode}`,\n akseptTallHver: (oppgaver: number, minutter: number, periode: string) =>\n `${oppgaver} oppgaver · ca. ${minutter} min hver · ${periode}`,\n akseptOppgaver: 'Hva vi ber om',\n akseptOppgaveTid: (minutter: number) => `ca. ${minutter} min`,\n akseptKjenteFeil: 'Kjente feil vi vet om',\n akseptInnsamling: 'Hva som samles inn',\n /** Samme ord som kontekstlista (DD-50): «enhet», ikke «plattform». */\n akseptInnsamlingTekst: 'Skjerm, appversjon, enhet og det du svarer. Aldri navn, e-post, telefon eller posisjon.',\n akseptVilkar: 'Les vilkårene',\n /**\n * Skjermens ENE hjelpesetning: taket og utgangen i én (DD-67). «høyst N» — tallet er\n * `maxContacts`, et TAK som kan senkes og aldri heves, og antall oppfølginger er malene,\n * som kan være færre. «Vi spør tre ganger» lover noe som ikke er sant (DD-14).\n */\n akseptTakOgUtgang: (maks: number) =>\n `Vi spør høyst ${tallord(maks)} ${maks === 1 ? 'gang' : 'ganger'} underveis. Du kan gå ut når som helst — ingen vilkår, ingen avtale.`,\n akseptTakOgUtgangVilkar: (maks: number) =>\n `Vi spør høyst ${tallord(maks)} ${maks === 1 ? 'gang' : 'ganger'} underveis. Du kan gå ut når som helst.`,\n bliMed: 'Bli med',\n bliMedHint: 'Samtykket gjelder bare dette programmet.',\n /** DD-12: tokenet er engangs og kom i leietakerens egen kanal — plattformen sender aldri. */\n bliMedUtenToken: 'Åpne lenken vi sendte deg for å bli med.',\n akseptFeil: (arsak: string) => `Kunne ikke bli med: ${arsak}`,\n\n // 3c — deltakelsen og «Gå ut» (DD-36). Kontakttaket står IKKE her (DD-14).\n deltakelseRegion: 'Ditt betaprogram',\n gaaUt: 'Gå ut av programmet',\n gaaUtTittel: 'Gå ut av programmet?',\n gaaUtTekst: (navn: string) =>\n `Du tas ut av testgruppen med en gang. «${navn}» slås av for deg, og vi tar ikke kontakt igjen. Det du allerede har svart, beholdes.`,\n bliVaerende: 'Bli værende',\n gaaUtBekreft: 'Gå ut',\n\n /* Programmets sporingslinje (P1 (a), produkteier 2026-09-20): deltakelsen bæres av\n linjen, ikke av et kvitteringskort — merkefargen er for det som er SENDT (DD-41). */\n programSporEtikett: 'Programmets gang',\n programBleMed: 'Du ble med',\n programGjort: (gjort: number, av: number) => `${gjort} av ${av} gjort`,\n programOver: 'Programmet er over',\n /** Under nå-leddet, ÉN linje. Aldri «to igjen»: «1 av 3» sier alt tallet sier (DD-08). */\n programNaarDetPasser: 'når det passer',\n\n // 3c — oppgavene\n oppgaverTittel: 'Oppgavene',\n oppgaveGjort: 'Gjort',\n oppgaveGjortLabel: (tittel: string) => `Gjort: ${tittel}`,\n /** Oppgavens ENE meta-linje i `small` (DD-67). Setningen hennes står i `body` under. */\n oppgaveGjortMeta: (dato: string, utfall: string) => `Gjort ${dato} · ${utfall.toLowerCase()}`,\n oppgaveTid: (minutter: number, skjerm?: string) => `ca. ${minutter} min${skjerm ? ` · ${skjerm}` : ''}`,\n oppgaveUbekreftet: 'Svaret ble ikke bekreftet — merk den på nytt',\n oppgaveRadA11y: (nr: number, tittel: string, status: string) => `Oppgave ${nr}: ${tittel}, ${status}`,\n oppgaveIkkeGjort: 'ikke gjort',\n\n // 3e — «Hvordan gikk det?»: tre lukkede valg, aldri en skala (DD-15)\n hvordanGikkDet: 'Hvordan gikk det?',\n utfallFungerte: 'Fungerte',\n utfallDelvis: 'Fungerte delvis',\n utfallIkke: 'Fungerte ikke',\n setningLabel: 'Vil du si én setning om det?',\n setningValgfritt: 'Valgfritt',\n lagre: 'Lagre',\n /** Etter «Ikke»: feilsporet er vertens — plattformen navigerer aldri selv. */\n meldFeil: 'Meld det som feil',\n svarFeil: (arsak: string) => `Kunne ikke lagre svaret: ${arsak}`,\n\n // 3d — oppfølgingskortene (DD-34): arten avgjør knappene. Ingen kontaktnummer (DD-14).\n oppfolgingRegion: 'Oppfølging fra betaprogrammet',\n oppfolgingKost: 'Ett spørsmål · tar under ett minutt',\n senere: 'Senere',\n svarNaa: 'Svar nå',\n aapneOppgavene: 'Åpne oppgavene',\n\n // Felles\n tilbake: 'Tilbake',\n lukk: 'Lukk',\n venterPaaNett: 'Venter på nett',\n feil: 'feil',\n onske: 'ønske',\n} as const;\n\n/**\n * Løftene som IKKE hører til en innsendingsstatus. Statusenes løfter står i\n * `submissionStatus` i `theme/theme.ts` og leses gjennom `status.ts` — det var tre kopier av\n * dem før 2026-09-14 (UX-gjennomgangen C5).\n */\nexport const lofte = {\n venterNett: 'Sendes automatisk når du er på nett.',\n} as const;\n\n/** Kontekstens verdi slik innsenderen leser den (DD-50). Verdien som sendes er uendret. */\nexport function kontekstVerdi(felt: string, verdi: string): string {\n if (felt === 'platform') return plattformOrd(verdi as Platform);\n if (felt === 'locale') return spraakOrd(verdi);\n return verdi;\n}\n","import React from 'react';\nimport { Pressable, Text, View } from 'react-native';\nimport { Ikon } from '../Ikon.js';\nimport { useTema } from '../tema.js';\nimport { H, Hint } from './primitiver.js';\nimport { tekst } from './tekster.js';\n\n/**\n * 2b — første valg, og eneste steg som ikke har «Tilbake».\n *\n * DD-02: ALDRI et tredje valg, og aldri spørsmål om kategori eller alvorlighet. Valget her\n * styrer alt etterpå: feilsporet får kjente feil FØR feltet og kan bære koblingsnøkler,\n * ønskesporet får dem etter og kan ikke.\n *\n * **R8.3 (widget-konsept v0.1):** valgene er RADER, ikke to rammede kort side om side. Det\n * fylte ikonet i merkefargen på en rund flate bærer vekten (DD-63) — 40 px ikon\n * (`storrelse=\"stor\"`, 2 × `icon.inline`) på en flate som er `touch + sm`; raden er\n * `touch + lg`. Vekten står ETT sted, så raden trenger ingen ramme.\n *\n * Undertekstene er VALGETS TEKST, ikke hjelpetekst (produkteier 2026-09-20): de skiller\n * sporene, og de er det eneste som sier hva valget betyr. Skjermen har derfor ingen\n * hjelpesetning — spørsmålet er overskriften.\n *\n * **Anonym modus** (DD-62 (3), DD-02): uten feedback-token finnes ingen «Mine innspill».\n * Én setning sier hva anonymt betyr, så fraværet ikke leses som en feil. Setningen er\n * portalens, ALDRI «du er ikke logget inn»: anonym modus er leietakerens valg ved `init()`,\n * og widgeten vet ikke om innsenderen er logget inn i vertsappen.\n */\nexport function Valg({ onVelg, anonym }: { onVelg: (spor: 'feil' | 'onske') => void; anonym?: boolean }) {\n const tema = useTema();\n\n const rad = (spor: 'feil' | 'onske', ikon: string, label: string, under: string, forst: boolean) => (\n <Pressable\n testID={`spor-${spor}`}\n accessibilityRole=\"button\"\n accessibilityLabel={`${label}, ${under}`}\n onPress={() => onVelg(spor)}\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n gap: tema.space.md,\n minHeight: tema.touch + tema.space.lg,\n paddingVertical: tema.space.sm,\n borderTopWidth: forst ? 0 : tema.hairline,\n borderTopColor: tema.color.border,\n }}\n >\n <View\n testID={`spor-${spor}-ikonflate`}\n style={{\n width: tema.touch + tema.space.sm,\n height: tema.touch + tema.space.sm,\n borderRadius: tema.radius.pill,\n backgroundColor: tema.color.brandBg,\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <Ikon navn={ikon} storrelse=\"stor\" farge={tema.color.brand} />\n </View>\n <View style={{ flex: 1, minWidth: 0 }}>\n <Text style={{ color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body, fontWeight: tema.weight.semibold }}>\n {label}\n </Text>\n {/* Valgets tekst, ikke hjelpetekst — måleren får unntak for denne (DD-67). */}\n <Text style={{ color: tema.color.textMuted, fontSize: tema.font.small, lineHeight: tema.lineHeight.small }}>\n {under}\n </Text>\n </View>\n <Ikon navn=\"chevron-forward-outline\" storrelse=\"minste\" farge={tema.color.textMuted} />\n </Pressable>\n );\n\n return (\n <View style={{ gap: tema.space.lg }}>\n <H>{tekst.valgTittel}</H>\n <View>\n {rad('feil', 'bug', tekst.sporFeil, tekst.sporFeilUnder, true)}\n {rad('onske', 'bulb', tekst.sporOnske, tekst.sporOnskeUnder, false)}\n </View>\n {anonym ? <Hint>{tekst.sendAnonymtHint}</Hint> : null}\n </View>\n );\n}\n","import type { KnownIssueCard } from '@innspel/core';\nimport React from 'react';\nimport { ActivityIndicator, ScrollView, Text, View } from 'react-native';\nimport { knownIssueStatus } from '../generated/tokens.js';\nimport { Ikon } from '../Ikon.js';\nimport { useTema } from '../tema.js';\nimport { Btn, H, Sek, Tekstknapp } from './primitiver.js';\nimport { tekst } from './tekster.js';\n\n/** DD-03: maks tre kort. Grensen er klientens — registeret kan ha flere. */\nconst MAKS_KORT = 3;\n\n/**\n * 2c — kjente feil. Differensiatoren: vises FØR feltet i feilsporet, ETTER i ønskesporet.\n *\n * DD-29 gir kortet TRE svar, ikke to: «Ja, jeg også» (Reach +1, ingen ny sak) · «Ligner,\n * men ikke helt» (eget innspill med lenke, uten tvunget match) · «Nei, det er noe annet»\n * (vanlig innsending). Det midterste er hele poenget — uten det tvinger man et valg mellom\n * å bli talt feil og å ikke bli talt.\n *\n * **R8.3 (widget-konsept v0.1, DD-63 presisert 2026-09-20):** ingen av de tre er skjermens\n * primærhandling, og INGEN av dem står i aksjonsfargen — tre fylte knapper var tre\n * primærknapper. «Ja, jeg også» er `tonet` fordi det er valget som sparer innsenderen for å\n * skrive; «Ligner, men ikke helt» er en tekstknapp ved siden av; «Nei, det er noe annet»\n * står alene i foten. Kortene er RADER med skillelinje, ikke kort i kort: nullpunktet fant\n * 10 rammede elementer på denne skjermen.\n *\n * DD-30 gir raden tre deler: tittelen i `body` halvfet, OMVEIEN i `body` — det er den\n * innsenderen faktisk trenger — og status som ikon + ord i ÉN meta-linje, med versjonen som\n * et tillegg («Aktiv · rettes i 3.2»). «Rettet i 3.1» står som ETT ledd; ordet «Rettet»\n * skal aldri stå to ganger.\n *\n * Undertittelen «Kjenner du igjen en av disse?» er ute: overskriften stiller spørsmålet, og\n * en skjerm har høyst én hjelpesetning (DD-67).\n *\n * Tilgjengelighet: kortet er IKKE én knapp. Tre svar må være tre fokusstopp, og `accessible`\n * på radcontaineren ville slukt dem. I stedet bærer hver knapp kortets samlede navn i\n * etiketten, så en skjermleserbruker som lander på «Ja, jeg også» vet hvilken feil svaret\n * gjelder.\n *\n * Treffene er et tilbud, aldri en sperre: feiler oppslaget eller er lista tom, hoppes\n * skjermen over uten melding. Det håndteres i Widget, ikke her.\n */\nexport function KjenteFeil({\n kort,\n spor,\n laster,\n sender,\n onJaOgsa,\n onLigner,\n onNei,\n}: {\n kort: KnownIssueCard[];\n spor: 'feil' | 'onske';\n laster?: boolean;\n /** «Ja, jeg også» er underveis: alle svar låses, så ett trykk gir én bekreftelse (C7). */\n sender?: boolean;\n onJaOgsa: (k: KnownIssueCard) => void;\n onLigner: (k: KnownIssueCard) => void;\n onNei: () => void;\n}) {\n const tema = useTema();\n const tittel = spor === 'onske' ? tekst.kjenteFeilTittelOnske : tekst.kjenteFeilTittelFeil;\n\n if (laster) {\n return (\n <View style={{ flex: 1, gap: tema.space.md }}>\n <H>{tittel}</H>\n <ActivityIndicator accessibilityLabel=\"Sjekker kjente feil\" color={tema.color.textSecondary} />\n </View>\n );\n }\n\n // Samme form som skjemaet: radene scroller, «Nei, det er noe annet» står fast.\n return (\n <View testID=\"kjente-feil\" style={{ flexGrow: 1, flexShrink: 1, gap: tema.space.md }}>\n <H>{tittel}</H>\n\n <ScrollView\n testID=\"kjente-feil-liste\"\n style={{ flexGrow: 0, flexShrink: 1 }}\n keyboardShouldPersistTaps=\"handled\"\n >\n {kort.slice(0, MAKS_KORT).map((k, i) => {\n // Kortet har ALLTID en status (C5/C6): «Aktiv» eller «Rettet», fra\n // knownIssueStatus i temaet. Er feilen RETTET, bærer statusordet versjonen som\n // ETT ledd («Rettet i 3.1»); er den aktiv, står versjonen som et tillegg til\n // pillens ord («Aktiv · rettes i 3.2»). Ordet «Rettet» står aldri to ganger.\n const o = knownIssueStatus[k.status] ?? knownIssueStatus.aktiv;\n const rettet = k.status === 'fikset';\n const statusOrd = rettet && k.fixedIn ? tekst.rettetI(k.fixedIn) : o.etikett;\n const tillegg = !rettet && k.fixedIn ? `· ${tekst.rettesI(k.fixedIn).toLowerCase()}` : undefined;\n const gruppe = tekst.kjentFeilGruppe(k.title, statusOrd, tillegg?.replace('· ', ''));\n\n return (\n <View\n key={k.id}\n testID={`kjent-feil-${k.id}`}\n style={{\n gap: tema.space.sm,\n paddingVertical: tema.space.md,\n borderTopWidth: i === 0 ? 0 : tema.hairline,\n borderTopColor: tema.color.border,\n }}\n >\n <Text\n testID={`kjent-feil-tittel-${k.id}`}\n style={{\n color: tema.color.textPrimary,\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n fontWeight: tema.weight.semibold,\n }}\n >\n {k.title}\n </Text>\n\n {/* Omveien er `body` — det er den innsenderen faktisk trenger (DD-30, DD-67). */}\n {k.workaround ? (\n <Sek testID={`kjent-feil-omvei-${k.id}`}>\n {tekst.omvei} {k.workaround}\n </Sek>\n ) : null}\n\n {/* ÉN meta-linje i `small` — ikon og ord, aldri farge alene (DD-08). */}\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: tema.space.sm, flexWrap: 'wrap' }}>\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: tema.space.xs }}>\n <Ikon navn={o.ikon} storrelse=\"minste\" farge={tema.color[o.fg as keyof typeof tema.color]} />\n <Text\n style={{\n color: tema.color[o.fg as keyof typeof tema.color],\n fontSize: tema.font.small,\n lineHeight: tema.lineHeight.small,\n fontWeight: tema.weight.semibold,\n }}\n >\n {statusOrd}\n </Text>\n </View>\n {tillegg ? (\n <Text style={{ color: tema.color.textMuted, fontSize: tema.font.small, lineHeight: tema.lineHeight.small }}>\n {tillegg}\n </Text>\n ) : null}\n </View>\n\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: tema.space.md }}>\n <Btn\n variant=\"tonet\"\n testID={`ja-ogsa-${k.id}`}\n label={tekst.svarJa}\n accessibilityLabel={`${tekst.svarJa}. ${gruppe}`}\n disabled={sender}\n busy={sender}\n onPress={() => onJaOgsa(k)}\n />\n <Tekstknapp\n testID={`ligner-${k.id}`}\n label={tekst.svarLigner}\n accessibilityLabel={`${tekst.svarLigner}. ${gruppe}`}\n disabled={sender}\n onPress={() => onLigner(k)}\n />\n </View>\n </View>\n );\n })}\n </ScrollView>\n\n <View testID=\"kjente-feil-fot\" style={{ flexShrink: 0 }}>\n <Btn variant=\"secondary\" testID=\"nei-noe-annet\" label={tekst.svarNei} disabled={sender} onPress={onNei} />\n </View>\n </View>\n );\n}\n","import type { SubmissionStatusView } from '@innspel/core';\nimport React from 'react';\nimport { Text, View } from 'react-native';\nimport { Ikon } from '../Ikon.js';\nimport { useTema } from '../tema.js';\nimport { Banner, Btn, Helt } from './primitiver.js';\nimport { Sporingslinje, sporingsledd } from './Sporingslinje.js';\nimport { formaterFrist, statusVisning } from './status.js';\nimport { tekst } from './tekster.js';\n\nexport type KvitteringArt = 'feil' | 'onske' | 'jaOgsa' | 'kø';\n\n/**\n * 2g — kvitteringen. Den LOVER noe, per spor (DD-07), og saksnummeret er der så innsenderen\n * kan vise til det hos support. Ingen «vurder appen». Ingen oppfordring til å dele.\n * Innsenderen har nettopp gjort oss en tjeneste — å be om en til er å ta betalt for den.\n *\n * **R8.3 (widget-konsept v0.1, DD-07 presisert 2026-09-20, P1 (a)):** kvitteringen er et\n * KORT — det innsenderen tar vare på. Leietakerens navn og saksnummeret i hjørnet, «Sendt\n * <dato>» som etikett, og **løftets setning som skjermens helt**. R8.1s brief ba om datoen\n * som helt, men en ny sak står i Mottatt, og en Mottatt-sak har med vilje ingen frist\n * («Svarfristen starter ikke ved innsending»). Datoen finnes ikke ennå; den tar heltens\n * plass i «Mine innspill» den dagen saken er i Vurderes (DD-28). Sporingslinjen under sier\n * hva som skjer videre.\n *\n * **Kø-kortet (DD-41)** er samme form, men ALDRI i merkefargen: merkefargen er for det som\n * er sendt. Stiplet kant på `surface`, «Ingen nett» med ikon der saksnummeret ellers står,\n * ingen sporingslinje og intet saksnummer — det finnes ikke noe å spore før serveren har\n * saken. Kortet er derfor ikke kvitteringen; kvitteringen kommer når køen tømmes.\n *\n * DD-42: feilet vedlegget, er saken likevel sendt. DD-47: helten er live-regionen — den\n * leses opp alene, uten at hele kortet gjentas.\n */\nexport function Kvittering({\n art,\n saksnummer,\n vedlegg,\n frist,\n sak,\n anonym,\n tenantName,\n onLukk,\n}: {\n art: KvitteringArt;\n saksnummer?: number;\n /** `feilet`: teksten er lagret, bildet kom ikke med. `forkastet`: køet offline uten bilde. */\n vedlegg?: 'feilet' | 'forkastet';\n /** Svarfristen fra svaret (`deadlineAt`). Tidsløftet er DATOEN, aldri «innen 90 dager» (DD-07, DD-28). */\n frist?: string;\n /** Saken slik serveren svarte. Gir sporingslinjen leddene — ingen nye felter. */\n sak?: SubmissionStatusView;\n /** Anonym modus (DD-62): linja om «Mine innspill» finnes ikke, for lista gjør det ikke. */\n anonym?: boolean;\n /** Leietakerens navn på kortet — aldri Innspels. */\n tenantName?: string;\n onLukk: () => void;\n}) {\n const tema = useTema();\n const ko = art === 'kø';\n\n const helt = {\n feil: tekst.kvitteringFeil,\n // Løftet er NØYAKTIG det «Mine innspill» og panelet viser for «Vurderes»: det leses fra\n // temaet, så kvitteringen og statusen ikke kan si to ting.\n onske: statusVisning('vurderes', 'onske', frist).lofte,\n jaOgsa: tekst.kvitteringJaOgsa,\n kø: tekst.koHelt,\n }[art];\n\n const dato = formaterFrist(sak?.createdAt ?? new Date().toISOString());\n const etikett =\n vedlegg === 'feilet' ? tekst.kvitteringVedleggFeilet\n : ko ? tekst.kvitteringLagretDato(dato)\n : art === 'jaOgsa' ? tekst.kvitteringRegistrertDato(dato)\n : anonym ? tekst.kvitteringSendtAnonymtDato(dato)\n : tekst.kvitteringSendtDato(dato);\n\n // Køet: ingenting er sendt, så det finnes ingen gang å spore og ingen sak å følge.\n const ledd = sak && !ko ? sporingsledd(sak, tenantName) : [];\n // Anonym modus har ingen liste, så linja om «Mine innspill» ville løyet (DD-62).\n const under = anonym ? undefined : ko ? tekst.koUnder : saksnummer ? tekst.kvitteringUnder : undefined;\n\n return (\n <View testID=\"kvittering\" style={{ flex: 1, gap: tema.space.md }}>\n {vedlegg === 'feilet' ? <Banner ikon=\"warning-outline\" tone=\"warning\" children={tekst.vedleggFeiletBanner} /> : null}\n {vedlegg === 'forkastet' ? <Banner ikon=\"image-outline\" tone=\"info\" children={tekst.offlineUtenBilde} /> : null}\n\n <View\n testID=\"kvittering-kort\"\n style={{\n backgroundColor: ko ? tema.color.surface : tema.color.brandFill,\n borderRadius: tema.radius.lg,\n borderWidth: ko ? tema.hairline : 0,\n borderStyle: ko ? 'dashed' : 'solid',\n borderColor: tema.color.borderInteractive,\n padding: tema.space.md,\n gap: tema.space.md,\n }}\n >\n <View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', gap: tema.space.sm }}>\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: tema.space.sm, flexShrink: 1 }}>\n <Ikon\n navn={ko ? 'swap-vertical-outline' : 'checkmark-circle-outline'}\n farge={ko ? tema.color.textSecondary : tema.color.onBrandFill}\n />\n {tenantName ? (\n <Text\n style={{\n color: ko ? tema.color.textPrimary : tema.color.onBrandFill,\n fontSize: tema.font.body,\n fontWeight: tema.weight.bold,\n }}\n >\n {tenantName}\n </Text>\n ) : null}\n </View>\n {ko ? (\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: tema.space.xs }}>\n <Ikon navn=\"cloud-offline-outline\" storrelse=\"minste\" farge={tema.color.textMuted} />\n <Text style={{ color: tema.color.textMuted, fontSize: tema.font.small, fontWeight: tema.weight.semibold }}>\n {tekst.koIngenNett}\n </Text>\n </View>\n ) : saksnummer ? (\n <Text\n style={{ color: tema.color.onBrandFill, fontSize: tema.font.small, fontWeight: tema.weight.semibold }}\n >\n {vedlegg === 'feilet' ? tekst.saksnummerUtenVedlegg(saksnummer) : tekst.saksnummer(saksnummer)}\n </Text>\n ) : null}\n </View>\n\n <View style={{ gap: tema.space.xs }}>\n <Text\n style={{\n color: ko ? tema.color.textMuted : tema.color.onBrandFill,\n fontSize: tema.font.small,\n lineHeight: tema.lineHeight.small,\n }}\n >\n {etikett}\n </Text>\n {/* HELTEN: løftets setning, ikke et tall (P1 (a)). Live-region (DD-47). */}\n <Helt testID=\"kvittering-tekst\" live farge={ko ? tema.color.textPrimary : tema.color.onBrandFill}>\n {vedlegg === 'feilet' ? `${tekst.tekstenErLagret} ${helt}` : helt}\n </Helt>\n </View>\n\n {under ? (\n <>\n <View\n style={{\n borderTopWidth: tema.hairline,\n borderTopColor: ko ? tema.color.borderStrong : tema.color.onBrandFill,\n borderStyle: 'dashed',\n }}\n />\n <Text\n testID=\"kvittering-under\"\n style={{\n color: ko ? tema.color.textPrimary : tema.color.onBrandFill,\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n }}\n >\n {under}\n </Text>\n </>\n ) : null}\n </View>\n\n {ledd.length > 0 ? <Sporingslinje ledd={ledd} testID=\"kvittering-spor\" /> : null}\n\n {/* Foten ligger utenfor det som ruller — primærhandlingen i tommelsonen (DD-47).\n Egen padding over: sporingslinjens siste linje har lang underkant, og uten den\n klistret knappen seg til teksten på telefonen. */}\n <View style={{ flex: 1, justifyContent: 'flex-end', paddingTop: tema.space.sm }}>\n <Btn testID=\"tilbake-til-appen\" label={tekst.tilbakeTilAppen} onPress={onLukk} />\n </View>\n </View>\n );\n}\n","import type { MySubmission, SubmissionStatus, SubmissionType } from '@innspel/core';\nimport React from 'react';\nimport { Text, View } from 'react-native';\nimport { Ikon } from '../Ikon.js';\nimport { useTema } from '../tema.js';\nimport { Helt } from './primitiver.js';\nimport { formaterFrist, formaterKortFrist, statusVisning } from './status.js';\nimport { tekst } from './tekster.js';\n\n/**\n * Sakens gang, for innsenderen (R8.3, widget-konsept v0.1 · DD-08 og DD-28 presisert\n * 2026-09-20). Samme komponent og samme regler som portalens\n * `portal/src/lib/widget/Sporingslinje.tsx` — én innsender, to flater, samme form.\n *\n * Reglene, som wireframen spesifiserer dem:\n *\n * - Bare ÅPNE saker (`statusType` `reviewing`/`active`) har linje. En avsluttet sak får\n * pillen og én linje — det er ikke noe igjen å spore, og aldri begge former (DD-08).\n * {@link sporingsledd} gir tom liste for dem, og den som kaller viser pillen i stedet.\n * - Leddene utledes av `status`, og INGEN ny kontrakt: datoene som finnes er `createdAt`\n * (Mottatt), `statusChangedAt` (nå-leddet) og `deadlineAt` (Vurderes).\n * - **Et passert mellomledd har ingen dato.** Kontrakten bærer bare den SISTE\n * statusendringen, så «Vurderes 6. sep» på en Planlagt-sak finnes ikke som felt, og en\n * gjettet dato er verre enn ingen (DD-28, presisert etter R7.3).\n * - SISTE ledd har et TALL bare når kontrakten har datoen — `deadlineAt`, som finnes kun i\n * Vurderes. Da er tallet skjermens helt (DD-67). Ellers står leddet uten tall.\n * - Nå-leddet bærer statusens ikon OG etikett fra temaet (DD-08): linjen erstatter pillen,\n * den skjuler ikke statusen.\n * - **Fristen er gått** (P3 (a), produkteier 2026-09-20): er `deadlineAt` passert mens saken\n * står i Vurderes, står siste ledd i `warning` med ⚠ i noden — én gang, som de andre\n * leddenes ikon — «Fristen er gått» som etikett og datoen som tall, fortsatt tallet hun\n * ble lovet. Løftet under er uendret: det er det leietakeren sa. Aldri rødt (DD-53).\n * Regelen er en KLIENTREGEL på `deadlineAt`; det finnes ingen slik status i kontrakten, og\n * ingen ny skal lages.\n */\n\nexport type LeddTilstand = 'gjort' | 'naa' | 'kommer' | 'brutt';\n\nexport interface Ledd {\n nokkel: string;\n etikett: string;\n tilstand: LeddTilstand;\n /** Ionicons-navn fra temaet. Nå-leddet og det brutte har det; passerte har haken. */\n ikon?: string;\n /** Linja under etiketten: datoen som finnes, eller hva som skjer. Aldri en gjettet dato. */\n detalj?: string;\n /** Datoen som tall — skjermens helt. Finnes bare på siste ledd i Vurderes (`deadlineAt`). */\n tall?: string;\n}\n\n/** Hovedlinjen i tilstandsmaskinen, slik innsenderen ser den (domain-model.md). */\nconst HOVEDLINJE: SubmissionStatus[] = ['ny', 'vurderes', 'planlagt', 'bygges', 'levert'];\n\n/** Statusene som fortsatt er i bevegelse. Avsluttede (`complete`/`closed`) har ingen linje. */\nfunction erApen(rad: MySubmission): boolean {\n if (rad.pending === true) return false;\n return rad.statusType === 'reviewing' || rad.statusType === 'active';\n}\n\n/**\n * Leddene for en åpen sak. Tom liste = ingen linje (avsluttet sak, køet rad, eller en status\n * utenfor hovedlinjen som ikke har en gang å spore).\n *\n * @param naa Injiseres av testene; ellers klokka nå. Regelen om passert frist er klientens.\n */\nexport function sporingsledd(rad: MySubmission, tenantName?: string, naa: Date = new Date()): Ledd[] {\n if (rad.pending === true || !erApen(rad)) return [];\n\n const type: SubmissionType = rad.type;\n const navn = (status: SubmissionStatus) => statusVisning(status, type).etikett;\n const ikon = (status: SubmissionStatus) => statusVisning(status, type).ikon;\n const ledd: Ledd[] = [];\n\n // «Kjent feil» står utenfor hovedlinjen: saken er bekreftet mot en kjent feil, og det\n // eneste som gjenstår er at den rettes.\n if (rad.status === 'kjent_feil') {\n ledd.push({ nokkel: 'ny', etikett: navn('ny'), tilstand: 'gjort', detalj: formaterFrist(rad.createdAt) });\n ledd.push({ nokkel: 'kjent_feil', etikett: navn('kjent_feil'), tilstand: 'naa', ikon: ikon('kjent_feil'), detalj: formaterFrist(rad.statusChangedAt) });\n ledd.push({ nokkel: 'slutt', etikett: navn('levert'), tilstand: 'kommer', detalj: tekst.sporIngenDato });\n return ledd;\n }\n\n const naaIndeks = HOVEDLINJE.indexOf(rad.status);\n if (naaIndeks < 0) return [];\n\n for (let i = 0; i <= naaIndeks; i++) {\n const status = HOVEDLINJE[i]!;\n const erNaa = i === naaIndeks;\n ledd.push({\n nokkel: status,\n etikett: navn(status),\n tilstand: erNaa ? 'naa' : 'gjort',\n ...(erNaa ? { ikon: ikon(status) } : {}),\n // Mottatt har `createdAt`, nå-leddet har `statusChangedAt`. Et passert ledd mellom dem\n // har ingen dato i kontrakten, og får derfor ingen.\n ...(i === 0 ? { detalj: formaterFrist(rad.createdAt) } : erNaa ? { detalj: formaterFrist(rad.statusChangedAt) } : {}),\n });\n }\n\n // En sak i Mottatt får vise hva som kommer — det er det eneste stedet linjen peker forbi\n // nå-leddet, fordi «Vurderes» er handlingen innsenderen venter på.\n if (rad.status === 'ny') {\n ledd.push({\n nokkel: 'vurderes',\n etikett: navn('vurderes'),\n tilstand: 'kommer',\n detalj: tenantName ? tekst.sporNaarTenantTarDen(tenantName) : tekst.sporNaarDenTasOpp,\n });\n }\n\n // Siste ledd. `reviewing` venter på et SVAR (fristen er tidsløftet); `active` venter på at\n // det blir levert, og der finnes ingen dato i kontrakten.\n if (rad.statusType === 'reviewing') {\n const frist = rad.deadlineAt;\n const gatt = frist !== undefined && rad.status === 'vurderes' && new Date(frist).getTime() < naa.getTime();\n ledd.push(\n gatt\n ? { nokkel: 'slutt', etikett: tekst.sporFristenErGatt, tilstand: 'brutt', ikon: 'warning-outline', tall: formaterKortFrist(frist) }\n : {\n nokkel: 'slutt',\n etikett: tekst.sporSvarInnen,\n tilstand: 'kommer',\n ...(frist ? { tall: formaterKortFrist(frist) } : { detalj: tekst.sporDatoenSettes }),\n },\n );\n } else {\n ledd.push({ nokkel: 'slutt', etikett: navn('levert'), tilstand: 'kommer', detalj: tekst.sporIngenDato });\n }\n\n return ledd;\n}\n\n/**\n * Linjen. Ett ledd per steg, med noden, navnet og enten tallet (helten) eller detaljen.\n * Ikonet er dekorativt og står i NODEN, én gang — etiketten bærer meningen (DD-08).\n */\nexport function Sporingslinje({\n ledd,\n testID,\n etikett = tekst.sporEtikett,\n}: {\n ledd: Ledd[];\n testID?: string;\n etikett?: string;\n}) {\n const tema = useTema();\n if (ledd.length === 0) return null;\n\n const farge = (l: Ledd): string =>\n l.tilstand === 'brutt' ? tema.color.warning\n : l.tilstand === 'gjort' ? tema.color.success\n : l.tilstand === 'naa' ? tema.color.brand\n : tema.color.borderStrong;\n\n return (\n <View\n testID={testID}\n accessibilityRole=\"list\"\n accessibilityLabel={etikett}\n style={{ flexDirection: 'row', alignItems: 'flex-start', gap: tema.space.xs }}\n >\n {ledd.map((l, i) => {\n const siste = i === ledd.length - 1;\n const c = farge(l);\n return (\n <View\n key={l.nokkel}\n testID={testID ? `${testID}-ledd-${l.nokkel}` : undefined}\n style={siste ? { flexShrink: 0, gap: tema.space.xs } : { flex: 1, minWidth: 0, gap: tema.space.xs }}\n >\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: tema.space.xs }}>\n {/* Noden er 24; ikonet i den er 16 — `icon.minste` er gulvet. */}\n <View\n style={{\n width: tema.space.lg,\n height: tema.space.lg,\n borderRadius: tema.radius.pill,\n borderWidth: tema.hairline * 2,\n borderColor: c,\n borderStyle: l.tilstand === 'kommer' ? 'dashed' : 'solid',\n backgroundColor: l.tilstand === 'gjort' ? tema.color.success : 'transparent',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n {l.tilstand === 'gjort' ? (\n <Ikon navn=\"checkmark-outline\" storrelse=\"minste\" farge={tema.color.bg} />\n ) : l.ikon ? (\n <Ikon navn={l.ikon} storrelse=\"minste\" farge={c} />\n ) : null}\n </View>\n {!siste ? (\n <View\n style={{\n flex: 1,\n height: tema.hairline * 2,\n borderRadius: tema.radius.pill,\n backgroundColor: l.tilstand === 'gjort' ? tema.color.success : tema.color.borderStrong,\n }}\n />\n ) : null}\n </View>\n {/* Leddenes etiketter er `small` — det er nettopp det `small` er til (DD-67). */}\n <Text\n style={{\n color: l.tilstand === 'brutt' ? tema.color.warning : l.tilstand === 'kommer' ? tema.color.textMuted : tema.color.textPrimary,\n fontSize: tema.font.small,\n lineHeight: tema.lineHeight.small,\n fontWeight: l.tilstand === 'naa' || l.tilstand === 'brutt' ? tema.weight.semibold : tema.weight.regular,\n }}\n >\n {l.etikett}\n </Text>\n {l.tall !== undefined ? (\n <Helt testID={testID ? `${testID}-tall` : undefined} farge={l.tilstand === 'brutt' ? tema.color.warning : tema.color.textPrimary}>\n {l.tall}\n </Helt>\n ) : l.detalj !== undefined ? (\n <Text style={{ color: tema.color.textMuted, fontSize: tema.font.small, lineHeight: tema.lineHeight.small }}>\n {l.detalj}\n </Text>\n ) : null}\n </View>\n );\n })}\n </View>\n );\n}\n","import type { SubmissionStatus, SubmissionStatusView, SubmissionType } from '@innspel/core';\nimport { lofteUtenFrist, submissionStatus } from '../generated/tokens.js';\nimport { lofte, tekst } from './tekster.js';\n\n/**\n * Statusen slik innsenderen ser den. ALT kommer fra `submissionStatus` i\n * `theme/theme.ts`, gjennom den genererte mappa: navnet per spor (DD-22),\n * setningen innsenderen får (DD-08), IKONNAVNET og tokennavnene for farge.\n *\n * Navn, farge og løfte sto hardkodet her OG i `@innspel/web` OG i panelet før\n * 2026-09-14 og spriket (UX-gjennomgangen C5). Ikonet sto igjen som emoji til\n * 2026-09-15, fordi Ionicons i React Native krever en peer-avhengighet — se\n * «`react-native-svg` som peer i @innspel/react-native» i `tech-decisions.md`.\n *\n * DD-08 / «Styling» i CLAUDE.md: **farge bærer aldri mening alene.** `brand` og\n * `info`, og `brand` og `danger`, er målt til under 1,5 i innbyrdes kontrast av\n * tema-generatoren, så etiketten er det som faktisk bærer meningen.\n */\nexport interface StatusVisning {\n /** Ionicons-navn fra temaet — aldri en emoji (brand-ui-guidelines). */\n ikon: string;\n etikett: string;\n /** Tokennavn i den aktive paletten, ikke en farge. */\n fg: string;\n bg: string;\n lofte: string;\n}\n\n/** Norsk dato uten klokkeslett — fristen er en dato, ikke et tidspunkt (DD-28). */\nexport function formaterFrist(iso: string): string {\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return iso;\n return new Intl.DateTimeFormat('nb-NO', { day: 'numeric', month: 'long' }).format(d);\n}\n\nconst KORT_MANED = ['jan', 'feb', 'mar', 'apr', 'mai', 'jun', 'jul', 'aug', 'sep', 'okt', 'nov', 'des'] as const;\n\n/**\n * Datoen som TALL i sporingslinjen — «28. sep», ikke «28. september» (R8.3).\n *\n * Tallet er skjermens helt og står i `h1` i en av tre kolonner på en telefon. «28.\n * september» i 24 px er bredere enn en tredjedel av arket, og skjøv linjen ut av\n * spalten; konseptsiden og wireframene tegner den korte formen av nettopp den grunn.\n * Ingenting går tapt: løftet under linjen skriver datoen ut i sin helhet («Svar innen 3.\n * desember — også hvis det er nei.»), og det er løftet som er tidsløftet (DD-28).\n * Forkortelsene står her, ikke i `Intl`: `month: 'short'` gir «28. sep.» med punktum i\n * nb-NO, og punktumet leses som en forkortet setning.\n */\nexport function formaterKortFrist(iso: string): string {\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return iso;\n return `${d.getDate()}. ${KORT_MANED[d.getMonth()]}`;\n}\n\n/**\n * Oversetter en innsending til det innsenderen skal se.\n *\n * @param status Maskinens status fra kontrakten.\n * @param type Sporet — avgjør «Rettet» mot «Levert» (DD-22).\n * @param deadlineAt Svarfristen, satt kun i `vurderes`.\n */\nexport function statusVisning(status: SubmissionStatus, type: SubmissionType, deadlineAt?: string): StatusVisning {\n const o = submissionStatus[status];\n const spor: 'feil' | 'onske' = type === 'onske' ? 'onske' : 'feil';\n return {\n ikon: o.ikon,\n etikett: o.etikett[spor],\n fg: o.fg,\n bg: o.bg,\n lofte: settInnFrist(o.lofte[spor], deadlineAt),\n };\n}\n\n/**\n * `{frist}` byttes med datoen (DD-28). Uten frist finnes ikke tidsløftet, og da\n * står den fristløse setningen i stedet — aldri en tom plassholder på skjermen.\n */\nfunction settInnFrist(mal: string, deadlineAt: string | undefined): string {\n if (!mal.includes('{frist}')) return mal;\n return deadlineAt ? mal.replace('{frist}', formaterFrist(deadlineAt)) : lofteUtenFrist;\n}\n\n/** Raden som venter på nett (DD-41). Den har ingen saksnummer og intet løfte om svar. */\nexport const venterVisning: StatusVisning = {\n ikon: 'cloud-offline-outline',\n etikett: 'Venter på nett',\n fg: 'textSecondary',\n bg: 'neutralBg',\n lofte: lofte.venterNett,\n};\n\n/**\n * Etikett for en hel rad, brukt som skjermleserens sammendrag. Ikonet er\n * `aria-hidden` i UI-et, så etiketten må bære alt.\n */\nexport function radEtikett(rad: SubmissionStatusView): string {\n const v = statusVisning(rad.status, rad.type, rad.deadlineAt);\n const spor = rad.type === 'onske' ? tekst.onske : tekst.feil;\n return `${tekst.sakHode(spor, rad.number)}: ${rad.text}. Status ${v.etikett.toLowerCase()}. ${v.lofte}`;\n}\n","import { InnspelApiError, NettverksFeil, type InnspelStorage, type MySubmission, type SubmissionStatusView } from '@innspel/core';\nimport React, { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';\nimport { ActivityIndicator, Keyboard, ScrollView, Text, TextInput, View, type ScrollViewInstance } from 'react-native';\nimport { Ikon } from '../Ikon.js';\nimport { useTema } from '../tema.js';\nimport { Brodtekst, Btn, Card, H, Hint, Meta, Pille, Sek, StatusPill, Tekstknapp } from './primitiver.js';\nimport { markerSvarSett, merkNyeSvar } from './nyttSvar.js';\nimport { Sporingslinje, sporingsledd } from './Sporingslinje.js';\nimport { formaterFrist, statusVisning, venterVisning } from './status.js';\nimport { tekst } from './tekster.js';\n\n/**\n * 2j — «Mine innspill» (DD-27).\n *\n * Tre ting skjer her som ikke skjer noe annet sted:\n *\n * - **Offline-køen er synlig** (DD-41). Raden som venter på nett står der den hører hjemme,\n * uten saksnummer og uten sporingslinje — serveren har ingen sak å spore. Shake er den\n * eneste leverandøren som viser dette til brukeren; en usynlig kø er ikke til å skille fra\n * tapt tekst.\n * - **Svaret står OVER sporingslinjen**, ordrett som i panelet (F14, DD-27): det er det\n * ferskeste som har skjedd. Innsenderen skal ikke måtte lete etter svaret i en e-post som\n * aldri kom — plattformen sender ingen e-post (K14).\n * - **«Legg til mer»** (DD-69): en åpen sak får en tekstknapp, bare når serveren sier\n * `canAddAddendum`. Trykk åpner ett felt INNE i kortet. Tilleggene står under innsenderens\n * egen tekst, FØR svaret, med nøytral kant: det er innsenderens ord, ikke en tråd.\n *\n * **R8.3 (widget-konsept v0.1, DD-08 presisert 2026-09-20):** statusen har to former, aldri\n * begge. En ÅPEN sak (`statusType` `reviewing`/`active`) viser {@link Sporingslinje} med\n * løftet i `body` under; en AVSLUTTET (`complete`/`closed`) viser pillen med løftet ved\n * siden av. Avvist har samme vekt som Rettet. Rekkefølgen i kortet er sakshodet →\n * innsenderens tekst → tilleggene → svaret → linjen/pillen → løftet.\n *\n * **F32/F33 (Følget, bygg 30):** mens et tillegg skrives, tar «Send» og «Avbryt» fotens\n * plass, og «Send nytt innspill» er borte: én primærhandling om gangen (DD-69).\n * Android-tilbake lukker BARE feltet ({@link MineInnspillHandtak.lukkFelt}) og beholder\n * teksten per sak, som skjemaet gjør (F1).\n */\n\n/** Det verten (Widget) trenger for Android-tilbake: lukk feltet før arket (F33). */\nexport interface MineInnspillHandtak {\n /** Lukker et åpent tillegg-felt og beholder teksten. `true` når det var ett å lukke. */\n lukkFelt(): boolean;\n}\n\nexport const MineInnspill = forwardRef<MineInnspillHandtak, {\n rader: MySubmission[];\n laster?: boolean;\n tenantName?: string;\n onNytt: () => void;\n /** Vertens lagring — «nytt svar» er per enhet, aldri noe plattformen vet (F14). */\n storage: InnspelStorage;\n /** DD-69: kjernens `subjects.addAddendum`. Utelatt = knappen finnes ikke (DD-26). */\n leggTil?: (submissionId: string, text: string) => Promise<SubmissionStatusView>;\n /** Den oppdaterte saken fra serveren etter et tillegg — byttes inn i `rader` av verten. */\n onOppdatert?: (sak: SubmissionStatusView) => void;\n /** Leietakerens grenser, som ved innsending (DD-44). */\n minTextLength?: number;\n textMaxLength?: number;\n /** F33: utkast per sak som overlever at lista lukkes og åpnes igjen. Verten eier det. */\n utkastLager?: Map<string, string>;\n}>(function MineInnspill({\n rader,\n laster,\n tenantName,\n onNytt,\n storage,\n leggTil,\n onOppdatert,\n minTextLength,\n textMaxLength,\n utkastLager,\n}, ref) {\n const tema = useTema();\n const min = minTextLength ?? 10;\n const maks = textMaxLength ?? 280;\n\n // DD-69: ett felt om gangen, i kortet det gjelder. Teksten beholdes til den er sendt\n // eller innsenderen avbryter — aldri mistet av en feil.\n const [apen, setApen] = useState<string | null>(null);\n const [utkast, setUtkast] = useState('');\n const [sender, setSender] = useState(false);\n const [feil, setFeil] = useState<{ id: string; tekst: string } | undefined>();\n const [lagtTil, setLagtTil] = useState<string | undefined>();\n\n // F33: teksten per sak overlever at feltet lukkes med tilbake. «Avbryt» tømmer med vilje.\n const egetLager = useRef(new Map<string, string>());\n const lager = utkastLager ?? egetLager.current;\n\n // F32: feltet rulles fram når det åpnes, så det ikke ligger under tastaturet.\n const rulleRef = useRef<ScrollViewInstance>(null);\n const kortY = useRef(new Map<string, number>());\n\n const apneFelt = (id: string) => {\n setApen(id);\n setUtkast(lager.get(id) ?? '');\n setFeil(undefined);\n setLagtTil(undefined);\n const y = kortY.current.get(id);\n if (y !== undefined) rulleRef.current?.scrollTo({ y, animated: true });\n };\n\n const lukkFelt = (): boolean => {\n if (apen === null) return false;\n Keyboard.dismiss();\n if (utkast.trim()) lager.set(apen, utkast);\n else lager.delete(apen);\n setApen(null);\n setUtkast('');\n setFeil(undefined);\n return true;\n };\n\n const avbryt = () => {\n if (apen !== null) lager.delete(apen);\n setApen(null);\n setUtkast('');\n setFeil(undefined);\n };\n\n useImperativeHandle(ref, () => ({ lukkFelt }));\n\n const send = async (id: string) => {\n if (!leggTil) return;\n setSender(true);\n setFeil(undefined);\n try {\n const sak = await leggTil(id, utkast.trim());\n onOppdatert?.(sak);\n lager.delete(id);\n setApen(null);\n setUtkast('');\n setLagtTil(id);\n } catch (e) {\n // 409 er ikke en feil i innsenderens tekst, men regelen sagt av serveren (race):\n // samme setning som når knappen er borte. Serverens egen setning ellers. Nettet borte\n // er kjernens `NettverksFeil` (F34) — aldri rå i UI-et: «Ingen nett …», og teksten står.\n const kode = e instanceof InnspelApiError ? e.code : undefined;\n const tekstFeil =\n kode === 'addendum_limit_reached' ? tekst.tilleggTak\n : kode === 'submission_closed' ? tekst.tilleggLukket\n : e instanceof InnspelApiError && e.message ? tekst.tilleggFeil(e.message)\n : e instanceof NettverksFeil ? tekst.tilleggIngenNett\n : tekst.tilleggFeilGenerisk;\n setFeil({ id, tekst: tekstFeil });\n } finally {\n setSender(false);\n }\n };\n\n // F14: nye svar først, og merket. «Nytt» er «kommet siden forrige gang denne enheten\n // viste lista» — kjernen eier både definisjonen og lagringen, så widget og portal kan\n // ikke drive fra hverandre. Feiler lagringen, vises lista umerket i serverens rekkefølge.\n const [visning, setVisning] = useState<{ rad: MySubmission; nytt: boolean }[]>(() => rader.map((rad) => ({ rad, nytt: false })));\n useEffect(() => {\n let gjelder = true;\n void merkNyeSvar(rader, storage)\n .then((m) => {\n if (gjelder) setVisning(m);\n })\n .catch(() => {\n if (gjelder) setVisning(rader.map((rad) => ({ rad, nytt: false })));\n });\n return () => {\n gjelder = false;\n };\n }, [storage, rader]);\n\n // Lista er vist. Ved neste åpning er disse svarene ikke nye lenger.\n useEffect(() => {\n if (!laster && rader.length) void markerSvarSett(storage).catch(() => undefined);\n }, [storage, laster, rader]);\n\n const tom = !laster && rader.length === 0;\n\n return (\n <View style={{ flex: 1, gap: tema.space.md }}>\n {/* DD-19: tomheten er OVERSKRIFTEN, ikke en grå linje under «Mine innspill». */}\n {tom ? (\n <H sub={tenantName ? tekst.mineTomHint(tenantName) : tekst.mineTomHintGenerisk}>{tekst.mineTomTittel}</H>\n ) : (\n <H>{tekst.mineTittel}</H>\n )}\n\n {laster ? (\n <ActivityIndicator accessibilityLabel={tekst.mineLaster} color={tema.color.textSecondary} />\n ) : tom ? null : (\n <ScrollView ref={rulleRef} style={{ flex: 1 }} contentContainerStyle={{ gap: tema.space.md }} keyboardShouldPersistTaps=\"handled\">\n {visning.map(({ rad, nytt }) => {\n const venter = rad.pending === true;\n const v = venter ? venterVisning : statusVisning(rad.status, rad.type, rad.deadlineAt);\n const nokkel = venter ? rad.clientRef : rad.id;\n const sakId = venter ? undefined : rad.id;\n const svar = venter ? undefined : rad.reply;\n const tillegg = venter ? [] : (rad.addenda ?? []);\n const kanLeggeTil = !venter && !!leggTil && rad.canAddAddendum === true;\n const taketNådd = !venter && rad.canAddAddendum === false && tillegg.length >= 3;\n const feltApent = sakId !== undefined && apen === sakId;\n const brukt = utkast.length;\n const full = brukt >= maks;\n const visTeller = brukt >= maks * 0.8;\n // DD-08: én status, én form. Åpen sak har linjen, avsluttet har pillen.\n const ledd = venter ? [] : sporingsledd(rad, tenantName);\n\n return (\n <View\n key={nokkel}\n onLayout={(e) => {\n if (sakId !== undefined) kortY.current.set(sakId, e.nativeEvent.layout.y);\n }}\n >\n <Card dashed={venter} testID={`sakskort-${nokkel}`}>\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: tema.space.sm, flexWrap: 'wrap' }}>\n <Ikon\n navn={rad.type === 'onske' ? 'bulb' : 'bug'}\n storrelse=\"minste\"\n farge={tema.color.brand}\n />\n <Meta>\n {venter\n ? tekst.mineIkkeSendtHode(rad.type === 'onske' ? tekst.onske : tekst.feil)\n : tekst.sakHode(rad.type === 'onske' ? tekst.onske : tekst.feil, rad.number)}\n </Meta>\n {nytt ? <Pille testID=\"nytt-svar\">{tekst.nyttSvar}</Pille> : null}\n </View>\n\n {/* Innsenderens egne ord — `body`, alltid (DD-67). */}\n <Brodtekst testID={`sakstekst-${nokkel}`}>{rad.text}</Brodtekst>\n\n {tillegg.length > 0 ? (\n <View testID={`tillegg-${sakId}`} style={{ gap: tema.space.sm }}>\n {tillegg.map((a) => (\n <View\n key={a.id}\n style={{\n borderLeftWidth: tema.hairline * 2,\n borderLeftColor: tema.color.border,\n paddingLeft: tema.space.md,\n gap: tema.space.xs,\n }}\n >\n <Meta>{tekst.duLaTil(formaterFrist(a.createdAt))}</Meta>\n <Brodtekst testID={`tillegg-tekst-${a.id}`}>{a.text}</Brodtekst>\n </View>\n ))}\n </View>\n ) : null}\n\n {/* Svaret OVER linjen (F14) — og i `body`, det er beslutningsgrunnlaget. */}\n {svar ? (\n <View\n testID={`svar-${sakId}`}\n style={{\n borderLeftWidth: tema.hairline * 2,\n borderLeftColor: tema.color.brand,\n paddingLeft: tema.space.md,\n gap: tema.space.xs,\n }}\n >\n <Meta>\n {tenantName ? tekst.svarFra(tenantName, formaterFrist(svar.at)) : tekst.svarFraGenerisk(formaterFrist(svar.at))}\n </Meta>\n <Brodtekst testID={`svar-tekst-${sakId}`}>{svar.text}</Brodtekst>\n </View>\n ) : null}\n\n {ledd.length > 0 ? (\n <Sporingslinje ledd={ledd} testID={`spor-${sakId}`} />\n ) : (\n <StatusPill testID={`status-pille-${nokkel}`} ikon={v.ikon} etikett={v.etikett} fg={v.fg} bg={v.bg} />\n )}\n <Sek testID={`lofte-${nokkel}`}>{v.lofte}</Sek>\n\n {!venter && rad.attachmentRemoved ? (\n <View testID={`bilde-fjernet-${rad.id}`} style={{ flexDirection: 'row', gap: tema.space.xs, alignItems: 'center' }}>\n <Ikon navn=\"trash-outline\" storrelse=\"minste\" farge={tema.color.textMuted} />\n <Hint>{tekst.bildeFjernet}</Hint>\n </View>\n ) : null}\n\n {sakId !== undefined && lagtTil === sakId ? (\n <Text accessibilityLiveRegion=\"polite\" testID={`lagt-til-${sakId}`} style={{ color: tema.color.success, fontSize: tema.font.small }}>\n {tekst.lagtTil}\n </Text>\n ) : null}\n\n {feltApent ? (\n <View testID={`tillegg-felt-${sakId}`} style={{ gap: tema.space.sm }}>\n <Meta>{tekst.leggTilMerLabel}</Meta>\n <TextInput\n testID=\"tillegg-tekst\"\n accessibilityLabel={tekst.leggTilMerLabel}\n value={utkast}\n onChangeText={setUtkast}\n maxLength={maks}\n multiline\n numberOfLines={3}\n autoFocus\n placeholder={tekst.leggTilMerPlaceholder}\n placeholderTextColor={tema.color.textMuted}\n style={{\n backgroundColor: tema.color.surfaceRaised,\n borderWidth: tema.hairline,\n borderColor: full ? tema.color.warning : tema.color.borderStrong,\n borderRadius: tema.radius.md,\n padding: tema.space.md,\n color: tema.color.textPrimary,\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n minHeight: tema.touch * 2,\n textAlignVertical: 'top',\n }}\n />\n {visTeller ? (\n <Text\n testID=\"tillegg-teller\"\n accessibilityLiveRegion={full ? 'assertive' : 'polite'}\n style={{ alignSelf: 'flex-end', color: full ? tema.color.warning : tema.color.textMuted, fontSize: tema.font.small }}\n >\n {brukt} / {maks}\n {full ? tekst.tellerFull : ''}\n </Text>\n ) : null}\n {feil?.id === sakId ? (\n <Text accessibilityLiveRegion=\"assertive\" testID={`tillegg-feil-${sakId}`} style={{ color: tema.color.danger, fontSize: tema.font.small, lineHeight: tema.lineHeight.small }}>\n {feil.tekst}\n </Text>\n ) : null}\n {/* F32: «Send» og «Avbryt» står i foten, utenfor det som ruller — ikke her. */}\n </View>\n ) : kanLeggeTil ? (\n <Tekstknapp\n testID={`legg-til-mer-${sakId}`}\n ikon=\"add-outline\"\n label={tekst.leggTilMer}\n accessibilityLabel={tekst.leggTilMerLabel}\n onPress={() => sakId !== undefined && apneFelt(sakId)}\n />\n ) : taketNådd ? (\n <Hint>{tekst.tilleggTak}</Hint>\n ) : null}\n </Card>\n </View>\n );\n })}\n </ScrollView>\n )}\n\n {apen !== null ? (\n // F32: fotens plass — én primærhandling om gangen. «Send nytt innspill» er borte til\n // tillegget er sendt eller avbrutt, så første trykk aldri treffer feil knapp.\n <View testID=\"tillegg-fot\" style={{ gap: tema.space.sm }}>\n <View style={{ flexDirection: 'row', gap: tema.space.sm }}>\n <Btn\n testID=\"tillegg-send\"\n label={sender ? tekst.sender : tekst.send}\n disabled={utkast.length < min || sender}\n busy={sender}\n {...(utkast.length < min ? { hint: tekst.forKort(min) } : {})}\n onPress={() => void send(apen)}\n grow\n />\n <Btn testID=\"tillegg-avbryt\" label={tekst.avbryt} variant=\"secondary\" onPress={avbryt} grow />\n </View>\n <Hint>{tekst.leggTilMerHint}</Hint>\n </View>\n ) : (\n <Btn testID=\"send-nytt\" ikon=\"chatbox-outline\" label={tom ? tekst.sendForste : tekst.sendNytt} onPress={onNytt} />\n )}\n </View>\n );\n});\n","import type { InnspelStorage, MySubmission } from '@innspel/core';\n\n/**\n * F14 (brukerreisene 2026-09-15) — «Saken med nytt svar ligger ikke øverst og er ikke\n * merket.» Produkteier svarte i panelet; i appen sto feilen nummer to, under et ønske uten\n * nytt svar, og ingenting sa at det var kommet noe.\n *\n * Løftet er at alle får svar. Et svar innsenderen ikke oppdager, er et brutt løfte — og\n * lista er sortert på når saken ble SENDT (serveren: `OrderByDescending(CreatedAt)`), som\n * ikke sier noe om når det skjedde noe med den.\n *\n * **Hva «nytt» betyr her.** Plattformen eier aldri sluttbrukere, og skal ikke vite hva hun\n * har lest. «Nytt» er derfor «kommet siden forrige gang DENNE enheten viste lista»: ett\n * tidspunkt i lagringen verten allerede injiserer, ingen serverstate, ingen pseudonym, og\n * ingenting som forlater enheten. Bytter hun telefon, ser hun svarene som nye én gang til\n * — en ærlig pris for ikke å spore mennesker.\n *\n * **Hvorfor her og ikke i `@innspel/core`.** Kjernen har et hardt tak på 10 kB gzip\n * (CLAUDE.md), og modulen dyttet den til 10273 B. En visningsregel er ikke verdt kjernens\n * budsjett. Skal `@innspel/web` ha det samme, kopieres de femten linjene dit — billigere\n * enn å bryte taket eller å presse koden til den blir uleselig.\n *\n * Forkastet: sortering på svartidspunkt alene, uten merke — da ville et svar fra i fjor\n * ligget øverst for alltid. Forkastet: å la serveren avgjøre — den måtte lagret «sett» per\n * pseudonym, altså nettopp det plattformen ikke skal vite.\n */\n\nconst NØKKEL = 'innspel:svar-sett';\n\n/** En rad med om svaret på den er kommet siden sist enheten viste lista. */\nexport interface MedNyhet {\n rad: MySubmission;\n nytt: boolean;\n}\n\n/**\n * Radene med nye svar først, hver merket. Rekkefølgen ellers er serverens — nyest sendt\n * først, som fortsatt er riktig for alt uten nytt svar. Køede rader har intet svar og er\n * aldri nye. En ødelagt eller uleselig lagring gir «alt er nytt»: heller vise at det finnes\n * svar enn å gjemme dem.\n */\nexport async function merkNyeSvar(rader: readonly MySubmission[], storage: InnspelStorage): Promise<MedNyhet[]> {\n let grense = 0;\n try {\n grense = Number.parseInt((await storage.get(NØKKEL)) ?? '', 10) || 0;\n } catch {\n grense = 0;\n }\n const tid = (r: MySubmission) => (r.pending === true ? NaN : Date.parse(r.reply?.at ?? ''));\n const merket = rader.map((rad) => ({ rad, nytt: tid(rad) > grense }));\n return [...merket.filter((m) => m.nytt), ...merket.filter((m) => !m.nytt)];\n}\n\n/**\n * Setter «sist sett» til nå. Kalles når innsenderen HAR sett lista — ikke når den hentes i\n * bakgrunnen for tellingen på knappen (DD-62), for da har hun ikke sett noe. Feiler\n * lagringen, vises merket én gang for mye; det er ikke verdt å avbryte visningen for.\n */\nexport async function markerSvarSett(storage: InnspelStorage, nå: number = Date.now()): Promise<void> {\n try {\n await storage.set(NØKKEL, String(nå));\n } catch {\n /* vertens lagring — ikke vår å redde */\n }\n}\n","import { skaler, strokTilRekter, treffer, trykkTilRekt, type MaskPoint, type MaskRect } from '@innspel/core';\nimport React, { useCallback, useMemo, useRef, useState, type RefObject } from 'react';\nimport { Image, Pressable, StyleSheet, Text, View, type GestureResponderEvent, type LayoutChangeEvent } from 'react-native';\nimport { screenRules } from '../generated/tokens.js';\nimport { Ikon } from '../Ikon.js';\nimport type { ScreenshotCapture, ViewRef } from '../skjermbilde.js';\nimport { useTema } from '../tema.js';\nimport { Btn, H, Hint } from './primitiver.js';\nimport { tekst } from './tekster.js';\n\nexport type MaskVerktoy = 'felt' | 'pensel';\n\n/**\n * 2f — skjermbildet, tatt ved trykk og forhåndsvist (K4). Tre likestilte\n * maskeringsveier (DD-40): «Masker felt» (ett trykk legger en boks), «Tegn over»\n * (fingerstrøk) og «Masker all tekst» (heldekkende uskarphet — se DD-40,\n * presisert for RN). Private views (DD-39) ligger der FØR innsenderen ser bildet,\n * merket «Maskert av appen», og kan ikke fjernes. Egne masker fjernes med ett\n * trykk på dem.\n *\n * Maskeringen skjer i bitmapen ved komposisjon: bildet vises med maskeringslagene\n * over, og «Legg ved og fortsett» fanger denne viewen på nytt. Det er komposittet\n * som lastes opp — rå-URI-en forlater aldri widgeten.\n *\n * Fargene her er `screenRules`: det ene stedet temaet ikke gjelder, fordi\n * maskene må være synlige uansett hva skjermbildet selv inneholder.\n */\nexport function Skjermbilde({\n bilde,\n automaskerRot,\n rotStorrelse,\n previewRef,\n komponerer,\n kilde = 'skjerm',\n notat,\n onFjern,\n onLeggVed,\n}: {\n bilde: ScreenshotCapture;\n /** Private views i vertsappens punkter (relativt til rot-viewen). */\n automaskerRot: MaskRect[];\n rotStorrelse: { width: number; height: number };\n previewRef: RefObject<ViewRef | null>;\n komponerer: boolean;\n /** Fra galleriet: private views kan ikke gjelde, og forhåndsvisningen sier det. */\n kilde?: 'skjerm' | 'galleri';\n /** Vertens setning ved bildesteget. */\n notat?: string;\n onFjern: () => void;\n onLeggVed: () => void;\n}) {\n const tema = useTema();\n const [verktoy, setVerktoy] = useState<MaskVerktoy>('pensel');\n const [allTekst, setAllTekst] = useState(false);\n const [egne, setEgne] = useState<MaskRect[]>([]);\n const [ramme, setRamme] = useState<{ width: number; height: number } | null>(null);\n const strok = useRef<MaskPoint[]>([]);\n\n // Bildet tilpasses rammen med bevart sideforhold; alt annet regnes i visningens punkter.\n const visning = useMemo(() => {\n if (!ramme) return null;\n const s = Math.min(ramme.width / bilde.width, ramme.height / bilde.height);\n return { width: Math.floor(bilde.width * s), height: Math.floor(bilde.height * s) };\n }, [ramme, bilde.width, bilde.height]);\n\n const automasker = useMemo(\n () => (visning ? automaskerRot.map((r) => skaler(r, rotStorrelse, visning)) : []),\n [automaskerRot, rotStorrelse, visning],\n );\n\n const onLayout = useCallback((e: LayoutChangeEvent) => {\n const { width, height } = e.nativeEvent.layout;\n setRamme({ width, height });\n }, []);\n\n const punkt = (e: GestureResponderEvent): MaskPoint => ({ x: e.nativeEvent.locationX, y: e.nativeEvent.locationY });\n\n const onGrant = (e: GestureResponderEvent) => {\n if (!visning) return;\n const p = punkt(e);\n // Ett trykk på en egen maske angrer den (wireframe 2f). Private views rører den aldri.\n const treff = egne.findIndex((r) => treffer(p, r));\n if (treff >= 0) {\n setEgne((x) => x.filter((_, i) => i !== treff));\n return;\n }\n if (verktoy === 'felt') {\n const r = trykkTilRekt(p, { width: tema.touch * 4, height: tema.touch }, visning);\n if (r) setEgne((x) => [...x, r]);\n return;\n }\n strok.current = [p];\n };\n\n const onMove = (e: GestureResponderEvent) => {\n if (verktoy !== 'pensel' || strok.current.length === 0) return;\n strok.current.push(punkt(e));\n };\n\n const onRelease = () => {\n if (verktoy !== 'pensel' || !visning || strok.current.length === 0) return;\n const rekter = strokTilRekter(strok.current, screenRules.brushWidth, visning);\n strok.current = [];\n if (rekter.length) setEgne((x) => [...x, ...rekter]);\n };\n\n const knapp = (id: MaskVerktoy | 'allTekst', ikon: string, label: string) => {\n const valgt = id === 'allTekst' ? allTekst : verktoy === id && !allTekst;\n return (\n <Pressable\n key={id}\n testID={`verktoy-${id}`}\n accessibilityRole=\"button\"\n accessibilityLabel={label}\n accessibilityState={{ selected: valgt }}\n onPress={() => (id === 'allTekst' ? setAllTekst((a) => !a) : setVerktoy(id))}\n style={{\n flex: 1,\n minHeight: tema.touch,\n alignItems: 'center',\n justifyContent: 'center',\n gap: tema.space.xs,\n padding: tema.space.xs,\n borderRadius: tema.radius.md,\n borderWidth: tema.hairline,\n borderColor: tema.color.actionSecondaryBorder,\n borderBottomWidth: valgt ? tema.hairline * 2 : tema.hairline,\n borderBottomColor: valgt ? tema.color.textPrimary : tema.color.actionSecondaryBorder,\n backgroundColor: valgt ? tema.color.surfaceRaised : 'transparent',\n }}\n >\n <Ikon navn={ikon} farge={tema.color.textPrimary} />\n <Text\n style={{\n color: tema.color.textPrimary,\n fontSize: tema.font.small,\n fontWeight: valgt ? tema.weight.semibold : tema.weight.regular,\n }}\n >\n {label}\n </Text>\n </Pressable>\n );\n };\n\n const a11y = tekst.skjermbildeA11y(automasker.length, egne.length, allTekst);\n\n // Høyden kommer ovenfra: arket har fast høyde i dette steget (Widget.tsx), rammen får det\n // som er igjen etter overskrift, verktøylinje og fot, og forhåndsvisningen ligger OVER rammen\n // i stedet for i flyten. Før vokste rammen med visningen, onLayout ga ny ramme, og et 9:20-\n // bilde endte begrenset av bredden alene — knappene havnet under navigasjonslinja. Ingen\n // scroll: berøring på forhåndsvisningen er maskering.\n return (\n <View testID=\"skjermbilde-steg\" style={{ flexGrow: 1, flexShrink: 1, gap: tema.space.md }}>\n <H sub={kilde === 'galleri' ? tekst.skjermbildeUnderGalleri : tekst.skjermbildeUnder}>{tekst.skjermbildeTittel}</H>\n {notat ? (\n <View testID=\"bilde-notat\">\n <Hint>{notat}</Hint>\n </View>\n ) : null}\n\n <View accessibilityRole=\"toolbar\" accessibilityLabel={tekst.maskering} style={{ flexDirection: 'row', gap: tema.space.sm }}>\n {knapp('felt', 'scan-outline', tekst.maskerFelt)}\n {knapp('pensel', 'brush-outline', tekst.tegnOver)}\n {knapp('allTekst', 'grid-outline', tekst.maskerAllTekst)}\n </View>\n\n <View\n testID=\"skjermbilde-ramme\"\n onLayout={onLayout}\n style={{\n flexGrow: 1,\n flexShrink: 1,\n flexBasis: 0,\n minHeight: tema.touch * 5,\n backgroundColor: screenRules.previewBackdrop,\n borderRadius: tema.radius.md,\n overflow: 'hidden',\n }}\n >\n <View testID=\"skjermbilde-flate\" pointerEvents=\"box-none\" style={[StyleSheet.absoluteFill, { alignItems: 'center', justifyContent: 'center' }]}>\n {visning ? (\n <View\n ref={previewRef}\n collapsable={false}\n testID=\"forhandsvisning\"\n accessibilityRole=\"image\"\n accessibilityLabel={a11y}\n onStartShouldSetResponder={() => !komponerer}\n onMoveShouldSetResponder={() => !komponerer}\n onResponderGrant={onGrant}\n onResponderMove={onMove}\n onResponderRelease={onRelease}\n onResponderTerminate={onRelease}\n style={{ width: visning.width, height: visning.height, backgroundColor: screenRules.previewBackdrop }}\n >\n <Image\n testID=\"skjermbilde-bilde\"\n source={{ uri: bilde.uri }}\n blurRadius={allTekst ? screenRules.textBlurRadius : 0}\n style={{ width: visning.width, height: visning.height }}\n accessibilityIgnoresInvertColors\n />\n\n {automasker.map((r, i) => (\n <View\n key={`auto-${i}`}\n testID={`automask-${i}`}\n pointerEvents=\"none\"\n style={{\n position: 'absolute',\n left: r.x,\n top: r.y,\n width: r.width,\n height: r.height,\n backgroundColor: screenRules.autoMaskFill,\n borderWidth: tema.hairline * 2,\n borderColor: screenRules.autoMaskStroke,\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n {!komponerer ? (\n // Etiketten står PÅ den maskerte flaten og måles mot NETTOPP den\n // (skjermKontrastpar i theme.ts). textSecondary var 2,2:1 (C11a).\n // Ikonet arver samme farge: det er unntaket i «Styling» — maskeringen\n // tegnes i faste signalfarger, ikke i palettens.\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: tema.space.xs }}>\n <Ikon navn=\"lock-closed-outline\" storrelse=\"minste\" farge={screenRules.autoMaskText} />\n <Text style={{ color: screenRules.autoMaskText, fontSize: tema.font.small }} numberOfLines={1}>\n {tekst.maskertAvAppen}\n </Text>\n </View>\n ) : null}\n </View>\n ))}\n\n {egne.map((r, i) => (\n <View\n key={`egen-${i}`}\n testID={`maske-${i}`}\n pointerEvents=\"none\"\n style={{ position: 'absolute', left: r.x, top: r.y, width: r.width, height: r.height, backgroundColor: screenRules.brushFill }}\n />\n ))}\n </View>\n ) : null}\n </View>\n </View>\n\n {automasker.length ? (\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: tema.space.xs }}>\n <Ikon navn=\"lock-closed-outline\" storrelse=\"minste\" farge={tema.color.textMuted} />\n <Hint>{tekst.maskertAvAppenHint}</Hint>\n </View>\n ) : null}\n {egne.length ? <Hint>{tekst.dittStrok}</Hint> : null}\n {allTekst ? <Hint>{tekst.allTekstHint}</Hint> : null}\n\n <View testID=\"skjermbilde-fot\" style={{ flexShrink: 0, gap: tema.space.sm }}>\n {/* «Angre siste» som KNAPP: å treffe en maske med fingeren er en motorisk\n oppgave, og angrefunksjonen kan ikke være den eneste veien tilbake — samme\n grunn som DD-40 gir både pensel og knapp (C11d). */}\n <Btn\n variant=\"secondary\"\n testID=\"angre-siste\"\n label={tekst.angreSiste}\n accessibilityLabel={tekst.angreSisteA11y}\n disabled={komponerer || egne.length === 0}\n onPress={() => setEgne((x) => x.slice(0, -1))}\n />\n <Btn\n variant=\"danger\"\n testID=\"fjern-bildet\"\n ikon=\"trash-outline\"\n label={tekst.fjernBildet}\n onPress={onFjern}\n disabled={komponerer}\n />\n <Btn testID=\"legg-ved\" label={tekst.leggVed} onPress={onLeggVed} disabled={komponerer || !visning} />\n </View>\n </View>\n );\n}\n","import React, { useEffect, useRef } from 'react';\nimport { View, type StyleProp, type ViewStyle } from 'react-native';\nimport { useSkjermbilde, type ViewRef } from './skjermbilde.js';\n\n/**\n * Merk det som aldri skal være med på et skjermbilde (DD-39): navn i en liste,\n * et kontonummer, en samtale. Pakk det inn, og widgeten maskerer det FØR\n * innsenderen ser forhåndsvisningen — som «Maskert av appen», og penselen kan\n * ikke oppheve det. Din kode er sannheten, ikke brukerens presisjon.\n *\n * Uten skjermbilde-adapter gjør komponenten ingenting utover å rendre barna.\n *\n * @example\n * ```tsx\n * <InnspelPrivate><Text>{bruker.navn}</Text></InnspelPrivate>\n * ```\n */\nexport function InnspelPrivate({ children, style }: { children?: React.ReactNode; style?: StyleProp<ViewStyle> }) {\n const ref = useRef<ViewRef | null>(null);\n const kontekst = useSkjermbilde();\n const registrer = kontekst?.privat.register;\n\n useEffect(() => {\n if (!registrer) return;\n return registrer(ref);\n }, [registrer]);\n\n // collapsable={false}: Android slår ellers sammen en View uten stil med\n // forelderen, og da finnes det ingenting å måle.\n return (\n <View ref={ref} collapsable={false} style={style} testID=\"innspel-privat\">\n {children}\n </View>\n );\n}\n","import {\n InnspelApiError,\n type FollowUpView,\n type MyPrograms,\n type ParticipationView,\n type ProgramTask,\n type ProgramView,\n type TaskOutcome,\n} from '@innspel/core';\nimport React, { useCallback, useEffect, useState } from 'react';\nimport { Modal, Pressable, View } from 'react-native';\nimport { Ikon } from '../Ikon.js';\nimport { useInnspel } from '../InnspelProvider.js';\nimport { useTema } from '../tema.js';\nimport { Banner, Brodtekst, Btn, Card, H, Tekstknapp } from '../widget/primitiver.js';\nimport { periode } from './periode.js';\nimport { tekst } from '../widget/tekster.js';\nimport { Aksept } from './Aksept.js';\nimport { HvordanGikkDet } from './HvordanGikkDet.js';\nimport { Oppfolging } from './Oppfolging.js';\nimport { Oppgaver } from './Oppgaver.js';\nimport { ProgramSpor, programErOver } from './ProgramSpor.js';\n\ntype Dialog = { type: 'oppgave'; task: ProgramTask } | { type: 'oppfolging'; oppfolging: FollowUpView };\n\n/**\n * Betaprogrammet i vertsappen: 3a banneret, 3b aksepten og deltakelsen med «Gå ut» (DD-36).\n * Sett den der vertsappen vil ha invitasjonen — typisk øverst på hjemskjermen. Uten\n * invitasjon og uten deltakelse rendrer den INGENTING.\n *\n * **Tokenet kommer fra verten** (DD-12). Plattformen sender aldri invitasjonen: leietakeren\n * får `program.invitation_created` med tokenet, løser pseudonymet til sin egen bruker og\n * sender lenken i sin egen kanal. Verten fanger tokenet fra dyplenken og gir det hit. Uten\n * det viser banneret fortsatt invitasjonen — men «Bli med» er inaktiv, med grunnen på\n * skjermen, i stedet for å feile ved trykk (DD-02).\n *\n * **R8.3 (widget-konsept v0.1, P1 (a)):** deltakelsen er et SAKSKORT med sporingslinje —\n * «Du ble med → N av M gjort → Programmet er over <dato>», der sluttdatoen er helten — og\n * oppgavene er en tett liste med «Gjort» tonet per rad. Merkefargen på en flate er for det\n * som er sendt (DD-41); et program pågår.\n *\n * **Kontakttaket står ingen steder i det testeren leser** (DD-14, presisert 2026-09-20):\n * ikke i banneret, ikke i deltakelsens meta-linje, ikke i oppfølgingskortet. `contactsSent`\n * og `maxContacts` finnes i kontrakten og leses av PANELET.\n *\n * @example\n * ```tsx\n * <InnspelProgram invitationToken={tokenFraDyplenke} />\n * ```\n */\nexport function InnspelProgram({\n invitationToken,\n onEndring,\n onMeldFeil,\n}: {\n /** Engangs-tokenet fra leietakerens egen kanal, typisk fanget fra en dyplenke. */\n invitationToken?: string;\n /** Kalles når testeren blir med eller går ut — for vertens egen navigasjon. */\n onEndring?: (deltakelse: ParticipationView | null) => void;\n /**\n * Kalles når testeren vil melde at en oppgave ikke gikk — verten åpner feilsporet med\n * oppgaven som kontekst. Utelatt = tilbudet vises ikke (DD-26).\n */\n onMeldFeil?: (task: ProgramTask) => void;\n}) {\n const { client } = useInnspel();\n const tema = useTema();\n\n const [mine, setMine] = useState<MyPrograms | undefined>();\n const [deltakelse, setDeltakelse] = useState<ParticipationView | undefined>();\n const [viserAksept, setViserAksept] = useState(false);\n const [viserGaaUt, setViserGaaUt] = useState(false);\n const [avvist, setAvvist] = useState(false);\n const [sender, setSender] = useState(false);\n const [feil, setFeil] = useState<string | undefined>();\n const [dialog, setDialog] = useState<Dialog | undefined>();\n const [svarFeil, setSvarFeil] = useState<string | undefined>();\n const [lagtBort, setLagtBort] = useState<ReadonlySet<string>>(new Set());\n\n const leggBort = useCallback((id: string) => setLagtBort((s) => new Set([...s, id])), []);\n\n /**\n * «Lagre» i «Hvordan gikk det?»: én dialog, to mål. Fullføringen legges på deltakelsen så\n * raden viser svaret straks; et svar på oppfølging tar kortet ut av lista.\n *\n * `meldEtterpaa`: «Meld det som feil» lagrer FØRST og gir så oppgaven til verten — svaret\n * skal ikke gå tapt fordi hun valgte den veien ut (DD-02).\n */\n const lagreSvar = useCallback(\n async (outcome: TaskOutcome, text: string | undefined, meldEtterpaa = false) => {\n if (!dialog || !deltakelse) return;\n setSender(true);\n setSvarFeil(undefined);\n try {\n if (dialog.type === 'oppgave') {\n const ny = await client.programs.completeTask(dialog.task.id, { outcome, ...(text ? { text } : {}) });\n setDeltakelse({ ...deltakelse, completions: [...deltakelse.completions, ny] });\n if (meldEtterpaa && onMeldFeil) onMeldFeil(dialog.task);\n } else {\n await client.programs.respond(dialog.oppfolging.id, { outcome, ...(text ? { text } : {}) });\n setMine((m) => (m ? { ...m, pendingFollowUps: m.pendingFollowUps.filter((f) => f.id !== dialog.oppfolging.id) } : m));\n }\n setDialog(undefined);\n } catch (e) {\n setSvarFeil(e instanceof InnspelApiError ? e.message : 'tjeneren svarte ikke.');\n } finally {\n setSender(false);\n }\n },\n [client, deltakelse, dialog, onMeldFeil],\n );\n\n // Anonym modus har ingen programmer, og skal ikke spørre: kallet ville blitt 401 uansett,\n // og et kall som alltid feiler er ikke en tilstand — det er støy.\n useEffect(() => {\n if (client.isAnonymous) return;\n let levende = true;\n void client.programs\n .list()\n .then((svar) => {\n if (!levende) return;\n setMine(svar);\n // Aktiv deltakelse er det som vises; trukket kommer aldri tilbake fra listen.\n setDeltakelse(svar.participations.find((p) => p.status !== 'trukket'));\n })\n // Programmet er et tilbud, aldri en sperre: svarer ikke kallet, finnes banneret ikke.\n .catch(() => undefined);\n return () => {\n levende = false;\n };\n }, [client]);\n\n const bliMed = useCallback(async () => {\n if (!invitationToken) return;\n setSender(true);\n setFeil(undefined);\n try {\n const ny = await client.programs.accept(invitationToken);\n setDeltakelse(ny);\n setViserAksept(false);\n onEndring?.(ny);\n } catch (e) {\n setFeil(e instanceof InnspelApiError ? e.message : 'tjeneren svarte ikke.');\n } finally {\n setSender(false);\n }\n }, [client, invitationToken, onEndring]);\n\n const gaaUt = useCallback(async () => {\n if (!deltakelse) return;\n setSender(true);\n try {\n await client.programs.withdraw(deltakelse.id);\n setDeltakelse(undefined);\n setViserGaaUt(false);\n onEndring?.(null);\n } catch (e) {\n setFeil(e instanceof InnspelApiError ? e.message : 'tjeneren svarte ikke.');\n } finally {\n setSender(false);\n }\n }, [client, deltakelse, onEndring]);\n\n // Deltakelsen vinner over invitasjonen: har man sagt ja, er banneret ferdig.\n const invitasjon = deltakelse ? undefined : mine?.invitations[0];\n const program: ProgramView | undefined = deltakelse?.program ?? invitasjon?.program;\n\n if (!program) return null;\n\n if (deltakelse) {\n // 3d: kortene for DETTE programmet, i den rekkefølgen kontaktene kom. Et kort testeren\n // har lagt bort i denne økten vises ikke igjen før neste oppstart.\n const kort = (mine?.pendingFollowUps ?? [])\n .filter((f) => f.programId === program.id && !lagtBort.has(f.id))\n .sort((a, b) => a.emittedAt.localeCompare(b.emittedAt));\n const over = programErOver(deltakelse, program);\n\n return (\n <View testID=\"program-deltakelse\" accessibilityLabel={tekst.deltakelseRegion} style={{ gap: tema.space.md }}>\n {/* Oppfølgingskortet ligger OVER deltakelseskortet, ikke i det: det er en annen\n avsender-handling, og deltakelsen står som den står. */}\n {kort.map((f) => (\n <Oppfolging\n key={f.id}\n oppfolging={f}\n onSenere={() => leggBort(f.id)}\n onSvar={() => {\n setSvarFeil(undefined);\n setDialog({ type: 'oppfolging', oppfolging: f });\n }}\n onAapneOppgavene={() => leggBort(f.id)}\n onGaaUt={() => setViserGaaUt(true)}\n />\n ))}\n\n <Card style={{ gap: tema.space.md }}>\n <H>{program.name}</H>\n <ProgramSpor deltakelse={deltakelse} program={program} />\n {feil ? <Banner live ikon=\"warning-outline\" tone=\"warning\" children={feil} /> : null}\n <Oppgaver\n tasks={program.tasks}\n completions={deltakelse.completions}\n over={over}\n onGjort={(task) => {\n setSvarFeil(undefined);\n setDialog({ type: 'oppgave', task });\n }}\n />\n {/* DD-36: «Gå ut» er ALLTID synlig — og i TEKSTFARGEN. Den røde er dialogen (DD-53). */}\n <Tekstknapp noytral testID=\"gaa-ut\" ikon=\"exit-outline\" label={tekst.gaaUt} onPress={() => setViserGaaUt(true)} />\n </Card>\n\n {dialog ? (\n <HvordanGikkDet\n {...(dialog.type === 'oppgave' ? { under: dialog.task.title } : { spoersmaal: dialog.oppfolging.question })}\n sender={sender}\n {...(svarFeil ? { feil: svarFeil } : {})}\n {...(dialog.type === 'oppgave' && onMeldFeil\n ? { onMeldFeil: (outcome: TaskOutcome, text: string | undefined) => void lagreSvar(outcome, text, true) }\n : {})}\n onLagre={(outcome, text) => void lagreSvar(outcome, text)}\n onLukk={() => setDialog(undefined)}\n />\n ) : null}\n\n {viserGaaUt ? (\n <Modal visible transparent animationType=\"fade\" onRequestClose={() => setViserGaaUt(false)} accessibilityViewIsModal>\n <View style={{ flex: 1, backgroundColor: tema.color.scrim, justifyContent: 'flex-end', padding: tema.space.md }}>\n <View\n testID=\"gaa-ut-dialog\"\n accessibilityViewIsModal\n style={{\n backgroundColor: tema.color.surface,\n borderRadius: tema.radius.lg,\n borderWidth: tema.hairline,\n borderColor: tema.color.borderStrong,\n padding: tema.space.md,\n gap: tema.space.md,\n }}\n >\n <H nivaa={3}>{tekst.gaaUtTittel}</H>\n <Brodtekst>{tekst.gaaUtTekst(program.name)}</Brodtekst>\n <View style={{ flexDirection: 'row', gap: tema.space.sm }}>\n {/* «Bli værende» står først: utgangen er et valg, ikke en felle med angreknapp. */}\n <Btn grow variant=\"secondary\" testID=\"bli-vaerende\" label={tekst.bliVaerende} onPress={() => setViserGaaUt(false)} />\n <Btn\n grow\n variant=\"danger\"\n testID=\"bekreft-gaa-ut\"\n ikon=\"exit-outline\"\n label={tekst.gaaUtBekreft}\n disabled={sender}\n onPress={() => void gaaUt()}\n />\n </View>\n </View>\n </View>\n </Modal>\n ) : null}\n </View>\n );\n }\n\n if (!invitasjon || avvist) return null;\n\n return (\n <>\n {/* 3a — invitasjonsbanneret. Flaten er `brandBg` UTEN ramme: flaten er nok. */}\n <View\n testID=\"program-banner\"\n accessibilityLabel={tekst.invitasjonRegion}\n style={{\n backgroundColor: tema.color.brandBg,\n borderRadius: tema.radius.lg,\n padding: tema.space.md,\n gap: tema.space.md,\n }}\n >\n <View style={{ flexDirection: 'row', gap: tema.space.sm, alignItems: 'flex-start' }}>\n <View style={{ paddingTop: tema.space.xs }}>\n <Ikon navn=\"flask-outline\" farge={tema.color.brand} />\n </View>\n <View style={{ flex: 1, minWidth: 0 }}>\n {/* Spørsmålet er kortets HELT, og ÉN meta-linje bærer det kontrakten har:\n antall oppgaver og perioden. Kontakttaket står ikke her (DD-14). */}\n <H nivaa={3} meta={tekst.invitasjonMeta(program.tasks.length, periode(program.opensAt, program.closesAt))}>\n {tekst.invitasjonHva(program.name)}\n </H>\n </View>\n {/* Avvisbart: invitasjonen er et tilbud. Den kommer tilbake ved neste oppstart. */}\n <Pressable\n testID=\"avvis-invitasjon\"\n accessibilityRole=\"button\"\n accessibilityLabel={tekst.avvisInvitasjon}\n onPress={() => setAvvist(true)}\n style={{ minWidth: tema.touch, minHeight: tema.touch, alignItems: 'center', justifyContent: 'center' }}\n >\n <Ikon navn=\"close-outline\" farge={tema.color.textSecondary} />\n </Pressable>\n </View>\n {feil && !viserAksept ? <Banner live ikon=\"warning-outline\" tone=\"danger\" children={tekst.akseptFeil(feil)} /> : null}\n {/* Kortets ENE handling, fylt. */}\n <Btn testID=\"les-mer\" label={tekst.lesMer} onPress={() => setViserAksept(true)} />\n </View>\n\n {viserAksept ? (\n <Aksept\n program={program}\n harToken={!!invitationToken}\n sender={sender}\n {...(feil ? { feil } : {})}\n onBliMed={() => void bliMed()}\n onLukk={() => setViserAksept(false)}\n />\n ) : null}\n </>\n );\n}\n","/**\n * Datoene testeren ser i aksepten (DD-32): «10.–24. oktober», eller med begge\n * måneder når perioden krysser et månedsskifte. Norsk bokmål, ingen klokkeslett —\n * et program varer i dager, og et tidspunkt ville lovet en presisjon som ikke finnes.\n */\nconst MANEDER = [\n 'januar',\n 'februar',\n 'mars',\n 'april',\n 'mai',\n 'juni',\n 'juli',\n 'august',\n 'september',\n 'oktober',\n 'november',\n 'desember',\n] as const;\n\nexport function periode(opensAt: string, closesAt: string): string {\n const fra = new Date(opensAt);\n const til = new Date(closesAt);\n if (Number.isNaN(fra.getTime()) || Number.isNaN(til.getTime())) return '';\n\n const sammeManed = fra.getMonth() === til.getMonth() && fra.getFullYear() === til.getFullYear();\n return sammeManed\n ? `${fra.getDate()}.–${til.getDate()}. ${MANEDER[til.getMonth()]}`\n : `${fra.getDate()}. ${MANEDER[fra.getMonth()]} – ${til.getDate()}. ${MANEDER[til.getMonth()]}`;\n}\n\n/**\n * Tiden aksepten skriver øverst (DD-32, presisert 2026-09-20): **tallet skal være SANT.**\n *\n * Fram til R8.3 sto her `minutterPerOppgave()`, som rundet av GJENNOMSNITTET: anslagene\n * 5, 3 og 2 minutter ble «ca. 3 min hver», som ikke er sant for noen av de tre — mens\n * radene under sa 5, 3 og 2. Regelen nå: `like` bare når alle oppgavene har samme anslag,\n * og da er tallet det anslaget («ca. M min hver»); ellers er tallet SUMMEN («ca. M min i\n * alt»). Anslaget er obligatorisk ved opprettelse, så lista er aldri tom i praksis.\n */\nexport function minutterLinje(tasks: ReadonlyArray<{ estimatedMinutes: number }>): { minutter: number; like: boolean } {\n if (tasks.length === 0) return { minutter: 0, like: true };\n const forste = tasks[0]!.estimatedMinutes;\n const like = tasks.every((t) => t.estimatedMinutes === forste);\n return like ? { minutter: forste, like: true } : { minutter: tasks.reduce((sum, t) => sum + t.estimatedMinutes, 0), like: false };\n}\n","import type { ProgramView } from '@innspel/core';\nimport React from 'react';\nimport { Linking, Modal, Pressable, ScrollView, Text, View } from 'react-native';\nimport { knownIssueStatus } from '../generated/tokens.js';\nimport { Ikon } from '../Ikon.js';\nimport { useTema } from '../tema.js';\nimport { Banner, Btn, H, Hint, Meta, Sek } from '../widget/primitiver.js';\nimport { tekst } from '../widget/tekster.js';\nimport { minutterLinje, periode } from './periode.js';\n\n/**\n * 3b — aksepten: forventningsavklaringen, i DD-13s rekkefølge — hva testes · hvor lenge ·\n * hva vi ber om · kjente feil (hele lista) · hva som samles inn · at det kommer høyst N\n * spørsmål og at hun kan gå ut.\n *\n * Fordi «hva testes» står først, er PROGRAMNAVNET skjermens helt og hypotesen ingressen\n * (DD-13, presisert 2026-09-20) — det er ikke et valg, det følger av rekkefølgen.\n *\n * **Tallene øverst (DD-32, presisert 2026-09-20)** skal være SANNE: hver oppgave bærer sitt\n * eget `estimatedMinutes` på raden, og linja øverst bærer SUMMEN når anslagene er ulike.\n * «ca. M min hver» står bare når alle er like. Se {@link minutterLinje}.\n *\n * **Kontakttaket som tall står ikke her** (DD-14, presisert 2026-09-20). Det testeren får\n * vite, er at det kommer HØYST N spørsmål — N er `maxContacts`, et tak som kan senkes og\n * aldri heves, og antall oppfølginger er malene, som kan være færre. «Vi tar kontakt maks 3\n * ganger» lovet noe som ikke er sant.\n *\n * Seksjonene er overskrift + innhold, ikke fire rammede kort. Vilkår er en LENKE, aldri en\n * avkryssing (DD-37); ved forpliktelsesfri form (tvunget når leietakeren har mindreårige\n * brukere, K37) finnes ingen vilkår ut over at man kan gå ut når som helst.\n *\n * «Bli med» krever tokenet leietakeren sendte i sin egen kanal (DD-12). Uten det verten har\n * fanget fra dyplenken er knappen inaktiv, med grunnen på skjermen — forklart lås, aldri en\n * 4xx som første møte med regelen (DD-02).\n */\nfunction Seksjon({ tittel, children }: { tittel: string; children: React.ReactNode }) {\n const tema = useTema();\n return (\n <View style={{ gap: tema.space.sm }}>\n <Text\n accessibilityRole=\"header\"\n style={{ color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body, fontWeight: tema.weight.bold }}\n >\n {tittel}\n </Text>\n {children}\n </View>\n );\n}\n\nexport function Aksept({\n program,\n harToken,\n sender,\n feil,\n onBliMed,\n onLukk,\n}: {\n program: ProgramView;\n harToken: boolean;\n sender: boolean;\n feil?: string;\n onBliMed: () => void;\n onLukk: () => void;\n}) {\n const tema = useTema();\n const { minutter, like } = minutterLinje(program.tasks);\n const tall = (like ? tekst.akseptTallHver : tekst.akseptTallSum)(\n program.tasks.length,\n minutter,\n periode(program.opensAt, program.closesAt),\n );\n const medVilkar = !!program.termsUrl && !program.commitmentFree;\n\n return (\n <Modal visible transparent animationType=\"slide\" onRequestClose={onLukk} accessibilityViewIsModal>\n <View style={{ flex: 1, backgroundColor: tema.color.scrim, justifyContent: 'flex-end' }}>\n <View\n testID=\"program-aksept\"\n accessibilityViewIsModal\n style={{\n backgroundColor: tema.color.bg,\n borderTopLeftRadius: tema.radius.lg * 2,\n borderTopRightRadius: tema.radius.lg * 2,\n padding: tema.screenPadding,\n gap: tema.space.md,\n maxHeight: '92%',\n minHeight: '60%',\n }}\n >\n <View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>\n <Btn variant=\"ghost\" testID=\"aksept-tilbake\" ikon=\"arrow-back-outline\" label={tekst.tilbake} onPress={onLukk} />\n <View />\n </View>\n\n {feil ? <Banner live ikon=\"warning-outline\" tone=\"danger\" children={tekst.akseptFeil(feil)} /> : null}\n\n <ScrollView contentContainerStyle={{ gap: tema.space.lg }}>\n {/* DD-13: «hva testes» først — programnavnet er helten, hypotesen ingressen. */}\n <H testID=\"aksept-tittel\" sub={program.hypothesis}>\n {program.name}\n </H>\n\n {/* DD-32: tallene på én linje, FØR forklaringen. Summen, når anslagene er ulike. */}\n <Text\n testID=\"aksept-tall\"\n style={{\n color: tema.color.textPrimary,\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n fontWeight: tema.weight.semibold,\n }}\n >\n {tall}\n </Text>\n\n <Seksjon tittel={tekst.akseptOppgaver}>\n <View>\n {program.tasks.map((o, i) => (\n <View\n key={o.id}\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n gap: tema.space.sm,\n minHeight: tema.touch + tema.space.sm,\n paddingVertical: tema.space.sm,\n borderTopWidth: i === 0 ? 0 : tema.hairline,\n borderTopColor: tema.color.border,\n }}\n >\n <View\n style={{\n width: tema.space.lg,\n height: tema.space.lg,\n borderRadius: tema.radius.pill,\n borderWidth: tema.hairline * 2,\n borderStyle: 'dashed',\n borderColor: tema.color.borderStrong,\n }}\n />\n <View style={{ flex: 1, minWidth: 0 }}>\n <Text\n style={{ color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body, fontWeight: tema.weight.semibold }}\n >\n {o.title}\n </Text>\n {/* Oppgavens ENE meta-linje i `small` (DD-67), med sitt EGET anslag. */}\n <Meta>{tekst.oppgaveTid(o.estimatedMinutes, o.screenHint)}</Meta>\n </View>\n </View>\n ))}\n </View>\n </Seksjon>\n\n {program.knownIssues.length > 0 ? (\n <Seksjon tittel={tekst.akseptKjenteFeil}>\n <View>\n {program.knownIssues.map((k, i) => {\n // Samme rad som widgetens kjente feil-steg (DD-30s tre deler), uten\n // svarknappene: aksepten forteller, den spør ikke.\n const o = knownIssueStatus[k.status] ?? knownIssueStatus.aktiv;\n const rettet = k.status === 'fikset';\n const statusOrd = rettet && k.fixedIn ? tekst.rettetI(k.fixedIn) : o.etikett;\n const tillegg = !rettet && k.fixedIn ? `· ${tekst.rettesI(k.fixedIn).toLowerCase()}` : undefined;\n return (\n <View\n key={k.id}\n style={{\n gap: tema.space.xs,\n paddingVertical: tema.space.sm,\n borderTopWidth: i === 0 ? 0 : tema.hairline,\n borderTopColor: tema.color.border,\n }}\n >\n <Text\n style={{ color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body, fontWeight: tema.weight.semibold }}\n >\n {k.title}\n </Text>\n {k.workaround ? (\n <Sek>\n {tekst.omvei} {k.workaround}\n </Sek>\n ) : null}\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: tema.space.sm, flexWrap: 'wrap' }}>\n <View style={{ flexDirection: 'row', alignItems: 'center', gap: tema.space.xs }}>\n <Ikon navn={o.ikon} storrelse=\"minste\" farge={tema.color[o.fg as keyof typeof tema.color]} />\n <Text\n style={{\n color: tema.color[o.fg as keyof typeof tema.color],\n fontSize: tema.font.small,\n lineHeight: tema.lineHeight.small,\n fontWeight: tema.weight.semibold,\n }}\n >\n {statusOrd}\n </Text>\n </View>\n {tillegg ? <Meta>{tillegg}</Meta> : null}\n </View>\n </View>\n );\n })}\n </View>\n </Seksjon>\n ) : null}\n\n <Seksjon tittel={tekst.akseptInnsamling}>\n {/* Samme ord som kontekstlista i feltet: «enhet», ikke «plattform» (DD-50). */}\n <Sek>{tekst.akseptInnsamlingTekst}</Sek>\n {/* DD-37: lenke, aldri avkryssing — og ingen vilkår i forpliktelsesfri form. */}\n {medVilkar ? (\n <Pressable\n testID=\"vilkar-lenke\"\n accessibilityRole=\"link\"\n accessibilityLabel={tekst.akseptVilkar}\n onPress={() => void Linking.openURL(String(program.termsUrl))}\n style={{ minHeight: tema.touch, flexDirection: 'row', alignItems: 'center', gap: tema.space.sm }}\n >\n <Ikon navn=\"open-outline\" storrelse=\"minste\" farge={tema.color.actionText} />\n <Text style={{ color: tema.color.actionText, fontSize: tema.font.body, fontWeight: tema.weight.semibold }}>\n {tekst.akseptVilkar}\n </Text>\n </Pressable>\n ) : null}\n {/* Skjermens ENE hjelpesetning: taket og utgangen i én (DD-67). */}\n <Hint>\n {medVilkar ? tekst.akseptTakOgUtgangVilkar(program.maxContacts) : tekst.akseptTakOgUtgang(program.maxContacts)}\n </Hint>\n </Seksjon>\n </ScrollView>\n\n <Btn\n testID=\"bli-med\"\n label={tekst.bliMed}\n disabled={!harToken || sender}\n hint={harToken ? tekst.bliMedHint : tekst.bliMedUtenToken}\n onPress={onBliMed}\n />\n </View>\n </View>\n </Modal>\n );\n}\n","import type { TaskOutcome } from '@innspel/core';\nimport React, { useState } from 'react';\nimport { Modal, Pressable, Text, TextInput, View } from 'react-native';\nimport { Ikon } from '../Ikon.js';\nimport { useTema } from '../tema.js';\nimport { Banner, Btn, H, Meta, Tekstknapp } from '../widget/primitiver.js';\nimport { tekst } from '../widget/tekster.js';\n\n/** Ionicons-navn fra ikonkartet i `design/wireframes/betaprogram-tester.jsx`, aldri en emoji. */\nexport const UTFALL: ReadonlyArray<{ verdi: TaskOutcome; ikon: string; etikett: string }> = [\n { verdi: 'fungerte', ikon: 'checkmark-circle-outline', etikett: tekst.utfallFungerte },\n { verdi: 'delvis', ikon: 'contrast-outline', etikett: tekst.utfallDelvis },\n { verdi: 'ikke', ikon: 'close-circle-outline', etikett: tekst.utfallIkke },\n];\n\nexport const SETNING_MAKS = 140;\n\nexport function utfallEtikett(verdi: TaskOutcome): string {\n return UTFALL.find((u) => u.verdi === verdi)?.etikett ?? verdi;\n}\n\n/**\n * 3e — «Hvordan gikk det?». TRE lukkede valg og ETT åpent, sist — aldri en skala, og aldri\n * en gradering av appen: det er OPPGAVEN som evalueres, ikke produktet (DD-15). Samme ark\n * for «Gjort» på en oppgave og for «Svar nå» på en oppfølging (3d): det er det samme\n * spørsmålet, og testeren skal kjenne det igjen.\n *\n * **R8.3 (widget-konsept v0.1):** spørsmålet er HELTEN, og oppgaven står i `small` over som\n * det spørsmålet gjelder. Valgene er radiorader i `body` med ikon, LIKE I VEKT og uten\n * farge: «Fungerte ikke» er like nyttig for leietakeren som «Fungerte». Det valgte har fylt\n * sirkel med hake OG halvfet tekst — form og vekt, ikke bare farge (DD-08).\n *\n * Den valgfrie setningen har INGEN eksempelsetning som plassholder: etiketten stiller\n * spørsmålet, og et eksempel i et fritekstfelt ber om etterligning. (Dagens\n * `setningPlaceholder` var dessuten en setning fra en annen leietakers domene — den hører\n * ikke i en plattformpakke, `CLAUDE.md`.)\n *\n * «Lagre» er den ENESTE fylte knappen, i foten, i tommelsonen. «Lagre» er slutten, og\n * hintet «Ferdig — ingen flere spørsmål nå.» er tatt ut: knappen sier det selv.\n *\n * Etter «Fungerte ikke» tilbys «Meld det som feil» som en TEKSTKNAPP, aldri en andre\n * primærknapp. Den lagrer svaret og gir oppgaven videre til verten, som åpner feilsporet —\n * plattformen navigerer aldri selv, og svaret skal ikke gå tapt på veien.\n */\nexport function HvordanGikkDet({\n under,\n spoersmaal,\n sender,\n feil,\n onLagre,\n onMeldFeil,\n onLukk,\n}: {\n /** Hva spørsmålet gjelder — oppgavens tittel. Utelatt når arket kom fra en oppfølging. */\n under?: string;\n /** Oppfølgingens eget spørsmål. Utelatt: «Hvordan gikk det?». */\n spoersmaal?: string;\n sender: boolean;\n feil?: string;\n onLagre: (outcome: TaskOutcome, text: string | undefined) => void;\n /** Utelatt = tilbudet finnes ikke (DD-26): verten har ikke sagt hvor feilsporet er. */\n onMeldFeil?: (outcome: TaskOutcome, text: string | undefined) => void;\n onLukk: () => void;\n}) {\n const tema = useTema();\n const [valgt, setValgt] = useState<TaskOutcome | undefined>();\n const [setning, setSetning] = useState('');\n\n const tekstVerdi = () => {\n const trimmet = setning.trim();\n return trimmet.length > 0 ? trimmet : undefined;\n };\n\n return (\n <Modal visible transparent animationType=\"slide\" onRequestClose={onLukk} accessibilityViewIsModal>\n <View style={{ flex: 1, backgroundColor: tema.color.scrim, justifyContent: 'flex-end' }}>\n <View\n testID=\"hvordan-gikk-det\"\n accessibilityViewIsModal\n style={{\n backgroundColor: tema.color.bg,\n borderTopLeftRadius: tema.radius.lg * 2,\n borderTopRightRadius: tema.radius.lg * 2,\n padding: tema.screenPadding,\n gap: tema.space.md,\n maxHeight: '92%',\n }}\n >\n <View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>\n <Btn variant=\"ghost\" testID=\"hvordan-tilbake\" ikon=\"arrow-back-outline\" label={tekst.tilbake} onPress={onLukk} />\n <View />\n </View>\n\n <View style={{ gap: tema.space.xs }}>\n {under ? <Meta>{under}</Meta> : null}\n <H>{spoersmaal ?? tekst.hvordanGikkDet}</H>\n </View>\n\n <View\n testID=\"utfall-gruppe\"\n accessibilityRole=\"radiogroup\"\n accessibilityLabel={spoersmaal ?? tekst.hvordanGikkDet}\n >\n {UTFALL.map((u, i) => {\n const aktiv = valgt === u.verdi;\n return (\n <Pressable\n key={u.verdi}\n testID={`utfall-${u.verdi}`}\n accessibilityRole=\"radio\"\n accessibilityLabel={u.etikett}\n accessibilityState={{ checked: aktiv }}\n onPress={() => setValgt(u.verdi)}\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n gap: tema.space.md,\n minHeight: tema.touch + tema.space.sm,\n borderTopWidth: i === 0 ? 0 : tema.hairline,\n borderTopColor: tema.color.border,\n }}\n >\n {/* Form OG vekt, ikke bare farge (DD-08). */}\n <View\n testID={aktiv ? `utfall-merke-${u.verdi}` : undefined}\n style={{\n width: tema.space.lg,\n height: tema.space.lg,\n borderRadius: tema.radius.pill,\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: aktiv ? tema.color.brand : 'transparent',\n borderWidth: tema.hairline * 2,\n borderColor: aktiv ? tema.color.brand : tema.color.borderInteractive,\n }}\n >\n {aktiv ? <Ikon navn=\"checkmark-outline\" storrelse=\"minste\" farge={tema.color.onBrand} /> : null}\n </View>\n <Ikon navn={u.ikon} farge={tema.color.textSecondary} />\n <Text\n testID={`utfall-etikett-${u.verdi}`}\n style={{\n flex: 1,\n color: tema.color.textPrimary,\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n fontWeight: aktiv ? tema.weight.semibold : tema.weight.regular,\n }}\n >\n {u.etikett}\n </Text>\n </Pressable>\n );\n })}\n </View>\n\n <View style={{ gap: tema.space.sm }}>\n <Text style={{ color: tema.color.textSecondary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }}>\n {tekst.setningLabel} <Text style={{ color: tema.color.textMuted }}>{tekst.setningValgfritt}</Text>\n </Text>\n <TextInput\n testID=\"hvordan-setning\"\n accessibilityLabel={tekst.setningLabel}\n value={setning}\n onChangeText={setSetning}\n maxLength={SETNING_MAKS}\n multiline\n numberOfLines={2}\n style={{\n backgroundColor: tema.color.surfaceRaised,\n borderWidth: tema.hairline,\n borderColor: tema.color.borderStrong,\n borderRadius: tema.radius.md,\n padding: tema.space.md,\n color: tema.color.textPrimary,\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n minHeight: tema.touch * 1.5,\n textAlignVertical: 'top',\n }}\n />\n </View>\n\n {/* Tilbudet er en tekstknapp, ikke en andre primærknapp (DD-58, DD-63). */}\n {valgt === 'ikke' && onMeldFeil ? (\n <Tekstknapp\n testID=\"meld-feil\"\n ikon=\"bug-outline\"\n label={tekst.meldFeil}\n disabled={sender}\n onPress={() => onMeldFeil('ikke', tekstVerdi())}\n />\n ) : null}\n\n {feil ? <Banner live ikon=\"warning-outline\" tone=\"danger\" children={tekst.svarFeil(feil)} /> : null}\n\n <Btn\n testID=\"hvordan-lagre\"\n label={tekst.lagre}\n disabled={valgt === undefined || sender}\n busy={sender}\n onPress={() => {\n if (valgt === undefined) return;\n onLagre(valgt, tekstVerdi());\n }}\n />\n </View>\n </View>\n </Modal>\n );\n}\n","import type { FollowUpView } from '@innspel/core';\nimport React from 'react';\nimport { View } from 'react-native';\nimport { Ikon } from '../Ikon.js';\nimport { useTema } from '../tema.js';\nimport { Btn, H } from '../widget/primitiver.js';\nimport { tekst } from '../widget/tekster.js';\n\n/** Kontakter med spørsmål tar svar; de andre er handlinger (tech-decisions «M3.2 (forts.)»). */\nexport function tarSvar(kind: FollowUpView['kind']): boolean {\n return kind === 'hvordan_gikk_det' || kind === 'sjekkpunkt';\n}\n\n/**\n * 3d — oppfølgingskortene i appen (DD-34). Ett spørsmål per kort, som kortets HELT, og ÉN\n * linje som sier hva det koster: ett spørsmål, under ett minutt.\n *\n * Arten avgjør knappene: et spørsmål får «Svar nå» (åpner «Hvordan gikk det?» med spørsmålet\n * som helt), en påminnelse «Åpne oppgavene» — og navngir fristen i selve spørsmålet, som\n * produkteier skrev det — og tilbudet om utgang «Bli værende» / «Gå ut», invertert fra press:\n * utgangen er svaret som tilbys. «Senere» legger kortet bort i denne økten; det kommer\n * tilbake ved neste oppstart, aldri som push — plattformen holder ingen push-tokens.\n *\n * **«Kontakt 1 av 3» er ute** (DD-14, presisert 2026-09-20): tellingen er en regel mellom\n * Innspel og leietakeren, ikke noe testeren kan gjøre noe med. `contactsSent` finnes i\n * kontrakten og leses av PANELET.\n *\n * Flaten er `brandBg` UTEN ramme, som invitasjonen — det er samme avsender, og flaten er nok.\n */\nexport function Oppfolging({\n oppfolging,\n onSenere,\n onSvar,\n onAapneOppgavene,\n onGaaUt,\n}: {\n oppfolging: FollowUpView;\n onSenere: () => void;\n onSvar: () => void;\n onAapneOppgavene: () => void;\n onGaaUt: () => void;\n}) {\n const tema = useTema();\n const art = tarSvar(oppfolging.kind) ? 'spoersmaal' : oppfolging.kind === 'tilbud_om_utgang' ? 'utgang' : 'paaminnelse';\n\n return (\n <View\n testID={`oppfolging-${oppfolging.id}`}\n accessibilityLabel={tekst.oppfolgingRegion}\n style={{\n backgroundColor: tema.color.brandBg,\n borderRadius: tema.radius.lg,\n padding: tema.space.md,\n gap: tema.space.md,\n }}\n >\n <View style={{ flexDirection: 'row', gap: tema.space.sm, alignItems: 'flex-start' }}>\n <View style={{ paddingTop: tema.space.xs }}>\n <Ikon navn=\"flask-outline\" farge={tema.color.brand} />\n </View>\n <View style={{ flex: 1, minWidth: 0 }}>\n <H nivaa={3} meta={tekst.oppfolgingKost}>\n {oppfolging.question}\n </H>\n </View>\n </View>\n <View style={{ flexDirection: 'row', gap: tema.space.sm }}>\n {art === 'utgang' ? (\n <>\n {/* «Bli værende» står først: utgangen er et valg, ikke en felle. */}\n <Btn grow variant=\"secondary\" testID={`bli-vaerende-${oppfolging.id}`} label={tekst.bliVaerende} onPress={onSenere} />\n <Btn grow variant=\"secondary\" testID={`gaa-ut-${oppfolging.id}`} ikon=\"exit-outline\" label={tekst.gaaUtBekreft} onPress={onGaaUt} />\n </>\n ) : (\n <>\n <Btn grow variant=\"secondary\" testID={`senere-${oppfolging.id}`} label={tekst.senere} onPress={onSenere} />\n {art === 'spoersmaal' ? (\n <Btn grow testID={`svar-naa-${oppfolging.id}`} label={tekst.svarNaa} onPress={onSvar} />\n ) : (\n <Btn grow testID={`aapne-oppgavene-${oppfolging.id}`} label={tekst.aapneOppgavene} onPress={onAapneOppgavene} />\n )}\n </>\n )}\n </View>\n </View>\n );\n}\n","import type { ParticipationView, ProgramTask, TaskCompletionView } from '@innspel/core';\nimport React from 'react';\nimport { Text, View } from 'react-native';\nimport { Ikon } from '../Ikon.js';\nimport { useTema } from '../tema.js';\nimport { Btn, Meta, Sek } from '../widget/primitiver.js';\nimport { formaterFrist } from '../widget/status.js';\nimport { tekst } from '../widget/tekster.js';\nimport { utfallEtikett } from './HvordanGikkDet.js';\n\n/**\n * 3c — oppgavelista i deltakelseskortet. En TETT LISTE, ikke kort i kort.\n *\n * **R8.3 (widget-konsept v0.1, P1 (a)):** den gjorte raden har fylt sirkel med hake, ÉN\n * meta-linje i `small` med dato og utfall («Gjort 17. september · fungerte delvis»), og\n * TESTERENS EGEN SETNING i `body` under — det er hennes ord, og de er beslutningsgrunnlag\n * (DD-67). Dagens `oppgaveGjortMed` («Prøvd · <utfall>») ble denne linja.\n *\n * De som gjenstår har «Gjort» TONET i merkefargen på raden: to like valg, ingen av dem i\n * aksjonsfargen, fordi oppgavene kan gjøres i den rekkefølgen som passer (DD-63). Ingen\n * «Ferdig» i en fot — kortet ligger i vertens skjerm og har ingen egen fot, og en\n * «Ferdig»-knapp for tre oppgaver måtte valgt en oppgave for henne.\n *\n * «Ikke begynt» som etikett er ute: en åpen sirkel sier det (DD-08 — ikon og form, ikke et\n * ord i tillegg). Er programmet over, er «Gjort» borte: det er ingenting mer å gjøre.\n */\nexport function Oppgaver({\n tasks,\n completions,\n over,\n onGjort,\n}: {\n tasks: ProgramTask[];\n completions: ParticipationView['completions'];\n /** `closesAt` er passert eller deltakelsen er fullført: ingen flere «Gjort». */\n over?: boolean;\n onGjort: (task: ProgramTask) => void;\n}) {\n const tema = useTema();\n const ferdig = new Map<string, TaskCompletionView>(completions.map((c) => [c.taskId, c]));\n\n return (\n <View testID=\"oppgaver\" accessibilityLabel={tekst.oppgaverTittel}>\n {[...tasks]\n .sort((a, b) => a.order - b.order)\n .map((o, i) => {\n const c = ferdig.get(o.id);\n const meta = c ? tekst.oppgaveGjortMeta(formaterFrist(c.at), utfallEtikett(c.outcome)) : tekst.oppgaveTid(o.estimatedMinutes, o.screenHint);\n return (\n <View\n key={o.id}\n testID={`oppgave-${o.id}`}\n accessibilityLabel={tekst.oppgaveRadA11y(i + 1, o.title, c ? meta : tekst.oppgaveIkkeGjort)}\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n gap: tema.space.sm,\n minHeight: tema.touch + tema.space.sm,\n paddingVertical: tema.space.sm,\n borderTopWidth: i === 0 ? 0 : tema.hairline,\n borderTopColor: tema.color.border,\n }}\n >\n <View\n style={{\n width: tema.space.lg,\n height: tema.space.lg,\n borderRadius: tema.radius.pill,\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: c ? tema.color.success : 'transparent',\n borderWidth: c ? 0 : tema.hairline * 2,\n borderStyle: 'dashed',\n borderColor: tema.color.borderStrong,\n }}\n >\n {c ? <Ikon navn=\"checkmark-outline\" storrelse=\"minste\" farge={tema.color.bg} /> : null}\n </View>\n\n <View style={{ flex: 1, minWidth: 0 }}>\n <Text\n testID={`oppgave-tittel-${o.id}`}\n style={{ color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body, fontWeight: tema.weight.semibold }}\n >\n {o.title}\n </Text>\n <Meta testID={`oppgave-meta-${o.id}`}>{meta}</Meta>\n {/* Testerens egne ord i `body` — ikke i meta-linja (DD-67). */}\n {c?.text ? <Sek testID={`oppgave-setning-${o.id}`}>{c.text}</Sek> : null}\n </View>\n\n {!c && !over ? (\n <Btn\n variant=\"tonet\"\n testID={`gjort-${o.id}`}\n label={tekst.oppgaveGjort}\n accessibilityLabel={tekst.oppgaveGjortLabel(o.title)}\n onPress={() => onGjort(o)}\n />\n ) : null}\n </View>\n );\n })}\n </View>\n );\n}\n","import type { ParticipationView, ProgramView } from '@innspel/core';\nimport React from 'react';\nimport { Sporingslinje, type Ledd } from '../widget/Sporingslinje.js';\nimport { formaterFrist, formaterKortFrist } from '../widget/status.js';\nimport { tekst } from '../widget/tekster.js';\n\n/**\n * Programmets gang — samme komponent og samme regler som sakens (DD-08).\n *\n * **P1 (a), produkteier 2026-09-20:** deltakelsen bæres av SPORINGSLINJEN, ikke av et\n * kvitteringskort. Merkefargen på en flate er for det som er SENDT (kvitteringen, DD-41);\n * et program pågår, og deltakelseskortet er derfor sakskortets form — `surface` med ramme.\n * Identisk med portalens programskjerm.\n *\n * Tre ledd: «Du ble med» (`joinedAt`, passert), «N av M gjort» (nå-leddet, med\n * programikonet) og «Programmet er over» med `closesAt` som TALL — kortets HELT. Det er det\n * eneste som roper.\n *\n * Under nå-leddet står ÉN linje i `small` om når oppgavene kan gjøres. Aldri «to igjen»:\n * «1 av 3» sier alt tallet sier (DD-08, F8 — samme opplysning ikke to steder).\n *\n * Er programmet over (`fullfoert`, eller `closesAt` passert), er siste ledd PASSERT og\n * datoen står som dato — ikke som helt. Da er det ingenting mer å gjøre.\n */\nexport function programErOver(deltakelse: ParticipationView, program: ProgramView, naa: Date = new Date()): boolean {\n return deltakelse.status === 'fullfoert' || new Date(program.closesAt).getTime() < naa.getTime();\n}\n\nexport function programledd(deltakelse: ParticipationView, program: ProgramView, naa: Date = new Date()): Ledd[] {\n const over = programErOver(deltakelse, program, naa);\n const gjort = deltakelse.completions.length;\n const av = program.tasks.length;\n const alt = av > 0 && gjort >= av;\n\n return [\n { nokkel: 'ble-med', etikett: tekst.programBleMed, tilstand: 'gjort', detalj: formaterFrist(deltakelse.joinedAt) },\n {\n nokkel: 'gjort',\n etikett: tekst.programGjort(gjort, av),\n ...(over || alt\n ? { tilstand: 'gjort' as const }\n : { tilstand: 'naa' as const, ikon: 'flask-outline', detalj: tekst.programNaarDetPasser }),\n },\n over\n ? { nokkel: 'over', etikett: tekst.programOver, tilstand: 'gjort', detalj: formaterFrist(program.closesAt) }\n // Kort form: tallet står i én av tre kolonner på en telefon (se `formaterKortFrist`).\n : { nokkel: 'over', etikett: tekst.programOver, tilstand: 'kommer', tall: formaterKortFrist(program.closesAt) },\n ];\n}\n\nexport function ProgramSpor({ deltakelse, program }: { deltakelse: ParticipationView; program: ProgramView }) {\n return <Sporingslinje ledd={programledd(deltakelse, program)} testID=\"program-spor\" etikett={tekst.programSporEtikett} />;\n}\n","import type { InnspelStorage } from '@innspel/core';\n\n/**\n * Formen på lagringspakkene i React Native-økosystemet: AsyncStorage, MMKV med\n * async-fasade, expo-secure-store. Alle tre har disse tre metodene.\n */\nexport interface AsyncStorageLike {\n getItem(key: string): Promise<string | null>;\n setItem(key: string, value: string): Promise<void>;\n removeItem(key: string): Promise<void>;\n}\n\n/**\n * Lager en {@link InnspelStorage} av vertens egen lagringspakke.\n *\n * Pakken tar ingen avhengighet på AsyncStorage eller MMKV med vilje: verten har\n * som regel én av dem allerede, og to kopier av samme lagring i én app er verre\n * enn litt oppsett. Send inn den du bruker:\n *\n * @example\n * ```ts\n * import AsyncStorage from '@react-native-async-storage/async-storage';\n * const storage = createStorage(AsyncStorage);\n * ```\n *\n * Det eneste som lagres er offline-køen (DD-41) — aldri feedback-tokenet, aldri\n * en install- eller enhets-ID (K20). Lagringen trenger derfor ikke være kryptert.\n */\nexport function createStorage(pakke: AsyncStorageLike): InnspelStorage {\n return {\n get: (key) => pakke.getItem(key),\n set: (key, value) => pakke.setItem(key, value),\n remove: (key) => pakke.removeItem(key),\n };\n}\n\n/**\n * Lagring i minne. Køen overlever da ikke at appen lukkes, så den er til\n * utvikling og test — ikke til produksjon. `InnspelProvider` sier fra i\n * konsollen hvis den brukes uten at det er sagt eksplisitt.\n */\nexport function createMemoryStorage(): InnspelStorage {\n const rader = new Map<string, string>();\n return {\n get: async (key) => rader.get(key) ?? null,\n set: async (key, value) => {\n rader.set(key, value);\n },\n remove: async (key) => {\n rader.delete(key);\n },\n };\n}\n"],"mappings":"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","names":["createContext","useCallback","useContext","useMemo","useRef","useState","View","createContext","useContext","createContext","useContext","InnspelApiError","useCallback","useContext","useEffect","useRef","useState","Pressable","View","storrelse","useMemo","Pressable","Text","View","jsx","periode","jsx","jsxs","useMemo","View","Text","Pressable","Pressable","Text","View","jsx","jsxs","Pressable","View","Text","ScrollView","Text","View","jsx","jsxs","View","ScrollView","Text","Text","View","Text","View","jsx","jsxs","View","Text","jsx","jsxs","View","Text","useRef","useState","ActivityIndicator","ScrollView","Text","TextInput","View","jsx","jsxs","MineInnspill","useState","useRef","View","ActivityIndicator","ScrollView","Text","TextInput","useMemo","useRef","useState","Image","Pressable","Text","View","jsx","jsxs","useState","useRef","useMemo","Pressable","Text","View","Image","Fragment","jsx","jsxs","useContext","useRef","useState","useCallback","useEffect","InnspelApiError","View","Pressable","jsx","jsxs","createContext","useState","useRef","useMemo","useCallback","View","useContext","useEffect","useRef","View","jsx","useRef","useEffect","View","InnspelApiError","useCallback","useEffect","useState","Modal","Pressable","View","t","Modal","Pressable","ScrollView","Text","View","jsx","jsxs","View","Text","Modal","ScrollView","Pressable","useState","Modal","Pressable","Text","TextInput","View","jsx","jsxs","useState","Modal","View","Pressable","Text","TextInput","View","Fragment","jsx","jsxs","View","Text","View","jsx","jsxs","View","Text","jsx","Fragment","jsx","jsxs","useState","useCallback","InnspelApiError","useEffect","View","Modal","Pressable"]}
|