/* Merkevaretealen og den lysaste grå er for lyse som TEKST på lys grunn.
   Målt i nettlesaren 14.09.2026: #11B49A ga 2,62:1 og #94a3b8 2,56:1 mot
   kravet 4,5:1. Denne fila er verts-eige CSS (lag 3) og propagerer
   gjennom ingenting — same rettinga er gjord i extension/styles/popup.css
   som tokena --accent-text og --text-muted. Held du på å endre den eine,
   endre den andre. */
/* Leksihjelp web app — app-shell chrome only.
 * The dictionary / spell-check / lær-mer surfaces bring their own styles from
 * /lexi/styles/ (the real extension CSS). This file styles the app frame:
 * header, controls, tabs, panels, and the TTS mock page. */
body { font-family: system-ui, sans-serif; padding: 24px 40px; background: #f8fafc; color: #1e293b; }
#container { max-width: 880px; margin: 0 auto; }
h1 { color: #0F766E; margin-bottom: 4px; display: flex; align-items: baseline; gap: 10px; }
#ver-badge { font-size: 13px; font-weight: 500; color: #64748b; background: #eef2f7; border: 1px solid #e2e8f0; border-radius: 6px; padding: 2px 8px; font-family: ui-monospace, monospace; vertical-align: middle; user-select: all; }
/* Task 10: account panel headline — the model's single state message
   (replaces the old #subscription-badge, which duplicated this text). */
.acct-headline { font-size: 14px; font-weight: 600; color: #1e293b; margin: 10px 0 2px; }
.acct-headline:empty { display: none; }
.sub { color: #64748b; margin-top: 0; font-size: 14px; }
.controls { background: #fff; padding: 16px 20px; border-radius: 10px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); margin: 16px 0; display: flex; gap: 16px; align-items: center; flex-wrap: wrap; }
label { font-size: 14px; font-weight: 600; }
select { padding: 7px 10px; font-size: 14px; border: 1px solid #cbd5e1; border-radius: 6px; }
#status { font-size: 13px; color: #64748b; margin-left: auto; }
#status.ready { color: #059669; font-weight: 600; }
#status.err { color: #dc2626; font-weight: 600; }
textarea { width: 100%; min-height: 300px; padding: 14px; font-size: 17px; line-height: 1.55; border: 1px solid #cbd5e1; border-radius: 10px; box-sizing: border-box; }

/* ── Papertek Core Editor host (#test-input) ──────────────────────────
   #test-input stopped being a <textarea> on 2026-08-12, so the rule above
   no longer reaches it. These declarations deliberately mirror it, so the
   writing box looks unchanged to a student; only the element type moved.
   Keep the two in step if either is touched. */
/* --write-zoom er den optiske forstørringa (1 = 100 %). Han blir sett på
   <html> av verktøyraden, og 17px er GRUNNSTORLEIKEN — eitt tal, éin stad.
   Regelen matchar på id, så han held om editoren byter ut eller flyttar
   noden; ein inline-stil på ein fanga referanse gjorde ikkje det. */
#test-input {
  width: 100%; min-height: 300px; padding: 14px;
  /* Taket, og kvifor det er relativt til vindauget og ikkje eit fast tal:
     boksen hadde overflow-y: auto men inga max-height, så han VOKS i staden
     for å scrolle. Ei innliming på nokre tusen ord dytta verktøyraden —
     ordteljar, «Les opp», forstørring, Word-eksport — langt under skjermen,
     og dei kontrollane er det einaste som finst for å gjere noko med teksten.
     Ikkje rein vh: alt OVER boksen — tittel, kontrollrad, faner — har fast
     høgde på brei skjerm, så ein prosentdel av vindauget skalerer feil veg
     når vindauget blir kort. calc trekkjer frå det faktiske vertsrommet, og
     240px er golvet så boksen aldri blir uråd å skrive i.

     dvh og ikkje vh: på mobil endrar vh seg når adresselinja glir bort, og
     boksen ville hoppa medan eleven skriv.

     Målt 19.09.2026 på 1280×768: boks 388px, verktøyraden på y=676 — altså
     synleg utan å scrolle, som er poenget. Rada ber ordteljar, «Les opp»,
     forstørring og Word-eksport, og det er det einaste som finst for å gjere
     noko med teksten. */
  max-height: max(240px, calc(100dvh - 380px));
  font-size: calc(17px * var(--write-zoom, 1)); line-height: 1.55;
  border: 1px solid #cbd5e1; border-radius: 10px; box-sizing: border-box;
  background: #fff; color: inherit;
  /* A textarea preserves newlines and wraps; a plain div does neither.
     Without pre-wrap, pasted multi-line text collapses onto one line. */
  white-space: pre-wrap;
  overflow-wrap: break-word;
  overflow-y: auto;
  /* The editor's own toolbars/handles position against this box. */
  position: relative;
}
/* -2px og ikkje -1px, og det er ikkje kosmetikk: forelderen
   (`flex-1 relative overflow-hidden`) har NØYAKTIG same topp-y som denne
   boksen. Ved -1px ligg 1 av dei 2 pikslane utanfor boksen, og forelderen
   klipper dei bort — så toppen vart halvtjukk medan venstre, høgre og botn
   stod heile. Det las ikkje som ei ramme, men som tre strekar.
   -2px legg heile omrisset innanfor, så ingenting kan klippast. */
#test-input:focus { outline: 2px solid #11B49A; outline-offset: -2px; }

/* Mobil. Kontrollradene brekk til fleire liner her, så vertsrommet over
   boksen er nær det dobbelte av på laptop — målt y=1014 på 375×812 med
   laptop-regelen. Å tvinge verktøyraden inn i vindauget ville då krevd ein
   ~230px skrivebok, og ein skriveboks ein ikkje kan skrive i er verre enn
   å scrolle. Boksen blir difor mindre enn på laptop, slik Geir bad om, og
   sida scrollar for å nå rada — det normale mobilmønsteret. */
@media (max-width: 700px) {
  #test-input { max-height: 50dvh; min-height: 200px; }
}

/* Scroll host for the editor. Exists so special-chars-panel has a container
   of its own to restructure — see the comment on #write-scroll in the
   markup. `position: relative` because that module appends an absolutely
   positioned panel here. */
#write-scroll { position: relative; }

/* special-chars-panel positions itself at `editorRect.left - scrollRect.left
   - 44`, i.e. it expects a left gutter to live in. Our editor fills its
   wrapper edge to edge, so that expression goes negative, clamps to 4px and
   the panel lands ON the text. The class is toggled from JS and only while a
   language with special characters is selected — de/fr/es — so Norwegian
   writing is not indented for a panel that will never appear. */
#write-scroll.has-special-chars { padding-left: 48px; }
#write-scroll.has-special-chars > #test-input { border-top-left-radius: 10px; border-bottom-left-radius: 10px; }

/* Word count + export row. */
#write-tools {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 10px;
}
#write-wordcount { margin: 0; }
#write-export-actions { margin-left: auto; display: flex; gap: 6px; }
#write-export-actions button {
  padding: 5px 12px; font-size: 13px; font-weight: 600;
  border: 1px solid #cbd5e1; border-radius: 8px;
  background: #fff; color: #334155; cursor: pointer;
}
#write-export-actions button:hover { background: #f8fafc; border-color: #94a3b8; }
#write-export-actions button:disabled { opacity: 0.5; cursor: default; }

/* Opplesing + optisk forstørring. Same knappeform som eksporten, av di dei
   ligg på same rad og elles ville lese som to ulike kontrollklassar.
   Verktøyraden har ÉIN opplesingsknapp — «Les alt». Markert tekst høyrer
   floating-widget.js til, som ligg i manifestets content_scripts og difor
   er lasta hjå kvar app-brukar. */
#write-read-actions, #write-zoom { display: flex; align-items: center; gap: 6px; }

/* Diktatknappen. Same form som dei andre i rada når han kviler — han skal
   ikkje rope før han gjer noko. Medan mikrofonen står på er han derimot den
   einaste raude tingen på sida, og det er med vilje: «mikrofonen er på» er
   den eine tilstanden ein elev aldri skal kunne vere i utan å sjå det.
   Pulsen er det same signalet ein gong til for den som ikkje les farge. */
#btn-dictate.is-listening {
  background: #dc2626; border-color: #dc2626; color: #fff; font-weight: 600;
  animation: lh-dictate-pulse 1.6s ease-in-out infinite;
}
#btn-dictate.is-listening:hover { background: #b91c1c; border-color: #b91c1c; }
@keyframes lh-dictate-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(220, 38, 38, 0.45); }
  50%      { box-shadow: 0 0 0 5px rgba(220, 38, 38, 0); }
}
/* Ein puls er ei rørsle, og rørsle er ikkje gratis for alle. Fargen og
   teksten ber meldinga åleine når han er slått av. */
@media (prefers-reduced-motion: reduce) {
  #btn-dictate.is-listening { animation: none; }
}
#dictate-row { display: flex; flex-wrap: wrap; gap: 4px; align-items: baseline; }
#dictate-row[hidden] { display: none; }
#dictate-state { font-weight: 600; }
#dictate-state.err { color: #dc2626; }
/* Førebels tekst står HER og ikkje i skrivefeltet. Å skyte eit gjett inn i
   ein contenteditable og byte det ut att for kvar hending kolliderer med
   editoren sin eigen angrehistorikk — eleven ville fått ti steg å angre for
   éi setning. Her er det ei framvising, og berre det som er endeleg blir
   skrive. */
#dictate-preview { font-style: italic; opacity: 0.75; }
#write-read-actions button,
#write-zoom button {
  padding: 5px 12px; font-size: 13px; font-weight: 600;
  border: 1px solid #cbd5e1; border-radius: 8px;
  background: #fff; color: #334155; cursor: pointer;
}
#write-read-actions button:hover,
#write-zoom button:hover {
  background: #f8fafc; border-color: #94a3b8;
}
#write-zoom button:disabled { opacity: 0.4; cursor: default; }
#zoom-label { margin: 0; min-width: 44px; text-align: center; font-variant-numeric: tabular-nums; }

