/* ══════════════════════════════════════════
   CMS — /crew/cms

   Skallet er en APP, ikke en side i crew-panelet: egen topbar, ingen
   crew-topbar over. Grunnen staar i beslutningen — en side i panelskallet
   har tilbake-knappen som eneste utgang, og da blir hvert bytte mellom
   nyheter og forsiden en tur innom hub-en. Det var nettopp turene som skulle
   bort.

   Ikonskinna navigerer INNE i appen, mellom flater i samme domene. Den er
   ikke sidebaren som ble fjernet i /admin — se docs/design/paneler.md.

   Klasseprefikset er `.cms-`. Appen laaner .btn, .form-control, .list-item
   og .badge fra resten av designsystemet der de passer, men trenger sitt
   eget skall fordi ingenting annet i appen er tre kolonner mot en
   fullskjermsflate.
   ══════════════════════════════════════════ */

/* Fullskjerm uten sentrering og padding — samme gruppe som kassa og
   innsjekk. Glemmes denne, faar appen #app-fullscreen sin sentrering og
   ser ut som et smalt kort midt paa skjermen. */
body.fullscreen-page #app-fullscreen:has(.cms-app) {
    align-items: stretch;
    justify-content: stretch;
    padding: 0;
    min-height: 100vh;
    height: 100vh;
    overflow: hidden;
}
body.fullscreen-page #app-fullscreen:has(.cms-app) #app-content-full {
    width: 100%;
    height: 100vh;
    overflow: hidden;
}

.cms-app {
    --cms-chrome: #11161d;
    --cms-chrome-2: #151b23;
    --cms-rail: 52px;
    --cms-panel: 300px;
    --cms-doc-side: 300px;

    height: 100vh;
    display: grid;
    grid-template-rows: 52px 1fr;
    overflow: hidden;
    color: var(--vl-text);
}

/* ── Topbar ────────────────────────────────────────────────── */

.cms-top {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0 0.8rem;
    background: var(--cms-chrome);
    border-bottom: 1px solid var(--vl-glass-border);
    min-width: 0;
}

.cms-exit {
    width: 32px;
    height: 32px;
    flex-shrink: 0;
    /* Brukes både som <a> (appens topbar) og <button> (dokumentets). En klasse
       som skal kle begge må nullstille BEGGE nettleserstilene: knappens ramme
       og grå flate, og lenkas understrek. Glemmer man den ene, ser den ene
       varianten riktig ut og den andre ikke — og det var understreken som ble
       stående under tilbakepila. Samme fallgruve som `.md-rail-new` i
       components.css. */
    border: none;
    background: none;
    padding: 0;
    text-decoration: none;
    border-radius: var(--vl-radius-xs);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--vl-text-muted);
    font-size: 0.9rem;
    transition: all 0.15s;
}
.cms-exit:hover { background: var(--vl-glass); color: var(--vl-text); }

.cms-ctx {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.3rem 0.55rem;
    border: none;
    background: none;
    border-radius: var(--vl-radius-xs);
    color: var(--vl-text);
    font-size: 0.88rem;
    font-weight: 600;
    min-width: 0;
    transition: background 0.15s;
}
.cms-ctx-kind {
    font-size: 0.6rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--vl-text-muted);
    padding: 0.1rem 0.4rem;
    border-radius: 99px;
    background: rgba(255, 255, 255, 0.05);
    flex-shrink: 0;
}
.cms-ctx-name {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cms-top-mid {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 0;
}
.cms-saved {
    font-size: 0.76rem;
    color: var(--vl-text-muted);
    white-space: nowrap;
}
.cms-saved--dirty { color: #f0c07a; }
.cms-saved--error { color: #f0a48f; }

.cms-tool {
    width: 30px;
    height: 30px;
    flex-shrink: 0;
    border: none;
    background: none;
    border-radius: 6px;
    font-size: 0.8rem;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--vl-text-muted);
    transition: all 0.14s;
}
.cms-tool:hover { background: var(--vl-glass); color: var(--vl-text); }
.cms-tool.active { background: rgba(0, 206, 201, 0.14); color: var(--vl-accent); }

.cms-top-actions {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-shrink: 0;
}

.cms-tool-group {
    display: flex;
    align-items: center;
    gap: 0.1rem;
    padding: 0 0.35rem;
    border-left: 1px solid var(--vl-glass-border);
    height: 22px;
    flex-shrink: 0;
}

/* ── Kropp ─────────────────────────────────────────────────── */

.cms-body {
    display: grid;
    /* `auto` er draghåndtaket mellom lista og scenen. */
    grid-template-columns: var(--cms-rail) var(--cms-panel) auto 1fr;
    min-height: 0;
    min-width: 0;
}

/* ── Ikonskinne ────────────────────────────────────────────── */

.cms-rail {
    background: var(--cms-chrome);
    border-right: 1px solid var(--vl-glass-border);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.2rem;
    padding: 0.6rem 0;
}

.cms-rail-btn {
    position: relative;
    width: 36px;
    height: 36px;
    flex-shrink: 0;
    border: none;
    background: none;
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--vl-text-muted);
    font-size: 1rem;
    transition: all 0.15s;
}
.cms-rail-btn:hover { background: var(--vl-glass); color: var(--vl-text); }
.cms-rail-btn.active { background: rgba(0, 206, 201, 0.14); color: var(--vl-accent); }

/* Etiketten er et pseudo-element og ikke title=": nettleserens egen
   forsinkelse paa ett sekund gjor en ikonskinne ubrukelig for den som ennaa
   ikke har laert ikonene. */
.cms-rail-btn::after {
    content: attr(data-tip);
    position: absolute;
    left: 44px;
    top: 50%;
    transform: translateY(-50%);
    z-index: 30;
    padding: 0.25rem 0.55rem;
    border-radius: 6px;
    white-space: nowrap;
    background: #000;
    color: var(--vl-text);
    font-size: 0.72rem;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.12s;
}
.cms-rail-btn:hover::after { opacity: 0.92; }

.cms-rail-sep {
    width: 22px;
    height: 1px;
    background: var(--vl-glass-border);
    margin: 0.45rem 0;
    flex-shrink: 0;
}

/* ── Panel ─────────────────────────────────────────────────── */

.cms-panel {
    background: var(--cms-chrome-2);
    border-right: 1px solid var(--vl-glass-border);
    display: flex;
    flex-direction: column;
    min-height: 0;
    min-width: 0;
}

.cms-panel-top {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.85rem 0.9rem 0.7rem;
    flex-shrink: 0;
}
.cms-panel-top h2 {
    margin: 0;
    font-size: 1rem;
    font-weight: 650;
    flex: 1;
    letter-spacing: -0.01em;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cms-panel-back,
.cms-panel-act {
    width: 26px;
    height: 26px;
    flex-shrink: 0;
    border: none;
    background: none;
    border-radius: 6px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--vl-text-muted);
    font-size: 0.8rem;
    transition: all 0.14s;
}
.cms-panel-back:hover,
.cms-panel-act:hover { background: var(--vl-glass); color: var(--vl-text); }

.cms-panel-scroll {
    flex: 1;
    overflow-y: auto;
    padding: 0 0.7rem 1.2rem;
    min-height: 0;
}
.cms-panel-scroll::-webkit-scrollbar { width: 8px; }
.cms-panel-scroll::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.1);
    border-radius: 99px;
}

.cms-search {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0 0.9rem 0.7rem;
    padding: 0.42rem 0.6rem;
    border-radius: var(--vl-radius-xs);
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid var(--vl-glass-border);
    flex-shrink: 0;
}
.cms-search i { font-size: 0.75rem; color: var(--vl-text-muted); }
.cms-search input {
    flex: 1;
    min-width: 0;
    border: none;
    background: none;
    outline: none;
    color: var(--vl-text);
    font-size: 0.82rem;
}
.cms-search input::placeholder { color: #5f6b76; }

.cms-group {
    margin: 0.9rem 0 0.35rem;
    padding: 0 0.35rem;
    font-size: 0.6rem;
    font-weight: 700;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--vl-text-muted);
    opacity: 0.8;
}
.cms-group:first-child { margin-top: 0.2rem; }

/* ── Panelrad ──────────────────────────────────────────────── */

.cms-row {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.5rem;
    width: 100%;
    text-align: left;
    border: 1px solid transparent;
    background: none;
    border-radius: var(--vl-radius-xs);
    color: var(--vl-text);
    font-size: 0.83rem;
    transition: all 0.13s;
}
.cms-row:hover { background: var(--vl-glass); color: var(--vl-text); }
.cms-row.active {
    background: rgba(0, 206, 201, 0.1);
    border-color: rgba(0, 206, 201, 0.3);
    color: #b5eeec;
}
.cms-row--off { opacity: 0.45; }

