/* ── /oversaettelse/ craft pass (4-lens designer panel, 17/7) ─────────────────
   Refinement only — no new elements, no layout moves. Loads LAST in index.php
   so document-order wins every tie against the un-rebuildable bundle,
   robot-darkmode.css (async) and ss-wait.css. The bundle's own custom props
   (--st-sage family) are hijacked rather than out-specified wherever the
   bundle applies them with !important — the var VALUE wins through.
   Panel findings this file implements, in three packages:
     1. Hero pill on canon      — one sage (#4A7A68) across the app; dark flips
                                  to #7DA893+ink (AA 5.92:1, was 2.40:1 FAIL);
                                  Cancel goes neutral (stop ≠ go); entrance/exit
                                  choreographed via @starting-style.
     2. The thinking state      — skeleton joins the warm sage wait-family and
                                  the target panel's own text grid.
     3. Line discipline         — one focus-ring voice, one icon stroke family,
                                  warm editor ink, quieter chrome labels.       */

/* ═══ 1 · HERO PILL ═══════════════════════════════════════════════════════ */

/* The robot minted its own green family (moss light + pale dark, off the
   app canon). All --st-sage consumers move to canon sage in one stroke. */
.translate-page .split-translator {
  --st-sage: #4A7A68;
  --st-sage-hover: #3E6553;
  --st-sage-light: rgba(74, 122, 104, .08);
  --st-sage-shadow: rgba(74, 122, 104, .35);
  /* Panel elevation joins the app's dual-layer shadow canon (crisp key +
     soft ambient) — the old single 12px blur read flat. */
  --st-warm-shadow: 0 1px 2px rgba(60, 55, 40, .05), 0 12px 28px -10px rgba(60, 55, 40, .10);
}
[data-theme="dark"] .translate-page .split-translator {
  /* Dark primary = light fill + ink text (the app's dark-accent model),
     never ivory-on-mid-green. */
  --st-sage: #7DA893;
  --st-sage-hover: #8CB5A1;
  --st-sage-light: rgba(125, 168, 147, .10);
  --st-sage-shadow: rgba(125, 168, 147, .30);
}
/* Warm ink at the token root: the bundle's cold text-primary (#131313 light /
   cool #e8e6e1 dark) feeds the editor — the largest surface in the robot —
   plus the chrome inks. Hijacking the token fixes the family; the bundle's
   own var() consumers carry it everywhere, including through !important. */