/* Uthevinga treng INGEN regel her. read-selection-highlight.js brukar CSS
   Custom Highlight API, og `::highlight(lh-read-selection)` +
   `::highlight(lh-read-selection-word)` står alt i /lexi/styles/content.css,
   som denne sida lastar. Ein kopi her ville vore ein andre sanning om ein
   farge — same klassen feil som duplikatet i popup.js. */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) #write-read-actions button,
  :root:not([data-theme="light"]) #write-zoom button {
    background: #1e293b; color: #e2e8f0; border-color: #475569;
  }
}
:root[data-theme="dark"] #write-read-actions button,
:root[data-theme="dark"] #write-zoom button {
  background: #1e293b; color: #e2e8f0; border-color: #475569;
}

/* contenteditable has no placeholder attribute; this is the stand-in.
   :empty is exact only while the node has NO children at all — a single
   stray <br> (which browsers happily insert) defeats it, so the JS side
   normalises the editor back to truly-empty. Both halves are required. */
#test-input:empty::before {
  content: attr(data-placeholder);
  color: #64748b;
  pointer-events: none;   /* never swallow the click that focuses the box */
}

/* The editor injects its own UI (slash menu, toolbars, dialogs). Those
   modules ship self-contained CSS, but they assume a stacking context
   above page content — the app's panels create their own, so lift them. */