.cms-row-grip {
    color: var(--vl-text-muted);
    opacity: 0.3;
    font-size: 0.72rem;
    cursor: grab;
    flex-shrink: 0;
    width: 10px;
    text-align: center;
}
.cms-row--locked .cms-row-grip { opacity: 0.1; cursor: default; }
.cms-row-grip:active { cursor: grabbing; }

.cms-row-icon {
    width: 24px;
    height: 24px;
    flex-shrink: 0;
    border-radius: 7px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.72rem;
    background: color-mix(in srgb, var(--tint, #8b949e) 16%, transparent);
    color: var(--tint, #8b949e);
}

.cms-row-body { flex: 1; min-width: 0; display: block; }
.cms-row-name {
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-weight: 500;
}
.cms-row-sub {
    display: block;
    font-size: 0.7rem;
    color: var(--vl-text-muted);
    margin-top: 0.08rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cms-row-eye {
    width: 22px;
    height: 22px;
    flex-shrink: 0;
    border: none;
    background: none;
    border-radius: 5px;
    font-size: 0.72rem;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--vl-text-muted);
    opacity: 0.55;
    transition: all 0.14s;
}
.cms-row-eye:hover { background: rgba(255, 255, 255, 0.07); opacity: 1; }
.cms-row--off .cms-row-eye { opacity: 0.9; color: #e17055; }

.cms-row-go {
    font-size: 0.7rem;
    color: var(--vl-text-muted);
    opacity: 0.5;
    flex-shrink: 0;
}

/* Statusprikk — publisert/utkast. Bevisst liten: den skal leses som en
   egenskap ved raden, ikke som et varsel. */
.cms-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    flex-shrink: 0;
    background: #00b894;
}
.cms-dot--draft { background: #7d8894; }

.cms-tag {
    font-size: 0.56rem;
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    padding: 0.08rem 0.35rem;
    border-radius: 4px;
    flex-shrink: 0;
    background: rgba(108, 92, 231, 0.2);
    color: #b6aaff;
}
.cms-tag--muted { background: rgba(255, 255, 255, 0.06); color: var(--vl-text-muted); }
.cms-tag--warn { background: rgba(225, 112, 85, 0.18); color: #f0a48f; }

.cms-add {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    width: 100%;
    margin-top: 0.6rem;
    padding: 0.5rem;
    border: 1px dashed var(--vl-glass-border);
    background: none;
    border-radius: var(--vl-radius-xs);
    color: var(--vl-text-muted);
    font-size: 0.79rem;
    transition: all 0.14s;
}
.cms-add:hover {
    border-color: rgba(0, 206, 201, 0.4);
    color: var(--vl-accent);
    background: rgba(0, 206, 201, 0.05);
}

/* «Dette redigeres et annet sted» — med veien dit.
   Ser ut som en knapp fordi den skal trykkes, men er dus fordi den fører BORT
   fra det man holder på med. Se `utenfor()` i editors.js. */
.cms-elsewhere {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    margin-top: 0.9rem;
    padding: 0.4rem 0.75rem;
    border: 1px solid var(--vl-glass-border);
    border-radius: 7px;
    background: none;
    color: var(--vl-text-muted);
    font-size: 0.78rem;
    font-weight: 600;
    text-decoration: none;
    transition: all 0.14s;
}
.cms-elsewhere:hover {
    background: var(--vl-glass);
    border-color: rgba(0, 206, 201, 0.35);
    color: var(--vl-accent);
}
.cms-elsewhere i { font-size: 0.72rem; opacity: 0.8; }

.cms-hint {
    font-size: 0.7rem;
    color: var(--vl-text-muted);
    line-height: 1.5;
    padding: 0.6rem 0.35rem 0;
}

.cms-empty {
    padding: 1.5rem 0.6rem;
    text-align: center;
    font-size: 0.8rem;
    color: var(--vl-text-muted);
    line-height: 1.6;
}

/* ── Media-rutenett ────────────────────────────────────────── */

.cms-media-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.5rem;
    padding-top: 0.2rem;
}
.cms-media-item {
    border-radius: var(--vl-radius-xs);
    overflow: hidden;
    border: 1px solid var(--vl-glass-border);
    background: rgba(255, 255, 255, 0.03);
    padding: 0;
    transition: all 0.14s;
}
.cms-media-item:hover { border-color: rgba(0, 206, 201, 0.45); }
.cms-media-item.active { border-color: var(--vl-accent); }
.cms-media-thumb {
    /* `display: block` er ikke pynt her — den er hele grunnen til at
       miniatyren VISES. Elementet er et <span>, altså inline, og `height`
       ignoreres på et inline-element uten innhold. Ruta kollapset til null
       høyde, så biblioteket sto med filnavn og ingen bilder. `padding` virker
       derimot på inline, og det er derfor navnet under alltid har vist seg. */
    display: block;
    height: 64px;
    background-size: cover;
    background-position: center;
    background-color: rgba(255, 255, 255, 0.04);
}
.cms-media-name {
    display: block;
    padding: 0.3rem 0.4rem;
    font-size: 0.66rem;
    color: var(--vl-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    text-align: left;
}

/* ── Feltgrupper i panelet ─────────────────────────────────── */

.cms-field { margin-bottom: 0.85rem; }
.cms-field:last-child { margin-bottom: 0; }
.cms-label {
    display: block;
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--vl-text-muted);
    margin-bottom: 0.3rem;
}
.cms-input {
    width: 100%;
    padding: 0.45rem 0.6rem;
    font-size: 0.82rem;
    background: rgba(255, 255, 255, 0.04);
    color: var(--vl-text);
    border: 1px solid var(--vl-glass-border);
    border-radius: 6px;
}
.cms-input:focus {
    outline: none;
    border-color: rgba(0, 206, 201, 0.5);
    background: rgba(255, 255, 255, 0.06);
}
.cms-input::placeholder { color: #5f6b76; }
textarea.cms-input { resize: vertical; min-height: 66px; line-height: 1.5; }
select.cms-input option { background: var(--vl-bg-card-solid); }

.cms-pair {
    display: grid;
    grid-template-columns: 1fr 1.15fr;
    gap: 0.4rem;
}

.cms-switch-line {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    font-size: 0.8rem;
    margin-bottom: 0.9rem;
}
.cms-switch-line span { flex: 1; }

.cms-switch {
    position: relative;
    width: 34px;
    height: 19px;
    flex-shrink: 0;
    border: 1px solid var(--vl-glass-border);
    background: rgba(255, 255, 255, 0.11);
    border-radius: 99px;
    padding: 0;
    transition: background 0.16s;
}
.cms-switch::after {
    content: "";
    position: absolute;
    top: 2px;
    left: 2px;
    width: 13px;
    height: 13px;
    border-radius: 50%;
    background: #8b949e;
    transition: transform 0.16s, background 0.16s;
}
.cms-switch.on {
    background: rgba(0, 184, 148, 0.35);
    border-color: rgba(0, 184, 148, 0.5);
}
.cms-switch.on::after { transform: translateX(15px); background: #00b894; }
.cms-switch:disabled { opacity: 0.4; cursor: not-allowed; }

.cms-panel-foot {
    display: flex;
    gap: 0.5rem;
    padding: 0.75rem 0.9rem;
    border-top: 1px solid var(--vl-glass-border);
    background: rgba(255, 255, 255, 0.02);
    flex-shrink: 0;
}
.cms-panel-foot .btn { flex: 1; }

/* ── Scenen ────────────────────────────────────────────────── */

.cms-stage {
    background: #070a10;
    overflow: hidden;
    min-height: 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

/* Forhaandsvisning: ekte forside i en iframe. En tegnet etterligning ville
   blitt feil i det noen endrer designet, og da er den verre enn ingen. */
.cms-preview {
    flex: 1;
    min-height: 0;
    display: flex;
    justify-content: center;
    padding: 1.1rem;
    overflow: auto;
}
.cms-preview-frame {
    width: 100%;
    max-width: 100%;
    height: 100%;
    border: 1px solid var(--vl-glass-border);
    border-radius: var(--vl-radius-sm);
    background: var(--vl-bg-dark);
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
    transition: max-width 0.2s ease;
}
.cms-preview--mobile .cms-preview-frame { max-width: 420px; }

/* Forhaandsvisning og editor er sosken som veksler med `hidden`. Begge setter
   `display` selv, saa nettleserens egen [hidden]-regel taper — den maa
   gjentas med hoyere spesifisitet. */
.cms-preview[hidden],
.cms-editor[hidden] { display: none; }

.cms-preview-empty {
    align-self: center;
    margin: auto;
    text-align: center;
    color: var(--vl-text-muted);
    font-size: 0.86rem;
    line-height: 1.7;
    max-width: 320px;
}

/* Editorflate i scenen — artikler, sider, sponsorer, innstillinger. */
.cms-editor {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: 1.6rem 1.8rem 3rem;
}
.cms-editor-inner { max-width: 1100px; margin: 0 auto; }
.cms-editor-head {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    margin-bottom: 1.4rem;
    flex-wrap: wrap;
}
.cms-editor-head h1 {
    margin: 0;
    font-size: 1.4rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    flex: 1;
    min-width: 0;
}
.cms-editor-sub {
    font-size: 0.85rem;
    color: var(--vl-text-muted);
    line-height: 1.6;
    margin: -0.9rem 0 1.4rem;
    max-width: 640px;
}

/* ── Responsivt ────────────────────────────────────────────── */

/* Under 992px er det ikke plass til skinne + panel + scene. Scenen viker:
   panelet er der arbeidet gjores, forhaandsvisningen er der for aa se
   resultatet — og den kan aapnes i ny fane med «Se paa nett». */
@media (max-width: 991.98px) {
    /* Under 992px er det ikke plass til aa dra i noe — kolonnene stables. */
    .cms-app { --cms-panel: 1fr; }
    .cms-body { grid-template-columns: var(--cms-rail) 1fr; }
    .cms-grip { display: none; }
    .cms-stage { display: none; }
    .cms-app.cms-app--stage .cms-panel { display: none; }
    .cms-app.cms-app--stage .cms-stage { display: flex; }
    .cms-editor { padding: 1.1rem 1rem 3rem; }
}

/* ── Dra og slipp ──────────────────────────────────────────── */

/* Handtaket er hele greie-ikonet, ikke raden: drar du fra teksten mister du
   muligheten til aa markere den. */
.cms-drag-handle { cursor: grab; }
.cms-drag-handle:active { cursor: grabbing; }

/* Raden som dras dempes framfor aa forsvinne — du skal fortsatt se HVA du
   flytter mens du leter etter plassen. */
.cms-dragging { opacity: 0.4; }

/* ── Bildevisning i scenen ─────────────────────────────────── */

.cms-media-full {
    display: block;
    max-width: 100%;
    max-height: 60vh;
    border-radius: var(--vl-radius-sm);
    border: 1px solid var(--vl-glass-border);
    background: rgba(255, 255, 255, 0.03);
}

/* ══════════════════════════════════════════
   DOKUMENTEDITOR — artikler og sider

   Teksten ligger på et ark, ikke i en boks. Innholdsfeltet er `.cms-content`,
   altså NØYAKTIG stilarket den publiserte artikkelen bruker — inline-editoren
   i `rich-text.js` legger ingen egen ramme rundt. Det du ser mens du skriver
   er det som kommer ut.

   Dokumentet ligger i SCENEN, med skinne og panel stående — så du bytter
   artikkel med ett klikk i lista. Editorens gamle kortstabel til høyre
   (Publisering, Metadata, Forsidebilde, Slett) er borte; feltene ligger i ett
   panel, og teksten har resten.
   ══════════════════════════════════════════ */

/* Dokumentet ligger i SCENEN, med skinne og panel stående. Første utgave
   skjulte dem og tok hele flata; det så ryddig ut og gikk tvers imot
   hensikten — uten lista må man ut og inn igjen for hvert bytte av artikkel.
   Se beslutning 185.

   Handlingene (publiser, lagre) legges i appens topbar gjennom luka
   `[data-actions]`, så det finnes én topbar og ett sted å lete etter «lagre». */

.cms-doc-host { flex: 1; min-height: 0; display: flex; }
.cms-doc-host[hidden] { display: none; }

.cms-doc {
    flex: 1;
    min-width: 0;
    display: flex;
    background: var(--vl-bg-dark);
}

/* ── Statusmerket i topbaren ───────────────────────────────────── */

/* Statusen er en ETIKETT, ikke en knapp.
   Foer hadde den bade fyll og ramme mens `.cms-btn` ved siden av bare hadde
   ramme — altsaa veide den ene tingen i raden man IKKE kan trykke paa tyngst.
   En bruker meldte det noyaktig slik: «Publiser ser ikke ut som en knapp,
   eller kanskje det er en knapp, men da ser Utkast ogsaa ut som en knapp?»
   Naa er den bar tekst med en prikk, og prikken baerer fargen. */
.cms-doc-status {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0;
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    flex-shrink: 0;
    background: none;
    border: 0;
    color: var(--vl-text-muted);
}
.cms-doc-status::before {
    content: "";
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--vl-text-muted);
    flex-shrink: 0;
}
.cms-doc-status.is-published { color: #6ee7c8; }
.cms-doc-status.is-published::before { background: #00b894; }

/* ── Ark og sidepanel ──────────────────────────────────────────── */

.cms-doc-body {
    flex: 1;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto var(--cms-doc-side);
    min-height: 0;
    min-width: 0;
}
.cms-doc--nosettings .cms-doc-body { grid-template-columns: 1fr; }
.cms-doc--nosettings .cms-doc-side,
.cms-doc--nosettings [data-grip-side] { display: none; }

.cms-doc-scroll {
    overflow-y: auto;
    min-height: 0;
    padding: 2.4rem 2rem 8rem;
}
.cms-doc-scroll::-webkit-scrollbar { width: 10px; }
.cms-doc-scroll::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.08);
    border-radius: 99px;
}

/* Arket har ingen bakgrunn, ramme eller skygge. Et «papir» med kant ville
   vært nok en boks — det er selve linjelengden som gjør flata til et ark. */
.cms-sheet {
    max-width: 720px;
    margin: 0 auto;
}

.cms-doc-title {
    font-size: 2.1rem;
    font-weight: 800;
    letter-spacing: -0.03em;
    line-height: 1.15;
    margin: 0 0 1.4rem;
    outline: none;
    color: var(--vl-text);
}

/* Tomt felt uten hint ser ut som noe som ikke virker. Samme mønster som
   resten av contenteditable-feltene — se docs/design/interaksjon.md. */
.cms-doc-title:empty::before,
.cms-rt:empty::before {
    content: attr(data-placeholder);
    color: var(--vl-text-muted);
    opacity: 0.45;
    pointer-events: none;
}

.cms-rt {
    outline: none;
    min-height: 40vh;
}
/* TinyMCE setter sin egen fokusramme på inline-elementet. Den tegner nettopp
   den boksen vi ble kvitt. */
.cms-rt.mce-edit-focus,
.cms-rt:focus,
.cms-rt:focus-visible { outline: none; }

.cms-doc-side {
    background: var(--cms-chrome-2);
    border-left: 1px solid var(--vl-glass-border);
    display: flex;
    flex-direction: column;
    min-height: 0;
}

.cms-doc-error { margin: 2rem; }

/* ── «/»-menyen ────────────────────────────────────────────────── */

.cms-slash {
    position: fixed;
    z-index: 1400;
    width: 268px;
    max-height: 320px;
    overflow-y: auto;
    padding: 0.35rem;
    border-radius: var(--vl-radius-sm);
    background: var(--cms-chrome-2);
    border: 1px solid var(--vl-glass-border);
    box-shadow: 0 18px 44px rgba(0, 0, 0, 0.55);
}
.cms-slash::-webkit-scrollbar { width: 8px; }
.cms-slash::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.1);
    border-radius: 99px;
}

.cms-slash-item {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    width: 100%;
    padding: 0.45rem 0.5rem;
    border: none;
    background: none;
    border-radius: var(--vl-radius-xs);
    color: var(--vl-text);
    text-align: left;
    font-size: 0.85rem;
}
.cms-slash-item:hover,
.cms-slash-item.active { background: rgba(0, 206, 201, 0.12); }

.cms-slash-icon {
    width: 26px;
    height: 26px;
    flex-shrink: 0;
    border-radius: 7px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.75rem;
    background: rgba(255, 255, 255, 0.06);
    color: var(--vl-text-muted);
}
.cms-slash-item.active .cms-slash-icon { color: var(--vl-accent); }

.cms-slash-body { flex: 1; min-width: 0; display: block; }
.cms-slash-label { display: block; font-weight: 500; }
.cms-slash-hint {
    display: block;
    font-size: 0.7rem;
    color: var(--vl-text-muted);
    margin-top: 0.05rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ── Smal skjerm ───────────────────────────────────────────────── */

@media (max-width: 991.98px) {
    .cms-doc-body { grid-template-columns: 1fr; }
    .cms-doc [data-grip-side] { display: none; }
    .cms-doc-side {
        border-left: none;
        border-top: 1px solid var(--vl-glass-border);
        max-height: 45vh;
    }
    .cms-doc-scroll { padding: 1.6rem 1rem 4rem; }
    .cms-doc-title { font-size: 1.6rem; }
}

/* ── Knapper i appens krom ─────────────────────────────────────
   Bootstrap-knappene er bygget for skjemaer og innholdsflater: høy, luftig,
   med gradient på den primære. Ved siden av `.cms-tool` og `.cms-rail-btn`
   — 30 og 36px, flate og dempede — ble de klumper i topbaren.

   `.cms-btn` er samme knapp i appens målestokk. Den gjelder KROMMET:
   topbaren og panelfoten. Skjemaer inne i scenen bruker fortsatt
   designsystemets vanlige knapper, for der er de innhold, ikke verktøy. */

.cms-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    height: 28px;
    padding: 0 0.65rem;
    border: 1px solid var(--vl-glass-border);
    /* Fyll, ikke `none`. En knapp med bare ramme leses som en etikett naar
       den staar ved siden av tekst — se kommentaren over `.cms-doc-status`. */
    background: rgba(255, 255, 255, 0.06);
    border-radius: 6px;
    color: var(--vl-text-muted);
    font-size: 0.76rem;
    font-weight: 600;
    white-space: nowrap;
    text-decoration: none;
    transition: all 0.14s;
}
.cms-btn:hover {
    background: var(--vl-glass);
    color: var(--vl-text);
    border-color: rgba(255, 255, 255, 0.16);
}
.cms-btn i { font-size: 0.72rem; }

/* Flat, ikke gradient. Gradienten trekker blikket til seg hele tiden, og
   «lagre» er en knapp man bruker ofte og bør slutte å legge merke til. */
.cms-btn--primary {
    background: var(--vl-primary);
    border-color: var(--vl-primary);
    color: #fff;
}
.cms-btn--primary:hover {
    background: var(--vl-primary-hover);
    border-color: var(--vl-primary-hover);
    color: #fff;
}
.cms-btn--primary:disabled { opacity: 0.55; }

.cms-btn--danger {
    color: #e07070;
    border-color: rgba(224, 112, 112, 0.35);
}
.cms-btn--danger:hover {
    background: rgba(224, 112, 112, 0.1);
    color: #f0a48f;
    border-color: rgba(224, 112, 112, 0.5);
}

.cms-panel-foot .cms-btn { flex: 1; justify-content: center; }

/* ══════════════════════════════════════════
   BLOKKEDITOREN — Editor.js på arket

   Editor.js har sitt eget lyse standardutseende og sin egen kolonnebredde.
   Her legges det om til appens: mørkt, vår typografi, og arkets bredde.

   Verdiene speiler `content.css` bevisst. Editor.js rendrer ikke `<p>` for
   avsnitt (den bruker `.ce-paragraph`), så `.cms-content p` treffer ikke —
   reglene må gjentas. Endrer du typografien i content.css, endre her også.
   ══════════════════════════════════════════ */

.cms-blocks .codex-editor { color: var(--vl-text); }

/* Arket bestemmer bredden, ikke editoren. Standard er 650px sentrert, som
   ville gitt en kolonne inne i kolonnen vår. */
.cms-blocks .ce-block__content,
.cms-blocks .ce-toolbar__content { max-width: none; }

.cms-blocks .codex-editor__redactor { padding-bottom: 12rem; }

/* ── Blokkene, som publisert ───────────────────────────────── */

.cms-blocks .ce-block { line-height: 1.7; font-size: 0.95rem; }

.cms-blocks .ce-paragraph {
    margin: 0 0 1em;
    line-height: 1.7;
}

.cms-blocks h2.ce-header {
    font-size: 1.35rem;
    margin: 1.8em 0 0.5em;
    font-weight: 700;
    color: var(--vl-text);
}
.cms-blocks h3.ce-header {
    font-size: 1.15rem;
    margin: 1.5em 0 0.5em;
    font-weight: 600;
    color: var(--vl-text);
}
.cms-blocks .ce-block:first-child h2.ce-header,
.cms-blocks .ce-block:first-child h3.ce-header { margin-top: 0; }

.cms-blocks .cdx-list {
    margin: 0 0 1em;
    padding-left: 1.5em;
}
.cms-blocks .cdx-list__item { padding: 0.1em 0; line-height: 1.7; }

.cms-blocks .cdx-quote,
.cms-blocks .cdx-quote__text {
    border-left: 3px solid var(--vl-primary);
    padding-left: 1em;
    font-style: italic;
    color: var(--vl-text-muted);
}
.cms-blocks .cdx-quote__caption {
    font-style: normal;
    font-size: 0.85rem;
    color: var(--vl-text-muted);
    padding-left: 1em;
}

.cms-blocks a { color: var(--vl-primary); text-decoration: underline; }
.cms-blocks a:hover { color: var(--vl-accent); }

.cms-blocks .ce-code__textarea,
.cms-blocks .cdx-input {
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid var(--vl-glass-border);
    border-radius: var(--vl-radius-xs);
    color: var(--vl-text);
    font-size: 0.88rem;
}
.cms-blocks .ce-code__textarea {
    font-family: ui-monospace, Menlo, Consolas, monospace;
    min-height: 120px;
}

.cms-blocks .ce-delimiter::before {
    content: "";
    display: block;
    height: 1px;
    background: var(--vl-glass-border);
    margin: 1.6em 0;
}
.cms-blocks .ce-delimiter { line-height: 0; }

.cms-blocks .tc-wrap {
    --color-border: var(--vl-glass-border);
    --color-background: rgba(255, 255, 255, 0.03);
    color: var(--vl-text);
}
.cms-blocks .tc-cell { border-color: var(--vl-glass-border); }

/* Rå HTML: markup vi ikke har en blokktype for. Merket, så det er tydelig at
   den ikke oppfører seg som resten. */
.cms-blocks .ce-rawtool__textarea {
    background: rgba(225, 112, 85, 0.06);
    border: 1px solid rgba(225, 112, 85, 0.25);
    border-radius: var(--vl-radius-xs);
    color: var(--vl-text);
    font-family: ui-monospace, Menlo, Consolas, monospace;
    font-size: 0.8rem;
}

/* ── Editorens eget krom ───────────────────────────────────── */

.cms-blocks .ce-toolbar__plus,
.cms-blocks .ce-toolbar__settings-btn {
    color: var(--vl-text-muted);
    background: transparent;
    border: 1px solid transparent;
    border-radius: 6px;
}
.cms-blocks .ce-toolbar__plus:hover,
.cms-blocks .ce-toolbar__settings-btn:hover {
    background: var(--vl-glass);
    color: var(--vl-text);
    border-color: var(--vl-glass-border);
}

.cms-blocks .ce-inline-toolbar {
    background: var(--cms-chrome-2);
    border: 1px solid var(--vl-glass-border);
    box-shadow: 0 12px 30px rgba(0, 0, 0, 0.5);
    color: var(--vl-text);
}
.cms-blocks .ce-inline-tool { color: var(--vl-text); }
.cms-blocks .ce-inline-tool:hover { background: var(--vl-glass); }

.cms-blocks .ce-block--selected .ce-block__content {
    background: rgba(0, 206, 201, 0.08);
    border-radius: var(--vl-radius-xs);
}

.cms-blocks .ce-stub {
    background: rgba(225, 112, 85, 0.08);
    border: 1px solid rgba(225, 112, 85, 0.25);
    border-radius: var(--vl-radius-xs);
    color: var(--vl-text-muted);
}

/* ── Våre egne blokker ─────────────────────────────────────── */

/* ── Bildeblokka ──
   Oppsettet vises i ARKET, ikke bare på den publiserte sida. Klassene speiler
   `.fig--*` i `content.css`; ser man ikke forskjellen der man redigerer, må
   man publisere for å sjekke. */

.cms-block-image { position: relative; margin: 0.6em 0; }
.cms-block-image.is-medium { max-width: 60%; margin-inline: auto; }
.cms-block-image.is-left,
.cms-block-image.is-right { max-width: 42%; }
.cms-block-image.is-left { float: left; margin: 0.3em 1.5em 0.8em 0; }
.cms-block-image.is-right { float: right; margin: 0.3em 0 0.8em 1.5em; }

/* Editor.js gir hver blokk sin egen rad. En float som ikke lukkes ville
   ligget over blokka under mens man redigerer. */
.cms-blocks .ce-block::after { content: ""; display: table; clear: both; }

.cms-block-image img {
    display: block;
    max-width: 100%;
    border-radius: var(--vl-radius);
}
.cms-block-image .cms-block-caption {
    margin-top: 0.5em;
    font-size: 0.85rem;
    color: var(--vl-text-muted);
    outline: none;
}
.cms-block-image .cms-block-caption:empty::before {
    content: attr(data-placeholder);
    opacity: 0.45;
}
.cms-block-change {
    position: absolute;
    top: 0.6rem;
    right: 0.6rem;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.28rem 0.6rem;
    border: none;
    border-radius: 99px;
    background: rgba(10, 14, 23, 0.82);
    color: var(--vl-text);
    font-size: 0.72rem;
    opacity: 0;
    transition: opacity 0.15s;
}
.cms-block-image:hover .cms-block-change { opacity: 1; }

/* ── Innbyggingsblokka ──
   Kort, ikke levende ramme: se toppen av `EmbedTool` i `block-editor.js`. */

.cms-block-embed { position: relative; margin: 0.6em 0; }

.cms-block-embed .cms-input { width: 100%; }
.cms-block-embed .cms-input.is-invalid { border-color: #e17055; }

.cms-block-embed-hint {
    margin: 0.45rem 0 0;
    font-size: 0.78rem;
    color: var(--vl-text-muted);
    line-height: 1.5;
}

.cms-block-embed-card {
    position: relative;
    display: flex;
    align-items: center;
    gap: 0.9rem;
    padding: 0.7rem;
    border: 1px solid var(--vl-glass-border);
    border-radius: var(--vl-radius-sm);
    background: rgba(255, 255, 255, 0.03);
}

.cms-block-embed-thumb {
    width: 116px;
    height: 66px;
    flex-shrink: 0;
    border-radius: 8px;
    overflow: hidden;
    background: rgba(255, 255, 255, 0.05);
    display: grid;
    place-items: center;
}
.cms-block-embed-thumb img { width: 100%; height: 100%; object-fit: cover; }
.cms-block-embed-mark { font-size: 1.6rem; }

.cms-block-embed-meta { min-width: 0; display: flex; flex-direction: column; gap: 0.15rem; }
.cms-block-embed-meta strong {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.86rem;
    color: var(--vl-text);
}
.cms-block-embed-meta code {
    font-size: 0.72rem;
    color: var(--vl-text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.cms-block-embed-meta span { font-size: 0.74rem; color: var(--vl-text-muted); }

/* Utsnittet kan endres uten aa hente en ny lenke — koordinatene ligger i
   blokka, og serveren regner ut boksen. */
.cms-block-embed-zoom {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    margin-top: 0.2rem;
    font-size: 0.74rem;
    color: var(--vl-text-muted);
}
.cms-block-embed-zoom select {
    height: 26px;
    padding: 0 0.4rem;
    font-size: 0.76rem;
    width: auto;
}

.cms-block-embed .cms-block-caption {
    margin-top: 0.5em;
    font-size: 0.85rem;
    color: var(--vl-text-muted);
    outline: none;
}
.cms-block-embed .cms-block-caption:empty::before {
    content: attr(data-placeholder);
    opacity: 0.45;
}
.cms-block-embed:hover .cms-block-change { opacity: 1; }

.cms-block-pick {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    width: 100%;
    padding: 2rem;
    border: 1px dashed var(--vl-glass-border);
    background: none;
    border-radius: var(--vl-radius-sm);
    color: var(--vl-text-muted);
    font-size: 0.86rem;
    transition: all 0.15s;
}
.cms-block-pick:hover {
    border-color: rgba(0, 206, 201, 0.4);
    color: var(--vl-accent);
    background: rgba(0, 206, 201, 0.05);
}

.cms-block-poll {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.9rem 1rem;
    border: 1px dashed rgba(232, 67, 147, 0.35);
    border-radius: var(--vl-radius-sm);
    background: rgba(232, 67, 147, 0.06);
    font-size: 0.86rem;
}
.cms-block-poll > i { color: #e84393; }
.cms-block-poll select { flex: 1; }

/* ── Draghåndtak mellom kolonnene ──────────────────────────────
   Et eget element mellom to kolonner, ikke en kant på den ene: en kant må
   treffes på to piksler, et håndtak på seks får man tak i. Selve streken er
   like tynn som før — det er treffområdet som er bredere. */

.cms-grip {
    width: 6px;
    cursor: col-resize;
    background: transparent;
    border: none;
    padding: 0;
    position: relative;
    flex-shrink: 0;
}
.cms-grip::before {
    content: "";
    position: absolute;
    inset: 0 2px;
    background: var(--vl-glass-border);
    transition: background 0.15s;
}
.cms-grip:hover::before,
.cms-grip:focus-visible::before { background: rgba(0, 206, 201, 0.55); }
.cms-grip:focus-visible { outline: none; }

/* Mens man drar: ingen tekstmarkering, og col-resize over hele skjermen —
   ellers bytter markøren så snart musa forlater det smale håndtaket. */
body.cms-resizing { cursor: col-resize; user-select: none; }
body.cms-resizing iframe { pointer-events: none; }

/* ══════════════════════════════════════════
   Blokkmenyen

   Den SYNLIGE flata er `.ce-popover__container`. `.ce-popover` er bare en
   posisjoneringsramme; styler man den, blir den mørk mens den hvite boksen
   står uendret oppå. Det er den fella som gjorde menyen lys første gang.

   Menyen er det man møter hver gang man setter inn noe, så den er verdt å
   gjøre ordentlig: ikonet i en tonet firkant som i resten av appen, tydelig
   markert rad, og et søkefelt som ser ut som våre andre søkefelt.
   ══════════════════════════════════════════ */

/* ── Hvor menyen aapner ────────────────────────────────────────
   Editor.js henger verktoykassa paa `.ce-toolbar__actions`, som staar
   `right: 100%` — altsaa HELT TIL VENSTRE for teksten, ute i margen. Menyen
   aapner derfra og stikker ~77px utenfor arket.

   Det synes ikke paa en bred skjerm, for da er det luft rundt arket. Men
   `.cms-doc-scroll` har `overflow-y: auto`, og CSS tillater ikke at én akse
   klipper mens den andre lar staa — `overflow-x` blir `auto` av seg selv. Saa
   paa en smal skjerm ble venstre halvdel av menyen klippet bort, og panelet
   ved siden av sto der den skulle vaert.

   `left: 100%` av handlingsknappene er noyaktig venstre tekstkant. Menyen
   aapner da innover, der det alltid er plass — arket er inntil 720px, menyen
   260. `>` holder undermenyene («Konverter til») utenfor: de posisjoneres av
   sin egen nesting-regel og skal ikke flyttes.                            */
.cms-blocks .ce-toolbar__actions > .ce-popover > .ce-popover__container,
.cms-blocks .ce-toolbar__actions > .ce-settings > .ce-popover > .ce-popover__container {
    --popover-left: 100%;
}

/* ── Feilen kom TILBAKE, og grunnen er verdt aa vite ───────────
   Regelen over hadde bare den forste linja. Editor.js skjot inn et nytt ledd
   — `.ce-settings` — mellom handlingsknappene og popoveren, og da sluttet
   `>` aa treffe. `--popover-left` falt tilbake til `0`, menyen aapnet ved
   handlingsknappenes `left: -58px`, og med 32px luft i arket ble 26px
   klippet bort av `.cms-doc-scroll`. Nøyaktig samme symptom som forste gang.

   Begge formene staar derfor oppfort. Og lærdommen, for neste
   versjonsloft av Editor.js: en `>`-kjede gjennom bibliotekets DOM er en
   regel som slutter aa virke STILLE naar biblioteket legger inn et ledd.
   Gaar du opp en versjon, aapne blokkmenyen paa en 1440px skjerm og se at
   den ikke klippes. */

/* Editor.js regner med 200px naar den plasserer undermenyer og speilvender.
   Vi tegner 260 (under). Uten dette la undermenyen seg 60px oppaa sin egen
   forelder. */
.cms-blocks .ce-popover { --width: 260px; }

.cms-blocks .ce-popover__container {
    background: var(--cms-chrome-2);
    border: 1px solid var(--vl-glass-border);
    border-radius: 12px;
    box-shadow: 0 20px 50px rgba(0, 0, 0, 0.6);
    color: var(--vl-text);
    padding: 6px;
    min-width: 260px;
}

.cms-blocks .ce-popover__items { padding: 0; }

.cms-blocks .ce-popover-item {
    padding: 6px;
    border-radius: 8px;
    gap: 0.65rem;
}

.cms-blocks .ce-popover-item__title {
    color: var(--vl-text);
    font-size: 0.86rem;
    font-weight: 600;
}
.cms-blocks .ce-popover-item__secondary-title {
    color: var(--vl-text-muted);
    font-size: 0.72rem;
}

/* Ikonet: tonet firkant, som `.stat-card i` og `.hub-tile i` ellers i appen. */
.cms-blocks .ce-popover-item__icon {
    width: 30px;
    height: 30px;
    min-width: 30px;
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid var(--vl-glass-border);
    color: var(--vl-text-muted);
    box-shadow: none;
    display: grid;
    place-items: center;
    font-size: 0.82rem;
    transition: background 0.14s, color 0.14s, border-color 0.14s;
}
.cms-blocks .ce-popover-item__icon svg { width: 15px; height: 15px; }

.cms-blocks .ce-popover-item:hover:not(.ce-popover-item--no-hover),
.cms-blocks .ce-popover-item--focused:not(.ce-popover-item--no-focus) {
    background: rgba(0, 206, 201, 0.1) !important;
}
.cms-blocks .ce-popover-item:hover .ce-popover-item__icon,
.cms-blocks .ce-popover-item--focused .ce-popover-item__icon {
    background: rgba(0, 206, 201, 0.16);
    border-color: rgba(0, 206, 201, 0.35);
    color: var(--vl-accent);
}

.cms-blocks .ce-popover-item--active { background: rgba(0, 206, 201, 0.16); }
.cms-blocks .ce-popover-item--confirmation { background: rgba(225, 112, 85, 0.16); }
.cms-blocks .ce-popover-item--confirmation .ce-popover-item__icon {
    background: rgba(225, 112, 85, 0.18);
    border-color: rgba(225, 112, 85, 0.4);
    color: #e17055;
}

.cms-blocks .ce-popover-item-separator__line {
    background: var(--vl-glass-border);
    margin: 4px 6px;
}

/* Søkefeltet skal kjennes igjen fra søkefeltene i panelene. */
.cms-blocks .ce-popover__search,
.cms-blocks .cdx-search-field {
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid var(--vl-glass-border);
    border-radius: 8px;
    color: var(--vl-text);
    margin-bottom: 6px;
    padding: 2px 8px;
}
.cms-blocks .cdx-search-field__input {
    color: var(--vl-text);
    font-size: 0.85rem;
    padding: 5px 0;
}
.cms-blocks .cdx-search-field__input::placeholder { color: #5f6b76; }
.cms-blocks .cdx-search-field__icon svg { color: var(--vl-text-muted); width: 14px; height: 14px; }

.cms-blocks .ce-popover__nothing-found-message {
    color: var(--vl-text-muted);
    font-size: 0.84rem;
    padding: 0.7rem 0.4rem;
}

/* Den flytende linja over et utvalg bruker samme popover-struktur, men skal
   være tett — der er ikonene knapper, ikke rader i en liste. */
.cms-blocks .ce-popover--inline .ce-popover__container {
    background: var(--cms-chrome-2);
    border-color: var(--vl-glass-border);
    min-width: 0;
}
.cms-blocks .ce-inline-toolbar .ce-popover__container { padding: 4px; }

/* ── Inline-linja er IKKE blokkmenyen ──────────────────────────
   Editor.js bygger den flytende linja av de SAMME klassene som blokkmenyen,
   men med lave rader: `.ce-popover-item` er 28px hoy her, mot en full rad i
   menyen. Reglene over er skrevet for menyen, og traff begge.

   Tre feil fulgte av det, meldt 21.09 med skjermbilde:

   1. `.ce-popover-item__icon` var 30x30 i en 28px rad, saa ikonet stakk 1px
      ut oppe og nede.
   2. Det ga `scrollHeight 32 > clientHeight 28` paa `.ce-popover__items`, som
      har `overflow: auto` — og et 6px rullefelt la seg inn til hoyre. Det saa
      ut som en tom knapp uten ikon.
   3. Hover malte to ulike gronne felt oppaa hverandre: `.10` paa knappen
      (42x28) og `.16` paa ikonet (30x30). Derfor «gikk den gronne utenfor
      B-boksen» — den var to bokser.

   Og linja var uensartet: fet og konverteren er `.ce-popover-item` (med
   tonet flate), mens lenke og kursiv er `.ce-inline-tool` (uten). Samme
   verktoylinje, to slags knapper. Her behandles begge likt. */

/* Ingen rulling. Rullefeltet kom av punkt 1 og er fikset under, men linja
   skal aldri kunne faa et — den har fire knapper og ingen hoyde aa rulle i. */
.cms-blocks .ce-popover--inline .ce-popover__items {
    overflow: visible;
}

/* Én hitflate per knapp, samme maal for begge slagene. */
.cms-blocks .ce-popover--inline .ce-popover-item,
.cms-blocks .ce-inline-toolbar .ce-inline-tool {
    min-height: 28px;
    padding: 0;
    border-radius: 8px;
    background: transparent;
}
.cms-blocks .ce-popover--inline .ce-popover-item__icon {
    width: 28px;
    height: 28px;
    min-width: 28px;
    border-radius: 8px;
    /* Flata males paa KNAPPEN, ikke her — ellers er vi tilbake til to bokser.
       Rammen maa vekk av samme grunn: blokkmenyen gir ikonet
       `border: 1px solid rgba(255,255,255,.08)`, og den tegnet to ruter inni
       konverteren selv etter at bakgrunnen ble gjennomsiktig. */
    background: transparent;
    border: 0;
    box-shadow: none;
}
/* 18px, ikke 15.
   Foerste utgave satte 15px paa alt for aa faa én storrelse i raden. Det var
   feil vei: `.ce-inline-tool` (lenke og kursiv) hadde 20px fra Editor.js, saa
   de KRYMPET — og samtidig mistet T, chevron og fet den tonede ruta som ga
   dem masse. Resultatet var fem ikoner det var vanskelig aa se. 18px i en
   28px knapp gir samme luft som blokkmenyen har, uten aa fylle boksen.

   Fargen er full tekstfarge, ikke `--vl-text-muted` som i blokkmenyen: der
   er ikonet et merke ved siden av en etikett som baerer betydningen, her ER
   ikonet hele knappen. */
.cms-blocks .ce-popover--inline .ce-popover-item__icon svg,
.cms-blocks .ce-inline-toolbar .ce-inline-tool svg {
    width: 18px;
    height: 18px;
}
.cms-blocks .ce-popover--inline .ce-popover-item__icon,
.cms-blocks .ce-inline-toolbar .ce-inline-tool {
    color: var(--vl-text);
}

/* Konverteren beholder en hvilende flate: den AAPNER noe, og «T» med en
   chevron ved siden av uten ramme leses som to knapper.
   `:has()` faller bort i en nettleser som ikke kan den — da staar den bar
   som de andre, som er en akseptabel degradering og ikke en odelagt linje. */
.cms-blocks .ce-popover--inline .ce-popover-item:has(.ce-popover-item__icon--chevron-right) {
    background: rgba(255, 255, 255, 0.05);
    padding: 0 2px;
}

/* Hover og aktiv males ÉN gang, paa knappen. */
.cms-blocks .ce-popover--inline .ce-popover-item:hover:not(.ce-popover-item--no-hover),
.cms-blocks .ce-inline-toolbar .ce-inline-tool:hover {
    background: var(--vl-glass);
}
.cms-blocks .ce-popover--inline .ce-popover-item:hover .ce-popover-item__icon,
.cms-blocks .ce-popover--inline .ce-popover-item--focused .ce-popover-item__icon,
.cms-blocks .ce-popover--inline .ce-popover-item--active .ce-popover-item__icon {
    background: transparent;
}
.cms-blocks .ce-popover--inline .ce-popover-item--active,
.cms-blocks .ce-inline-toolbar .ce-inline-tool--active {
    background: rgba(0, 206, 201, 0.16);
    color: var(--vl-primary);
}

/* Lenkefeltet: Editor.js setter `background:#F8F8F8` og INGEN `color`, saa
   det arvet `color: var(--vl-text)` fra linja over — lys tekst paa nesten
   hvitt. Det eneste synlige var plassholderen, som Editor.js farger selv.
   Soesknene (`.cdx-input`, `.cdx-search-field__input`) var alt rettet; dette
   feltet ble glemt. Samme behandling som dem. */
.cms-blocks .ce-inline-tool-input {
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid var(--vl-glass-border);
    border-radius: var(--vl-radius-xs);
    color: var(--vl-text);
    font-size: 0.85rem;
    margin-top: 4px;
    padding: 6px 8px;
}
.cms-blocks .ce-inline-tool-input::placeholder { color: #5f6b76; }

/* Editor.js setter `.codex-editor ::selection { background-color: #d4ecff }`
   og INGEN `color`. Den vinner paa spesifisitet over vaar egen `::selection`
   i `base.css`, saa markert tekst i editoren ble naer-hvit paa lyseblaa —
   man saa ikke hva man markerte. Samme feil som base.css alt hadde rettet
   for resten av appen; den gjaldt bare ikke her.

   Verdiene kommer fra de samme variablene, saa de to stedene ikke kan drive
   fra hverandre. */
.cms-blocks .codex-editor ::selection {
    background: var(--vl-selection-bg);
    color: var(--vl-selection-fg);
}
.cms-blocks .ce-inline-tool-input:focus {
    border-color: var(--vl-primary);
    outline: none;
}

/* ── Repeater: lister man kan legge til og fjerne i ────────────
   Kortene under «Om LAN-et» og tallene i stripa. Alternativet var ett
   tekstfelt med JSON i — som ville krevd at redaktøren skriver syntaks, og
   at én glemt komma tømmer seksjonen. */

.cms-repeat { display: flex; flex-direction: column; gap: 0.5rem; }

.cms-repeat-row {
    display: flex;
    align-items: flex-start;
    gap: 0.4rem;
    padding: 0.5rem;
    border: 1px solid var(--vl-glass-border);
    border-radius: var(--vl-radius-xs);
    background: rgba(255, 255, 255, 0.02);
}
.cms-repeat-grip {
    color: var(--vl-text-muted);
    opacity: 0.3;
    font-size: 0.7rem;
    margin-top: 0.5rem;
    flex-shrink: 0;
}
.cms-repeat-fields {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}
.cms-repeat-fields .cms-input { flex: 1 1 100%; min-width: 0; }

.cms-repeat-del {
    width: 24px;
    height: 24px;
    flex-shrink: 0;
    margin-top: 0.35rem;
    border: none;
    background: none;
    border-radius: 5px;
    font-size: 0.72rem;
    color: var(--vl-text-muted);
    opacity: 0.5;
    transition: all 0.14s;
}
.cms-repeat-del:hover { opacity: 1; color: #e07070; background: rgba(224, 112, 112, 0.1); }

/* ══════════════════════════════════════════════════════════════════════
   Galleri-editoren — scenen i CMS-et
   ══════════════════════════════════════════════════════════════════════

   Rutenettet som VISES kommer fra `.gallery-*` i components.css. Det som
   ligger her er redigeringen: dropzone, kø, forsidemerke og feltene rundt.
   Skillet er med vilje — endrer noen rutestørrelsen på nettstedet, skal
   forhåndsvisningen følge med av seg selv. */

/* Miniatyr i stedet for ikon i en panelrad. En liste over album der alle
   radene har samme ikon sier ingenting om hva som ligger i hvilket. */
.cms-row-icon--img {
    background-size: cover;
    background-position: center;
    background-color: var(--vl-bg-elevated);
}

.gal-bar {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin-bottom: 1.25rem;
}

.gal-bar-spacer { flex: 1; }

.gal-count { margin: 0; white-space: nowrap; }

/* Synlighet som tre knapper og ikke et nedtrekk: valget er det viktigste på
   flaten, og et nedtrekk skjuler to av tre alternativer bak et klikk. */
.gal-vis {
    display: inline-flex;
    border: 1px solid var(--vl-glass-border);
    border-radius: var(--vl-radius-sm);
    overflow: hidden;
}

.gal-vis-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.7rem;
    background: none;
    border: none;
    border-right: 1px solid var(--vl-glass-border);
    color: var(--vl-text-muted);
    font-size: 0.8rem;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}

.gal-vis-btn:last-child { border-right: none; }
.gal-vis-btn:hover { background: var(--vl-glass); color: var(--vl-text); }

.gal-vis-btn.active {
    background: color-mix(in srgb, var(--vl-primary) 20%, transparent);
    color: var(--vl-text);
}

.gal-fields {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    margin-bottom: 1.25rem;
}

.gal-field-row {
    display: flex;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.gal-field-row .gal-field { flex: 1 1 200px; }

.gal-field { display: block; }

.gal-field > span {
    display: block;
    margin-bottom: 0.25rem;
    font-size: 0.75rem;
    color: var(--vl-text-muted);
}

.gal-field input,
.gal-field textarea {
    width: 100%;
    padding: 0.4rem 0.6rem;
    background: var(--vl-glass);
    border: 1px solid var(--vl-glass-border);
    border-radius: var(--vl-radius-sm);
    color: var(--vl-text);
    font-size: 0.85rem;
    resize: vertical;
}

.gal-field input:focus,
.gal-field textarea:focus {
    outline: none;
    border-color: var(--vl-primary);
}

.gal-field-note {
    display: block;
    margin-top: 0.25rem;
    font-size: 0.72rem;
    color: var(--vl-text-muted);
}

/* Dropområdet ligger RUNDT rutenettet, ikke over det. Med 40 bilder i albumet
   er en stripe i toppen noe man må sikte på for å legge til det 41.

   I hvile er den usynlig — en stiplet ramme rundt hele albumet hele tiden ville
   vært et kart over noe man sjelden gjør. Rammen kommer først når en fil
   faktisk henger over flata. */
.gal-drop-area {
    position: relative;
    border: 1px dashed transparent;
    border-radius: var(--vl-radius);
    padding: 0.5rem;
    margin: 0 -0.5rem;
    transition: border-color 0.15s, background 0.15s;
}

.gal-drop-area--over {
    border-color: var(--vl-primary);
    background: color-mix(in srgb, var(--vl-primary) 8%, transparent);
}

/* Teksten vises bare når albumet er tomt. Med bilder i er rutenettet selv
   målet, og en instruksjon under 40 ruter er en instruksjon ingen leser. */
.gal-drop-hint { display: none; }

.gal-drop-area--empty {
    border-color: var(--vl-glass-border);
    padding: 2.5rem 1rem;
}

.gal-drop-area--empty .gal-drop-hint {
    display: block;
    text-align: center;
}

.gal-drop-hint i {
    font-size: 2.5rem;
    color: var(--vl-primary);
    /* Auto-marger: FontAwesome gir ikonet fast bredde, så en blokk uten dem
       står til venstre. Se design/komponenter.md. */
    margin: 0 auto 0.75rem;
    display: block;
}

.gal-drop-hint p { margin-bottom: 0.5rem; }

.gal-drop-hint small {
    color: var(--vl-text-muted);
    font-size: 0.8rem;
}

/* «velg filer» midt i setningen. En knapp og ikke en lenke — den navigerer
   ikke noe sted, den åpner en filvelger. */
.gal-drop-link {
    background: none;
    border: none;
    padding: 0;
    font: inherit;
    color: var(--vl-primary);
    text-decoration: underline;
    cursor: pointer;
}

.gal-drop-link:hover { color: var(--vl-primary-hover); }

/* Mens en fil henger over albumet skal rutene ikke ta imot pekeren — ellers
   kan slippet lande på en enkelt rute i stedet for på området. */
.gal-drop-area--over .gal-item { pointer-events: none; }

/* Køen. Hver fil får sin egen rad, og en rad som feilet blir STÅENDE — en
   toast som forsvinner etter fire sekunder er feil sted for «disse tre filene
   kom ikke med», for man trenger å lese navnene. */
.gal-queue {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    margin-bottom: 1.25rem;
    font-size: 0.8rem;
}

.gal-q {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.3rem 0.6rem;
    background: var(--vl-glass);
    border-radius: var(--vl-radius-xs);
}

.gal-q-name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--vl-text-muted);
}

.gal-q-state {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    color: var(--vl-text-muted);
    text-align: right;
}

.gal-q-state--ok { color: #00b894; }
.gal-q-state--error { color: #e17055; }

.gal-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 0.6rem;
}

.gal-item {
    margin: 0;
    border-radius: var(--vl-radius-sm);
    background: var(--vl-glass);
    border: 1px solid transparent;
    overflow: hidden;
    cursor: grab;
}

.gal-item--cover { border-color: var(--vl-primary); }

.gal-item--dragging { opacity: 0.4; }

.gal-thumb {
    position: relative;
    aspect-ratio: 1;
    background-size: cover;
    background-position: center;
    background-color: var(--vl-bg-elevated);
    cursor: zoom-in;
}

.gal-thumb--blank { background: repeating-linear-gradient(45deg, var(--vl-bg-elevated), var(--vl-bg-elevated) 8px, var(--vl-bg-tertiary) 8px, var(--vl-bg-tertiary) 16px); }

.gal-badge {
    position: absolute;
    top: 5px;
    left: 5px;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 1px 6px;
    border-radius: 4px;
    background: var(--vl-primary);
    color: #fff;
    font-size: 0.65rem;
}

.gal-item figcaption {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.25rem 0.3rem 0.3rem;
}

.gal-caption {
    flex: 1;
    min-width: 0;
    padding: 0.15rem 0.25rem;
    background: none;
    border: none;
    border-bottom: 1px solid transparent;
    color: var(--vl-text);
    font-size: 0.75rem;
}

.gal-caption::placeholder { color: var(--vl-text-muted); opacity: 0.6; }

.gal-caption:focus {
    outline: none;
    border-bottom-color: var(--vl-primary);
}

.gal-item-acts {
    display: flex;
    gap: 0.1rem;
    flex-shrink: 0;
}

.gal-act {
    padding: 0.2rem 0.3rem;
    background: none;
    border: none;
    color: var(--vl-text-muted);
    font-size: 0.75rem;
    cursor: pointer;
    border-radius: var(--vl-radius-xs);
}

.gal-act:hover { background: var(--vl-glass); color: var(--vl-text); }
.gal-act--danger:hover { color: #e17055; }

.gal-hint,
.gal-blank { margin-top: 0.75rem; }

/* Sletting av hele albumet står nederst, med luft over. Det er den ene
   ugjenkallelige handlingen på flaten, og den skal ikke ligge ved siden av
   noe man gjør ofte. */
.gal-danger {
    margin-top: 3rem;
    padding-top: 1rem;
    border-top: 1px solid var(--vl-glass-border);
}

/* Merknaden under galleri-velgeren i blokkeditoren: «dette er et utkast —
   leserne ser det ikke ennå». */
.cms-block-note {
    display: block;
    margin-top: 0.35rem;
    font-size: 0.75rem;
    color: #e6a23c;
}

@media (max-width: 575.98px) {
    .gal-grid { grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); }
}

/* ── «Bilde og tekst» i editoren ──────────────────────────────────────
   Speiler `.cms-split` i content.css, så arket viser resultatet mens man
   skriver. Vekslingen vises IKKE her: i editoren er hver blokk en rad man
   redigerer, og en rad som hopper fra side til side mens man skriver ville
   gjort det vanskelig å se hva man holder på med. Sida veksler ved
   publisering. */

.cms-block-split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.25rem;
    align-items: start;
    margin: 1em 0;
    padding: 0.9rem;
    border: 1px dashed var(--vl-glass-border);
    border-radius: var(--vl-radius-xs);
}
.cms-block-split.is-right { direction: rtl; }
.cms-block-split.is-right > * { direction: ltr; }

.cms-block-split-media { position: relative; min-height: 7rem; }
.cms-block-split-media img {
    display: block;
    width: 100%;
    height: 100%;
    max-height: 12rem;
    object-fit: cover;
    border-radius: var(--vl-radius-xs);
}

.cms-block-split-title {
    font-family: var(--lp-display, inherit);
    font-size: 1.3rem;
    font-weight: 600;
    line-height: 1.2;
    margin-bottom: 0.4rem;
}
.cms-block-split-text { color: var(--vl-text-muted); font-size: 0.92rem; }

.cms-block-split-link { display: flex; gap: 0.4rem; margin-top: 0.7rem; }
.cms-block-split-link input {
    flex: 1;
    min-width: 0;
    padding: 0.3rem 0.5rem;
    font-size: 0.75rem;
    color: var(--vl-text);
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid var(--vl-glass-border);
    border-radius: var(--vl-radius-xs);
}

/* Plassholder for tomme contenteditable-felter. Uten den ser en tom rad ut
   som en blokk som ikke virker. */
.cms-block-split-title:empty::before,
.cms-block-split-text:empty::before {
    content: attr(data-placeholder);
    color: var(--vl-text-muted);
    opacity: 0.55;
}

@media (max-width: 60rem) {
    .cms-block-split { grid-template-columns: 1fr; }
}

/* Hintet under kildefeltet.
   Staar alltid, ikke bare naar feltet er tomt: plassholderen forsvinner i det
   adressen er satt, og da er det ingenting som forteller at feltet ogsaa tar
   video. Se `SplitMediaTool.draw()`. */
.cms-block-split-hint {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.3rem;
    margin: 0.35rem 0 0;
    font-size: 0.68rem;
    line-height: 1.45;
    color: var(--vl-text-muted);
}
.cms-block-split-hint i { color: var(--vl-accent); font-size: 0.72rem; }
.cms-block-split-hint code {
    font-size: 0.92em;
    padding: 0 0.2rem;
    border-radius: 3px;
    background: rgba(255, 255, 255, 0.06);
}

/* Kildefeltet under forhandsvisningen: adressen, og en knapp til biblioteket. */
.cms-block-split-kilde { display: flex; gap: 0.35rem; margin-top: 0.45rem; }
.cms-block-split-kilde input {
    flex: 1;
    min-width: 0;
    padding: 0.28rem 0.45rem;
    font-size: 0.72rem;
    color: var(--vl-text);
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid var(--vl-glass-border);
    border-radius: var(--vl-radius-xs);
}
.cms-block-split-bibl {
    flex-shrink: 0;
    width: 26px;
    border: 1px solid var(--vl-glass-border);
    background: rgba(255, 255, 255, 0.04);
    border-radius: var(--vl-radius-xs);
    color: var(--vl-text-muted);
    font-size: 0.72rem;
}
.cms-block-split-bibl:hover { color: var(--vl-text); border-color: rgba(0, 206, 201, 0.45); }

.cms-block-split-media video {
    display: block;
    width: 100%;
    max-height: 12rem;
    object-fit: cover;
    border-radius: var(--vl-radius-xs);
}

/* En innbygd video vises ikke i editoren — iframe-en ville lastet YouTube inn i
   redigeringsflaten. En merkelapp sier hva som kommer. */
.cms-block-split-embed {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    min-height: 7rem;
    border: 1px dashed var(--vl-glass-border);
    border-radius: var(--vl-radius-xs);
    color: var(--vl-text-muted);
    font-size: 0.78rem;
}
.cms-block-split-embed i { font-size: 1.5rem; color: #ff0033; }

/* Video i mediebiblioteket og i bildevelgeren.
   Ruta er alltid et bilde — plakaten. Merket sier at det er en video, saa ingen
   trenger aa klikke for aa finne det ut. */

/* Panelets rute er en <span> med bakgrunnsbilde og ingen barn, saa merket maa
   vaere et pseudo-element. Unicode og ikke ikonfonten: den installerte
   FontAwesome er versjon 7, og en `content: "\f04b"` mot «Font Awesome 6»
   ville gitt en tom rute uten feilmelding. */
.cms-media-item--video .cms-media-thumb { position: relative; }
.cms-media-item--video .cms-media-thumb::after {
    content: "\25B6";
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1rem;
    color: #fff;
    text-shadow: 0 2px 8px rgba(0, 0, 0, 0.85);
    background: rgba(0, 0, 0, 0.22);
    pointer-events: none;
}

/* Velgerens rute har et ekte <i>-element inni, saa her trengs bare overlegget. */
.imgpicker-thumb { position: relative; }
.imgpicker-thumb-play {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.1rem;
    color: #fff;
    text-shadow: 0 2px 8px rgba(0, 0, 0, 0.85);
    background: rgba(0, 0, 0, 0.22);
    pointer-events: none;
}

/* Ingen plakat — en kodek nettleseren ikke kunne dekode. Da et ikon, ikke en
   tom rute som ser ut som en feil. */
.imgpicker-thumb-tom {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    min-height: 64px;
    color: var(--vl-text-muted);
    background: rgba(255, 255, 255, 0.04);
}

video.cms-media-full { width: 100%; border-radius: var(--vl-radius-xs); background: #000; }