.translate-page .split-translator { --color-text-primary: #3A3730; }
[data-theme="dark"] .translate-page .split-translator { --color-text-primary: #E8E0D8; }
[data-theme="dark"] .translate-page .split-translator .st-floating-translate {
  color: #1F2422;
}
/* Glow-only shadow → canon dual layer (sage ambient kept, crisp key added).
   The calm block pins its glow with !important — match the weight. Desktop
   only: the mobile bar is flat by design and keeps its own shadow. */
@media (min-width: 768px) {
  .translate-page .split-translator .st-floating-translate {
    box-shadow: 0 1px 2px rgba(31, 36, 34, .18), 0 12px 28px -10px var(--st-sage-shadow) !important;
  }
}
/* 26px was the page's only off-beat interval — 24 puts the pill and the
   toolbar on the same 12/16/24/32 grid as everything else. */
@media (min-width: 768px) {
  .translate-page .split-translator .st-floating-translate { bottom: 82px; }
}

/* Cancel must not wear the action colour (app cancel canon: neutral).
   Doubled class beats the shared slot rule; !important matches the
   bundle's own weight on background. */
.translate-page .split-translator .st-cancel-btn.st-cancel-btn {
  background: #FFFEFB !important;
  color: #5C4D43 !important;
  border: 1px solid rgba(60, 55, 40, .14) !important;
  box-shadow: 0 1px 2px rgba(60, 55, 40, .08), 0 12px 28px -10px rgba(60, 55, 40, .16) !important;
}
[data-theme="dark"] .translate-page .split-translator .st-cancel-btn.st-cancel-btn {
  background: #36342F !important;
  color: #E8E6E1 !important;
  border: 1px solid rgba(255, 255, 255, .14) !important;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .30), 0 12px 28px -10px rgba(0, 0, 0, .40) !important;
}
/* Hover: ss-wait.css swaps only the background to a grey fill and leaves the
   dark neutral text unchanged — dark text on grey reads as broken. Keep the
   neutral canon on hover: a subtle darkening of the light pill with readable
   text. Specificity (0,6,0) + later load order beats ss-wait's :hover. */
.translate-page .split-translator .st-cancel-btn.st-cancel-btn:hover:not(:disabled) {
  background: #F3EFE9 !important;
  color: #4A3E36 !important;
  border-color: rgba(60, 55, 40, .22) !important;
}
[data-theme="dark"] .translate-page .split-translator .st-cancel-btn.st-cancel-btn:hover:not(:disabled) {
  background: #423F39 !important;
  color: #F2F0EB !important;
  border-color: rgba(255, 255, 255, .22) !important;
}

/* The bundle authors a 180ms rise on the pill but shows/hides it with
   inline display flips, so the entrance never plays. @starting-style +
   allow-discrete resurrect the authored choreography without touching JS;
   browsers without support keep today's instant swap. The reduced-motion
   global guard (transition-duration:.01ms) covers all of it. */
.translate-page .split-translator .st-floating-translate {
  transition: opacity .18s cubic-bezier(.2, 0, 0, 1), transform .18s cubic-bezier(.2, 0, 0, 1),
              box-shadow .18s ease, background-color .18s ease, display .18s;
  transition-behavior: allow-discrete;
}
/* Cancel lands just after Translate releases — one pill changing its mind. */
.translate-page .split-translator .st-cancel-btn.st-cancel-btn { transition-delay: .06s; }
@starting-style {
  .translate-page .split-translator .st-floating-translate:not([style*="display: none"]):not([style*="display:none"]) {
    opacity: 0;
    transform: translate(-50%) translateY(8px);
  }
}
@media (max-width: 767px) {
  /* Mobile positions the bar with left/right, not translate — entrance is
     opacity-only there, and the transform lock stays intact. */
  @starting-style {
    html body .translate-page .split-translator .st-floating-translate:not([style*="display: none"]):not([style*="display:none"]) {
      opacity: 0;
      transform: none;
    }
  }
  /* The primary CTA gave zero response to touch: the mobile block locks
     transform and :active re-declared the resting colour. */
  html body .translate-page .split-translator .st-floating-translate:active:not(:disabled) {
    background: var(--st-sage-hover) !important;
    transform: scale(.98) !important;
    transition-duration: .08s !important;
  }
}

/* ═══ 2 · THE THINKING STATE ══════════════════════════════════════════════ */

/* Cold template bars (#EEF1F0 on ivory) → the app's own sage wait-family
   stops, on the target panel's own text grid: 24px inset (was 16 — the
   answer no longer shifts 8px when it lands), 28.8px pitch (= editor
   line-height), first bar on the placeholder's optical line. */
.translate-page .split-translator .st-skeleton {
  padding: 24px;
  gap: 12.8px;
}
.translate-page .split-translator .st-skeleton-line {
  height: 16px;
  border-radius: 8px;
  opacity: 1;
  background: linear-gradient(90deg, rgba(110, 138, 126, .10) 25%, rgba(110, 138, 126, .22) 50%, rgba(110, 138, 126, .10) 75%);
  background-size: 800px 100%;
  animation: st-craft-shimmer 2.2s infinite linear;
}
.translate-page .split-translator .st-skeleton-line:first-child { margin-top: 14px; }
[data-theme="dark"] .translate-page .split-translator .st-skeleton-line {
  background: linear-gradient(90deg, rgba(125, 168, 147, .10) 25%, rgba(125, 168, 147, .24) 50%, rgba(125, 168, 147, .10) 75%);
  background-size: 800px 100%;
}
/* The old 1.5s ease-in-out sweep loitered off-canvas then whipped across,
   all four bars in sync. Linear glide + a rest beat + stagger = breathing. */
@keyframes st-craft-shimmer {
  0%   { background-position: -400px 0; }
  65%  { background-position: 400px 0; }
  100% { background-position: 400px 0; }
}
.translate-page .split-translator .st-skeleton-line:nth-child(2) { animation-delay: .12s; }
.translate-page .split-translator .st-skeleton-line:nth-child(3) { animation-delay: .24s; }
.translate-page .split-translator .st-skeleton-line:nth-child(4) { animation-delay: .36s; }

/* Save-star joins the same first line — desktop is nudged 15px up to meet the
   placeholder's optical line; mobile already sits right. */
@media (min-width: 768px) {
  .translate-page .split-translator .ss-saved-star { margin-top: -15px; margin-right: 5px; }
}
[data-theme="dark"] .translate-page .split-translator .ss-saved-star { color: #A3A19B; }
[data-theme="dark"] .translate-page .split-translator .ss-saved-star.on { color: #7DA893; }

/* ═══ 3 · LINE DISCIPLINE ═════════════════════════════════════════════════ */

/* 3a · Focus rings: REMOVED on Morten's call 17/7 ("I hate fokus-ringe —
   tell-tale sign of AI"). Keyboard focus falls back to the bundle's own
   quiet alpha outlines. Never reintroduce visible rings on this robot. */

/* 3b · One icon stroke family (~1.4px optical). The header trio rendered
   at 0.83–1.11px (mic stroke-width="5%", paste/upload default 1) against
   the chrome's 1.4 norm — CSS stroke-width beats presentation attributes. */
.translate-page .split-translator .st-source-header .st-footer-btn svg { stroke-width: 1.7; }
.translate-page .split-translator #pasteBtn svg,
.translate-page .split-translator [data-mirror="pasteBtn"] svg { stroke-width: 1.5; } /* 18-unit viewBox → 1.44 optical */
/* Toolbar glyphs: one box (16/17/18 → 18), one resting ink, UI letterforms
   for B/I/T (no stray platform serif fallbacks). */
.translate-page .split-translator .st-format-btn svg { width: 18px; height: 18px; }
/* …men .st-format-btn rammer IKKE højttaleren (#sourceTtsBtn bærer .ss-play) og
   heller ikke papirkurven (.st-format-clear-btn), så de to stod tilbage på
   markup'ens 16px midt i en stribe af 18px-glyffer. Et mindre ikon med samme
   streg læser tyndere = "mat", hvilket var præcis det, der stak ud ved
   højttaleren. Grammatikrobotten normaliserer HELE striben til ét mål
   (bundle-overrides.css `.format-toolbar .format-btn svg { 16px !important }`);
   her gør vi det samme på translatorens eget mål. Stregen samles på 2 —
   kopiknappen lå på 1.9 og var den sidste vægt-afvigelse. Header-trioen har sin
   egen 1.7-regel ovenfor og er uden for dette scope. */
.translate-page
  .split-translator
  .st-source-footer
  .st-format-group
  .st-footer-btn svg {
  width: 18px;
  height: 18px;
  stroke-width: 2;
}
/* Blæk-kanon fra skrivebord (v2.css: `.format-toolbar .format-btn { color:
   var(--sk-ink) }`): HELE stribens ikoner hviler i varm næsten-sort #3A2F26, og
   deaktiveret bæres af FARVEN alene — `opacity: 1`, ikke en ekstra nedtoning.
   Translatoren hvilede i #736F66 OG fik `.st-footer-btn:disabled{opacity:.3}`
   (main.css) oveni, så hele pillen læste mat ved siden af grammatikrobottens.
   Scope er kildepillen, så header-trioen og alle andre .st-footer-btn er urørt.
   Bemærk: #sourceTtsBtn bærer .ss-play og IKKE .st-format-btn — den gamle regel
   ramte den aldrig, og højttaleren stod derfor endnu blegere (#9A8E82) end
   resten. Container-scope frem for knap-klasse fanger den med.
   `.st-format-group` skal med i vælgeren: main.css' egen pille-regel
   (`… .st-source-footer .st-format-group .st-format-btn { color:
   var(--st-warm-secondary) }`) vejer (0,5,0), og denne fil ligger sidst i
   dokumentet — samme vægt + senere = vinder, uden !important. */
.translate-page .split-translator .st-source-footer .st-format-group .st-footer-btn {
  color: #3A2F26;
}
[data-theme="dark"]
  .translate-page
  .split-translator
  .st-source-footer
  .st-format-group
  .st-footer-btn {
  color: #E8DDD4;
}
.translate-page
  .split-translator
  .st-source-footer
  .st-format-group
  .st-footer-btn:disabled {
  color: #9A8E82;
  opacity: 1;
}
[data-theme="dark"]
  .translate-page
  .split-translator
  .st-source-footer
  .st-format-group
  .st-footer-btn:disabled {
  color: rgba(232, 221, 212, 0.24);
  opacity: 1;
}

/* Samme blæk-kanon for MÅLPILLEN. Blokken ovenfor sagde selv "Scope er
   kildepillen", så resultatpillen (kopiér / download / oplæs / spørg) blev
   stående på bundlens
   `… .st-target-wrap > .st-floating-actions .st-float-btn { color:
   var(--st-warm-secondary) }` = #736F66 — hvilepositionen for ALLE FIRE.
   Rapporten lød "kun højttaleren har den rigtige aktive farve", men de fire
   deler faktisk blæk: den ene knap, der så mørkere ud, stod i :hover
   (`color: var(--st-warm-text)` = #3A3730). Fejlen er altså ikke, at tre er
   for lyse i forhold til den fjerde — det er, at HELE pillens hvileblæk er ét
   trin for lyst, så et tilfældigt hover læser som "kun den her er aktiv".
   Ingen af dem er slået fra: setTargetToolbarEnabled tænder og slukker
   kopiér/download/oplæs SAMMEN (06-st-ui.js), og spørg-knappen deaktiveres
   aldrig.
   Bemærk også, at samme bundle-regel (0,5,0) spiser
   `.translate-page .split-translator .st-float-btn.st-float-chat { color:
   var(--st-sage) }` (0,4,0) — derfor er spørg-knappen grå frem for salvie.
   Blækket er kildepillens EGET, tal for tal: #3A2F26 / #E8DDD4 i hvile,
   #9A8E82 / rgba(232,221,212,.24) deaktiveret. Målpillen er ikke en variant af
   kildepillen — det er den samme stribe knapper i den anden rude, så den skal
   ikke have sin egen tone.
   Vægt: selektorerne herunder GENBRUGER bundlens egen form (0,5,0) og vinder
   på dokumentorden — denne fil ligger sidst. De taber bevidst til
   mobilblokkens !important, så <=767 er urørt (den står stadig på #5C4D43;
   mobilpillen har sit eget 32px/16px-forhold og er en separat beslutning). */
.translate-page .split-translator .st-target-wrap > .st-floating-actions .st-float-btn {
  color: #3A2F26;
}
[data-theme="dark"] .translate-page .split-translator .st-target-wrap > .st-floating-actions .st-float-btn {
  color: #E8DDD4;
}
/* Hover holder blækket STILLE, præcis som kildepillen: den har ingen
   hover-farve, fordi den allerede hviler i #3A2F26. Reglerne her er derfor
   ikke en effekt, men en neutralisering — uden dem vinder bundlens
   `… .st-float-btn:hover:not(:disabled) { color: var(--st-warm-text) }`
   (#3A3730), og så ville et hover gøre ikonet LYSERE end hvile. Den bløde
   baggrundstoning fra samme bundle-regel er feedback nok.
   Deaktiveret bæres af FARVEN alene (`opacity: 1`) — samme recept som
   kildepillen; `.st-float-btn:disabled { opacity: .3 }` var netop det, der fik
   en utilgængelig knap til at se mat ud frem for bevidst. */
.translate-page .split-translator .st-target-wrap > .st-floating-actions .st-float-btn:hover:not(:disabled) {
  color: #3A2F26;
}
[data-theme="dark"] .translate-page .split-translator .st-target-wrap > .st-floating-actions .st-float-btn:hover:not(:disabled) {
  color: #E8DDD4;
}
.translate-page .split-translator .st-target-wrap > .st-floating-actions .st-float-btn:disabled {
  color: #9A8E82;
  opacity: 1;
}
[data-theme="dark"] .translate-page .split-translator .st-target-wrap > .st-floating-actions .st-float-btn:disabled {
  color: rgba(232, 221, 212, 0.24);
  opacity: 1;
}
/* Spørg-knappen fylder hele sin cirkel med salvie i .active-tilstand, og dér
   skal ikonet blive hvidt — hover-reglen ovenfor må ikke tage det.
   IKKE :hover: i DENNE pille vinder bundlens generiske
   `… .st-target-wrap > .st-floating-actions .st-float-btn:hover
   { background: rgba(154,142,130,.08) }` over `.st-float-chat:hover
   { background: var(--st-sage) }` (samme vægt, står senere), så den salviefyldte
   hover findes ikke her. Et hvidt ikon oven på den næsten usynlige baggrund
   ville forsvinde — spørg-knappen hover'er derfor som de tre andre. */
.translate-page .split-translator .st-target-wrap > .st-floating-actions .st-float-btn.st-float-chat.active {
  color: #fff;
}

/* ÉT ikonmål og ÉN streg i målpillen — samme normalisering som kildepillen fik
   ovenfor ("Toolbar glyphs: one box, one resting ink"). Tegningerne er i
   forvejen de SAMME: #ttsBtn og #sourceTtsBtn deler polygon+buer, #copyBtn og
   #sourceCopyBtn deler rect+path. Forskellen var kun optisk — kildepillen
   tegner 18px/streg 2, målpillen stod på markup'ens 16px, og spørg-knappen
   endda på streg 1.5. Samme ikon i to mål læser som to ikonfamilier.
   Knappen bliver på 34px (kildepillens 38px hører til dens egen stribe); det
   er glyffen, ikke trykfladen, der samles. Kun >=768: mobilpillen har sit eget
   bevidste 32px/16px-forhold (oversaettelse-mobile.css) og er urørt. */
@media (min-width: 768px) {
  .translate-page .split-translator .st-target-wrap > .st-floating-actions .st-float-btn svg {
    width: 18px;
    height: 18px;
    stroke-width: 2;
  }
}

/* T-triggeren er ét trin lysere end resten — præcis som skrivebords
   `.calm-heading-trigger { color: var(--sk-ink-2) }` (#5C4D43). Står EFTER
   reglen ovenfor, så den vinder på dokumentorden ved samme vægt. */
.translate-page
  .split-translator
  .st-source-footer
  .st-format-group
  .st-calm-heading-trigger {
  color: #5C4D43;
}
[data-theme="dark"]
  .translate-page
  .split-translator
  .st-source-footer
  .st-format-group
  .st-calm-heading-trigger {
  color: rgba(232, 221, 212, 0.78);
}
.translate-page .split-translator .st-format-btn span {
  font-family: inherit;
  font-size: 15px;
}

/* Ikon-kanon med grammatik-robotten: dens T-trigger bærer Georgia-»T«-et
   (calm-ed-overflow.css .calm-trigger-label) — typografi-semantikken er selve
   glyffen. `font-family: inherit` ovenfor tog tidligere .st-calm-trigger-label
   med og gjorde translatorens T grotesk/sans, så de to værktøjslinjer viste to
   forskellige T'er for samme formatmenu. Kun font-family gives tilbage; 15px
   holdes, så knappens metrik og pillebredde er uændret.
   Caret'en skjules af samme grund som i skrivebord (.bb-skrivebord
   .calm-trigger-caret { display:none }): den bliver i DOM'en for a11y/JS,
   men tegnes ikke — knappen forbliver klikbar og popoveren uændret. */
.translate-page .split-translator .st-format-btn span.st-calm-trigger-label {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 15px;
}

.translate-page .split-translator .st-calm-trigger-caret {
  display: none;
}

/* 3c · Warm ink where the template's cold tokens still showed. The editor —
   the largest surface in the robot — rendered #131313 on a warm page. */
.translate-page .split-translator .ql-editor,
.translate-page .split-translator .ql-editor p,
.translate-page .split-translator .ql-editor li { color: #3A3730; }
[data-theme="dark"] .translate-page .split-translator .ql-editor,
[data-theme="dark"] .translate-page .split-translator .ql-editor p,
[data-theme="dark"] .translate-page .split-translator .ql-editor li { color: #E8E0D8; }
/* Header trio + swap: cold secondary → the panel's warm secondary. */
.translate-page .split-translator .st-source-header .st-footer-btn { color: #736F66; }
.translate-page .split-translator .st-swap-btn { color: #7A6F66; }
/* Idle tone pills, light: cold border/label → warm (dark idle is Morten-
   approved 12/7 and untouched — :not(.active) outweighs the tone overlay's
   runtime <style>, which sits after this <link> in the DOM). Icons
   duplicated the dock glyph at 1.05px — text-only pills, calmer row. */
.translate-page .split-translator .st-tone-segment .st-tone-preset-btn:not(.active) {
  border-color: rgba(60, 55, 40, .14);
  color: #736F66;
}
[data-theme="dark"] .translate-page .split-translator .st-tone-segment .st-tone-preset-btn:not(.active) {
  border-color: rgba(255, 255, 255, .14); /* restate the Morten-approved 12/7 dark idle so the light warm-border can't bleed */
  color: #A3A19B;
}
.translate-page .split-translator .st-tone-segment .st-tone-preset-btn {
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.translate-page .split-translator .st-tone-ico { display: none; }
.translate-page .split-translator .st-tone-segment .st-tone-preset-btn { padding: 4px 12px; }
/* Active pill keeps canon sage in light; dark flips to the dark-accent
   model so it agrees with the fixed CTA beside it. The bundle paints the
   active pill via --st-tone-active with an !important trio — hijack the
   token for the fill/shadow, and match the literal color's weight. */
[data-theme="dark"] .translate-page .split-translator {
  --st-tone-active: #7DA893;
  --st-tone-active-shadow: rgba(0, 0, 0, .25);
}
.translate-page .split-translator .st-tone-segment .st-tone-preset-btn.active {
  border-color: transparent;
  color: #FFFEFB !important;
}
[data-theme="dark"] .translate-page .split-translator .st-tone-segment .st-tone-preset-btn.active {
  color: #1F2422 !important;
}

/* 3d · Chrome quiet-downs. "More" was the page's only elevation-less white
   card (sticker) and over-weighted for a tertiary control → ghost twin of
   the selectors. Its shipped block is ID-anchored (#overflowMenuBtn), so
   these carry the same anchor. Half-pixel label sizes → the 13/14/16 scale. */
.translate-page .split-translator .st-language-bar .st-overflow-btn#overflowMenuBtn {
  background: transparent;
  border-color: transparent;
  border-radius: 10px;
  box-shadow: none;
}
.translate-page .split-translator .st-language-bar .st-overflow-btn#overflowMenuBtn:hover {
  background: rgba(60, 55, 40, .05);
  border-color: transparent;
  color: #3A2F26;
}
[data-theme="dark"] .translate-page .split-translator .st-language-bar .st-overflow-btn#overflowMenuBtn {
  background: transparent;
  border-color: transparent;
}
[data-theme="dark"] .translate-page .split-translator .st-language-bar .st-overflow-btn#overflowMenuBtn:hover {
  background: rgba(255, 255, 255, .06);
}
.translate-page .split-translator .st-language-bar .st-overflow-btn#overflowMenuBtn .st-overflow-label { font-size: 13px; }
.translate-page .split-translator .st-language-bar .st-lang-name { font-size: 14px; } /* 4-class: the langbar block pins 14.5px at this weight */
/* Enumerated transitions (transition:all is the template fingerprint). */
.translate-page .split-translator .st-swap-btn,
.translate-page .split-translator .st-overflow-btn {
  transition: background .12s ease, color .12s ease, border-color .12s ease, box-shadow .12s ease;
}
/* Globe column joins the text column above it (16.5px near-miss at rest). */
@media (min-width: 768px) {
  .translate-page .split-translator .st-language-bar > .st-lang-group:first-child { margin-inline-start: 17px; }
}

/* 3e · Menus breathe like their chevrons. Both lang dropdowns (and More)
   snapped open while their chevrons animated 180ms. Keep display, gate with
   visibility so closed menus stay out of the accessibility tree. */
.translate-page .split-translator .st-lang-dropdown {
  display: flex;
  visibility: hidden;
  opacity: 0;
  transform: translateY(-4px);
  pointer-events: none;
  transition: opacity .14s ease, transform .14s cubic-bezier(.2, 0, 0, 1), visibility .14s;
}
.translate-page .split-translator .st-lang-dropdown.open {
  visibility: visible;
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
.translate-page .split-translator .st-overflow-dropdown {
  display: block;
  visibility: hidden;
  opacity: 0;
  transform: translateY(-4px);
  pointer-events: none;
  transition: opacity .14s ease, transform .14s cubic-bezier(.2, 0, 0, 1), visibility .14s;
}
.translate-page .split-translator .st-overflow-dropdown.open {
  visibility: visible;
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

/* 3f · Dark-mode containment fixes (no global dark retune — contained
   only): target panel's page-coloured base flashed through the 14px
   corners (the bundle pins it with !important — match the weight); the
   floating toolbar had zero elevation against the panel (bundle anchors it
   at .st-source-footer — match the anchor). */
[data-theme="dark"] .translate-page .split-translator .st-target-panel { background: #2B2A27 !important; }
[data-theme="dark"] .translate-page .split-translator .st-source-footer .st-format-group {
  background: #33322E;
  border-color: rgba(232, 224, 216, .08);
}

/* 3g · Touch targets: the ≤767px block 44px-ed every panel icon but
   exempted the langbar and the action pills for this exact audience. */
@media (max-width: 767px) {
  html body .translate-page .split-translator .st-language-bar .st-swap-btn,
  html body .translate-page .split-translator .st-language-bar .st-overflow-btn {
    width: 44px;
    height: 44px;
  }
  /* The 38px compact bar is deliberate (equal-width groups, !important) —
     grow the TAP zone to 44 with an inset pseudo, not the visual box. */
  html body .translate-page .split-translator .st-language-bar .st-lang-selector { position: relative; }
  html body .translate-page .split-translator .st-language-bar .st-lang-selector::before {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: -3px;
    bottom: -3px;
  }
  html body .translate-page .split-translator .st-float-btn { min-height: 44px; }
}
@media (min-width: 768px) and (max-width: 1023px) {
  /* Tablet dropped tone pills to 11px/18px targets on touch hardware. */
  html body .translate-page .split-translator .st-tone-segment .st-tone-preset-btn {
    font-size: 12px;
    padding: 6px 10px;
  }
  /* 19/7 QA: five tones overflow the header's hidden overflow at 768 -
     Akademisk and Kreativ sat past the viewport with no scrollbar and no
     affordance (pointer users could never reach them). Let the segment
     wrap onto extra rows; the header grows with it. */
  html body .translate-page .split-translator .st-target-header {
    height: auto;
    min-height: 36px;
    flex-wrap: wrap;
  }
  html body .translate-page .split-translator .st-tone-segment {
    flex-wrap: wrap;
    justify-content: flex-end;
    row-gap: 2px;
  }
}

/* ============================================================
   Kilde-toolbarens glas-pille = skrivebordets counter-nav-div 1:1
   (Mortens ordre 19/7: én kilde til sandhed — containeren HAVDE
   allerede klasserne counter-nav-div/format-toolbar fra en tidligere
   halv leverance, men skrivebord-reglerne er .bb-skrivebord-scoped og
   ramte aldrig. Værdierne herunder er kopieret uændret fra
   robots/skrivebord/css/skrivebord-v2.css §counter-nav-div + dark-
   card-fladen; kun scope-prefixet er translatorens.) */
@media (min-width: 768px) {
.st-source-panel { position: relative; }
.st-source-panel .st-source-footer.counter-nav-div {
  position: absolute !important;
  left: 50% !important;
  bottom: 32px !important;
  transform: translateX(-50%) !important;
  z-index: 30 !important;
  width: max-content !important;
  max-width: calc(100% - 24px) !important;
  height: 56px !important;
  min-height: 56px !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  flex-wrap: nowrap !important;
  overflow: visible !important;
  gap: 0 !important;
  padding: 0 18px !important;
  box-sizing: border-box !important;
  background: rgba(255, 254, 251, 0.96) !important;
  border: 1px solid rgba(228, 220, 212, 0.78) !important;
  border-radius: 20px !important;
  box-shadow: 0 2px 8px rgba(92, 77, 67, 0.07), 0 14px 42px rgba(92, 77, 67, 0.11), inset 0 1px 0 rgba(255,255,255,0.72) !important;
  backdrop-filter: blur(16px) !important;
  -webkit-backdrop-filter: blur(16px) !important;
}
.st-source-panel .st-format-group.format-toolbar {
  order: 1 !important;
  display: flex !important;
  align-items: center !important;
  flex-wrap: nowrap !important;
  max-width: 100% !important;
  overflow: visible !important;
  gap: 0 !important;
  height: 100% !important;
  margin: 0 !important;
  padding: 0 !important;
  background: transparent !important;
  border: 0 !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}
/* 5a-dark (Mortens skud 19/7 aften): robot-darkmode.css' generiske
   skrivebords-regel `[data-theme="dark"] body .robot-container
   .format-toolbar { background: var(--color-card) !important }`
   (specificitet 0,3,1) slaar parity-transparensen ovenfor (0,3,0 —
   begge !important) og maler gruppe-FIRKANTEN kort-moerk (#2b2a27,
   border-radius:0, height:100%) OVENPAA glas-pillen — kun pillens
   afrundede ender ses i dark. Hoejere specificitet (0,4,0) giver
   transparensen tilbage; counter-nav-div-pillen ejer dark-fladen. */
[data-theme="dark"] .st-source-panel .st-format-group.format-toolbar {
  background: transparent !important;
}
/* Editor-teksten maa ikke ligge under pillen. */
.st-source-panel .st-source-editor .ql-editor { padding-bottom: 104px; }
[data-theme="dark"] .st-source-panel .st-source-footer.counter-nav-div {
  background: rgba(42, 38, 34, 0.85) !important;
  border-color: rgba(232, 224, 216, 0.08) !important;
}
}

/* ============================================================
   5b (Mortens go 19/7): outputtets flyde-række arver kilde-pillens
   glas-anatomi 1:1 — samme flade, kant, skygge og blur som counter-
   nav-pillen ovenfor. Position/knapper er bundlens (36px begge steder);
   kun CONTAINERENS look ensrettes. Desktop-gated som 5a. */
@media (min-width: 768px) {
  .st-target-panel .st-floating-actions {
    height: 56px !important;
    padding: 0 18px !important;
    border-radius: 20px !important;
    background: rgba(255, 254, 251, 0.96) !important;
    border: 1px solid rgba(228, 220, 212, 0.78) !important;
    box-shadow: 0 2px 8px rgba(92, 77, 67, 0.07), 0 14px 42px rgba(92, 77, 67, 0.11), inset 0 1px 0 rgba(255,255,255,0.72) !important;
    backdrop-filter: blur(16px) !important;
    -webkit-backdrop-filter: blur(16px) !important;
  }
  [data-theme="dark"] .st-target-panel .st-floating-actions {
    background: rgba(42, 38, 34, 0.85) !important;
    border-color: rgba(232, 224, 216, 0.08) !important;
  }
}

/* ============================================================
   Regression-fix (Mortens skud 19/7): (1) dark-pillerne arvede LYS-
   skyggens hvide inset-linje ("ny farve foroven") — dark får sin egen
   skygge uden inset; (2) den flydende Oversæt-knap (bundle bottom:84px,
   målt mod den gamle kompakte footer) rørte den 56px høje pille —
   løftes til 104px så der er luft. Desktop-gated som resten. */
@media (min-width: 768px) {
  [data-theme="dark"] .st-source-panel .st-source-footer.counter-nav-div,
  [data-theme="dark"] .st-target-panel .st-floating-actions {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.22), 0 14px 42px rgba(0, 0, 0, 0.30) !important;
  }
  .st-source-panel .st-floating-translate {
    bottom: 104px !important;
  }
  /* (3) Pillerne FLUGTER: output-raekken loeftes til kilde-pillens 32px
     (bundlens 16px + rest-translateY laa den ~8px lavere). Visible-
     animationen (translateY 8->0) bevares - slutlejet er rent 32px. */
  .st-target-panel .st-floating-actions {
    bottom: 32px !important;
  }
}

/* ============================================================
   Frossen-transition-vaernet (fundet paa public 19/7, bekraeftet paa
   app samme nat): bundlens visible-transition paa output-raekken
   (translateY 8px -> 0) kan FRYSE som evig-running CSSTransition -
   transitions vinder over !important i kaskaden, saa raekken stod 8px
   under kilde-pillens 32px-baseline (intermittent - afhaenger af om
   transitionens foerste tick naar at koere). Ingen transform-transition
   + laast slutleje = deterministisk flugtning. Desktop-gated som
   resten af pille-blokkene. */
@media (min-width: 768px) {
  .st-target-panel .st-floating-actions {
    transition-property: opacity !important;
    transform: translate(-50%) !important;
  }
}

/* ============================================================
   Regression-fix (Mortens skud 19/7): "Tekst N af M"-navigationen
   (bundle bottom:72px, maalt mod den gamle 48px-raekke) kolliderede
   med den 56px hoeje parity-pille paa 32px-baselinen (topkant 88px).
   Loeftes til 96px = samme 8px-luft over pillen som foer parity.
   Desktop-gated som pille-blokkene (mobil-raekken er statisk footer
   = ingen kollision der). */
@media (min-width: 768px) {
  .st-target-panel .st-response-nav {
    bottom: 96px !important;
  }
}

/* ============================================================
   Stale-resultat-vaernet (GPT-mega-QA 19/7, BLOCKER verificeret live):
   naar kildeteksten aendres efter en oversaettelse beholdt output-panelet
   fuldt aktive Kopier/Download/Oplaes-knapper paa det GAMLE resultat.
   Bundlens updateCharCount saetter nu .st-result-stale paa target-panelet
   (og deaktiverer knaprakken) saa snart vist kilde != oversat kilde;
   dimningen her goer tilstanden aflaeselig i begge temaer. Ny
   oversaettelse / historik-indlaesning / tilbage-redigering fjerner den. */
.st-target-panel.st-result-stale .st-target-output {
  /* !important + transition:none er frossen-transition-vaernet (#6234-
     klassen): bundlens egen opacity-transition paa outputtet kan staa som
     evig-running CSSTransition og VINDER ellers over kaskaden — maalt live
     paa tr108 (getAnimations()=1, computed 1.0 trods matchende regel);
     transition-property-skiftet ANNULLERER den frosne transition
     deterministisk (bevist: anims 0, computed 0.55). Ingen fade — dim
     skal lande oejeblikkeligt alligevel. */
  opacity: 0.55 !important;
  transition: none !important;
}

/* ============================================================
   Taellerkontrakten (19/7 QA MAJOR): UI'et lover "{count} / 50.000
   tegn" i alle 8 locales, men #charCount-elementet fandtes aldrig i
   markuppen - taeller, varsel og forklaring var doede, og Oversaet
   blev tavst disabled ved 49.000 MENS :not()-opacity-reglen holdt den
   fuldt synlig. Nu: elementet er genindsat i editor-wrappen; bundlens
   egen updateCharCount skriver tallet og toggler klasserne. Ro-kanon:
   usynlig under 45k (ingen permanent stoej), amber 45-49k, roed fra
   49k (fortsat aktiv til 50k - graensen er MAX_CHARS), og disabled
   ligner nu disabled. Dark = oe-behandlingen (tint-baggrunde drukner
   paa panel-striben - footer-banner-klassen). */
.translate-page .split-translator .st-char-count {
  display: none;
  position: absolute;
  right: 16px;
  bottom: 76px;
  z-index: 12;
  padding: 4px 12px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.4;
  pointer-events: none;
  background: #FFFEFB;
  border: 1px solid rgba(60, 55, 40, .14);
  box-shadow: 0 1px 2px rgba(60, 55, 40, .08);
}
.translate-page .split-translator .st-char-count.st-char-warning {
  display: block;
  color: var(--color-warning-text, #a67200);
}
.translate-page .split-translator .st-char-count.st-char-error {
  display: block;
  color: #B3402E;
}
[data-theme="dark"] .translate-page .split-translator .st-char-count {
  background: rgba(255, 255, 255, .05);
  border-color: rgba(255, 255, 255, .1);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .3);
}
[data-theme="dark"] .translate-page .split-translator .st-char-count.st-char-warning {
  color: #D9B85C;
}
[data-theme="dark"] .translate-page .split-translator .st-char-count.st-char-error {
  color: #E08A7A;
}
/* Disabled-sandheden: bundlens :not([style*=display:none])-regel
   (opacity:1) slaar :disabled-reglen (opacity:.5) paa specificitet,
   saa en disabled Oversaet lignede en aktiv knap. Match vaegten. */
.translate-page .split-translator .st-floating-translate:disabled {
  opacity: .55 !important;
  cursor: not-allowed;
  box-shadow: none !important;
}

/* ============================================================
   44px-beroeringsflader paa mobil (GPT-mega-QA 19/7, MAJOR):
   ved 390px maalte Kopier/Oplaes 32x32 og Dikter/Tag billede/Indsaet
   32px hoeje - under 44px-minimum. Samme recept som email-fixpakken
   (#6247) og sidens egen ss-saved-star: en usynlig ::before baerer
   44px-tapboksen, den synlige geometri aendres IKKE. width:max(100%,
   44px) vokser aldrig brede piller vandret - kun hoejden loeftes. */
@media (max-width: 767px) {
  .st-floating-actions .st-float-btn,
  .calm-stt-btn,
  .calm-quickpaste-btn,
  .st-lang-expand-btn,
  .st-drawer-close,
  .st-chat-mic-btn,
  .st-chat-send-btn {
    position: relative;
  }
  .st-floating-actions .st-float-btn::before,
  .calm-stt-btn::before,
  .calm-quickpaste-btn::before,
  .st-lang-expand-btn::before,
  .st-drawer-close::before,
  .st-chat-mic-btn::before,
  .st-chat-send-btn::before {
    content: '';
    position: absolute;
    left: 50%;
    top: 50%;
    width: max(100%, 44px);
    height: max(100%, 44px);
    transform: translate(-50%, -50%);
  }
}

/* ============================================================
   Kilde-pillen paa tablet (768-1023) - #tabletfix
   Pillen blev kopieret 1:1 fra skrivebordets counter-nav-div, men UDEN
   skrivebordets responsive trin: den har flex-wrap:nowrap, en fast
   max-width paa calc(100% - 24px) og 8 knapper a 38px + 3 skillelinjer
   = 351px indhold. Kildepanelet er kun 306px bredt ved 768px viewport,
   saa Kopier + Ryd blev skaaret af udenfor pillens kant (browser-maalt:
   768 -> 90px udenfor, 820 -> 64px, 900 -> 24px). Translatoren har ingen
   overflow-menu, saa knapperne maa IKKE skjules - i stedet strammes
   pillen (mindre ramme, ingen skillelinjer, mindre knapper) saa alle 8
   bliver paa EN raekke i hele baandet. flex-wrap:wrap staar som sikkerhed
   ved sidezoom/store systemskrifter. ============================ */
@media (min-width: 768px) and (max-width: 1023.98px) {
  .st-source-panel .st-source-footer.counter-nav-div {
    max-width: calc(100% - 6px) !important;
    padding: 0 6px !important;
    /* auto hoejde = ombrud i stedet for afklipning hvis nogen sidezoomer eller
       koerer stor systemskrift. Prisen er 2px: pillen maaler 58px i baandet mod
       desktoppens faste 56px, fordi de to 1px-kanter lagges til den auto hoejde. */
    height: auto !important;
    min-height: 56px !important;
    flex-wrap: wrap !important;
    row-gap: 2px !important;
  }

  .st-source-panel .st-format-group.format-toolbar {
    flex-wrap: wrap !important;
    justify-content: center !important;
    row-gap: 2px !important;
  }

  .st-source-panel .st-source-footer .st-format-divider,
  .st-source-panel .st-source-footer .st-calm-sep {
    display: none !important;
  }

  .st-source-panel .st-source-footer .st-format-clear-btn {
    margin-left: 0 !important;
  }
}

/* 768-899: 8 x 38px passer ikke i det 306-330px brede kildepanel; 34px goer.
   Over 900px er der plads til den fulde 38px-knap igen. */
@media (min-width: 768px) and (max-width: 899.98px) {
  .st-source-panel .st-source-footer .st-footer-btn {
    width: 34px !important;
    min-width: 34px !important;
    height: 34px !important;
  }
}

@media (min-width: 900px) and (max-width: 1023.98px) {
  .st-source-panel .st-source-footer.counter-nav-div {
    padding: 0 12px !important;
  }
}