#panel-write { position: relative; }
.skriv-slash-menu, .skriv-toolbar, .skriv-table-toolbar, .skriv-image-toolbar { z-index: 60; }

/* Tables and images inserted by the editor. The modules style their own
   chrome but inherit block styling from the host page, which here had
   none — an unstyled <table> renders as borderless run-together text. */
/* Headings the STUDENT writes, not the site's. The global `h1` rule above is
   the Leksihjelp brand heading — teal, flex, baseline-aligned — and it was
   reaching into the editor, so a pupil's own title rendered as site chrome
   (and `display:flex` on a heading full of inline text is its own mess).
   Reset to something that reads like a document. */
#test-input h1, #test-input h2, #test-input h3 {
  display: block; color: inherit; gap: 0;
  font-weight: 700; line-height: 1.25; margin: 0.6em 0 0.3em;
}
#test-input h1 { font-size: 1.5em; }
#test-input h2 { font-size: 1.25em; }
#test-input h3 { font-size: 1.1em; }
#test-input p { margin: 0 0 0.6em; }
#test-input ul, #test-input ol { margin: 0 0 0.6em; padding-left: 1.6em; }
#test-input li { margin: 0.15em 0; }
#test-input > :first-child { margin-top: 0; }

#test-input table { border-collapse: collapse; margin: 10px 0; }
#test-input th, #test-input td { border: 1px solid #cbd5e1; padding: 6px 10px; }
#test-input img { max-width: 100%; height: auto; }
.hint { font-size: 13px; color: #64748b; margin-top: 10px; }
.hint code { background: #eef2f7; padding: 1px 5px; border-radius: 4px; }
.foot { margin-top: 28px; font-size: 13px; color: #64748b; }
.foot a { color: #0F766E; }
#errlog { white-space: pre-wrap; font-family: ui-monospace, monospace; font-size: 12px; color: #b91c1c; background: #fef2f2; border: 1px solid #fecaca; border-radius: 8px; padding: 10px; margin-top: 12px; display: none; }
#ext-warning { font-size: 13px; color: #92400e; background: #fffbeb; border: 1px solid #fcd34d; border-radius: 8px; padding: 10px 14px; margin: 12px 0; }
/* tabs */
.tabs { display: flex; gap: 6px; margin: 18px 0 0; }
.tab-btn { padding: 9px 18px; font-size: 14px; font-weight: 600; border: 1px solid #cbd5e1; border-bottom: none; border-radius: 10px 10px 0 0; background: #eef2f7; color: #475569; cursor: pointer; }
.tab-btn.active { background: #fff; color: #0F766E; }
.panel { background: #fff; border: 1px solid #cbd5e1; border-radius: 0 10px 10px 10px; padding: 18px; display: none; }
.panel.active { display: block; }
/* ordbok panel: give the popup view a sane frame */
#dict-mount { max-width: 460px; }

/* …but not a frame narrower than the content on a screen that has room.
 *
 * The dictionary view is authored for the ~400 px extension popup, and 460 px
 * reproduces that. A bøyingstabell with four equal spellings is wider than
 * that on its own: «bjørkeskog / bjerkeskog / bjørkeskau / bjerkeskau» measured
 * 461 px against a 394 px viewport on 2026-08-17, so 67 px — most of the fourth
 * column — sat outside the frame, at every screen width, because this cap and
 * not the screen decided it. On a resource being assessed on whether one
 * allowed form is less prominent than another (§ 15-4), that is worth the
 * width wherever the screen has it.
 *
 * Both queries are min-width, so they NEVER match the extension popup or a
 * phone. Those keep the 460 px frame and the scroll track under the table —
 * imperfect there by choice, since the popup genuinely is that narrow.
 *
 * 560 px is the first width that fits the four-column table whole (the card
 * chrome between #dict-mount and the scroll wrapper measures 66 px, so
 * 560 − 66 = 494 > 461). Above 900 px the cap comes off entirely and
 * #container's own 880 px max-width governs, which keeps the line length sane
 * without a second magic number here. */
@media (min-width: 640px) {
  #dict-mount { max-width: 560px; }
}

@media (min-width: 900px) {
  #dict-mount { max-width: none; }
}
#dict-mount .search-box { display: flex; align-items: center; gap: 8px; border: 1px solid #cbd5e1; border-radius: 10px; padding: 8px 12px; background: #fff; }
#dict-mount .search-box input { flex: 1; border: none; outline: none; font-size: 15px; }
#dict-mount .search-clear { border: none; background: none; font-size: 18px; cursor: pointer; color: #64748b; }
#dict-mount .search-clear.hidden { display: none; }
#dict-mount .search-direction { display: flex; gap: 6px; margin-top: 8px; }
#dict-mount .dir-btn { padding: 5px 12px; font-size: 12px; border: 1px solid #cbd5e1; border-radius: 8px; background: #f8fafc; cursor: pointer; }
#dict-mount .dir-btn.active { background: #11B49A; color: #fff; border-color: #0F766E; }
#dict-mount .results { margin-top: 14px; max-height: 480px; overflow-y: auto; }
#dict-mount .lang-switcher { display: flex; gap: 4px; margin-top: 8px; flex-wrap: wrap; }
/* tts panel */
.tts-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 12px; }
.tts-row input, .tts-row textarea { flex: 1; min-width: 220px; padding: 10px 12px; font-size: 15px; border: 1px solid #cbd5e1; border-radius: 8px; font-family: inherit; resize: vertical; }
#tts-mock-page { border: 1px solid #cbd5e1; border-radius: 10px; overflow: hidden; background: #fff; box-shadow: 0 2px 10px rgba(0,0,0,.06); }
.mock-chrome { display: flex; align-items: center; gap: 6px; padding: 8px 12px; background: #eef1f5; border-bottom: 1px solid #dbe1e8; }
.mock-dot { width: 10px; height: 10px; border-radius: 50%; background: #cbd5e1; }
.mock-url { margin-left: 10px; font-size: 12px; color: #64748b; background: #fff; border-radius: 6px; padding: 3px 12px; flex: 1; max-width: 340px; }
.mock-article { padding: 22px 26px 26px; max-width: 640px; }
.mock-article h2 { margin: 0 0 4px; font-size: 22px; color: #1e293b; }
.mock-byline { margin: 0 0 14px; font-size: 12px; color: #64748b; }
.mock-body { margin: 0; font-size: 17px; line-height: 1.7; color: #334155; }
.tts-btn { padding: 10px 16px; font-size: 14px; font-weight: 600; border: none; border-radius: 8px; cursor: pointer; }
.tts-browser { background: #475569; color: #fff; }
.tts-eleven { background: #11B49A; color: #fff; }
#tts-result { font-size: 13px; margin-top: 10px; color: #64748b; }
#tts-result.ok { color: #059669; }
#tts-result.warn { color: #92400e; }

/* Opplesing paste-in reader (default) + example-mode toggle. #panel-tts is
 * outside the scoped .hidden rules (#dict-mount / #leksihjelp-sidepanel-root),
 * so the mode swap needs its own display:none. */
#tts-paste-wrap.hidden, #tts-example-wrap.hidden { display: none; }
#tts-paste { width: 100%; box-sizing: border-box; padding: 10px 12px; font-size: 15px; border: 1px solid #cbd5e1; border-radius: 8px; font-family: inherit; resize: vertical; }
.tts-count { font-size: 12px; color: #64748b; font-variant-numeric: tabular-nums; }
.tts-example-toggle { display: flex; align-items: center; gap: 8px; margin-top: 16px; font-size: 14px; color: #475569; cursor: pointer; }
.tts-example-toggle input { width: 16px; height: 16px; cursor: pointer; margin: 0; }
[data-theme="dark"] .tts-example-toggle { color: #a3b3af; }

/* Dark mode — data-theme="dark" is set by the Settings view + on boot. This
 * covers the app SHELL only; the dictionary / lær-mer / settings surfaces theme
 * themselves via the vendored popup-views.css dark tokens under
 * #leksihjelp-sidepanel-root. Keeps the two from clashing. */
[data-theme="dark"] body { background: #0e1513; color: #e6efec; }
[data-theme="dark"] h1 { color: #2fd0b4; }
[data-theme="dark"] .controls,
[data-theme="dark"] .panel { background: #16211f; border-color: #2a3835; box-shadow: none; }
[data-theme="dark"] .tab-btn { background: #1b2624; color: #9fb4af; border-color: #2a3835; }
[data-theme="dark"] .tab-btn.active { background: #16211f; color: #2fd0b4; }
[data-theme="dark"] textarea,
[data-theme="dark"] select,
[data-theme="dark"] .tts-row input,
[data-theme="dark"] .tts-row textarea { background: #16211f; color: #e6efec; border-color: #2a3835; }
[data-theme="dark"] #ver-badge { background: #1b2624; border-color: #2a3835; color: #7c8e89; }
[data-theme="dark"] .acct-headline { color: #e6efec; }
[data-theme="dark"] .sub,
[data-theme="dark"] .hint,
[data-theme="dark"] .foot,
[data-theme="dark"] #status { color: #9fb4af; }
[data-theme="dark"] .hint code { background: #1b2624; }
#sync-local-note.hidden { display: none; }

/* «Marker teksten du vil høre først» — vises i 4 sekunder når ▶ trykkes uten
   markering. Inline i verktøyraden, ikke et varsel: en knapp som ikke svarer
   leses som en feil, men en modal for dette ville vært verre enn tausheten. */
.read-selection-hint { margin: 0; color: #0F766E; font-weight: 600; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .read-selection-hint { color: #5eead4; }
}
:root[data-theme="dark"] .read-selection-hint { color: #5eead4; }

#write-read-actions button:disabled { opacity: 0.5; cursor: default; }

/* Lasteskjermen (index.html #app-loading) */
.app-loading { margin: 12px 0 16px; padding: 14px 16px; border: 1px solid #e2e8f0; border-radius: 10px; background: #f8fafc; }
.app-loading[hidden] { display: none; }
.app-loading-bar { height: 8px; border-radius: 4px; background: #e2e8f0; overflow: hidden; }
.app-loading-fill { height: 100%; width: 0; background: #11B49A; transition: width .25s ease-out; }
.app-loading-text { margin: 10px 0 2px; font-weight: 600; color: #0f172a; }
.app-loading-pct { font-variant-numeric: tabular-nums; color: #11B49A; }
.app-loading-note { margin: 0 0 8px; font-size: 14px; color: #475569; }
.app-loading-source { margin: 0; font-size: 12px; color: #64748b; }
[data-theme="dark"] .app-loading { background: #1e293b; border-color: #334155; }
[data-theme="dark"] .app-loading-bar { background: #334155; }
[data-theme="dark"] .app-loading-text { color: #f1f5f9; }
[data-theme="dark"] .app-loading-note { color: #cbd5e1; }
[data-theme="dark"] .app-loading-source { color: #94a3b8; }
